📄 tapeio.c
字号:
tapetype_t *tape; char *conf_tapetype; conf_tapetype = getconf_str(CNF_TAPETYPE); if (!conf_tapetype || strlen(conf_tapetype) == 0) return MAX_TAPE_BLOCK_KB; tape = lookup_tapetype(conf_tapetype); if (!tape) return MAX_TAPE_BLOCK_KB; return tapetype_get_readblocksize(tape);}#ifdef TEST/* * The following test program may be used to exercise I/O patterns through * the tapeio interface. Commands may either be on the command line or * read from stdin (e.g. for a test suite). */#include "token.h"#if USE_RAND/* If the C library does not define random(), try to use rand() by defining USE_RAND, but then make sure you are not using hardware compression, because the low-order bits of rand() may not be that random... :-( */#define random() rand()#define srandom(seed) srand(seed)#endifstatic char *pgm;static voiddo_help(void){ g_fprintf(stderr, _(" ?|help\n")); g_fprintf(stderr, _(" open [\"file\"|$TAPE [\"mode\":O_RDONLY]]\n")); g_fprintf(stderr, _(" read [\"records\":\"all\"]\n")); g_fprintf(stderr, _(" write [\"records\":1] [\"file#\":\"+\"] [\"record#\":\"+\"] [\"host\"] [\"disk\"] [\"level\"]\n")); g_fprintf(stderr, _(" eof|weof [\"count\":1]\n")); g_fprintf(stderr, _(" fsf [\"count\":1]\n")); g_fprintf(stderr, _(" rewind\n")); g_fprintf(stderr, _(" unload\n"));}static voidusage(void){ g_fprintf(stderr, _("usage: %s [-c cmd [args] [%% cmd [args] ...]]\n"), pgm); do_help();}#define TEST_BLOCKSIZE (32 * 1024)#define MAX_TOKENS 10extern int optind;static char *token_area[MAX_TOKENS + 1];static char **token;static int token_count;static int fd = -1;static off_t current_file = (off_t)0;static off_t current_record = (off_t)0;static int have_length = 0;static int length = (off_t)0;static int show_timestamp = 0;char write_buf[TEST_BLOCKSIZE];static voiddo_open(void){ mode_t mode; char *file; if(token_count < 2 || (token_count >= 2 && strcmp(token[1], "$TAPE") == 0)) { if((file = getenv("TAPE")) == NULL) { g_fprintf(stderr, _("tape_open: no file name and $TAPE not set\n")); return; } } else { file = token[1]; } if(token_count > 2) { mode = atoi(token[2]); } else { mode = O_RDONLY; } g_fprintf(stderr, _("tapefd_open(\"%s\", %d): "), file, mode); if((fd = tape_open(file, mode, 0644)) < 0) { perror(""); } else { g_fprintf(stderr, _("%d (OK)\n"), fd); if(have_length) { tapefd_setinfo_length(fd, length); } }}static voiddo_close(void){ int result; g_fprintf(stderr, _("tapefd_close(): ")); if((result = tapefd_close(fd)) < 0) { perror(""); } else { g_fprintf(stderr, _("%d (OK)\n"), result); }}static voiddo_read(void){ ssize_t result; off_t count = (off_t)0; int have_count = 0; char buf[SIZEOF(write_buf)]; int *p; off_t i; char *s; time_t then; struct tm *tm; if(token_count > 1 && strcmp(token[1], "all") != 0) { count = OFF_T_ATOI(token[1]); have_count = 1; } p = (int *)buf; for(i = 0; (! have_count) || (i < count); i++) { g_fprintf(stderr, _("tapefd_read(%lld): "), (long long)i); if((result = tapefd_read(fd, buf, SIZEOF(buf))) < 0) { perror(""); break; } else if(result == 0) { g_fprintf(stderr, _("%zd (EOF)\n"), result); /* * If we were not given a count, EOF breaks the loop, otherwise * we keep trying (to test read after EOF handling). */ if(! have_count) { break; } } else { if(result == (ssize_t)sizeof(buf)) { s = _("OK"); } else { s = _("short read"); } /* * If the amount read is really short, we may refer to junk * when displaying the record data, but things are pretty * well screwed up at this point anyway so it is not worth * the effort to deal with. */ g_fprintf(stderr, _("%zd (%s): file %d: record %d"), result, s, p[0], p[1]); if(show_timestamp) { then = p[2]; tm = localtime(&then); g_fprintf(stderr, ": %04d/%02d/%02d %02d:%02d:%02d\n", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); } fputc('\n', stderr); } }}static voiddo_write(void){ int result; off_t count; off_t *p; off_t i; char *s; time_t now; struct tm *tm; if(token_count > 1) { count = OFF_T_ATOI(token[1]); } else { count = (off_t)1; } if(token_count > 2 && strcmp(token[2], "+") != 0) { current_file = OFF_T_ATOI(token[2]); } if(token_count > 3 && strcmp(token[3], "+") != 0) { current_record = OFF_T_ATOI(token[3]); } if(token_count > 4 && token[4][0] != '\0') { tapefd_setinfo_host(fd, token[4]); } if(token_count > 5 && token[5][0] != '\0') { tapefd_setinfo_disk(fd, token[5]); } if(token_count > 6 && token[6][0] != '\0') { tapefd_setinfo_level(fd, atoi(token[6])); } p = (off_t *)write_buf; time(&now); p[2] = now; tm = localtime(&now); for(i = 0; i < count; i++, (current_record += (off_t)1)) { p[0] = current_file; p[1] = current_record; g_fprintf(stderr, _("tapefd_write(%lld): "), i); if((result = tapefd_write(fd, write_buf, SIZEOF(write_buf))) < 0) { perror(""); break; } else { if(result == (ssize_t)sizeof(write_buf)) { s = _("OK"); } else { s = _("short write"); } g_fprintf(stderr, _("%d (%s): file %lld: record %lld"), result, s, p[0], p[1]); if(show_timestamp) { g_fprintf(stderr, ": %04d/%02d/%02d %02d:%02d:%02d\n", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); } fputc('\n', stderr); } }}static voiddo_fsf(void){ int result; off_t count; if(token_count > 1) { count = OFF_T_ATOI(token[1]); } else { count = (off_t)1; } g_fprintf(stderr, _("tapefd_fsf(%lld): "), (long long)count); if((result = tapefd_fsf(fd, count)) < 0) { perror(""); } else { g_fprintf(stderr, _("%d (OK)\n"), result); current_file += count; current_record = (off_t)0; }}static voiddo_weof(void){ int result; off_t count; if(token_count > 1) { count = OFF_T_ATOI(token[1]); } else { count = (off_t)1; } g_fprintf(stderr, _("tapefd_weof(%lld): "), count); if((result = tapefd_weof(fd, count)) < 0) { perror(""); } else { g_fprintf(stderr, _("%d (OK)\n"), result); current_file += count; current_record = (off_t)0; }}static voiddo_rewind(void){ int result; g_fprintf(stderr, _("tapefd_rewind(): ")); if((result = tapefd_rewind(fd)) < 0) { perror(""); } else { g_fprintf(stderr, _("%d (OK)\n"), result); current_file = (off_t)0; current_record = (off_t)0; }}static voiddo_unload(void){ int result; g_fprintf(stderr, _("tapefd_unload(): ")); if((result = tapefd_unload(fd)) < 0) { perror(""); } else { g_fprintf(stderr, _("%d (OK)\n"), result); current_file = (off_t)-1; current_record = (off_t)-1; }}struct cmd { char *name; int min_chars; void (*func)(void);} cmd[] = { { "?", 0, do_help }, { "help", 0, do_help }, { "eof", 0, do_weof }, { "weof", 0, do_weof }, { "fsf", 0, do_fsf }, { "rewind", 0, do_rewind }, { "offline", 0, do_unload }, { "open", 0, do_open }, { "close", 0, do_close }, { "read", 0, do_read }, { "write", 0, do_write }, { NULL, 0, NULL }};intmain( int argc, char ** argv){ int ch; int cmdline = 0; char *line = NULL; char *s; int i; int j; time_t now; /* * 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"); /* Don't die when child closes pipe */ signal(SIGPIPE, SIG_IGN); if((pgm = strrchr(argv[0], '/')) != NULL) { pgm++; } else { pgm = argv[0]; } /* * Compute the minimum abbreviation for each command. */ for(i = 0; cmd[i].name; i++) { cmd[i].min_chars = 1; while(1) { for(j = 0; cmd[j].name; j++) { if(i == j) { continue; } if(0 == strncmp(cmd[i].name, cmd[j].name, cmd[i].min_chars)) { break; } } if(0 == cmd[j].name) { break; } cmd[i].min_chars++; } } /* * Process the command line flags. */ while((ch = getopt(argc, argv, "hcl:t")) != EOF) { switch (ch) { case 'c': cmdline = 1; break; case 'l': have_length = 1; length = OFF_T_ATOI(optarg); j = strlen(optarg); if(j > 0) { switch(optarg[j-1] ) { case 'k': break; case 'b': length /= (off_t)2; break; case 'M': length *= (off_t)1024; break; default: length /= (off_t)1024; break; } } else { length /= (off_t)1024; } break; case 't': show_timestamp = 1; break; case 'h': default: usage(); return 1; } } /* * Initialize the write buffer. */ time(&now); srandom(now); for(j = 0; j < (int)SIZEOF(write_buf); j++) { write_buf[j] = (char)random(); } /* * Do the tests. */ token = token_area + 1; token_area[0] = ""; /* if cmdline */ while(1) { if(cmdline) { for(token_count = 1; token_count < (int)(SIZEOF(token_area) / SIZEOF(token_area[0])) && optind < argc; token_count++, optind++) { if(strcmp(argv[optind], "%") == 0) { optind++; break; } token_area[token_count] = argv[optind]; } token_count--; if(token_count == 0 && optind >= argc) { break; } } else { if((line = areads(0)) == NULL) { break; } if((s = strchr(line, '#')) != NULL) { *s = '\0'; } s = line + strlen(line) - 1; while(s >= line && isspace(*s)) { *s-- = '\0'; } token_count = split(line, token_area, SIZEOF(token_area) / SIZEOF(token_area[0]), " "); } amfree(line); /* * Truncate tokens at first comment indicator, then test for * empty command. */ for(i = 0; i < token_count; i++) { if(token[i][0] == '#') { token_count = i; break; } } if(token_count <= 0) { continue; /* blank/comment input line */ } /* * Find the command to run, the do it. */ j = strlen(token[0]); for(i = 0; cmd[i].name; i++) { if(strncmp(cmd[i].name, token[0], j) == 0 && j >= cmd[i].min_chars) { break; } } if(cmd[i].name == NULL) { g_fprintf(stderr, _("%s: unknown command: %s\n"), pgm, token[0]); exit(1); } (*cmd[i].func)(); } return 0;}#endif /* TEST */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -