|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.