Annotation of coherent/d/usr/bin/pax/shipping/buffer.c, revision 1.1

1.1     ! root        1: /* $Source: /newbits/usr/bin/pax/shipping/buffer.c,v $
        !             2:  *
        !             3:  * $Revision: 1.1 $
        !             4:  *
        !             5:  * buffer.c - Buffer management functions
        !             6:  *
        !             7:  * DESCRIPTION
        !             8:  *
        !             9:  *     These functions handle buffer manipulations for the archiving
        !            10:  *     formats.  Functions are provided to get memory for buffers, 
        !            11:  *     flush buffers, read and write buffers and de-allocate buffers.  
        !            12:  *     Several housekeeping functions are provided as well to get some 
        !            13:  *     information about how full buffers are, etc.
        !            14:  *
        !            15:  * AUTHOR
        !            16:  *
        !            17:  *     Mark H. Colburn, NAPS International ([email protected])
        !            18:  *
        !            19:  * Sponsored by The USENIX Association for public distribution. 
        !            20:  *
        !            21:  * Copyright (c) 1989 Mark H. Colburn.
        !            22:  * All rights reserved.
        !            23:  *
        !            24:  * Redistribution and use in source and binary forms are permitted
        !            25:  * provided that the above copyright notice is duplicated in all such 
        !            26:  * forms and that any documentation, advertising materials, and other 
        !            27:  * materials related to such distribution and use acknowledge that the 
        !            28:  * software was developed * by Mark H. Colburn and sponsored by The 
        !            29:  * USENIX Association. 
        !            30:  *
        !            31:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
        !            32:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
        !            33:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
        !            34:  *
        !            35:  * $Log:       /newbits/usr/bin/pax/shipping/buffer.c,v $
        !            36:  * Revision 1.1        91/02/05  11:55:12      bin
        !            37:  * Initial revision
        !            38:  * 
        !            39:  * Revision 1.2  89/02/12  10:04:02  mark
        !            40:  * 1.2 release fixes
        !            41:  * 
        !            42:  * Revision 1.1  88/12/23  18:02:01  mark
        !            43:  * Initial revision
        !            44:  * 
        !            45:  */
        !            46: 
        !            47: #ifndef lint
        !            48: static char *ident = "$Id: buffer.c,v 1.2 89/02/12 10:04:02 mark Exp $";
        !            49: static char *copyright = "Copyright (c) 1989 Mark H. Colburn.\nAll rights reserved.\n";
        !            50: #endif /* ! lint */
        !            51: 
        !            52: 
        !            53: /* Headers */
        !            54: 
        !            55: #include "pax.h"
        !            56: 
        !            57: 
        !            58: /* Function Prototypes */
        !            59: 
        !            60: #if __STDC__
        !            61: 
        !            62: static int ar_write(int, char *, uint);
        !            63: static void buf_pad(OFFSET);
        !            64: static int indata(int, OFFSET, char *);
        !            65: static void outflush(void);
        !            66: static void buf_use(uint);
        !            67: static int buf_in_avail(char **, uint *);
        !            68: static uint buf_out_avail(char **);
        !            69: 
        !            70: #else /* !__STDC__ */
        !            71: 
        !            72: static int ar_write();
        !            73: static void buf_pad();
        !            74: static int indata();
        !            75: static void outflush();
        !            76: static void buf_use();
        !            77: static int buf_in_avail();
        !            78: static uint buf_out_avail();
        !            79: 
        !            80: #endif /* __STDC__ */
        !            81: 
        !            82: 
        !            83: /* inentry - install a single archive entry
        !            84:  *
        !            85:  * DESCRIPTION
        !            86:  *
        !            87:  *     Inentry reads an archive entry from the archive file and writes it
        !            88:  *     out the the named file.  If we are in PASS mode during archive
        !            89:  *     processing, the pass() function is called, otherwise we will
        !            90:  *     extract from the archive file.
        !            91:  *
        !            92:  *     Inentry actaully calls indata to process the actual data to the
        !            93:  *     file.
        !            94:  *
        !            95:  * PARAMETERS
        !            96:  *
        !            97:  *     char    *name   - name of the file to extract from the archive
        !            98:  *     Stat    *asb    - stat block of the file to be extracted from the
        !            99:  *                       archive.
        !           100:  *
        !           101:  * RETURNS
        !           102:  *
        !           103:  *     Returns zero if successful, -1 otherwise. 
        !           104:  */
        !           105: 
        !           106: #if __STDC__
        !           107: 
        !           108: int inentry(char *name, Stat *asb)
        !           109: 
        !           110: #else
        !           111: 
        !           112: int inentry(name, asb)
        !           113: char           *name;
        !           114: Stat           *asb;
        !           115: 
        !           116: #endif
        !           117: {
        !           118:     Link           *linkp;
        !           119:     int             ifd;
        !           120:     int             ofd;
        !           121:     time_t          tstamp[2];
        !           122: 
        !           123:     if ((ofd = openout(name, asb, linkp = linkfrom(name, asb), 0)) > 0) {
        !           124:        if (asb->sb_size || linkp == (Link *)NULL || linkp->l_size == 0) {
        !           125:            close(indata(ofd, asb->sb_size, name));
        !           126:        } else if ((ifd = open(linkp->l_path->p_name, 0)) < 0) {
        !           127:            warn(linkp->l_path->p_name, strerror());
        !           128:        } else {
        !           129:            passdata(linkp->l_path->p_name, ifd, name, ofd);
        !           130:            close(ifd);
        !           131:            close(ofd);
        !           132:        }
        !           133:     } else {
        !           134:        return(buf_skip((OFFSET) asb->sb_size) >= 0);
        !           135:     }
        !           136:     tstamp[0] = (!f_pass && f_access_time) ? asb->sb_atime : time((time_t *) 0);
        !           137:     tstamp[1] = f_mtime ? asb->sb_mtime : time((time_t *) 0);
        !           138:     utime(name, tstamp);
        !           139:     return (0);
        !           140: }
        !           141: 
        !           142: /* outdata - write archive data
        !           143:  *
        !           144:  * DESCRIPTION
        !           145:  *
        !           146:  *     Outdata transfers data from the named file to the archive buffer.
        !           147:  *     It knows about the file padding which is required by tar, but no
        !           148:  *     by cpio.  Outdata continues after file read errors, padding with 
        !           149:  *     null characters if neccessary.   Closes the input file descriptor 
        !           150:  *     when finished.
        !           151:  *
        !           152:  * PARAMETERS
        !           153:  *
        !           154:  *     int     fd      - file descriptor of file to read data from
        !           155:  *     char   *name    - name of file
        !           156:  *     OFFSET  size    - size of the file
        !           157:  *
        !           158:  */
        !           159: 
        !           160: #if __STDC__
        !           161: 
        !           162: void outdata(int fd, char *name, OFFSET size)
        !           163: 
        !           164: #else
        !           165: 
        !           166: void outdata(fd, name, size)
        !           167: int             fd;
        !           168: char           *name;
        !           169: OFFSET          size;
        !           170: 
        !           171: #endif
        !           172: {
        !           173:     uint            chunk;
        !           174:     int             got;
        !           175:     int             oops;
        !           176:     uint            avail;
        !           177:     int                    pad;
        !           178:     char           *buf;
        !           179: 
        !           180:     oops = got = 0;
        !           181:     if (pad = (size % BLOCKSIZE)) {
        !           182:        pad = (BLOCKSIZE - pad);
        !           183:     }
        !           184:     while (size) {
        !           185:        avail = buf_out_avail(&buf);
        !           186:        size -= (chunk = size < avail ? (uint) size : avail);
        !           187:        if (oops == 0 && (got = read(fd, buf, (unsigned int) chunk)) < 0) {
        !           188:            oops = -1;
        !           189:            warn(name, strerror());
        !           190:            got = 0;
        !           191:        }
        !           192:        if (got < chunk) {
        !           193:            if (oops == 0) {
        !           194:                oops = -1;
        !           195:            }
        !           196:            warn(name, "Early EOF");
        !           197:            while (got < chunk) {
        !           198:                buf[got++] = '\0';
        !           199:            }
        !           200:        }
        !           201:        buf_use(chunk);
        !           202:     }
        !           203:     close(fd);
        !           204:     if (ar_format == TAR) {
        !           205:        buf_pad((OFFSET) pad);
        !           206:     }
        !           207: }
        !           208: 
        !           209: 
        !           210: /* write_eot -  write the end of archive record(s)
        !           211:  *
        !           212:  * DESCRIPTION
        !           213:  *
        !           214:  *     Write out an End-Of-Tape record.  We actually zero at least one 
        !           215:  *     record, through the end of the block.  Old tar writes garbage after 
        !           216:  *     two zeroed records -- and PDtar used to.
        !           217:  */
        !           218: 
        !           219: #if __STDC__
        !           220: 
        !           221: void write_eot(void)
        !           222: 
        !           223: #else
        !           224: 
        !           225: void write_eot()
        !           226: 
        !           227: #endif
        !           228: {
        !           229:     OFFSET           pad;
        !           230:     char            header[M_STRLEN + H_STRLEN + 1];
        !           231: 
        !           232:     if (ar_format == TAR) {
        !           233:        /* write out two zero blocks for trailer */
        !           234:        pad = 2 * BLOCKSIZE;
        !           235:     } else {
        !           236:        if (pad = (total + M_STRLEN + H_STRLEN + TRAILZ) % BLOCKSIZE) {
        !           237:            pad = BLOCKSIZE - pad;
        !           238:        }
        !           239:        strcpy(header, M_ASCII);
        !           240:        sprintf(header + M_STRLEN, H_PRINT, 0, 0,
        !           241:                       0, 0, 0, 1, 0, (time_t) 0, TRAILZ, pad);
        !           242:        outwrite(header, M_STRLEN + H_STRLEN);
        !           243:        outwrite(TRAILER, TRAILZ);
        !           244:     }
        !           245:     buf_pad((OFFSET) pad);
        !           246:     outflush();
        !           247: }
        !           248: 
        !           249:  
        !           250: /* outwrite -  write archive data
        !           251:  *
        !           252:  * DESCRIPTION
        !           253:  *
        !           254:  *     Writes out data in the archive buffer to the archive file.  The
        !           255:  *     buffer index and the total byte count are incremented by the number
        !           256:  *     of data bytes written.
        !           257:  *
        !           258:  * PARAMETERS
        !           259:  *     
        !           260:  *     char   *idx     - pointer to data to write
        !           261:  *     uint    len     - length of the data to write
        !           262:  */
        !           263: 
        !           264: #if __STDC__
        !           265: 
        !           266: void outwrite(char *idx, uint len)
        !           267: 
        !           268: #else
        !           269: 
        !           270: void outwrite(idx, len)
        !           271: char           *idx;   /* pointer to data to write */
        !           272: uint            len;   /* length of data to write */
        !           273: 
        !           274: #endif
        !           275: {
        !           276:     uint            have;
        !           277:     uint            want;
        !           278:     char           *endx;
        !           279: 
        !           280:     endx = idx + len;
        !           281:     while (want = endx - idx) {
        !           282:        if (bufend - bufidx < 0) {
        !           283:            fatal("Buffer overlow in out_write\n");
        !           284:        }
        !           285:        if ((have = bufend - bufidx) == 0) {
        !           286:            outflush();
        !           287:        }
        !           288:        if (have > want) {
        !           289:            have = want;
        !           290:        }
        !           291:        memcpy(bufidx, idx, (int) have);
        !           292:        bufidx += have;
        !           293:        idx += have;
        !           294:        total += have;
        !           295:     }
        !           296: }
        !           297: 
        !           298: 
        !           299: /* passdata - copy data to one file
        !           300:  *
        !           301:  * DESCRIPTION
        !           302:  *
        !           303:  *     Copies a file from one place to another.  Doesn't believe in input 
        !           304:  *     file descriptor zero (see description of kludge in openin() comments). 
        !           305:  *     Closes the provided output file descriptor. 
        !           306:  *
        !           307:  * PARAMETERS
        !           308:  *
        !           309:  *     char    *from   - input file name (old file)
        !           310:  *     int     ifd     - input file descriptor
        !           311:  *     char    *to     - output file name (new file)
        !           312:  *     int     ofd     - output file descriptor
        !           313:  */
        !           314: 
        !           315: #if __STDC__
        !           316: 
        !           317: void passdata(char *from, int ifd, char *to, int ofd)
        !           318: 
        !           319: #else
        !           320: 
        !           321: void passdata(from, ifd, to, ofd)
        !           322: char           *from;
        !           323: int             ifd;
        !           324: char           *to;
        !           325: int             ofd;
        !           326: 
        !           327: #endif
        !           328: {
        !           329:     int             got;
        !           330:     int             sparse;
        !           331:     char            block[BUFSIZ];
        !           332: 
        !           333:     if (ifd) {
        !           334:        lseek(ifd, (OFFSET) 0, 0);
        !           335:        sparse = 0;
        !           336:        while ((got = read(ifd, block, sizeof(block))) > 0
        !           337:               && (sparse = ar_write(ofd, block, (uint) got)) >= 0) {
        !           338:            total += got;
        !           339:        }
        !           340:        if (got) {
        !           341:            warn(got < 0 ? from : to, strerror());
        !           342:        } else if (sparse > 0
        !           343:                 && (lseek(ofd, (OFFSET)(-sparse), 1) < 0
        !           344:                     || write(ofd, block, (uint) sparse) != sparse)) {
        !           345:            warn(to, strerror());
        !           346:        }
        !           347:     }
        !           348:     close(ofd);
        !           349: }
        !           350: 
        !           351: 
        !           352: /* buf_allocate - get space for the I/O buffer 
        !           353:  *
        !           354:  * DESCRIPTION
        !           355:  *
        !           356:  *     buf_allocate allocates an I/O buffer using malloc.  The resulting
        !           357:  *     buffer is used for all data buffering throughout the program.
        !           358:  *     Buf_allocate must be called prior to any use of the buffer or any
        !           359:  *     of the buffering calls.
        !           360:  *
        !           361:  * PARAMETERS
        !           362:  *
        !           363:  *     int     size    - size of the I/O buffer to request
        !           364:  *
        !           365:  * ERRORS
        !           366:  *
        !           367:  *     If an invalid size is given for a buffer or if a buffer of the 
        !           368:  *     required size cannot be allocated, then the function prints out an 
        !           369:  *     error message and returns a non-zero exit status to the calling 
        !           370:  *     process, terminating the program.
        !           371:  *
        !           372:  */
        !           373: 
        !           374: #if __STDC__
        !           375: 
        !           376: void buf_allocate(OFFSET size)
        !           377: 
        !           378: #else
        !           379: 
        !           380: void buf_allocate(size)
        !           381: OFFSET            size;
        !           382: 
        !           383: #endif
        !           384: {
        !           385:     if (size <= 0) {
        !           386:        fatal("invalid value for blocksize");
        !           387:     }
        !           388:     if ((bufstart = malloc((unsigned) size)) == (char *)NULL) {
        !           389:        fatal("Cannot allocate I/O buffer");
        !           390:     }
        !           391:     bufend = bufidx = bufstart;
        !           392:     bufend += size;
        !           393: }
        !           394: 
        !           395: 
        !           396: /* buf_skip - skip input archive data
        !           397:  *
        !           398:  * DESCRIPTION
        !           399:  *
        !           400:  *     Buf_skip skips past archive data.  It is used when the length of
        !           401:  *     the archive data is known, and we do not wish to process the data.
        !           402:  *
        !           403:  * PARAMETERS
        !           404:  *
        !           405:  *     OFFSET  len     - number of bytes to skip
        !           406:  *
        !           407:  * RETURNS
        !           408:  *
        !           409:  *     Returns zero under normal circumstances, -1 if unreadable data is 
        !           410:  *     encountered. 
        !           411:  */
        !           412: 
        !           413: #if __STDC__
        !           414: 
        !           415: int buf_skip(OFFSET len)
        !           416: 
        !           417: #else
        !           418: 
        !           419: int buf_skip(len)
        !           420: OFFSET           len;
        !           421: 
        !           422: #endif
        !           423: {
        !           424:     uint            chunk;
        !           425:     int             corrupt = 0;
        !           426: 
        !           427:     while (len) {
        !           428:        if (bufend - bufidx < 0) {
        !           429:            fatal("Buffer overlow in buf_skip\n");
        !           430:        }
        !           431: 
        !           432:        while ((chunk = bufend - bufidx) == 0) {
        !           433:            corrupt |= ar_read();
        !           434:        }
        !           435:        if (chunk > len) {
        !           436:            chunk = len;
        !           437:        }
        !           438:        bufidx += chunk;
        !           439:        len -= chunk;
        !           440:        total += chunk;
        !           441:     } 
        !           442:     return (corrupt);
        !           443: }
        !           444: 
        !           445: /* buf_read - read a given number of characters from the input archive
        !           446:  *
        !           447:  * DESCRIPTION
        !           448:  *
        !           449:  *     Reads len number of characters from the input archive and
        !           450:  *     stores them in the buffer pointed at by dst.
        !           451:  *
        !           452:  * PARAMETERS
        !           453:  *
        !           454:  *     char   *dst     - pointer to buffer to store data into
        !           455:  *     uint    len     - length of data to read
        !           456:  *
        !           457:  * RETURNS
        !           458:  *
        !           459:  *     Returns zero with valid data, -1 if unreadable portions were 
        !           460:  *     replaced by null characters. 
        !           461:  */
        !           462: 
        !           463: #if __STDC__
        !           464: 
        !           465: int buf_read(char *dst, uint len)
        !           466: 
        !           467: #else
        !           468: 
        !           469: int buf_read(dst, len)
        !           470: char           *dst;
        !           471: uint            len;
        !           472: 
        !           473: #endif
        !           474: {
        !           475:     int             have;
        !           476:     int             want;
        !           477:     int             corrupt = 0;
        !           478:     char           *endx = dst + len;
        !           479: 
        !           480:     while (want = endx - dst) {
        !           481:        if (bufend - bufidx < 0) {
        !           482:            fatal("Buffer overlow in buf_read\n");
        !           483:        }
        !           484:        while ((have = bufend - bufidx) == 0) {
        !           485:            have = 0;
        !           486:            corrupt |= ar_read();
        !           487:        }
        !           488:        if (have > want) {
        !           489:            have = want;
        !           490:        }
        !           491:        memcpy(dst, bufidx, have);
        !           492:        bufidx += have;
        !           493:        dst += have;
        !           494:        total += have;
        !           495:     }
        !           496:     return (corrupt);
        !           497: }
        !           498: 
        !           499: /* indata - install data from an archive
        !           500:  *
        !           501:  * DESCRIPTION
        !           502:  *
        !           503:  *     Indata writes size bytes of data from the archive buffer to the output 
        !           504:  *     file specified by fd.  The filename which is being written, pointed
        !           505:  *     to by name is provided only for diagnostics.
        !           506:  *
        !           507:  * PARAMETERS
        !           508:  *
        !           509:  *     int     fd      - output file descriptor
        !           510:  *     OFFSET  size    - number of bytes to write to output file
        !           511:  *     char    *name   - name of file which corresponds to fd
        !           512:  *
        !           513:  * RETURNS
        !           514:  *
        !           515:  *     Returns given file descriptor. 
        !           516:  */
        !           517: 
        !           518: #if __STDC__
        !           519: 
        !           520: static int indata(int fd, OFFSET size, char *name)
        !           521: 
        !           522: #else
        !           523: 
        !           524: static int indata(fd, size, name)
        !           525: int             fd;
        !           526: OFFSET          size;
        !           527: char           *name;
        !           528: 
        !           529: #endif
        !           530: {
        !           531:     uint            chunk;
        !           532:     char           *oops;
        !           533:     int             sparse;
        !           534:     int             corrupt;
        !           535:     char           *buf;
        !           536:     uint            avail;
        !           537: 
        !           538:     corrupt = sparse = 0;
        !           539:     oops = (char *)NULL;
        !           540:     while (size) {
        !           541:        corrupt |= buf_in_avail(&buf, &avail);
        !           542:        size -= (chunk = size < avail ? (uint) size : avail);
        !           543:        if (oops == (char *)NULL && (sparse = ar_write(fd, buf, chunk)) < 0) {
        !           544:            oops = strerror();
        !           545:        }
        !           546:        buf_use(chunk);
        !           547:     }
        !           548:     if (corrupt) {
        !           549:        warn(name, "Corrupt archive data");
        !           550:     }
        !           551:     if (oops) {
        !           552:        warn(name, oops);
        !           553:     } else if (sparse > 0 && (lseek(fd, (OFFSET) - 1, 1) < 0
        !           554:                              || write(fd, "", 1) != 1)) {
        !           555:        warn(name, strerror());
        !           556:     }
        !           557:     return (fd);
        !           558: }
        !           559: 
        !           560: 
        !           561: /* outflush - flush the output buffer
        !           562:  *
        !           563:  * DESCRIPTION
        !           564:  *
        !           565:  *     The output buffer is written, if there is anything in it, to the
        !           566:  *     archive file.
        !           567:  */
        !           568: 
        !           569: #if __STDC__
        !           570: 
        !           571: static void outflush(void)
        !           572: 
        !           573: #else
        !           574: 
        !           575: static void outflush()
        !           576: 
        !           577: #endif
        !           578: {
        !           579:     char           *buf;
        !           580:     int             got;
        !           581:     uint            len;
        !           582: 
        !           583:     /* if (bufidx - buf > 0) */
        !           584:        for (buf = bufstart; len = bufidx - buf;) {
        !           585:            if ((got = write(archivefd, buf, MIN(len, blocksize))) > 0) {
        !           586:                buf += got;
        !           587:            } else if (got < 0) {
        !           588:                next(AR_WRITE);
        !           589:            }
        !           590:        }
        !           591:     bufend = (bufidx = bufstart) + blocksize;
        !           592: }
        !           593: 
        !           594: 
        !           595: /* ar_read - fill the archive buffer
        !           596:  *
        !           597:  * DESCRIPTION
        !           598:  *
        !           599:  *     Remembers mid-buffer read failures and reports them the next time 
        !           600:  *     through.  Replaces unreadable data with null characters.   Resets
        !           601:  *     the buffer pointers as appropriate.
        !           602:  *
        !           603:  * RETURNS
        !           604:  *
        !           605:  *     Returns zero with valid data, -1 otherwise. 
        !           606:  */
        !           607: 
        !           608: #if __STDC__
        !           609: 
        !           610: int ar_read(void)
        !           611: 
        !           612: #else
        !           613: 
        !           614: int ar_read()
        !           615: 
        !           616: #endif
        !           617: {
        !           618:     int             got;
        !           619:     static int      failed;
        !           620:     static int             myfld = 0;
        !           621: 
        !           622:     bufend = bufidx = bufstart;
        !           623:     if (!failed) {
        !           624:        if (areof) {
        !           625:            if (total == 0) {
        !           626:                fatal("No input");
        !           627:            } else {
        !           628:                next(AR_READ);
        !           629:            }
        !           630:        }
        !           631:        while (!failed && !areof && bufstart + blocksize - bufend >= blocksize) {
        !           632:            if ((got = read(archivefd, bufend, (unsigned int) blocksize)) > 0) {
        !           633:                bufend += got;
        !           634:                if (myfld == 0)
        !           635:                        myfld++;
        !           636:            } else if (got < 0 && myfld == 0) {
        !           637:                failed = -1;
        !           638:                warnarch(strerror(), (OFFSET) 0 - (bufend - bufidx));
        !           639:            } else {
        !           640:                got = 0;
        !           641:                ++areof;
        !           642:            }
        !           643:         }
        !           644:     }
        !           645:     if (failed && bufend == bufstart) {
        !           646:        failed = 0;
        !           647:        for (got = 0; got < blocksize; ++got) {
        !           648:            *bufend++ = '\0';
        !           649:        }
        !           650:        return (-1);
        !           651:     }
        !           652:     return (0);
        !           653: }
        !           654: 
        !           655: 
        !           656: /* ar_write - write a filesystem block
        !           657:  *
        !           658:  * DESCRIPTION
        !           659:  *
        !           660:  *     Writes len bytes of data data from the specified buffer to the 
        !           661:  *     specified file.   Seeks past sparse blocks. 
        !           662:  *
        !           663:  * PARAMETERS
        !           664:  *
        !           665:  *     int     fd      - file to write to
        !           666:  *     char   *buf     - buffer to get data from
        !           667:  *     uint    len     - number of bytes to transfer
        !           668:  *
        !           669:  * RETURNS
        !           670:  *
        !           671:  *     Returns 0 if the block was written, the given length for a sparse 
        !           672:  *     block or -1 if unsuccessful. 
        !           673:  */
        !           674: 
        !           675: #if __STDC__
        !           676: 
        !           677: static int ar_write(int fd, char *buf, uint len)
        !           678: 
        !           679: #else
        !           680: 
        !           681: static int ar_write(fd, buf, len)
        !           682: int             fd;
        !           683: char           *buf;
        !           684: uint            len;
        !           685: 
        !           686: #endif
        !           687: {
        !           688:     char           *bidx;
        !           689:     char           *bend;
        !           690: 
        !           691:     bend = (bidx = buf) + len;
        !           692:     while (bidx < bend) {
        !           693:        if (*bidx++) {
        !           694:            return (write(fd, buf, len) == len ? 0 : -1);
        !           695:        }
        !           696:     }
        !           697:     return (lseek(fd, (OFFSET) len, 1) < 0 ? -1 : len);
        !           698: }
        !           699: 
        !           700: 
        !           701: /* buf_pad - pad the archive buffer
        !           702:  *
        !           703:  * DESCRIPTION
        !           704:  *
        !           705:  *     Buf_pad writes len zero bytes to the archive buffer in order to 
        !           706:  *     pad it.
        !           707:  *
        !           708:  * PARAMETERS
        !           709:  *
        !           710:  *     OFFSET  pad     - number of zero bytes to pad
        !           711:  *
        !           712:  */
        !           713: 
        !           714: #if __STDC__
        !           715: 
        !           716: static void buf_pad(OFFSET pad)
        !           717: 
        !           718: #else
        !           719: 
        !           720: static void buf_pad(pad)
        !           721: OFFSET           pad;
        !           722: 
        !           723: #endif
        !           724: {
        !           725:     int             idx;
        !           726:     int             have;
        !           727: 
        !           728:     while (pad) {
        !           729:        if ((have = bufend - bufidx) > pad) {
        !           730:            have = pad;
        !           731:        }
        !           732:        for (idx = 0; idx < have; ++idx) {
        !           733:            *bufidx++ = '\0';
        !           734:        }
        !           735:        total += have;
        !           736:        pad -= have;
        !           737:        if (bufend - bufidx == 0) {
        !           738:            outflush();
        !           739:        }
        !           740:     }
        !           741: }
        !           742: 
        !           743: 
        !           744: /* buf_use - allocate buffer space
        !           745:  *
        !           746:  * DESCRIPTION
        !           747:  *
        !           748:  *     Buf_use marks space in the buffer as being used; advancing both the
        !           749:  *     buffer index (bufidx) and the total byte count (total).
        !           750:  *
        !           751:  * PARAMETERS
        !           752:  *
        !           753:  *     uint    len     - Amount of space to allocate in the buffer
        !           754:  */
        !           755: 
        !           756: #if __STDC__
        !           757: 
        !           758: static void buf_use(uint len)
        !           759: 
        !           760: #else
        !           761: 
        !           762: static void buf_use(len)
        !           763: uint            len;
        !           764: 
        !           765: #endif
        !           766: {
        !           767:     bufidx += len;
        !           768:     total += len;
        !           769: }
        !           770: 
        !           771: 
        !           772: /* buf_in_avail - index available input data within the buffer
        !           773:  *
        !           774:  * DESCRIPTION
        !           775:  *
        !           776:  *     Buf_in_avail fills the archive buffer, and points the bufp
        !           777:  *     parameter at the start of the data.  The lenp parameter is
        !           778:  *     modified to contain the number of bytes which were read.
        !           779:  *
        !           780:  * PARAMETERS
        !           781:  *
        !           782:  *     char   **bufp   - pointer to the buffer to read data into
        !           783:  *     uint    *lenp   - pointer to the number of bytes which were read
        !           784:  *                       (returned to the caller)
        !           785:  *
        !           786:  * RETURNS
        !           787:  *
        !           788:  *     Stores a pointer to the data and its length in given locations. 
        !           789:  *     Returns zero with valid data, -1 if unreadable portions were 
        !           790:  *     replaced with nulls. 
        !           791:  *
        !           792:  * ERRORS
        !           793:  *
        !           794:  *     If an error occurs in ar_read, the error code is returned to the
        !           795:  *     calling function.
        !           796:  *
        !           797:  */
        !           798: 
        !           799: #if __STDC__
        !           800: 
        !           801: static int buf_in_avail(char **bufp, uint *lenp)
        !           802: 
        !           803: #else
        !           804: 
        !           805: static int buf_in_avail(bufp, lenp)
        !           806: char          **bufp;
        !           807: uint           *lenp;
        !           808: 
        !           809: #endif
        !           810: {
        !           811:     uint            have;
        !           812:     int             corrupt = 0;
        !           813: 
        !           814:     while ((have = bufend - bufidx) == 0) {
        !           815:        corrupt |= ar_read();
        !           816:     }
        !           817:     *bufp = bufidx;
        !           818:     *lenp = have;
        !           819:     return (corrupt);
        !           820: }
        !           821: 
        !           822: 
        !           823: /* buf_out_avail  - index buffer space for archive output
        !           824:  *
        !           825:  * DESCRIPTION
        !           826:  *
        !           827:  *     Stores a buffer pointer at a given location. Returns the number 
        !           828:  *     of bytes available. 
        !           829:  *
        !           830:  * PARAMETERS
        !           831:  *
        !           832:  *     char    **bufp  - pointer to the buffer which is to be stored
        !           833:  *
        !           834:  * RETURNS
        !           835:  *
        !           836:  *     The number of bytes which are available in the buffer.
        !           837:  *
        !           838:  */
        !           839: 
        !           840: #if __STDC__
        !           841: 
        !           842: static uint buf_out_avail(char **bufp)
        !           843: 
        !           844: #else
        !           845: 
        !           846: static uint buf_out_avail(bufp)
        !           847: char          **bufp;
        !           848: 
        !           849: #endif
        !           850: {
        !           851:     int             have;
        !           852: 
        !           853:     if (bufend - bufidx < 0) {
        !           854:        fatal("Buffer overlow in buf_out_avail\n");
        !           855:     }
        !           856:     if ((have = bufend - bufidx) == 0) {
        !           857:        outflush();
        !           858:     }
        !           859:     *bufp = bufidx;
        !           860:     return (have);
        !           861: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.