Annotation of coherent/d/usr/bin/pax/shipping/buffer.c, revision 1.1.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.