putfile.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 1,538 行 · 第 1/3 页
C
1,538 行
/* * 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 volume as VARIABLE format */ resl = res + RECOFF; sprintf(Rb, "%04d", resl); addrtyp(Rb, &rectype); bytcnt -= res; Rb += resl; rp = Rb + RECOFF; }/*E While irec-- */ /* * 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(name, Outbuf); Rb = Bb; rp = Rb + RECOFF; } res = read(fileno(fp), rp, lastbit); if (res < 0) { PERROR "\n%s: %s%c\n\n", Progname, EOFINM, BELL); return((long)(-1)); } if (res != lastbit) { PERROR "%\n%s: %s%c\n\n", Progname, WRLINM, BELL); 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; }/*E if bycnt > 0 */ }/*T if nbytes > 0L */ else { if (Rb - Bb + RECOFF > Blocksize) { bflush(name, Outbuf); Rb = Bb; rp = Rb + RECOFF; } sprintf(Rb, "%04d", RECOFF); rectype = ALL; addrtyp(Rb, &rectype); Rb += RECOFF; rp = Rb + RECOFF; }/*F if nbytes > 0L */ res = read(fileno(fp), (char *)&nbytesl, sizeof(long)); if (res < 0) { PERROR "\n%s: %s%c\n\n", Progname, EOFINM, BELL); return((long)(-1)); } if (nbytesl != nbytes) { PERROR "\n%s: %s%c\n\n", Progname, BFRCNE, BELL); return((long)(-1)); } }/*E while res= read ..*/ if (res < 0) { PERROR "\n%s: %s %s\n", Progname, CANTRD, name); perror(Progname); exit(FAIL); } bflush(name, Outbuf);}/*E if type == FUF *//* * Return to the caller the number of blocks * that were output to the volume. */return(Blocks);}/*E append()*//**//* * * Function: * * process * * Function Description: * * This functions writes the ANSI file header labels, * file data, and ANSI file trailer labels to the * output volume. * * Arguments: * * char *reallong; Contains the full pathname & file name * char *longname; Contains the pathname & file name * char *shortname; File name only * int type; Ultrix disk file type * * Return values: * * none * * Side Effects: * * If the function encounters an error condition during * the output of the file, a message is output to * "stderr" and the function exits to system control. */process(reallong, longname, shortname, type) char *reallong; /* Full path name_+_filename */ char *longname; /* Relative path name_+_filename */ char *shortname; /* Contains the file name only */ int type; /* Type of Ultrix disk file */{/* * +--> Local Variables */char ansift; /* Save ANSI file type character from HDR2 * for later verbose messge output. */int ch; /* Character returned from getc to check line * size for TEXT files */char crecent; /* Creation date century */char *ctime(); /* Declare ctime routine */char dummy[MAXPATHLEN+1]; /* dummy variable */int found = 0; /* a head link is not on tape yet */FILE *fp;int hlink = 0; /* Flag set for field in HDR2 if hard link */char interchange[18]; /* Interchange name */int length; /* size of complete filename */int linkflag = NO; /* Used to trigger output linked files * message. Set to YES if the current file * is linked to a file that has already * been appended to the output volume. */int lnkseq = 0; /* Field in HDR2 for file sequence number that * a hard link points to */struct tm *localtime();struct ALINKBUF *lp; /* Node for hard link files */struct tm *ltime;int max; /* maximum line length */int nlinks; /* number of links to file */int otype = 0; /* If outputting sym link file, save SYMLNK * file type to check in append routine *//* * Outbuf is a character array declared globally * to ensure that it begins on a word boundary. */char pathname[MAXPATHLEN+1]; /* path name */int version = 1; /* version number (1 is default) *//*------*\ Code\*------*/if (strlen(longname) >= MAXPATHLEN) { PERROR "\n%s: %s %s%c\n\n", Progname, FNTL, longname, BELL); /* * A string that long is probably fatal... */ exit(FAIL);}strcpy(dummy, longname);pathname[0] = '\0';if (cp = rindex(dummy, '/')) { *++cp = '\0';/* * ?_? NOTE: When we get to putting loong file names on * the output volume.. This logic will need to * be updated... */ if (strlen(dummy) >= MAXPATHLEN) { PERROR "\n%s: %s %s%c\n\n", Progname, FNTL, longname, BELL); /* * A string that long is probably fatal... */ exit(FAIL); } strcpy(pathname, dummy);}/* * Make the ANSI interchange file name */ strcpy(dummy,shortname);j = 0;if (!(filter_to_a(dummy,REPORT_ERRORS))) if (Warning) { PERROR "%s: %s %s", Progname, NONAFN, shortname); PERROR "\n%s: %s %s", Progname, INVVID2, dummy); j++; }if (strlen(dummy) > 17) { /* * If user has requested warnings, tell user file name * is too long for HDR1 and that it will be truncated. */ dummy[17] = '\0'; if (Warning) { PROMPT "\n%s: %s %s%c", Progname, FNTL, shortname, BELL); j++; }}if ((j > 0) && Warning) PERROR "\n%s: %s\n\n", Progname, FILENNG);strcpy(interchange, dummy);interchange[17] = '\0';if ((fp = fopen(reallong, "r")) == NULL) { PERROR "\n%s: %s %s%c\n\n", Progname, CANTOPEN, reallong, BELL); perror(Progname); exit(FAIL);}nlinks = Inode.st_nlink;/* * Get file owner's name string for HDR3. */if (getpw(Inode.st_uid,Name)) { PERROR "\n%s: %s %d%c\n", Progname, CANTFPW, Inode.st_uid, BELL); strcpy(Name, " ");}/* * Owner id field in HDR3 label is maximum of 10 characters */for (j=0; j < 11 && Name[j] && Name[j] != ':'; j++) Owner[j] = Name[j];Owner[j] = NULL;cp = ctime((long *)&Inode.st_mtime);if (cp[20] == '2' && cp [21] == '0') crecent = '0';else crecent = ' ';ltime = localtime((long *)&Inode.st_mtime);Blocks = 0L;max = 0;if (type == TEXT || type == SYMLNK && Nosym) { /* * If we find a really long line in the text, * we should output it as a spanned/segmented * record rather variable length record. * * Find length of longest line. */ Format = 0; ch = TRUE; while (ch != EOF) { length = 0; while ((ch = getc(fp)) != EOF && ch != '\n') length++; if (length > max) max = length; }/*E while (ch) */ fclose(fp); if ((fp = fopen(reallong, "r")) == NULL) { PERROR "\n%s: %s %s%c\n\n", Progname, CANTOPEN, reallong, BELL); exit(FAIL); }#ifdef U11 if (max + 5 > Reclength && Reclength != MAXRECSIZE) { PERROR "\n%s: %s %s%c\n\n", Progname, RECLTS, longname, BELL); return; }/*T if (max + 5 > Reclength ... */ if (max + 5 > Reclength || max + 5 > Blocksize) {#else if (max + 5 > Blocksize) {#endif Format = SEGMENT; Maxrec = max; }/*T if (max + 5 ... */ else { Format = VARIABLE; Maxrec = max + 4; }/*F if (max + 5 ... */}/*E if (type == TEXT || type == SYMLNK && Nosym) */fseek(fp, 0L, 0);/****\ * Write HDR1 on volume.. ****/sprintf(Dummy, "HDR1%-17.17s%-6.6s%04d%04d%04d%02d%c%02d%03d %02d%03d %06d%-13.13s%7.7s", interchange, Volid, Fsecno, Fseqno, (version-1) / 100 + 1, (version-1) % 100, crecent, ltime->tm_year, ltime->tm_yday+1, 99, 366, 0, type == FUF ? "DECFILE11A" : IMPID, Spaces);if (Ansiv != '4') (void) filter_to_a(Dummy,IGNORE_ERRORS);if (write(fileno(Magtfp), Dummy, BUFSIZE) != BUFSIZE) { PERROR "\n%s: %s %s\n", Progname, ERRWRF, longname); perror(Magtdev); ceot();}if (type == FUF) max = MAXREC4;/****\ * Write HDR2 on volume.. ****//* * Directories always have a link count > 1 ... * So, we don't bother to enter them in the linked files list. * Also, can't hard link directories ... */if (type != DIRECT && nlinks > 1 && !Nosym) { hlink = 1; /* If this file is linked to another, * find the ANSI file sequence number that it * is linked to. */ for (lp = A_head; lp; lp = lp->a_next) if (lp->a_inum == Inode.st_ino && lp->a_dev == Inode.st_dev) { found++; break; } /* If we found the file that this file is linked to in our list, * get it's file sequence number and set linkflag. */ if (found) { lnkseq = lp->a_fseqno; linkflag = YES; } else { /* Else, enter info into a node for a possible reference */ lp = (struct ALINKBUF *) malloc(sizeof(*lp)); if (lp == NULL) { PERROR "\n%s: %s%c%c\n\n", Progname, NOMEM, BELL, BELL); exit(FAIL); }/*T if lp == NULL */ else { lp->a_next = A_head; A_head = lp; lp->a_inum = Inode.st_ino; lp->a_dev = Inode.st_dev; lp->a_fsecno = Fsecno; lp->a_fseqno = Fseqno; lp->a_pathname = (char *) malloc(strlen(longname) + 1); if (lp == NULL) { PERROR "\n%s: %s%c%c\n\n", Progname, NOMEM, BELL, BELL); exit(FAIL); }/*T if lp == NULL */ else { strcpy(lp->a_pathname, longname); } lnkseq = 0; }/*F if lp == NULL */ }/*F if (found) */}/*E if (type != DIRECT && nlinks > 1) *//* * Perform any special functions required for symbolic links */if (type == SYMLNK) { otype = type; type = TEXT; if (!Nosym) { /* * Read the link to find out what * it points to. */ dummy[0] = 0; if ((ch = readlink(reallong, dummy, MAXNAMLEN)) < 0) { PERROR "\n%s: %s %s\n",Progname, CANTRSL, reallong); perror(Progname); } else dummy[ch] = '\0'; linkflag = YES; /* * For Symbolic links, the file data is the full * path name of the file pointed to by the * symbolic link. */ strcpy(Outbuf,dummy); max = strlen(Outbuf); Outbuf[max] = '\n'; Outbuf[max+1] = '\0';#ifdef U11 if (max + 5 > Reclength || max + 5 > Blocksize || max + 5 > MAXRECSIZE) {#else if (max + 5 > Blocksize) {#endif Format = SEGMENT; Maxrec = max; } else { Format = VARIABLE; Maxrec = max + 4; } }/*T if (!Nosym) */ }/*T if (type == SYMLNK) *//****** * * Calculate the number of HDR / EOF labels that will be needed * to contain the full path/file name. * */length = (strlen(longname)) -1;Lhdrl = 3;Leofl = 0;length -= 36;/* * Determine the number of HDR labels needed. */while ((length > 0) && (Lhdrl !=9)) { length -= 76; Lhdrl++;}/* * Determine the number of EOF labels needed. */if (length > 0) { Leofl = 2; while ((length >0) && (Leofl != 9)) { length -= 76; Leofl++; }}/* Set the format of the record if it is not a TEXT file. If it is, * it has already been set. */if (type == FUF || type == COUNTED) Format = VARIABLE;else if (type != TEXT) Format = FIXED;if (type == FUF) Maxrec = max + 4;else if (type != TEXT)#ifdef U11 Maxrec = Reclength;#else Maxrec = Blocksize;#endifsprintf(Dummy, "HDR2%c%05d%05d%06o%04d%04d%04d%3.3s%c%010ld%1.1d%1.1d%1.1d00%-28.28s", Format, Blocksize, Maxrec, Inode.st_mode & 0177777, Inode.st_uid, Inode.st_gid, lnkseq, Tftypes, (type == BINARY) ? 'M' : Carriage, (type == SYMLNK && !Nosym) ? max : Inode.st_size, Lhdrl, Leofl, hlink, Spaces);/* * Save ANSI file type for verbose messgae use. */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?