rdt.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 2,753 行 · 第 1/5 页
C
2,753 行
} /* * Give the user a chance to change some * parameters before appending the file. BUT WHY ??? */ fprintf(stderr, "%s: Is %s a TEXT or a BINARY file (t/b)? ", progname, fstat.f_src); gets(line); if(line[0] == 't') type = TEXT; else if(line[0] == 'b') type = BINARY; else if(line[0] == 'd') type = COUNTED; else { error("input must be 't', 'b' or 'd'. %s not dumped.", fstat.f_src, 0); return; } if(type == TEXT) { /* WHY ? TO WHAT ? Is there no default size we can suggest ? If we know to what size, why ASK USER ? */ error("You MUST now increase the record length.", 0, 0); fprintf(stderr, "%s: New record length (current value is %d)? ", progname, reclength); gets(line); sscanf(line, "%d", &reclength); if(max + 4 > reclength) { if(reclength > MAXRECSIZE || line[0] <= '0' || line[0] > '9') error("invalid record length (max 512).", 0, 0); else if(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); } else error("record length is still too small. %s not dumped.", fstat.f_src, 0); return; } } } } else charcnt = inode.st_size; fseek(fp, 0L, 0); sscanf(fstat.f_version, "%d", &version);/* PUT A FILE ON TAPE HERE....*/ /* HDR1 - Identify the file and the system that created the tape. */sprintf(dummy, "HDR1%-17.17s%-6.6s%04d%04d%04d%02d %02d%03d %02d%03d %06d%-13.13s%7.7s", fstat.f_dest, label, fsecno, fseqno, (version-1) / 100 + 1, (version-1) % 100, ltime->tm_year, ltime->tm_yday+1, 99, 366, 0, type == FUF ? "DECFILE11A" : SYSNAME, spaces); write(fileno(magtfp), dummy, LABSIZE); if(type == FUF) max = MAXREC4;/* HDR2 - describe the record format, maximum record size, & maximum block length of the file..*/ if(type != TEXT) /* Tell VMS NOT to give carriage return attributes */ sprintf(dummy, "HDR2%c%05d%05df%20.20sM%13.13s00%28.28s", (type == TEXT || type == FUF || type == COUNTED) ? VARIABLE : FIXED, blocksize, (type == TEXT || type == FUF) ? max + 4 : reclength, spaces, spaces,spaces); else /* Tell VMS it is ok to give carriage return attributes */ sprintf(dummy, "HDR2%c%05d%05df%34.34s00%28.28s", (type == TEXT || type == FUF || type == COUNTED) ? VARIABLE : FIXED, blocksize, (type == TEXT || type == FUF) ? max + 4 : reclength, spaces, spaces,spaces); write(fileno(magtfp), dummy, LABSIZE);/* HDR3 - Stores the VAX/VMS RMS file attributes. For Ultrix, we put out path component here (org vsn).*/ if(type == FUF) { sprintf(ldummy, "HDR3%04x0002%010d01%044d%12.12s", MAXREC4, 0, 0, spaces);/* sprintf(&ldummy[81],"_-_prototype test_-_'\n'");*/ write(fileno(magtfp), ldummy, LABSIZE); } else { upper(pathname); sprintf(ldummy, "HDR3%-76.76s", pathname);/* sprintf(&ldummy[81],"_-_prototype test_-_'\n'");*/ write(fileno(magtfp), ldummy, LABSIZE); if(inode.st_nlink > 1) { for(lp = a_head; lp != NULL; lp = lp->a_next) if(lp->a_inum == inode.st_ino && lp->a_dev == inode.st_dev) { found++; break; } if(found) { /* HDR4 - A hard link was found, head seen, point this file to it. */ sprintf(ldummy, "HDR4%04o%04d%04d%04d%04d%010ld%010ld%39.39s", inode.st_mode & 07777, inode.st_uid, inode.st_gid, lp->a_fsecno, lp->a_fseqno, charcnt, inode.st_mtime, spaces);/* sprintf(&ldummy[81],"_-_prototype test_-_'\n'");*/ write(fileno(magtfp), ldummy, LABSIZE); /* HDR5 - the head file name */ sprintf(ldummy, "HDR5%-76.76s", lp->a_pathname);/* sprintf(&ldummy[81],"_-_prototype test_-_'\n'");*/ write(fileno(magtfp), ldummy, LABSIZE); linkflag = YES; lp->a_count--; } else { /* Hard link, head not seen, this must be considered the head link ? */ sprintf(ldummy, "HDR4%04o%04d%04d%04d%04d%010ld%010ld%39.39s", inode.st_mode & 07777, inode.st_uid, inode.st_gid, 0, 0, charcnt, inode.st_mtime, spaces);/* sprintf(&ldummy[81],"_-_prototype test_-_'\n'");*/ write(fileno(magtfp), ldummy, LABSIZE); lp = (struct alinkbuf *) malloc(sizeof(*lp)); if(lp == NULL) { if(freemem) { error("Out of memory. Link information lost.", 0, 0); freemem = NO; } } else /* Not a hard link seen. */ { lp->a_next = a_head; a_head = lp; lp->a_inum = inode.st_ino; lp->a_dev = inode.st_dev; lp->a_count = inode.st_nlink - 1; lp->a_fsecno = fsecno; lp->a_fseqno = fseqno; strcpy(lp->a_pathname, longname); } } } else { sprintf(ldummy, "HDR4%04o%04d%04d%04d%04d%010ld%010ld%39.39s", inode.st_mode & 07777, inode.st_uid, inode.st_gid, 0, 0, charcnt, inode.st_mtime, spaces);/* sprintf(&ldummy[81],"_-_prototype test_-_'\n'");*/ write(fileno(magtfp), ldummy, LABSIZE); } } /* write an end-of-file mark on tape */ weof();/* The label headers have been done, now write the file itself on to the tape.*/ if((block = append(fp, type, max)) < 0L) { if(block == (long)(-1)) error("%s not dumped.", fstat.f_src, 0); else { error("content type in question. %s not dumped.", fstat.f_src, 0); error("Try appending as a BINARY file (with the -b flag).", 0, 0); } fclose(fp); if(fseqno == 1 && fsecno == 1) { struct mtop mt; fclose(magtfp); rew(); if((magtfp = fopen(magtdev, "w")) == NULL) errorexit("cannot open %s for writing", magtdev, 0); mt.mt_count = 1; mt.mt_op = MTFSR; if(ioctl(fileno(magtfp), MTIOCTOP, &mt) < 0) errorexit("cannot skip 1 tape record", 0, 0); } else back(1); if(! found && lp != NULL) { a_head = lp->a_next; free((char *) lp); } return; } fclose(fp);/* Headers and file data done, now put the trailer lables on the tape and move on to the next file.*/ weof(); sprintf(dummy, "EOF1%-17.17s%-6.6s%04d%04d%04d%02d %02d%03d %02d%03d %06ld%-13.13s%7.7s", fstat.f_dest, label, fsecno, fseqno, (version-1) / 100 + 1, (version-1) % 100, ltime->tm_year, ltime->tm_yday+1, 99, 365, block, type == FUF ? "DECFILE11A" : SYSNAME, spaces); write(fileno(magtfp), dummy, LABSIZE); sprintf(dummy, "EOF2%c%05d%05d%35.35s00%28.28s", (type == TEXT || type == FUF) ? VARIABLE : FIXED, blocksize, (type == TEXT || type == FUF) ? max + 4 : reclength, spaces, spaces); write(fileno(magtfp), dummy, LABSIZE); if(type == FUF) { sprintf(dummy, "EOF3%04x0002%010d01%044d%12.12s", MAXREC4, 0, 0, spaces); write(fileno(magtfp), dummy, LABSIZE); } else { sprintf(dummy, "EOF3%-76.76s", pathname); write(fileno(magtfp), dummy, LABSIZE); if(found) { sprintf(dummy, "EOF4%04o%04d%04d%04d%04d%010ld%010ld%39.39s", inode.st_mode & 07777, inode.st_uid, inode.st_gid, lp->a_fsecno, lp->a_fseqno, charcnt, inode.st_mtime, spaces); write(fileno(magtfp), dummy, LABSIZE); sprintf(dummy, "EOF5%-76.76s", lp->a_pathname); write(fileno(magtfp), dummy, LABSIZE); } else { sprintf(dummy, "EOF4%04o%04d%04d%04d%04d%010ld%010ld%39.39s", inode.st_mode & 07777, inode.st_uid, inode.st_gid, 0, 0, charcnt, inode.st_mtime, spaces); write(fileno(magtfp), dummy, LABSIZE); } } weof(); if(verbose) { lower(fstat.f_dest); lower(pathname); if(use_versnum) printf("a %s%s.%d", pathname, fstat.f_dest, version); else { remove_c(fstat.f_dest); printf("a %s%s", pathname, fstat.f_dest); } if(linkflag) printf(" linked to %s", lp->a_pathname); else printf(", %ld tape block%c", block, block == 1L ? 0 : 's'); printf("\n"); } fseqno++; }/*--------------------------------------------------------------------- * * APPEND - appends the given file onto tape in the appropriate * record and block format. It returns the number of * blocks appended. * *-------------------------------------------------------------------*/longappend(fp, type, max)FILE *fp;int type, max; { char line[512]; int length; char *p; block = 0L; p = inbuf; if(type == TEXT) { while(fgets(line, reclength, fp) != NULL) { length = strlen(line); if(line[length-1] == '\n') line[--length] = 0; else return((long)(-2));/* if(length == 0) { length = 2; line[0] = line[1] = ' '; }*/ if(length > max) { error("file changed size.", 0, 0); return((long)(-1)); } if(&p[length+4] > &inbuf[blocksize]) { while(p < &inbuf[blocksize]) *p++ = PAD; write(fileno(magtfp), inbuf, blocksize); p = inbuf; block++; } sprintf(p, "%04d%s", length+4, line); p = &p[length+4]; } if(p != inbuf) { while(p < &inbuf[blocksize]) *p++ = PAD; write(fileno(magtfp), inbuf, blocksize); block++; } } else if(type == BINARY) while((length = read(fileno(fp), p=inbuf, blocksize)) > 0) { if(length < blocksize) { p = &p[length]; while(p < &inbuf[blocksize]) *p++ = PAD; } write(fileno(magtfp), inbuf, blocksize); p = inbuf; block++; } else if (type == COUNTED) /* Variable length records */ { while( fread( &length, sizeof (short), 1, fp)) { if( length == -1 || p+length+4 > &inbuf[blocksize]) { while( p < &inbuf[blocksize]) *p++ = PAD; write( fileno( magtfp), inbuf, blocksize); p = inbuf; block++; } sprintf( p, "%04d", length+4); fread( p+4, 2, (length+1)/2, fp); /* fudge for COUNTED records always beginning on a word boundary in file */ p += length+4; } if(p != inbuf) { while(p < &inbuf[blocksize]) *p++ = PAD; write(fileno(magtfp), inbuf, blocksize); block++; } } else /* type == FUF */ { char rectype; char *rp; long nbytes, nbytesl, bytcnt; int nrec, res, irec, lastbit, resl; /* initialize buffer pointers */ bb = inbuf; rb = bb; rp = rb + RECOFF; /* * Loop over all records in the file. The unformatted * format for f77 is as follows: each record is * followed and preceded by a long int which contains * the byte count of the record excluding the 2 long * integers. */ while((res = read(fileno(fp), &nbytes, sizeof(long))) > 0) { if(nbytes > 0L) { bytcnt = nbytes; nrec = ((int)nbytes-1) / MAXREC6; irec = nrec; /* * if record is greater than MAXREC6, * then output it in chunks of MAXREC6 * first. */ while(irec--) { if(rb - bb + MAXRECFUF > blocksize) { bflush(); rb = bb; rp = rb + RECOFF; } /* read record in chunks of MAXREC6 */ res = read(fileno(fp), rp, MAXREC6); if(res < 0) { error("eof in middle of file", 0, 0); return((long)(-1)); } if(res != MAXREC6) { error("wrong record length in middle of file", 0, 0); return((long)(-1)); } /* * Set up the record type. Note: * to get here the record must * be > MAXREC6 and it must be * split. Thus there must be a * FIRST record and all other * records must be MIDDLE records. * There could be a LAST record * if the record was an exact * multiple of MAXREC6. */ if(irec == nrec - 1) rectype = FIRST; else if(bytcnt > MAXREC6) rectype = MIDDLE; else rectype = LAST; /* * now output chunk of record * on tape as VARIABLE format */ resl = res + RECOFF; sprintf(rb, "%04d", resl); addrtyp(rb, &rectype); bytcnt -= res; rb += resl; rp = rb + RECOFF; } /* * output final part (unless exact * multiple of MAXREC6) of record or * all of it if record is < MAXREC6. */ if(bytcnt > 0) { lastbit = bytcnt; if(rb - bb + lastbit + RECOFF > blocksize) { bflush(); rb = bb; rp = rb + RECOFF; } res = read(fileno(fp), rp, lastbit); if(res < 0) { error("eof in middle of file", 0, 0); return((long)(-1)); } if(res != lastbit) { error("wrong record length in middle of file", 0, 0); return((long)(-1)); } if(lastbit == nbytes) rectype = ALL; else rectype = LAST; resl = res + RECOFF; sprintf(rb, "%04d", resl); addrtyp(rb, &rectype); rb += resl; rp = rb + RECOFF; } } else { if(rb - bb + RECOFF > blocksize) { bflush(); rb = b
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?