Annotation of coherent/e/bin/pax/buffer.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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