rdt.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 2,753 行 · 第 1/5 页
C
2,753 行
if(ret < 0) { error("cannot read tape.", 0, 0); if(oflag) error("Incorrect tape density???", 0, 0); return(ndone); } else inbuf[ret] = 0; /* eofok is always equal to NO with the -O option */ if(! oflag && ret) { labelid[0] = 0; sscanf(inbuf, "%4s", labelid); if(! strcmp(labelid, "EOF1")) eofok = YES; else if(! strcmp(labelid, "HDR1")) eofok = NO; } if(! ret && ! eofok) { if(ndone + 1 == nwanted) return(++ndone); else { /* * set eofok equal to YES because EOF1 * label will be skipped over by ioctl. * i.e., assume next label is EOF. */ if(! oflag) eofok = YES; ndone++; } } else if(! ret && eofok) { /* * if a second eof is found (eot) * back up two file and stop. */ mt.mt_count = 2; mt.mt_op = MTBSF; if(ioctl(fileno(magtfp), MTIOCTOP, &mt) < 0) errorexit("cannot backskip tape", 0, 0); break; } } mt.mt_count = 1; mt.mt_op = MTFSF; if(ioctl(fileno(magtfp), MTIOCTOP, &mt) < 0) errorexit("cannot skip tape", 0, 0); return(ndone); }/*--------------------------------------------------------------------- * * XTRACTF - extracts next LTF file to disk. It returns the * the character count of the extracted file or -1 if * error. Xtractf must return -1 upon error because a * zero-length file will have a return value of 0. * *-------------------------------------------------------------------*/longxtractf(path, s, charcnt, name)char *path; /* pathname only */char *s; /* file name */long charcnt; /* character count (if applicable) */char *name; /* extracted filename (if different) */ { FILE *xfp; char xname[MAXLEN]; int nbytes, count; long num = 0L; char *p; if(*s == 0) {/* We are not sure if versions of a file come off the tape correctly as of yet...rjg*/ if(use_versnum) sprintf(xname, "%s%s.%d", path, l_filename, (l_gen-1) * 100 + l_genver+1); else { sprintf(xname, "%s%s", path, l_filename); /* remove '.' at end of string */ remove_c(xname); } } else { strcpy(name, s); strcpy(xname, s); } for(p = xname, count = 0; xname[count]; count++) { if(xname[count] == '/') p = &xname[count]; } if(p != xname) p++; if(stat(xname, &inode) >= 0) { if(warning_only) ;#if 0 Ray Glaser and Tom Tresvik decided that since no other unix utility warns you (which may be alarming to field service) about overwriting files, then 'rdt' should not either. It may be a wrong descision, but it's ours to make and this is our choice. error("%s already exists. Overwriting.", xname, 0);#endif 0 else { fprintf(stderr, "%s: %s already exists. Overwrite (y/n)? ", progname, xname); gets(labelbuf); if(labelbuf[0] != 'y') { char dummy[256]; fprintf(stderr, "Alternative pathname ('return' to quit processing this file)? "); gets(dummy); if(dummy[0] == 0) { skip(3); return((long)(-1)); } else { if(strlen(dummy) > MAXLEN - 1) { error("%s: file name too long", dummy, 0); skip(3); return((long)(-1)); } else { strcpy(xname, dummy); strcpy(name, xname); } } } } } /* Open the destination file on the disk. */ if((xfp = fopen(xname, "w")) == NULL) { checkdir(path); if((xfp = fopen(xname, "w")) == NULL) { error("cannot create %s", xname, 0); skip(3); return((long)(-1)); } } /* Skip over the tape mark between the last HDRn & the start of real file data. */ skip(1); while((nbytes = read(fileno(magtfp), p=inbuf, l_blklen)) > 0) { if(l_recformat == FIXED) { /* * test if charcnt == 0L because some old tapes * with SYSNAME won't have a character count. * Foreign tapes won't have a charcnt either. * CHARCNT comes from HDR4 in orginal LTF. */ if(charcnt == 0L) { char *pp; pp = p; pp += nbytes; while(*--pp == PAD); pp++; num += (long)(pp - p); if(write(fileno(xfp), p, pp - p) < 0) errorexit("cannot write on filesystem", 0, 0); } else /* If charcnt > nbytes, we read less than we should have according to HDR4 (in org LTF). */ if(charcnt >= (long)nbytes) { /* We get here if more bytes were read in than HDR4 says we should have (in org LTF). */ if(write(fileno(xfp), inbuf, nbytes) < 0) errorexit("cannot write on filesystem", 0, 0); charcnt -= (long)nbytes; num += (long)nbytes; } else if(charcnt > 0L) { if(write(fileno(xfp), inbuf, (int)charcnt) < 0) errorexit("cannot write on filesystem", 0, 0); num += charcnt; /* Set charcnt equal to -1 so that we don't try to get any more of this apparent garbage from the tape. */ charcnt = (long)(-1); } } else { while(p < &inbuf[nbytes] && (count = getlen(p)) >= 0) { if(l_recformat == VARIABLE) { p += 4; /* What are we skipping ? */ if(count == 0) { putc('\n', xfp); /* Why are we tacking this on ?*/ fflush(xfp); num++; continue; } } else if(l_recformat == FUF) { p += 4; if(! fufcnv(p, count, xfp)) { error("fuf record too long. %s not dumped", xname, 0); skip(3); return((long)(-1)); } p += count; continue; } else /* l_recformat == DD */ count += 4; if(write(fileno(xfp), p, count) < 0) errorexit("cannot write on filesystem", 0, 0); p += count; num += (long)count; if(l_recformat == VARIABLE) { putc('\n', xfp); fflush(xfp); num++; } } } } fclose(xfp); return(num); /* Go do next, if any, file.*/ }/*end XTRACTF*//*--------------------------------------------------------------------- * * GETLEN - returns the length of the next variable-length record * on an extract from tape. * *-------------------------------------------------------------------*/getlen(s)char *s; { int val, i; if(*s == PAD) return(-1); val = 0; for(i=0; i < 4; i++) val = 10 * val + (*s++ - '0'); return(val-4); }static int days[2][13] = { { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } };static char *months[] = { 0, "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };/*--------------------------------------------------------------------- * * DATE_YEAR - fills the string 'sdate' with the appropriate * month, day, and year. * *-------------------------------------------------------------------*/date_year(sdate, date)char *sdate, *date; { int leap, i, year, yearday; sscanf(date, "%2d%3d", &year, &yearday); i = 1900 + year; leap = i%4 == 0 && i%100 != 0 || i%400 == 0; for(i= 0; yearday > days[leap][i]; i++) yearday -= days[leap][i]; sprintf(sdate, "%s %2d %4d", months[i], yearday, year + 1900); }/*--------------------------------------------------------------------- * * DATE_TIME - fills the string 'sdate' with the appropriate * month, day, and modification time. * *-------------------------------------------------------------------*/date_time(sdate, sec)char *sdate;long *sec; { int thisyear; long rettime; struct tm *localtime(), *ltime; rettime = time(NULL); ltime = localtime(&rettime); thisyear = ltime->tm_year; ltime = localtime(sec); if(ltime->tm_year == thisyear) sprintf(sdate, "%s %2d %02d:%02d", months[ltime->tm_mon + 1], ltime->tm_mday, ltime->tm_hour, ltime->tm_min); else sprintf(sdate, "%s %2d %4d", months[ltime->tm_mon + 1], ltime->tm_mday, ltime->tm_year + 1900); }/*--------------------------------------------------------------------- * * CREATETP - initializes the tape and calls 'proc_args' to * process the file arguments. * *-------------------------------------------------------------------*/createtp(num, args, iflag, inputfile)int num; /* number of arguments to process */char *args[]; /* array of pointers to arguments */int iflag; /* -I option */char *inputfile; { char line[512]; /* line from passwd file */ char owner[14]; /* login name of owner */ int j; /* * NOTE: createtp does not check whether you are overwriting * something on tape. */ if((magtfp = fopen(magtdev, "w")) == NULL) errorexit("cannot write on tape. Offline or needs write ring???", 0, 0); /* Attempt to get the user's login name from the password file. NOTE: this fails... You always end up with the last name in the /etc/passwd file. */ getpw(getuid() & 0377, line); for(j=0; j < 14 && line[j] && line[j] != ':'; j++) owner[j] = line[j]; if(line[j] == ':') owner[j] = 0; upper(owner);/* Write the VOLUME label (VOL1) .. See VMS note 2-6 of VMS MTAACP documentation for important information.*/ sprintf(labelbuf, "VOL1%-6.6s %26.26s%-14.14s%28.28s3", label, spaces, owner, spaces); write(fileno(magtfp), labelbuf, LABSIZE); fsecno = fseqno = 1; proc_args(num, args, iflag, inputfile); }/*end CREATETP*//*--------------------------------------------------------------------- * * PROCESS - processes the given file and its label sets. * ?? Which means ? *-------------------------------------------------------------------*/process(longname, shortname, type)char *longname; /* contains the pathname and file name */char *shortname; /* file name only */int type; /* type of file */ { /* dummy is a buffer for sprintf and is also a copy of longname */ static char dummy[MAXLEN]; static char ldummy[MAXLEN*2]; FILE *fp; struct filestat fstat; struct alinkbuf *lp; int linkflag = NO; /* * YES if the file is linked to * a file that has already been * appended. */ int found = 0; /* a head link is not on tape yet */ int version = 1; /* version number (1 is default) */ int length; /* length of a line of text file */ long append(); long charcnt = 0L; /* * character count. This is * just a precaution in case * the last character of a * binary file is the same as * the padding character. */ int max; /* maximum line length */ char pathname[77]; char *l, *l2; char line[512]; /* buffer for reading text files */ struct tm *localtime(); struct tm *ltime; register int j; pathname[0] = 0; l = dummy; l2 = longname; for(j=0; (*l++ = *l2++) && j < MAXLEN; j++); /* Copy longname into dummy */ if(j >= MAXLEN) { error("%s: file name too long", longname, 0); return; }/* Put a good string copy of the longname in filestat buffer.*/ strcpy(fstat.f_src, dummy);/* Now, separate the base file name from the pathname+filename.*/ l = dummy; l += strlen(dummy); while(--l != dummy) if(*l == '/') break; if(*l == '/') { char *s1, *s2; s1 = pathname; s2 = dummy; *l = 0; /* The following will eventually hit the trailing zero and stop... */ for(j=0; (*s1++ = *s2++) && j < 76; j++); if(j >= 76) { error("%s: pathname too long", longname, 0); return; } strcat(pathname, "/"); if(! make_num(++l, fstat.f_dest, fstat.f_version)) return; } else /* We come here when there is apparantly only a filename. i.e. Not /path/name form.. */ { if(! make_num(l, fstat.f_dest, fstat.f_version)) return; } if(strlen(fstat.f_dest) > 17) { error("%s: destination file name too long", longname, 0); return; } /* * Must open shortname (rather than longname) * because we might be in a subdirectory. WHY ??? */ if((fp = fopen(shortname, "r")) == NULL) { error("cannot open %s", fstat.f_src, 0); return; } if(stat(shortname, &inode) < 0) { error("cannot stat %s", fstat.f_src, 0); return; } ltime = localtime(&inode.st_mtime); block = 0L; max = 0; if(type == TEXT) { /* find length of longest line */ while(fgets(line, 512, fp) != NULL) { length = strlen(line); if(line[length-1] == '\n') length--; if(length > max) max = length; if(max + 4 > reclength) break; } if(max + 4 > reclength) { error("line too long", 0, 0); if(warning_only) { if(reclength == MAXRECSIZE) { /* Would be nice to say why */ error("cannot append as a text file. %s not dumped.", fstat.f_src, 0); error("Try appending as a BINARY file (with the -b flag).", 0, 0); } else error("record length too small. %s not dumped.", fstat.f_src, 0); return; } if(type == TEXT && reclength == MAXRECSIZE) { error("cannot append as a text file. %s not dumped.", fstat.f_src, 0); error("Try appending as a BINARY file (with the -b flag).", 0, 0); return;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?