⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tapetype.c

📁 开源备份软件源码 AMANDA, the Advanced Maryland Automatic Network Disk Archiver, is a backup system that a
💻 C
📖 第 1 页 / 共 2 页
字号:
  off_t blockdiff;  off_t filediff;  size_t filemark;  unsigned long speed;  off_t size;  char *sizeunits;  int ch;  char *suffix = NULL;  char *typename;  time_t now;  int hwcompr = 0;  int comprtstonly = 0;  int overwrite_label = 0;  int is_labeled = 0;  char *result;  char *datestamp = NULL;  char *label = NULL;  /*   * Configure program for internationalization:   *   1) Only set the message locale for now.   *   2) Set textdomain for all amanda related programs to "amanda"   *      We don't want to be forced to support dozens of message catalogs.   */    setlocale(LC_MESSAGES, "C");  textdomain("amanda");   config_init(0, NULL);  if ((sProgName = strrchr(*argv, '/')) == NULL) {    sProgName = *argv;  } else {    sProgName++;  }  /* Don't die when child closes pipe */  signal(SIGPIPE, SIG_IGN);  estsize = (off_t)0;  tapedev = getenv("TAPE");  typename = "unknown-tapetype";  while ((ch = getopt(argc, argv, "b:e:f:t:hco")) != EOF) {    switch (ch) {    case 'b':      blockkb = (size_t)strtol(optarg, &suffix, 0);      if (!(*suffix == '\0' || *suffix == 'k' || *suffix == 'K')) {	if (*suffix == 'm' || *suffix == 'M') {	  blockkb *= 1024;	} else if (*suffix == 'g' || *suffix == 'G') {	  blockkb *= (1024 * 1024);	} else {	  g_fprintf(stderr, _("%s: unknown size suffix \'%c\'\n"),		  sProgName, *suffix);	  return 1;	}      }      break;    case 'e':      estsize = OFF_T_STRTOL(optarg, &suffix, 0);      if (!(*suffix == '\0' || *suffix == 'k' || *suffix == 'K')) {	if (*suffix == 'm' || *suffix == 'M') {	  estsize *= (off_t)1024;	} else if (*suffix == 'g' || *suffix == 'G') {	  estsize *= (off_t)(1024 * 1024);	} else {	  g_fprintf(stderr, _("%s: unknown size suffix \'%c\'\n"),		  sProgName, *suffix);	  return 1;	}      }      break;    case 'f':      tapedev = stralloc(optarg);      break;    case 't':      typename = stralloc(optarg);      break;    case 'c':      comprtstonly = 1;      break;    case 'h':      help();      return 1;    case 'o':      overwrite_label=1;      break;    default:      g_fprintf(stderr, _("%s: unknown option \'%c\'\n"), sProgName, ch);      /*FALLTHROUGH*/    case '?':      usage();      return 1;    }  }  blocksize = blockkb * 1024;  if (tapedev == NULL) {    g_fprintf(stderr, _("%s: No tapedev specified\n"), sProgName);    usage();    return 1;  }  if (optind < argc) {    usage();    return 1;  }  if (estsize == 0) {    if (comprtstonly) {      estsize = (off_t)(1024 * 1024);		/* assume 1 GByte for now */    } else {      g_fprintf(stderr, _("%s: please specify estimated tape capacity (e.g. '-e 4g')\n"), sProgName);      usage();      return 1;    }  }/* verifier tape */  fd = tape_open(tapedev, O_RDONLY, 0);  if (fd == -1) {    g_fprintf(stderr, _("%s: could not open %s: %s\n"),	    sProgName, tapedev, strerror(errno));    return 1;  }  if((result = tapefd_rdlabel(fd, &datestamp, &label)) == NULL) {    is_labeled = 1;  }  else if (strcmp(result,_("not an amanda tape")) == 0) {    is_labeled = 2;  }  if(tapefd_rewind(fd) == -1) {    g_fprintf(stderr, _("%s: could not rewind %s: %s\n"),	    sProgName, tapedev, strerror(errno));    tapefd_close(fd);    return 1;  }  tapefd_close(fd);  if(is_labeled == 1 && overwrite_label == 0) {    g_fprintf(stderr, _("%s: The tape is an amanda tape, use -o to overwrite the tape\n"),	    sProgName);    return 1;  }  else if(is_labeled == 2 && overwrite_label == 0) {    g_fprintf(stderr, _("%s: The tape is already used, use -o to overwrite the tape\n"),	    sProgName);    return 1;  }  fd = tape_open(tapedev, O_RDWR, 0);  if (fd == -1) {    g_fprintf(stderr, _("%s: could not open %s: %s\n"),	    sProgName, tapedev, strerror(errno));    return 1;  }  do_tty = isatty(fileno(stderr));  /*   * Estimate pass: write twice a small file, once with compressable   * data and once with uncompressable data.   * The theory is that if the drive is in hardware compression mode   * we notice a significant difference in writing speed between the two   * (at least if we can provide data as fast the tape streams).   */  initnotrandombytes();  g_fprintf(stderr, _("Estimate phase 1..."));  pass0size = (off_t)(8 * 1024 / blockkb);  pass1time = 0;  pass2time = 0;  /*   * To get accurate results, we should write enough data   * so that rewind/start/stop time is small compared to   * the total time; let's take 10%.   * The timer has a 1 sec granularity, so the test   * should take at least 10 seconds to measure a   * difference with 10% accuracy; let's take 25 seconds.   */   while (pass1time < 25 || ((100*(pass2time-pass1time)/pass2time) >= 10) ) {    if (pass1time != 0) {      time_t t = pass1time;      do {	  pass0size *= (off_t)2;	  t *= 2;      } while (t < 25);    }    /*     * first a dummy pass to rewind, stop, start and     * get drive streaming, then do the real timing     */    do_pass0(pass0size, &pass2time, 1);    do_pass0(pass0size, &pass1time, 0);    if (pass0size >= (off_t)(10 * 1024 * 1024)) {      g_fprintf(stderr, "\r");      g_fprintf(stderr,	_("Tape device is too fast to detect hardware compression...\n"));      break;	/* avoid loops if tape is superfast or broken */    }  }  g_fprintf(stderr, "\r");  g_fprintf(stderr,	_("Writing %lld Mbyte   compresseable data:  %jd sec\n"),	(long long)((off_t)blockkb * pass0size / (off_t)1024),	(intmax_t)pass1time);  /*   * now generate uncompressable data and try again   */  time(&now);  srandom((unsigned)now);  initrandombytes();  g_fprintf(stderr, _("Estimate phase 2..."));  do_pass0(pass0size, &pass2time, 1);	/* rewind and get drive streaming */  do_pass0(pass0size, &pass2time, 0);  g_fprintf(stderr, "\r");  g_fprintf(stderr, _("Writing %lld Mbyte uncompresseable data: %jd sec\n"),	(long long)((off_t)blockkb * pass0size / (off_t)1024),	(intmax_t)pass2time);  /*   * Compute the time difference between writing the compressable and   * uncompressable data.  If it differs more than 20%, then warn   * user that the tape drive has probably hardware compression enabled.   */  if (pass1time > pass2time) {    /*     * Strange!  I would expect writing compresseable data to be     * much faster (or about equal, if hardware compression is disabled)     */    timediff = 0;  } else {    timediff = pass2time - pass1time;  }  if (((100 * timediff) / pass2time) >= 20) {	/* 20% faster? */    g_fprintf(stderr, _("WARNING: Tape drive has hardware compression enabled\n"));    hwcompr = 1;  }  /*   * Inform about estimated time needed to run the remaining of this program   */  g_fprintf(stderr, _("Estimated time to write 2 * %lu Mbyte: "), (unsigned long) (estsize / (off_t)1024));  pass1time = (time_t)(2.0 * (double)pass2time * (double)estsize /		(1.0 * (double)pass0size * (double)blockkb));	/* avoid overflow and underflow by doing math in floating point */  g_fprintf(stderr, _("%jd sec = %jd h %jd min\n"),	  (intmax_t)pass1time,	  (intmax_t)(pass1time/(time_t)3600),	  (intmax_t)((pass1time%(time_t)3600) / (time_t)60));  if (comprtstonly) {	exit(hwcompr);  }  /*   * Do pass 1 -- write files that are 1% of the estimated size until error.   */  pass1size = (off_t)(((double)estsize * 0.01) / (double)blockkb); /* 1% of estimate */  if(pass1size <= (off_t)0) {    pass1size = (off_t)2;				/* strange end case */  }  do_pass(pass1size, &pass1blocks, &pass1files, &pass1time);  /*   * Do pass 2 -- write smaller files until error.   */  pass2size = pass1size / (off_t)2;  do_pass(pass2size, &pass2blocks, &pass2files, &pass2time);  /*   * Compute the size of a filemark as the difference in data written   * between pass 1 and pass 2 divided by the difference in number of   * file marks written between pass 1 and pass 2.  Note that we have   * to be careful in case size_t is unsigned (i.e. do not subtract   * things and then check for less than zero).   */  if (pass1blocks <= pass2blocks) {    /*     * If tape marks take up space, there should be fewer blocks in pass     * 2 than in pass 1 since we wrote twice as many tape marks.  But     * odd things happen, so make sure the result does not go negative.     */    blockdiff = (off_t)0;  } else {    blockdiff = pass1blocks - pass2blocks;  }  if (pass2files <= pass1files) {    /*     * This should not happen, but just in case ...     */    filediff = (off_t)1;  } else {    filediff = pass2files - pass1files;  }  filemark = (size_t)((blockdiff * (off_t)blockkb) / filediff);  /*   * Compute the length as the average of the two pass sizes including   * tape marks.   */  size = ((pass1blocks * (off_t)blockkb + (off_t)filemark * pass1files)           + (pass2blocks * (off_t)blockkb + (off_t)filemark * pass2files))	   / (off_t)2;  if (size >= (off_t)(1024 * 1024 * 1000)) {    size /= (off_t)(1024 * 1024);    sizeunits = "gbytes";  } else if (size >= (off_t)(1024 * 1000)) {    size /= (off_t)1024;    sizeunits = "mbytes";  } else {    sizeunits = "kbytes";  }  /*   * Compute the speed as the average of the two passes.   */  speed = (unsigned long)((((double)pass1blocks	   * (double)blockkb / (double)pass1time)           + ((double)pass2blocks * (double)blockkb / (double)pass2time)) / 2.0);  /*   * Dump the tapetype.   */  g_printf("define tapetype %s {\n", typename);  g_printf(_("    comment \"just produced by tapetype prog (hardware compression %s)\"\n"),	hwcompr ? _("on") : _("off"));  g_printf("    length %lld %s\n", (long long)size, sizeunits);  g_printf("    filemark %zu kbytes\n", filemark);  g_printf("    speed %lu kps\n", speed);  g_printf("}\n");  if (tapefd_rewind(fd) == -1) {    g_fprintf(stderr, _("%s: could not rewind %s: %s\n"),	    sProgName, tapedev, strerror(errno));    return 1;  }  if (tapefd_close(fd) == -1) {    g_fprintf(stderr, _("%s: could not close %s: %s\n"),	    sProgName, tapedev, strerror(errno));    return 1;  }  return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -