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