rdt.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 2,753 行 · 第 1/5 页
C
2,753 行
struct mtop mt; mt.mt_count = 1; mt.mt_op = MTBSF; if(ioctl(fileno(magtfp), MTIOCTOP, &mt) < 0) errorexit("cannot backskip tape", 0, 0); error("cannot read HDR3 from tape", 0, 0); } else {#ifdef DEBUG fprintf(stdout,"\n_tp: DECFILE11A seen_\n"); pr_label();#endif sscanf(labelbuf, "%3s%1d%4x%4x", l_labelid, &l_labelno, &num1, &num2); if(strcmp(l_labelid, "HDR") || l_labelno != 3) { errorexit("%s%d: illegal label format (HDR3)", l_labelid, l_labelno); } if(num1 == MAXREC4 && num2 == 2) l_recformat = FUF; } } /* Expanded version number (combines l_gen and l_genver) */ verno_exp = (l_gen-1) * 100 + l_genver + 1; itoa(verno_exp, verno_exp_a); sprintf(name, "%s%s", pathname, l_filename);/* The next question says: We have been told to position the tape but have not (as yet) reached the position.*/ if(pos == -1) { /* for additional interpretation */ char posname2[MAXLEN]; posname2[0] = 0; if(! use_versnum) { int length; length = strlen(posname); /* * skip '.' at end of posname. second dot * must be 2, 3, or 4 places behind ending dot. * e.g., ansi.exe. , ansi.ex. , ansi.c. */ for(i = length - 2; i >= length - 5; i--) { if(posname[i] == '.') { if(i == length - 2) break; strcpy(posname2, posname); posname2[length-1] = 0; break; } if(posname[i] < 'a' || posname[i] > 'z') break; } } if(! (*cmp)(name, posname) || (! use_versnum && ! (*cmp)(name, posname2))) { /* true if (! use_versnum) or * if (use_versnum && mstrcmp()). */ if(! use_versnum || ! mstrcmp(verno_exp_a, posnum)) { if(poscount == -1) pos = 1; else if(poscount == 1) { poscount--; pos = 1; } else if(poscount) { poscount--; skip(3); continue; } } else { skip(3); continue; } } else { skip(3); continue; } } /* * numrecs equals 0 if no file arguments are specified. * Thus the entire tape must be processed. */ if(! numrecs || ((fstat = lookup(name, verno_exp_a)) != NULL)) /* The last comment seems to be saying: Do this is if we are extracting ALL files; -or- The user wants the one we are positioned at. */ { if(use_versnum) sprintf(name, "%s%s.%d", pathname, l_filename, verno_exp); else /* remove '.' at end of string */ remove_c(name); if(func == TABLE) skip(2); else /* Does the file have links ? */ if(lnk_fsecno != 0 && lnk_fseqno != 0) { int found = 0; for(lp = x_head; lp != NULL; lp = lp->x_next) { /* Look thru our links.. */ if(lp->x_fsecno == lnk_fsecno && lp->x_fseqno == lnk_fseqno) { found++; break; } } if(found) { char path[MAXLEN]; char *p; if(stat(name, &inode) >= 0) /* ck for any error rtn */ { if(warning_only) error("%s already exists. Overwriting and linking.", name, 0); else { fprintf(stderr, "%s: %s already exists. Overwrite and link (y/n)? ", progname, name); gets(labelbuf); if(labelbuf[0] != 'y') { skip(3); continue; } } } else { strcpy(path, name); p = path; p += strlen(path); while(--p != path) { if(*p == '/') break; } if(*p == '/') { *++p = 0; checkdir(path); } } unlink(name); if(link(lp->x_pathname, name) < 0) error("cannot link %s to %s", lp->x_pathname, name); else { linkflag = YES; skip(2); } } else if(freemem) error("cannot link %s. Head link was not extracted.", name, 0); } else { lp = (struct xlinkbuf *) malloc(sizeof(*lp)); if(lp == NULL) { if(freemem) { error("Out of memory. Link information lost", 0, 0); freemem = NO; } } else { /* Add this into the list of "link" files in case we are one or are pointed to by someone. */ lp->x_next = x_head; x_head = lp; lp->x_fsecno = l_fsecno; lp->x_fseqno = l_fseqno; strcpy(lp->x_pathname, name); } } xname[0] = 0; /* The following test basically says: Did the user want to override what we think the disk file file format should be ? */ if(func == EXTRACT && numrecs && fstat->f_flags) { if(fstat->f_flags & FUF && fstat->f_flags & DD) error("your -u request has precedence over the -d option.", 0, 0); if(fstat->f_flags & FUF) { if(l_recformat == VARIABLE) l_recformat = FUF; else error("the -u option does not apply when extracting binary files", 0, 0); } if(fstat->f_flags & DD) { if(l_recformat == VARIABLE) l_recformat = DD; else error("the -d option does not apply when extracting binary files", 0, 0); } } /* This file is not a link. */ if(func == EXTRACT && ! linkflag) { /* Go extract a real file from the tape. */ ret = xtractf(pathname, ! numrecs ? "" : fstat->f_src, charcnt, xname); /* Did the extract go ok and is this an Ultrix tape ? */ if(ret >= 0L && ! strcmp(l_systemid, SYSNAME)) /* /\--> a ret of -1 === an error */ { char temp[MAXLEN]; /* The following says: Did the user give us a name to use for this file on the disk, or should we use the name of the file as we interpreted it from the tape ? */ strcpy(temp, xname[0] != 0 ? xname : name); chmod(temp, mode); chown(temp, uid); /* no chgrp routine chgrp(temp, gid); */ if(modtime > 0L) { time_t timep[2]; timep[0] = time(NULL); timep[1] = modtime; utime(temp, timep); } } /* Ask the question: If this is "NOT" a -link- file ? */ if((lnk_fsecno == 0 || lnk_fseqno == 0) && lp != NULL) { /* If error on extract & we have something in our extract list - then do the following. */ if(ret < 0L) { /* Remove this file name from our list of extracted files. (used for links) */ x_head = lp->x_next; free((char*)lp); continue; } else /* Else, if the user specified an extract name, put that name in our list instead of the name it has on tape. */ if(xname[0] != 0) strcpy(lp->x_pathname, xname); } /* stop processing any files with * ret < 0L that haven't been caught * before this. e.g., non-head link * files that were not extracted. */ if(ret < 0L) continue; } if(read(fileno(magtfp), labelbuf, LABSIZE) < 0) errorexit("cannot read EOF1 from tape", 0, 0); sscanf(labelbuf, "%3s%1d%*50c%6ld", l_labelid, &l_labelno, &l_nblocks);#ifdef DEBUG pr_label();#endif if(strcmp(l_labelid, "EOF") || l_labelno != 1) { errorexit("%s%d: illegal label format (EOF1)", l_labelid, l_labelno); } /* The following constant of 1 will fail when we implement all of LTF functionality. */ /* skip rest of EOF label set */ skip(1); if(func == TABLE) { if(verbose) { sprintf(cat_misc, "(%d,%d)", l_fseqno, l_fsecno); printf("%-7s", cat_misc); if(strcmp(l_systemid, SYSNAME)) printf("--------- -/- "); else { expand_mode(mode); printf("%4d/%-4d", uid, gid); } if(modtime > 0L) date_time(sdate, &modtime); else date_year(sdate, l_credate); printf("%12s", sdate); sprintf(cat_misc, "%ld(%d)%c", l_nblocks, l_blklen, l_recformat == 'D' ? 't' : 'b'); printf("%11s", cat_misc); if(strlen(name) > 30) printf("\n %s", name); else printf(" %s", name); } else printf("%s", name); if(lnk_fsecno != 0 && lnk_fseqno != 0) printf("%slinked to %s\n", verbose ? "\n " : " ", lnk_name); else printf("\n"); } else if(verbose) { if(linkflag) printf("x %s linked to %s\n", name, lp->x_pathname); else { printf("x %s, %ld byte%c, %ld %d-byte tape block%c", name, ret, ret == 1 ? 0 : 's', l_nblocks, l_blklen, l_nblocks == 1L ? 0 : 's'); if(l_recformat == FUF) printf(" (fuf)\n"); else if(l_recformat == DD) printf(" (dd)\n"); else printf("\n"); if(xname[0] != 0) printf(" > %s\n", xname);if ((func == EXTRACT)) { char *sp; int wildc; wildc = NO; sp = fstat->f_dest; while (*sp != '\n') { if ((*sp == '*') || (*sp == '?')) { wildc = YES; break; } sp++; } if ((!wildc) && (numrecs)) { strcpy(fstat->f_src,"1extracted1"); strcpy(fstat->f_dest,"1extracted1"); fstat->f_numleft =0; numrecs--; if (!numrecs) exit(0); }} } } } else skip(3); }/*E for ;;..*/ }/*end SCANTAPE*//*--------------------------------------------------------------------- * * LOOKUP - looks up the given LTF entry among user-input * file arguments. * *-------------------------------------------------------------------*/struct filestat *lookup(name, gen)char *name; /* file name (and file type) */char *gen; /* version number */ { struct filestat *fstat; char *d, *n; char dest2[MAXLEN]; /* for additional interpretation */ for(fstat = f_head; fstat != NULL; fstat = fstat->f_next) { if(! fstat->f_numleft) continue; dest2[0] = 0; if(! use_versnum) { int i, length; length = strlen(fstat->f_dest); /* * skip '.' at end of dest. second dot * must be 2, 3, or 4 places behind ending dot. * e.g., ansi.exe. , ansi.ex. , ansi.c. */ for(i = length - 2; i >= length - 5; i--) { if(fstat->f_dest[i] == '.') { if(i == length - 2) break; strcpy(dest2, fstat->f_dest); dest2[length-1] = 0; break; } } } if(! (*cmp)(name, fstat->f_dest) || (! use_versnum && ! (*cmp)(name, dest2))) { if(! use_versnum || ! mstrcmp(gen, fstat->f_version)) { if(fstat->f_numleft == -1) return(fstat); if(fstat->f_numleft == 1) { fstat->f_numleft--; return(fstat); } /* decrement if f_numleft > 1 */ if(fstat->f_numleft) fstat->f_numleft--; return(NULL); } } /* * check if the LTF entry is a file * (recursively) under a requested directory. */ n = name; d = fstat->f_dest; while(*n == *d) { n++; d++; } if(*d == '.' && *(d+1) == 0 && (*(d-1) == '/' || *n == '/')) return(fstat); } return(NULL); }/*--------------------------------------------------------------------- * * SKIP - skips 'nwanted' number of tape files. It returns the * number of files actually skipped. * *-------------------------------------------------------------------*/skip(nwanted)int nwanted; { int ndone; struct mtop mt; int ret; char labelid[5]; int eofok = NO; /* * determines when an eof * indicates an eot. A * zero-length LTF file * will cause a premature eot * unless we use 'eofok'. */ mt.mt_count = 1; mt.mt_op = MTFSF; for(ndone=1; ndone != nwanted; ndone++) { if(ioctl(fileno(magtfp), MTIOCTOP, &mt) < 0) errorexit("cannot skip tape", 0, 0); inbuf[0] = 0; ret = read(fileno(magtfp), inbuf, sizeof(inbuf));
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?