* University of Maryland at College Park
*/
/*
- * $Id: tapetype.c,v 1.3.2.3.4.3.2.9 2003/11/28 12:34:52 martinea Exp $
+ * $Id: tapetype.c,v 1.27 2006/08/24 01:57:16 paddy_s Exp $
*
* tests a tape in a given tape unit and prints a tapetype entry for
* it. */
#include "amanda.h"
+#include "conffile.h"
#include "tapeio.h"
static char *tapedev;
static int fd;
-static int blockkb = 32;
-static int blocksize;
+static size_t blockkb = 32;
+static size_t blocksize;
static char *randombytes = (char *) NULL;
#define srandom(seed) srand(seed)
#endif
-static void allocrandombytes() {
- int i, j, page_size;
- char *p;
+static char *getrandombytes(void);
+static int writeblock(int fd);
+static off_t writeblocks(int fd, off_t nblks);
+static void allocrandombytes(void);
+static void do_pass0(off_t size, time_t *seconds, int dorewind);
+static void do_pass(off_t size, off_t *blocks, off_t *files, time_t *seconds);
+static void help(void);
+static void initnotrandombytes(void);
+static void initrandombytes(void);
+static void show_progress(off_t *blocks, off_t *files);
+static void usage(void);
+
+int main(int argc, char **argv);
+
+static void
+allocrandombytes(void)
+{
+ size_t i;
+ size_t j;
+ size_t page_size;
+ char *p;
if (randombytes == (char *)NULL) {
#if defined(HAVE_GETPAGESIZE)
- page_size = getpagesize();
+ page_size = (size_t)getpagesize();
#else
- page_size = 1024;
+ page_size = (size_t)1024;
#endif
j = (NBLOCKS * blocksize) + page_size; /* buffer space plus one page */
j = am_round(j, page_size); /* even number of pages */
- p = alloc(j);
- i = (p - (char *)0) & (page_size - 1); /* page boundary offset */
+ p = (char *)alloc(j);
+ i = (size_t)(p - (char *)0) & (page_size - 1);/* page boundary offset */
if(i != 0) {
- randombytes = p + page_size - i; /* round up to page boundary */
+ randombytes = p + (page_size - i); /* round up to page boundary */
} else {
randombytes = p; /* alloc already on boundary */
}
}
}
-static void initnotrandombytes() {
- int i, j;
+static void
+initnotrandombytes(void)
+{
+ unsigned long i;
+ unsigned long j;
char *p;
allocrandombytes();
- j =NBLOCKS * blocksize;
+ j = NBLOCKS * blocksize;
p = randombytes;
for(i=0; i < j; ++i) {
*p++ = (char) (i % 256);
}
}
-static void initrandombytes() {
- int i, j;
+static void
+initrandombytes(void)
+{
+ unsigned long i, j;
char *p;
allocrandombytes();
}
}
-static char *getrandombytes() {
- static int counter = 0;
+static char *
+getrandombytes(void)
+{
+ static unsigned long counter = 0;
return randombytes + ((counter++ % NBLOCKS) * blocksize);
}
static int short_write;
-int writeblock(fd)
- int fd;
+static int
+writeblock(
+ int fd)
{
- size_t w;
+ ssize_t w;
- if ((w = tapefd_write(fd, getrandombytes(), blocksize)) == blocksize) {
+ if ((w = tapefd_write(fd, getrandombytes(), blocksize)) == (ssize_t)blocksize) {
return 1;
}
if (w >= 0) {
/* returns number of blocks actually written */
-size_t writeblocks(int fd, size_t nblks)
+static off_t
+writeblocks(
+ int fd,
+ off_t nblks)
{
- size_t blks = 0;
+ off_t blks = (off_t)0;
while (blks < nblks) {
if (! writeblock(fd)) {
- return 0;
+ return (off_t)0;
}
- blks++;
+ blks += (off_t)1;
}
return blks;
}
-void usage()
+static void
+usage(void)
{
- fputs("usage: ", stderr);
+ fputs(_("usage: "), stderr);
fputs(sProgName, stderr);
- fputs(" -h", stderr);
- fputs(" [-c]", stderr);
- fputs(" [-b blocksize]", stderr);
- fputs(" [-e estsize]", stderr);
- fputs(" [-f tapedev]", stderr);
- fputs(" [-t typename]", stderr);
+ fputs(_(" [-h]"), stderr);
+ fputs(_(" [-c]"), stderr);
+ fputs(_(" [-o]"), stderr);
+ fputs(_(" [-b blocksize]"), stderr);
+ fputs(_(" -e estsize"), stderr);
+ fputs(_(" [-f tapedev]"), stderr);
+ fputs(_(" [-t typename]"), stderr);
fputc('\n', stderr);
}
-void help()
+static void
+help(void)
{
usage();
- fputs("\
- -h display this message\n\
- -c run hardware compression detection test only\n\
- -b blocksize record block size (default: 32k)\n\
- -e estsize estimated tape size (default: 1g == 1024m)\n\
- -f tapedev tape device name (default: $TAPE)\n\
- -t typename tapetype name (default: unknown-tapetype)\n\
-\n\
-Note: disable hardware compression when running this program.\n\
-", stderr);
+ fputs(_("-h display this message\n"
+ "-c run hardware compression detection test only\n"
+ "-o overwrite amanda tape\n"
+ "-b blocksize record block size (default: 32k)\n"
+ "-e estsize estimated tape size (No default!)\n"
+ "-f tapedev tape device name (default: $TAPE)\n"
+ "-t typename tapetype name (default: unknown-tapetype)\n"
+ "\n"
+ "Note: disable hardware compression when running this program.\n"),
+ stderr);
}
int do_tty;
-void show_progress(blocks, files)
- size_t *blocks, *files;
+static void
+show_progress(
+ off_t * blocks,
+ off_t * files)
{
- fprintf(stderr, "wrote %ld %dKb block%s in %ld file%s",
- (long)*blocks, blockkb, (*blocks == 1) ? "" : "s",
- (long)*files, (*files == 1) ? "" : "s");
+ g_fprintf(stderr,
+ plural(_("wrote %lld %zu Kb block"),
+ _("wrote %lld %zu Kb blocks"),
+ *blocks),
+ (long long)*blocks,
+ blockkb);
+ g_fprintf(stderr,
+ plural(_(" in %lld file"),
+ _(" in %lld files"),
+ *files),
+ (long long)*files);
}
-void do_pass(size, blocks, files, seconds)
- size_t size, *blocks, *files;
- time_t *seconds;
+static void
+do_pass(
+ off_t size,
+ off_t * blocks,
+ off_t * files,
+ time_t * seconds)
{
- size_t blks;
+ off_t blks;
time_t start, end;
int save_errno;
if (tapefd_rewind(fd) == -1) {
- fprintf(stderr, "%s: could not rewind %s: %s\n",
+ g_fprintf(stderr, _("%s: could not rewind %s: %s\n"),
+ sProgName, tapedev, strerror(errno));
+ exit(1);
+ }
+ if (((-1 == tapefd_close(fd)) ||
+ (-1 == (fd = tape_open(tapedev, O_RDWR))))) {
+ g_fprintf(stderr, "%s: could not re-open %s: %s\n",
sProgName, tapedev, strerror(errno));
exit(1);
}
while(1) {
- if ((blks = writeblocks(fd, size)) <= 0 || tapefd_weof(fd, 1) != 0)
+ if ((blks = writeblocks(fd, size)) <= (off_t)0 || tapefd_weof(fd, (off_t)1) != 0)
break;
*blocks += blks;
- (*files)++;
+ *files += (off_t)1;
if(do_tty) {
putc('\r', stderr);
show_progress(blocks, files);
time(&end);
- if (*blocks == 0) {
- fprintf(stderr, "%s: could not write any data in this pass: %s\n",
- sProgName, short_write ? "short write" : strerror(save_errno));
+ if (*blocks == (off_t)0) {
+ g_fprintf(stderr, _("%s: could not write any data in this pass: %s\n"),
+ sProgName, short_write ? _("short write") : strerror(save_errno));
exit(1);
}
putc('\r', stderr);
}
show_progress(blocks, files);
- fprintf(stderr, " in %ld second%s (%s)\n",
- (long)*seconds, ((long)*seconds == 1) ? "" : "s",
- short_write ? "short write" : strerror(save_errno));
+ g_fprintf(stderr,
+ plural(_(" in %jd second (%s)\n"),
+ _(" in %jd seconds (%s)\n"),
+ *seconds),
+ (intmax_t)*seconds,
+ short_write ? _("short write") : strerror(save_errno));
}
-void do_pass0(size, seconds, dorewind)
- size_t size;
- time_t *seconds;
- int dorewind;
+static void
+do_pass0(
+ off_t size,
+ time_t * seconds,
+ int dorewind)
{
- size_t blks;
+ off_t blks;
time_t start, end;
int save_errno;
if (dorewind && tapefd_rewind(fd) == -1) {
- fprintf(stderr, "%s: could not rewind %s: %s\n",
+ g_fprintf(stderr, _("%s: could not rewind %s: %s\n"),
sProgName, tapedev, strerror(errno));
exit(1);
}
+ if (dorewind &&
+ ((-1 == tapefd_close(fd)) ||
+ (-1 == (fd = tape_open(tapedev, O_RDWR))))) {
+ g_fprintf(stderr, "%s: could not re-open %s: %s\n",
+ sProgName, tapedev, strerror(errno));
+ exit(1);
+ }
+
+
time(&start);
blks = writeblocks(fd, size);
- tapefd_weof(fd, 1);
+ tapefd_weof(fd, (off_t)1);
save_errno = errno;
time(&end);
- if (blks <= 0) {
- fprintf(stderr, "%s: could not write any data in this pass: %s\n",
- sProgName, short_write ? "short write" : strerror(save_errno));
+ if (blks <= (off_t)0) {
+ g_fprintf(stderr, _("%s: could not write any data in this pass: %s\n"),
+ sProgName, short_write ? _("short write") : strerror(save_errno));
exit(1);
}
}
-int main(argc, argv)
- int argc;
- char *argv[];
+int
+main(
+ int argc,
+ char ** argv)
{
- size_t pass1blocks = 0;
- size_t pass2blocks = 0;
+ off_t pass1blocks = (off_t)0;
+ off_t pass2blocks = (off_t)0;
time_t pass1time;
time_t pass2time;
time_t timediff;
- size_t pass1files = 0;
- size_t pass2files = 0;
- size_t estsize;
- size_t pass0size;
- size_t pass1size;
- size_t pass2size;
- size_t blockdiff;
- size_t filediff;
- long filemark;
- long speed;
- size_t size;
+ off_t pass1files = (off_t)0;
+ off_t pass2files = (off_t)0;
+ off_t estsize;
+ off_t pass0size;
+ off_t pass1size;
+ off_t pass2size;
+ off_t blockdiff;
+ off_t filediff;
+ size_t filemark;
+ unsigned long speed;
+ off_t size;
char *sizeunits;
int ch;
- char *suffix;
+ 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;
sProgName++;
}
- estsize = 1024 * 1024; /* assume 1 GByte for now */
+ /* 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:hc")) != EOF) {
+ while ((ch = getopt(argc, argv, "b:e:f:t:hco")) != EOF) {
switch (ch) {
case 'b':
- blockkb = strtol(optarg, &suffix, 0);
- if (*suffix == '\0' || *suffix == 'k' || *suffix == 'K') {
- } else if (*suffix == 'm' || *suffix == 'M') {
- blockkb *= 1024;
- } else if (*suffix == 'g' || *suffix == 'G') {
- blockkb *= 1024 * 1024;
- } else {
- fprintf(stderr, "%s: unknown size suffix \'%c\'\n", sProgName, *suffix);
- return 1;
+ 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 = strtol(optarg, &suffix, 0);
- if (*suffix == '\0' || *suffix == 'k' || *suffix == 'K') {
- } else if (*suffix == 'm' || *suffix == 'M') {
- estsize *= 1024;
- } else if (*suffix == 'g' || *suffix == 'G') {
- estsize *= 1024 * 1024;
- } else {
- fprintf(stderr, "%s: unknown size suffix \'%c\'\n", sProgName, *suffix);
- return 1;
+ 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:
- fprintf(stderr, "%s: unknown option \'%c\'\n", sProgName, ch);
- /* fall through to ... */
+ g_fprintf(stderr, _("%s: unknown option \'%c\'\n"), sProgName, ch);
+ /*FALLTHROUGH*/
+
case '?':
usage();
return 1;
- break;
}
}
blocksize = blockkb * 1024;
- if (tapedev == NULL || optind < argc) {
+ if (tapedev == NULL) {
+ g_fprintf(stderr, _("%s: No tapedev specified\n"), sProgName);
+ usage();
+ return 1;
+ }
+ if (optind < argc) {
usage();
return 1;
}
- fd = tape_open(tapedev, O_RDWR);
+ 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) {
- fprintf(stderr, "%s: could not open %s: %s\n",
+ g_fprintf(stderr, _("%s: could not open %s: %s\n"),
sProgName, tapedev, strerror(errno));
return 1;
}
initnotrandombytes();
- fprintf(stderr, "Estimate phase 1...");
- pass0size = 8 * 1024 / blockkb;
+ g_fprintf(stderr, _("Estimate phase 1..."));
+ pass0size = (off_t)(8 * 1024 / blockkb);
pass1time = 0;
pass2time = 0;
/*
*/
while (pass1time < 25 || ((100*(pass2time-pass1time)/pass2time) >= 10) ) {
if (pass1time != 0) {
- int i = pass1time;
+ time_t t = pass1time;
do {
- pass0size *= 2;
- i *= 2;
- } while (i < 25);
+ pass0size *= (off_t)2;
+ t *= 2;
+ } while (t < 25);
}
/*
* first a dummy pass to rewind, stop, start and
*/
do_pass0(pass0size, &pass2time, 1);
do_pass0(pass0size, &pass1time, 0);
- if (pass0size >= 10 * 1024 * 1024) {
- fprintf(stderr,
- "\rTape device is too fast to detect hardware compression...\n");
+ 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 */
}
}
- fprintf(stderr, "\rWriting %d Mbyte compresseable data: %d sec\n",
- (int)(blockkb * pass0size / 1024), (int)pass1time);
+ 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(now);
+ srandom((unsigned)now);
initrandombytes();
- fprintf(stderr, "Estimate phase 2...");
+ g_fprintf(stderr, _("Estimate phase 2..."));
do_pass0(pass0size, &pass2time, 1); /* rewind and get drive streaming */
do_pass0(pass0size, &pass2time, 0);
- fprintf(stderr, "\rWriting %d Mbyte uncompresseable data: %d sec\n",
- (int)(blockkb * pass0size / 1024), (int)pass2time);
+ 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
timediff = pass2time - pass1time;
}
if (((100 * timediff) / pass2time) >= 20) { /* 20% faster? */
- fprintf(stderr, "WARNING: Tape drive has hardware compression enabled\n");
+ 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
*/
- fprintf(stderr, "Estimated time to write 2 * %d Mbyte: ", estsize / 1024);
- pass1time = (time_t)(2.0 * pass2time * estsize / (1.0 * pass0size * blockkb));
+ 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 */
- fprintf(stderr, "%ld sec = ", pass1time);
- fprintf(stderr, "%ld h %ld min\n", (pass1time/3600), ((pass1time%3600) / 60));
+ 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 = (estsize * 0.01) / blockkb; /* 1% of estimate */
- if(pass1size <= 0) {
- pass1size = 2; /* strange end case */
+ 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 / 2;
+ pass2size = pass1size / (off_t)2;
do_pass(pass2size, &pass2blocks, &pass2files, &pass2time);
/*
* 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 = 0;
+ blockdiff = (off_t)0;
} else {
blockdiff = pass1blocks - pass2blocks;
}
/*
* This should not happen, but just in case ...
*/
- filediff = 1;
+ filediff = (off_t)1;
} else {
filediff = pass2files - pass1files;
}
- filemark = blockdiff * blockkb / filediff;
+ filemark = (size_t)((blockdiff * (off_t)blockkb) / filediff);
/*
* Compute the length as the average of the two pass sizes including
* tape marks.
*/
- size = ((pass1blocks * blockkb + filemark * pass1files)
- + (pass2blocks * blockkb + filemark * pass2files)) / 2;
- if (size >= 1024 * 1024 * 1000) {
- size /= 1024 * 1024;
+ 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 >= 1024 * 1000) {
- size /= 1024;
+ } 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 = (((double)pass1blocks * blockkb / pass1time)
- + ((double)pass2blocks * blockkb / pass2time)) / 2;
+ speed = (unsigned long)((((double)pass1blocks
+ * (double)blockkb / (double)pass1time)
+ + ((double)pass2blocks * (double)blockkb / (double)pass2time)) / 2.0);
/*
* Dump the tapetype.
*/
- printf("define tapetype %s {\n", typename);
- printf(" comment \"just produced by tapetype prog (hardware compression %s)\"\n",
- hwcompr ? "on" : "off");
- printf(" length %ld %s\n", (long)size, sizeunits);
- printf(" filemark %ld kbytes\n", filemark);
- printf(" speed %ld kps\n", speed);
- printf("}\n");
+ 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) {
- fprintf(stderr, "%s: could not rewind %s: %s\n",
+ g_fprintf(stderr, _("%s: could not rewind %s: %s\n"),
sProgName, tapedev, strerror(errno));
return 1;
}
if (tapefd_close(fd) == -1) {
- fprintf(stderr, "%s: could not close %s: %s\n",
+ g_fprintf(stderr, _("%s: could not close %s: %s\n"),
sProgName, tapedev, strerror(errno));
return 1;
}