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

1.1     ! root        1: /* $Source: /newbits/usr/bin/pax/shipping/extract.c,v $
        !             2:  *
        !             3:  * $Revision: 1.1 $
        !             4:  *
        !             5:  * extract.c - Extract files from a tar archive. 
        !             6:  *
        !             7:  * DESCRIPTION
        !             8:  *
        !             9:  * AUTHOR
        !            10:  *
        !            11:  *     Mark H. Colburn, NAPS International ([email protected])
        !            12:  *
        !            13:  * Sponsored by The USENIX Association for public distribution. 
        !            14:  *
        !            15:  * Copyright (c) 1989 Mark H. Colburn.
        !            16:  * All rights reserved.
        !            17:  *
        !            18:  * Redistribution and use in source and binary forms are permitted
        !            19:  * provided that the above copyright notice is duplicated in all such 
        !            20:  * forms and that any documentation, advertising materials, and other 
        !            21:  * materials related to such distribution and use acknowledge that the 
        !            22:  * software was developed * by Mark H. Colburn and sponsored by The 
        !            23:  * USENIX Association. 
        !            24:  *
        !            25:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
        !            26:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
        !            27:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
        !            28:  *
        !            29:  * $Log:       /newbits/usr/bin/pax/shipping/extract.c,v $
        !            30:  * Revision 1.1        91/02/05  11:55:52      bin
        !            31:  * Initial revision
        !            32:  * 
        !            33:  * Revision 1.3  89/02/12  10:29:43  mark
        !            34:  * Fixed misspelling of Replstr
        !            35:  * 
        !            36:  * Revision 1.2  89/02/12  10:04:24  mark
        !            37:  * 1.2 release fixes
        !            38:  * 
        !            39:  * Revision 1.1  88/12/23  18:02:07  mark
        !            40:  * Initial revision
        !            41:  * 
        !            42:  */
        !            43: 
        !            44: #ifndef lint
        !            45: static char *ident = "$Id: extract.c,v 1.3 89/02/12 10:29:43 mark Exp Locker: mark $";
        !            46: static char *copyright = "Copyright (c) 1989 Mark H. Colburn.\nAll rights reserved.\n";
        !            47: #endif /* ! lint */
        !            48: 
        !            49: 
        !            50: /* Headers */
        !            51: 
        !            52: #include "pax.h"
        !            53: 
        !            54: 
        !            55: /* Defines */
        !            56: 
        !            57: /*
        !            58:  * Swap bytes. 
        !            59:  */
        !            60: #define        SWAB(n) ((((ushort)(n) >> 8) & 0xff) | (((ushort)(n) << 8) & 0xff00))
        !            61: 
        !            62: 
        !            63: /* Function Prototypes */
        !            64: 
        !            65: #if __STDC__
        !            66: 
        !            67: static int inbinary(char *, char *, Stat *);
        !            68: static int inascii(char *, char *, Stat *);
        !            69: static int inswab(char *, char *, Stat *);
        !            70: static int readtar(char *, Stat *);
        !            71: static int readcpio(char *, Stat *);
        !            72: 
        !            73: #else /* !__STDC__ */
        !            74: 
        !            75: static int inbinary();
        !            76: static int inascii();
        !            77: static int inswab();
        !            78: static int readtar();
        !            79: static int readcpio();
        !            80: 
        !            81: #endif /* __STDC__ */
        !            82: 
        !            83: 
        !            84: /* read_archive - read in an archive
        !            85:  *
        !            86:  * DESCRIPTION
        !            87:  *
        !            88:  *     Read_archive is the central entry point for reading archives.
        !            89:  *     Read_archive determines the proper archive functions to call
        !            90:  *     based upon the archive type being processed.
        !            91:  *
        !            92:  * RETURNS
        !            93:  *
        !            94:  */
        !            95: 
        !            96: #if __STDC__
        !            97: 
        !            98: int read_archive(void)
        !            99: 
        !           100: #else
        !           101:     
        !           102: int read_archive()
        !           103: 
        !           104: #endif
        !           105: {
        !           106:     Stat            sb;
        !           107:     char            name[PATH_MAX + 1];
        !           108:     int             match;
        !           109:     int                    pad;
        !           110: 
        !           111:     name_gather();             /* get names from command line */
        !           112:     name[0] = '\0';
        !           113:     while (get_header(name, &sb) == 0) {
        !           114:        match = name_match(name) ^ f_reverse_match;
        !           115:        if (f_list) {           /* only wanted a table of contents */
        !           116:            if (match) {
        !           117:                print_entry(name, &sb);
        !           118:            }
        !           119:            if (((ar_format == TAR) 
        !           120:                ? buf_skip(ROUNDUP((OFFSET) sb.sb_size, BLOCKSIZE)) 
        !           121:                : buf_skip((OFFSET) sb.sb_size)) < 0) {
        !           122:                warn(name, "File data is corrupt");
        !           123:            }
        !           124:        } else if (match) {
        !           125:            if (rplhead != (Replstr *)NULL) {
        !           126:                rpl_name(name);
        !           127:                if (strlen(name) == 0) {
        !           128:                    continue;
        !           129:                }
        !           130:            }
        !           131:            if (get_disposition("extract", name) || 
        !           132:                 get_newname(name, sizeof(name))) {
        !           133:                /* skip file... */
        !           134:                if (((ar_format == TAR) 
        !           135:                    ? buf_skip(ROUNDUP((OFFSET) sb.sb_size, BLOCKSIZE)) 
        !           136:                    : buf_skip((OFFSET) sb.sb_size)) < 0) {
        !           137:                    warn(name, "File data is corrupt");
        !           138:                }
        !           139:                continue;
        !           140:            } 
        !           141:            if (inentry(name, &sb) < 0) {
        !           142:                warn(name, "File data is corrupt");
        !           143:            }
        !           144:            if (f_verbose) {
        !           145:                print_entry(name, &sb);
        !           146:            }
        !           147:            if (ar_format == TAR && sb.sb_nlink > 1) {
        !           148:                /*
        !           149:                 * This kludge makes sure that the link table is cleared
        !           150:                 * before attempting to process any other links.
        !           151:                 */
        !           152:                if (sb.sb_nlink > 1) {
        !           153:                    linkfrom(name, &sb);
        !           154:                }
        !           155:            }
        !           156:            if (ar_format == TAR && (pad = sb.sb_size % BLOCKSIZE) != 0) {
        !           157:                pad = BLOCKSIZE - pad;
        !           158:                buf_skip((OFFSET) pad);
        !           159:            }
        !           160:        } else {
        !           161:            if (((ar_format == TAR) 
        !           162:                ? buf_skip(ROUNDUP((OFFSET) sb.sb_size, BLOCKSIZE)) 
        !           163:                : buf_skip((OFFSET) sb.sb_size)) < 0) {
        !           164:                warn(name, "File data is corrupt");
        !           165:            }
        !           166:        }
        !           167:     }
        !           168:     close_archive();
        !           169: }
        !           170: 
        !           171: 
        !           172: 
        !           173: /* get_header - figures which type of header needs to be read.
        !           174:  *
        !           175:  * DESCRIPTION
        !           176:  *
        !           177:  *     This is merely a single entry point for the two types of archive
        !           178:  *     headers which are supported.  The correct header is selected
        !           179:  *     depending on the archive type.
        !           180:  *
        !           181:  * PARAMETERS
        !           182:  *
        !           183:  *     char    *name   - name of the file (passed to header routine)
        !           184:  *     Stat    *asb    - Stat block for the file (passed to header routine)
        !           185:  *
        !           186:  * RETURNS
        !           187:  *
        !           188:  *     Returns the value which was returned by the proper header
        !           189:  *     function.
        !           190:  */
        !           191: 
        !           192: #if __STDC__
        !           193: 
        !           194: int get_header(char *name, Stat *asb)
        !           195: 
        !           196: #else
        !           197:     
        !           198: int get_header(name, asb)
        !           199: char *name;
        !           200: Stat *asb;
        !           201: 
        !           202: #endif
        !           203: {
        !           204:     if (ar_format == TAR) {
        !           205:        return(readtar(name, asb));
        !           206:     } else {
        !           207:        return(readcpio(name, asb));
        !           208:     }
        !           209: }
        !           210: 
        !           211: 
        !           212: /* readtar - read a tar header
        !           213:  *
        !           214:  * DESCRIPTION
        !           215:  *
        !           216:  *     Tar_head read a tar format header from the archive.  The name
        !           217:  *     and asb parameters are modified as appropriate for the file listed
        !           218:  *     in the header.   Name is assumed to be a pointer to an array of
        !           219:  *     at least PATH_MAX bytes.
        !           220:  *
        !           221:  * PARAMETERS
        !           222:  *
        !           223:  *     char    *name   - name of the file for which the header is
        !           224:  *                       for.  This is modified and passed back to
        !           225:  *                       the caller.
        !           226:  *     Stat    *asb    - Stat block for the file for which the header
        !           227:  *                       is for.  The fields of the stat structure are
        !           228:  *                       extracted from the archive header.  This is
        !           229:  *                       also passed back to the caller.
        !           230:  *
        !           231:  * RETURNS
        !           232:  *
        !           233:  *     Returns 0 if a valid header was found, or -1 if EOF is
        !           234:  *     encountered.
        !           235:  */
        !           236: 
        !           237: #if __STDC__
        !           238: 
        !           239: static int readtar(char *name, Stat *asb)
        !           240: 
        !           241: #else
        !           242:     
        !           243: static int readtar(name, asb)
        !           244: char   *name;
        !           245: Stat    *asb;
        !           246: 
        !           247: #endif
        !           248: {
        !           249:     int             status = 3;        /* Initial status at start of archive */
        !           250:     static int      prev_status;
        !           251: 
        !           252:     for (;;) {
        !           253:        prev_status = status;
        !           254:        status = read_header(name, asb);
        !           255:        switch (status) {
        !           256:        case 1:         /* Valid header */
        !           257:                return(0);
        !           258:        case 0:         /* Invalid header */
        !           259:            switch (prev_status) {
        !           260:            case 3:             /* Error on first record */
        !           261:                warn(ar_file, "This doesn't look like a tar archive");
        !           262:                /* FALLTHRU */
        !           263:            case 2:             /* Error after record of zeroes */
        !           264:            case 1:             /* Error after header rec */
        !           265:                warn(ar_file, "Skipping to next file...");
        !           266:                /* FALLTHRU */
        !           267:            default:
        !           268:            case 0:             /* Error after error */
        !           269:                break;
        !           270:            }
        !           271:            break;
        !           272: 
        !           273:        case 2:                 /* Record of zeroes */
        !           274:        case EOF:               /* End of archive */
        !           275:        default:
        !           276:            return(-1);
        !           277:        }
        !           278:     }
        !           279: }
        !           280: 
        !           281: 
        !           282: /* readcpio - read a CPIO header 
        !           283:  *
        !           284:  * DESCRIPTION
        !           285:  *
        !           286:  *     Read in a cpio header.  Understands how to determine and read ASCII, 
        !           287:  *     binary and byte-swapped binary headers.  Quietly translates 
        !           288:  *     old-fashioned binary cpio headers (and arranges to skip the possible 
        !           289:  *     alignment byte). Returns zero if successful, -1 upon archive trailer. 
        !           290:  *
        !           291:  * PARAMETERS
        !           292:  *
        !           293:  *     char    *name   - name of the file for which the header is
        !           294:  *                       for.  This is modified and passed back to
        !           295:  *                       the caller.
        !           296:  *     Stat    *asb    - Stat block for the file for which the header
        !           297:  *                       is for.  The fields of the stat structure are
        !           298:  *                       extracted from the archive header.  This is
        !           299:  *                       also passed back to the caller.
        !           300:  *
        !           301:  * RETURNS
        !           302:  *
        !           303:  *     Returns 0 if a valid header was found, or -1 if EOF is
        !           304:  *     encountered.
        !           305:  */
        !           306: 
        !           307: #if __STDC__
        !           308: 
        !           309: static int readcpio(char *name, Stat *asb)
        !           310: 
        !           311: #else
        !           312:     
        !           313: static int readcpio(name, asb)
        !           314: char           *name;
        !           315: Stat           *asb;
        !           316: 
        !           317: #endif
        !           318: {
        !           319:     OFFSET          skipped;
        !           320:     char            magic[M_STRLEN];
        !           321:     static int      align;
        !           322: 
        !           323:     if (align > 0) {
        !           324:        buf_skip((OFFSET) align);
        !           325:     }
        !           326:     align = 0;
        !           327:     for (;;) {
        !           328:        buf_read(magic, M_STRLEN);
        !           329:        skipped = 0;
        !           330:        while ((align = inascii(magic, name, asb)) < 0
        !           331:               && (align = inbinary(magic, name, asb)) < 0
        !           332:               && (align = inswab(magic, name, asb)) < 0) {
        !           333:            if (++skipped == 1) {
        !           334:                if (total - sizeof(magic) == 0) {
        !           335:                    fatal("Unrecognizable archive");
        !           336:                }
        !           337:                warnarch("Bad magic number", (OFFSET) sizeof(magic));
        !           338:                if (name[0]) {
        !           339:                    warn(name, "May be corrupt");
        !           340:                }
        !           341:            }
        !           342:            memcpy(magic, magic + 1, sizeof(magic) - 1);
        !           343:            buf_read(magic + sizeof(magic) - 1, 1);
        !           344:        }
        !           345:        if (skipped) {
        !           346:            warnarch("Apparently resynchronized", (OFFSET) sizeof(magic));
        !           347:            warn(name, "Continuing");
        !           348:        }
        !           349:        if (strcmp(name, TRAILER) == 0) {
        !           350:            return (-1);
        !           351:        }
        !           352:        if (nameopt(name) >= 0) {
        !           353:            break;
        !           354:        }
        !           355:        buf_skip((OFFSET) asb->sb_size + align);
        !           356:     }
        !           357: #ifdef S_IFLNK
        !           358:     if ((asb->sb_mode & S_IFMT) == S_IFLNK) {
        !           359:        if (buf_read(asb->sb_link, (uint) asb->sb_size) < 0) {
        !           360:            warn(name, "Corrupt symbolic link");
        !           361:            return (readcpio(name, asb));
        !           362:        }
        !           363:        asb->sb_link[asb->sb_size] = '\0';
        !           364:        asb->sb_size = 0;
        !           365:     }
        !           366: #endif                         /* S_IFLNK */
        !           367: 
        !           368:     /* destroy absolute pathnames for security reasons */
        !           369:     if (name[0] == '/') {
        !           370:        if (name[1]) {
        !           371:            while (name[0] = name[1]) {
        !           372:                ++name;
        !           373:            }
        !           374:        } else {
        !           375:            name[0] = '.';
        !           376:        }
        !           377:     }
        !           378:     asb->sb_atime = asb->sb_ctime = asb->sb_mtime;
        !           379:     if (asb->sb_nlink > 1) {
        !           380:        linkto(name, asb);
        !           381:     }
        !           382:     return (0);
        !           383: }
        !           384: 
        !           385: 
        !           386: /* inswab - read a reversed by order binary header
        !           387:  *
        !           388:  * DESCRIPTIONS
        !           389:  *
        !           390:  *     Reads a byte-swapped CPIO binary archive header
        !           391:  *
        !           392:  * PARMAMETERS
        !           393:  *
        !           394:  *     char    *magic  - magic number to match
        !           395:  *     char    *name   - name of the file which is stored in the header.
        !           396:  *                       (modified and passed back to caller).
        !           397:  *     Stat    *asb    - stat block for the file (modified and passed back
        !           398:  *                       to the caller).
        !           399:  *
        !           400:  *
        !           401:  * RETURNS
        !           402:  *
        !           403:  *     Returns the number of trailing alignment bytes to skip; -1 if 
        !           404:  *     unsuccessful. 
        !           405:  *
        !           406:  */
        !           407: 
        !           408: #if __STDC__
        !           409: 
        !           410: static int inswab(char *magic, char *name, Stat *asb)
        !           411: 
        !           412: #else
        !           413:     
        !           414: static int inswab(magic, name, asb)
        !           415: char           *magic;
        !           416: char           *name;
        !           417: Stat           *asb;
        !           418: 
        !           419: #endif
        !           420: {
        !           421:     ushort          namesize;
        !           422:     uint            namefull;
        !           423:     Binary          binary;
        !           424: 
        !           425:     if (*((ushort *) magic) != SWAB(M_BINARY)) {
        !           426:        return (-1);
        !           427:     }
        !           428:     memcpy((char *) &binary,
        !           429:                  magic + sizeof(ushort),
        !           430:                  M_STRLEN - sizeof(ushort));
        !           431:     if (buf_read((char *) &binary + M_STRLEN - sizeof(ushort),
        !           432:                 sizeof(binary) - (M_STRLEN - sizeof(ushort))) < 0) {
        !           433:        warnarch("Corrupt swapped header",
        !           434:                 (OFFSET) sizeof(binary) - (M_STRLEN - sizeof(ushort)));
        !           435:        return (-1);
        !           436:     }
        !           437:     asb->sb_dev = (dev_t) SWAB(binary.b_dev);
        !           438:     asb->sb_ino = (ino_t) SWAB(binary.b_ino);
        !           439:     asb->sb_mode = SWAB(binary.b_mode);
        !           440:     asb->sb_uid = SWAB(binary.b_uid);
        !           441:     asb->sb_gid = SWAB(binary.b_gid);
        !           442:     asb->sb_nlink = SWAB(binary.b_nlink);
        !           443:     asb->sb_rdev = (dev_t) SWAB(binary.b_rdev);
        !           444:     asb->sb_mtime = SWAB(binary.b_mtime[0]) << 16 | SWAB(binary.b_mtime[1]);
        !           445:     asb->sb_size = SWAB(binary.b_size[0]) << 16 | SWAB(binary.b_size[1]);
        !           446:     if ((namesize = SWAB(binary.b_name)) == 0 || namesize >= PATH_MAX) {
        !           447:        warnarch("Bad swapped pathname length",
        !           448:                 (OFFSET) sizeof(binary) - (M_STRLEN - sizeof(ushort)));
        !           449:        return (-1);
        !           450:     }
        !           451:     if (buf_read(name, namefull = namesize + namesize % 2) < 0) {
        !           452:        warnarch("Corrupt swapped pathname", (OFFSET) namefull);
        !           453:        return (-1);
        !           454:     }
        !           455:     if (name[namesize - 1] != '\0') {
        !           456:        warnarch("Bad swapped pathname", (OFFSET) namefull);
        !           457:        return (-1);
        !           458:     }
        !           459:     return (asb->sb_size % 2);
        !           460: }
        !           461: 
        !           462: 
        !           463: /* inascii - read in an ASCII cpio header
        !           464:  *
        !           465:  * DESCRIPTION
        !           466:  *
        !           467:  *     Reads an ASCII format cpio header
        !           468:  *
        !           469:  * PARAMETERS
        !           470:  *
        !           471:  *     char    *magic  - magic number to match
        !           472:  *     char    *name   - name of the file which is stored in the header.
        !           473:  *                       (modified and passed back to caller).
        !           474:  *     Stat    *asb    - stat block for the file (modified and passed back
        !           475:  *                       to the caller).
        !           476:  *
        !           477:  * RETURNS
        !           478:  *
        !           479:  *     Returns zero if successful; -1 otherwise. Assumes that  the entire 
        !           480:  *     magic number has been read. 
        !           481:  */
        !           482: 
        !           483: #if __STDC__
        !           484: 
        !           485: static int inascii(char *magic, char *name, Stat *asb)
        !           486: 
        !           487: #else
        !           488:     
        !           489: static int inascii(magic, name, asb)
        !           490: char           *magic;
        !           491: char           *name;
        !           492: Stat           *asb;
        !           493: 
        !           494: #endif
        !           495: {
        !           496:     uint            namelen;
        !           497:     char            header[H_STRLEN + 1];
        !           498: 
        !           499:     if (strncmp(magic, M_ASCII, M_STRLEN) != 0) {
        !           500:        return (-1);
        !           501:     }
        !           502:     if (buf_read(header, H_STRLEN) < 0) {
        !           503:        warnarch("Corrupt ASCII header", (OFFSET) H_STRLEN);
        !           504:        return (-1);
        !           505:     }
        !           506:     header[H_STRLEN] = '\0';
        !           507:     if (sscanf(header, H_SCAN, &asb->sb_dev,
        !           508:               &asb->sb_ino, &asb->sb_mode, &asb->sb_uid,
        !           509:               &asb->sb_gid, &asb->sb_nlink, &asb->sb_rdev,
        !           510:               &asb->sb_mtime, &namelen, &asb->sb_size) != H_COUNT) {
        !           511:        warnarch("Bad ASCII header", (OFFSET) H_STRLEN);
        !           512:        return (-1);
        !           513:     }
        !           514:     if (namelen == 0 || namelen >= PATH_MAX) {
        !           515:        warnarch("Bad ASCII pathname length", (OFFSET) H_STRLEN);
        !           516:        return (-1);
        !           517:     }
        !           518:     if (buf_read(name, namelen) < 0) {
        !           519:        warnarch("Corrupt ASCII pathname", (OFFSET) namelen);
        !           520:        return (-1);
        !           521:     }
        !           522:     if (name[namelen - 1] != '\0') {
        !           523:        warnarch("Bad ASCII pathname", (OFFSET) namelen);
        !           524:        return (-1);
        !           525:     }
        !           526:     return (0);
        !           527: }
        !           528: 
        !           529: 
        !           530: /* inbinary - read a binary header
        !           531:  *
        !           532:  * DESCRIPTION
        !           533:  *
        !           534:  *     Reads a CPIO format binary header.
        !           535:  *
        !           536:  * PARAMETERS
        !           537:  *
        !           538:  *     char    *magic  - magic number to match
        !           539:  *     char    *name   - name of the file which is stored in the header.
        !           540:  *                       (modified and passed back to caller).
        !           541:  *     Stat    *asb    - stat block for the file (modified and passed back
        !           542:  *                       to the caller).
        !           543:  *
        !           544:  * RETURNS
        !           545:  *
        !           546:  *     Returns the number of trailing alignment bytes to skip; -1 if 
        !           547:  *     unsuccessful. 
        !           548:  */
        !           549: 
        !           550: #if __STDC__
        !           551: 
        !           552: static int inbinary(char *magic, char *name, Stat *asb)
        !           553: 
        !           554: #else
        !           555:     
        !           556: static int inbinary(magic, name, asb)
        !           557: char           *magic;
        !           558: char           *name;
        !           559: Stat           *asb;
        !           560: 
        !           561: #endif
        !           562: {
        !           563:     uint            namefull;
        !           564:     Binary          binary;
        !           565: 
        !           566:     if (*((ushort *) magic) != M_BINARY) {
        !           567:        return (-1);
        !           568:     }
        !           569:     memcpy((char *) &binary,
        !           570:                  magic + sizeof(ushort),
        !           571:                  M_STRLEN - sizeof(ushort));
        !           572:     if (buf_read((char *) &binary + M_STRLEN - sizeof(ushort),
        !           573:                 sizeof(binary) - (M_STRLEN - sizeof(ushort))) < 0) {
        !           574:        warnarch("Corrupt binary header",
        !           575:                 (OFFSET) sizeof(binary) - (M_STRLEN - sizeof(ushort)));
        !           576:        return (-1);
        !           577:     }
        !           578:     asb->sb_dev = binary.b_dev;
        !           579:     asb->sb_ino = binary.b_ino;
        !           580:     asb->sb_mode = binary.b_mode;
        !           581:     asb->sb_uid = binary.b_uid;
        !           582:     asb->sb_gid = binary.b_gid;
        !           583:     asb->sb_nlink = binary.b_nlink;
        !           584:     asb->sb_rdev = binary.b_rdev;
        !           585:     asb->sb_mtime = binary.b_mtime[0] << 16 | binary.b_mtime[1];
        !           586:     asb->sb_size = binary.b_size[0] << 16 | binary.b_size[1];
        !           587:     if (binary.b_name == 0 || binary.b_name >= PATH_MAX) {
        !           588:        warnarch("Bad binary pathname length",
        !           589:                 (OFFSET) sizeof(binary) - (M_STRLEN - sizeof(ushort)));
        !           590:        return (-1);
        !           591:     }
        !           592:     if (buf_read(name, namefull = binary.b_name + binary.b_name % 2) < 0) {
        !           593:        warnarch("Corrupt binary pathname", (OFFSET) namefull);
        !           594:        return (-1);
        !           595:     }
        !           596:     if (name[binary.b_name - 1] != '\0') {
        !           597:        warnarch("Bad binary pathname", (OFFSET) namefull);
        !           598:        return (-1);
        !           599:     }
        !           600:     return (asb->sb_size % 2);
        !           601: }

unix.superglobalmegacorp.com

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