Annotation of coherent/e/bin/pax/list.c, revision 1.1

1.1     ! root        1: /* $Source: /src386/usr/bin/pax/list.c,v $
        !             2:  *
        !             3:  * $Revision: 1.1 $
        !             4:  *
        !             5:  * list.c - List all files on an archive
        !             6:  *
        !             7:  * DESCRIPTION
        !             8:  *
        !             9:  *     These function are needed to support archive table of contents and
        !            10:  *     verbose mode during extraction and creation of achives.
        !            11:  *
        !            12:  * AUTHOR
        !            13:  *
        !            14:  *     Mark H. Colburn, NAPS International ([email protected])
        !            15:  *
        !            16:  * Sponsored by The USENIX Association for public distribution. 
        !            17:  *
        !            18:  * Copyright (c) 1989 Mark H. Colburn.
        !            19:  * All rights reserved.
        !            20:  *
        !            21:  * Redistribution and use in source and binary forms are permitted
        !            22:  * provided that the above copyright notice is duplicated in all such 
        !            23:  * forms and that any documentation, advertising materials, and other 
        !            24:  * materials related to such distribution and use acknowledge that the 
        !            25:  * software was developed * by Mark H. Colburn and sponsored by The 
        !            26:  * USENIX Association. 
        !            27:  *
        !            28:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
        !            29:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
        !            30:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
        !            31:  *
        !            32:  * $Log:       list.c,v $
        !            33:  * Revision 1.1  92/08/28  08:02:15  bin
        !            34:  * Initial revision
        !            35:  * 
        !            36:  * Revision 1.1  89/02/14  16:47:59  jep
        !            37:  * Initial revision
        !            38:  * 
        !            39:  * Revision 1.1  88/12/23  18:02:14  mark
        !            40:  * Initial revision
        !            41:  * 
        !            42:  */
        !            43: 
        !            44: #ifndef lint
        !            45: static char *ident = "$Id: list.c,v 1.1 92/08/28 08:02:15 bin Exp Locker: bin $";
        !            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:  * isodigit returns non zero iff argument is an octal digit, zero otherwise
        !            59:  */
        !            60: #define        ISODIGIT(c)     (((c) >= '0') && ((c) <= '7'))
        !            61: 
        !            62: 
        !            63: /* Function Prototypes */
        !            64: 
        !            65: #if __STDC__
        !            66: 
        !            67: static void cpio_entry(char *, Stat *);
        !            68: static void tar_entry(char *, Stat *);
        !            69: static void pax_entry(char *, Stat *);
        !            70: static void print_mode(ushort);
        !            71: static long from_oct(int digs, char *where);
        !            72: 
        !            73: #else /* !__STDC__ */
        !            74: 
        !            75: static void cpio_entry();
        !            76: static void tar_entry();
        !            77: static void pax_entry();
        !            78: static void print_mode();
        !            79: static long from_oct();
        !            80: 
        !            81: #endif /* __STDC__ */
        !            82: 
        !            83: 
        !            84: /* Internal Identifiers */
        !            85: 
        !            86: static char       *monnames[] = {
        !            87:     "Jan", "Feb", "Mar", "Apr", "May", "Jun",
        !            88:     "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
        !            89: };
        !            90: 
        !            91: 
        !            92: /* read_header - read a header record
        !            93:  *
        !            94:  * DESCRIPTION
        !            95:  *
        !            96:  *     Read a record that's supposed to be a header record. Return its 
        !            97:  *     address in "head", and if it is good, the file's size in 
        !            98:  *     asb->sb_size.  Decode things from a file header record into a "Stat". 
        !            99:  *     Also set "head_standard" to !=0 or ==0 depending whether header record 
        !           100:  *     is "Unix Standard" tar format or regular old tar format. 
        !           101:  *
        !           102:  * PARAMETERS
        !           103:  *
        !           104:  *     char   *name            - pointer which will contain name of file
        !           105:  *     Stat   *asb             - pointer which will contain stat info
        !           106:  *
        !           107:  * RETURNS
        !           108:  *
        !           109:  *     Return 1 for success, 0 if the checksum is bad, EOF on eof, 2 for a 
        !           110:  *     record full of zeros (EOF marker). 
        !           111:  */
        !           112: 
        !           113: #if __STDC__
        !           114: 
        !           115: int read_header(char *name, Stat *asb)
        !           116: 
        !           117: #else
        !           118:     
        !           119: int read_header(name, asb)
        !           120: char           *name;
        !           121: Stat           *asb;
        !           122: 
        !           123: #endif
        !           124: {
        !           125:     int             i;
        !           126:     long            sum;
        !           127:     long           recsum;
        !           128:     Link           *link;
        !           129:     char           *p;
        !           130:     char            hdrbuf[BLOCKSIZE];
        !           131: 
        !           132:     memset((char *)asb, 0, sizeof(Stat));
        !           133:     /* read the header from the buffer */
        !           134:     if (buf_read(hdrbuf, BLOCKSIZE) != 0) {
        !           135:        return (EOF);
        !           136:     }
        !           137: 
        !           138:     strcpy(name, hdrbuf);
        !           139: 
        !           140:     recsum = from_oct(8, &hdrbuf[148]);
        !           141:     sum = 0;
        !           142:     p = hdrbuf;
        !           143:     for (i = 0 ; i < 500; i++) {
        !           144: 
        !           145:        /*
        !           146:         * We can't use unsigned char here because of old compilers, e.g. V7. 
        !           147:         */
        !           148:        sum += 0xFF & *p++;
        !           149:     }
        !           150: 
        !           151:     /* Adjust checksum to count the "chksum" field as blanks. */
        !           152:     for (i = 0; i < 8; i++) {
        !           153:        sum -= 0xFF & hdrbuf[148 + i];
        !           154:     }
        !           155:     sum += ' ' * 8;
        !           156: 
        !           157:     if (sum == 8 * ' ') {
        !           158: 
        !           159:        /*
        !           160:         * This is a zeroed record...whole record is 0's except for the 8
        !           161:         * blanks we faked for the checksum field. 
        !           162:         */
        !           163:        return (2);
        !           164:     }
        !           165:     if (sum == recsum) {
        !           166:        /*
        !           167:         * Good record.  Decode file size and return. 
        !           168:         */
        !           169:        if (hdrbuf[156] != LNKTYPE) {
        !           170:            asb->sb_size = from_oct(1 + 12, &hdrbuf[124]);
        !           171:        }
        !           172:        asb->sb_mtime = from_oct(1 + 12, &hdrbuf[136]);
        !           173:        asb->sb_mode = from_oct(8, &hdrbuf[100]);
        !           174: 
        !           175:        if (strcmp(&hdrbuf[257], TMAGIC) == 0) {
        !           176:            /* Unix Standard tar archive */
        !           177:            head_standard = 1;
        !           178: #ifdef NONAMES
        !           179:            asb->sb_uid = from_oct(8, &hdrbuf[108]);
        !           180:            asb->sb_gid = from_oct(8, &hdrbuf[116]);
        !           181: #else
        !           182:            asb->sb_uid = finduid(&hdrbuf[265]);
        !           183:            asb->sb_gid = findgid(&hdrbuf[297]);
        !           184: #endif
        !           185:            switch (hdrbuf[156]) {
        !           186:            case BLKTYPE:
        !           187:            case CHRTYPE:
        !           188:                asb->sb_rdev = makedev(from_oct(8, &hdrbuf[329]),
        !           189:                                      from_oct(8, &hdrbuf[337]));
        !           190:                break;
        !           191:            default:
        !           192:                /* do nothing... */
        !           193:                break;
        !           194:            }
        !           195:        } else {
        !           196:            /* Old fashioned tar archive */
        !           197:            head_standard = 0;
        !           198:            asb->sb_uid = from_oct(8, &hdrbuf[108]);
        !           199:            asb->sb_gid = from_oct(8, &hdrbuf[116]);
        !           200:        }
        !           201: 
        !           202:        switch (hdrbuf[156]) {
        !           203:        case REGTYPE:
        !           204:        case AREGTYPE:
        !           205:            /*
        !           206:             * Berkeley tar stores directories as regular files with a
        !           207:             * trailing /
        !           208:             */
        !           209:            if (name[strlen(name) - 1] == '/') {
        !           210:                name[strlen(name) - 1] = '\0';
        !           211:                asb->sb_mode |= S_IFDIR;
        !           212:            } else {
        !           213:                asb->sb_mode |= S_IFREG;
        !           214:            }
        !           215:            break;
        !           216:        case LNKTYPE:
        !           217:            asb->sb_nlink = 2;
        !           218:            linkto(&hdrbuf[157], asb);
        !           219:            linkto(name, asb);
        !           220:            asb->sb_mode |= S_IFREG;
        !           221:            break;
        !           222:        case BLKTYPE:
        !           223:            asb->sb_mode |= S_IFBLK;
        !           224:            break;
        !           225:        case CHRTYPE:
        !           226:            asb->sb_mode |= S_IFCHR;
        !           227:            break;
        !           228:        case DIRTYPE:
        !           229:            asb->sb_mode |= S_IFDIR;
        !           230:            break;
        !           231: #ifdef S_IFLNK
        !           232:        case SYMTYPE:
        !           233:            asb->sb_mode |= S_IFLNK;
        !           234:            strcpy(asb->sb_link, &hdrbuf[157]);
        !           235:            break;
        !           236: #endif
        !           237: #ifdef S_IFIFO
        !           238:        case FIFOTYPE:
        !           239:            asb->sb_mode |= S_IFIFO;
        !           240:            break;
        !           241: #endif
        !           242: #ifdef S_IFCTG
        !           243:        case CONTTYPE:
        !           244:            asb->sb_mode |= S_IFCTG;
        !           245:            break;
        !           246: #endif
        !           247:        }
        !           248:        return (1);
        !           249:     }
        !           250:     return (0);
        !           251: }
        !           252: 
        !           253: 
        !           254: /* print_entry - print a single table-of-contents entry
        !           255:  *
        !           256:  * DESCRIPTION
        !           257:  * 
        !           258:  *     Print_entry prints a single line of file information.  The format
        !           259:  *     of the line is the same as that used by the LS command.  For some
        !           260:  *     archive formats, various fields may not make any sense, such as
        !           261:  *     the link count on tar archives.  No error checking is done for bad
        !           262:  *     or invalid data.
        !           263:  *
        !           264:  * PARAMETERS
        !           265:  *
        !           266:  *     char   *name            - pointer to name to print an entry for
        !           267:  *     Stat   *asb             - pointer to the stat structure for the file
        !           268:  */
        !           269: 
        !           270: #if __STDC__
        !           271: 
        !           272: void print_entry(char *name, Stat *asb)
        !           273: 
        !           274: #else
        !           275:     
        !           276: void print_entry(name, asb)
        !           277: char           *name;
        !           278: Stat           *asb;
        !           279: 
        !           280: #endif
        !           281: {
        !           282:     switch (ar_interface) {
        !           283:     case TAR:
        !           284:        tar_entry(name, asb);
        !           285:        break;
        !           286:     case CPIO:
        !           287:        cpio_entry(name, asb);
        !           288:        break;
        !           289:     case PAX: pax_entry(name, asb);
        !           290:        break;
        !           291:     }
        !           292: }
        !           293: 
        !           294: 
        !           295: /* cpio_entry - print a verbose cpio-style entry
        !           296:  *
        !           297:  * DESCRIPTION
        !           298:  *
        !           299:  *     Print_entry prints a single line of file information.  The format
        !           300:  *     of the line is the same as that used by the traditional cpio 
        !           301:  *     command.  No error checking is done for bad or invalid data.
        !           302:  *
        !           303:  * PARAMETERS
        !           304:  *
        !           305:  *     char   *name            - pointer to name to print an entry for
        !           306:  *     Stat   *asb             - pointer to the stat structure for the file
        !           307:  */
        !           308: 
        !           309: #if __STDC__
        !           310: 
        !           311: static void cpio_entry(char *name, Stat *asb)
        !           312: 
        !           313: #else
        !           314:     
        !           315: static void cpio_entry(name, asb)
        !           316: char          *name;
        !           317: Stat          *asb;
        !           318: 
        !           319: #endif
        !           320: {
        !           321:     struct tm         *atm;
        !           322:     Link              *from;
        !           323:     struct passwd      *pwp;
        !           324:     struct group       *grp;
        !           325: 
        !           326:     if (f_list && f_verbose) {
        !           327:        fprintf(msgfile, "%-7o", asb->sb_mode);
        !           328:        atm = localtime(&asb->sb_mtime);
        !           329:        if (pwp = getpwuid((int) USH(asb->sb_uid))) {
        !           330:            fprintf(msgfile, "%-6s", pwp->pw_name);
        !           331:        } else {
        !           332:            fprintf(msgfile, "%-6u", USH(asb->sb_uid));
        !           333:        }
        !           334:        fprintf(msgfile,"%7ld  %3s %2d %02d:%02d:%02d %4d  ",
        !           335:                       asb->sb_size, monnames[atm->tm_mon], 
        !           336:                       atm->tm_mday, atm->tm_hour, atm->tm_min, 
        !           337:                       atm->tm_sec, atm->tm_year + 1900);
        !           338:     }
        !           339:     fprintf(msgfile, "%s", name);
        !           340:     if ((asb->sb_nlink > 1) && (from = islink(name, asb))) {
        !           341:        fprintf(msgfile, " linked to %s", from->l_name);
        !           342:     }
        !           343: #ifdef S_IFLNK
        !           344:     if ((asb->sb_mode & S_IFMT) == S_IFLNK) {
        !           345:        fprintf(msgfile, " symbolic link to %s", asb->sb_link);
        !           346:     }
        !           347: #endif /* S_IFLNK */
        !           348:     putc('\n', msgfile);
        !           349: }
        !           350: 
        !           351: 
        !           352: /* tar_entry - print a tar verbose mode entry
        !           353:  *
        !           354:  * DESCRIPTION
        !           355:  *
        !           356:  *     Print_entry prints a single line of tar file information.  The format
        !           357:  *     of the line is the same as that produced by the traditional tar 
        !           358:  *     command.  No error checking is done for bad or invalid data.
        !           359:  *
        !           360:  * PARAMETERS
        !           361:  *
        !           362:  *     char   *name            - pointer to name to print an entry for
        !           363:  *     Stat   *asb             - pointer to the stat structure for the file
        !           364:  */
        !           365: 
        !           366: #if __STDC__
        !           367: 
        !           368: static void tar_entry(char *name, Stat *asb)
        !           369: 
        !           370: #else
        !           371:     
        !           372: static void tar_entry(name, asb)
        !           373: char           *name;
        !           374: Stat            *asb;
        !           375: 
        !           376: #endif
        !           377: {
        !           378:     struct tm                 *atm;
        !           379:     int                        i;
        !           380:     int                        mode;
        !           381:     char               *symnam = "NULL";
        !           382:     Link               *link;
        !           383: 
        !           384:     if ((mode = asb->sb_mode & S_IFMT) == S_IFDIR) {
        !           385:        return;                 /* don't print directories */
        !           386:     }
        !           387:     if (f_extract) {
        !           388:        switch (mode) {
        !           389: #ifdef S_IFLNK
        !           390:        case S_IFLNK:   /* This file is a symbolic link */
        !           391:            i = readlink(name, symnam, PATH_MAX - 1);
        !           392:            if (i < 0) {                /* Could not find symbolic link */
        !           393:                warn("can't read symbolic link", strerror());
        !           394:            } else {            /* Found symbolic link filename */
        !           395:                symnam[i] = '\0';
        !           396:                fprintf(msgfile, "x %s symbolic link to %s\n", name, symnam);
        !           397:            }
        !           398:            break;
        !           399: #endif
        !           400:        case S_IFREG:   /* It is a link or a file */
        !           401:            if ((asb->sb_nlink > 1) && (link = islink(name, asb))) {
        !           402:                fprintf(msgfile, "%s linked to %s\n", name, link->l_name); 
        !           403:            } else {
        !           404:                fprintf(msgfile, "x %s, %ld bytes, %d tape blocks\n", 
        !           405:                        name, asb->sb_size, ROUNDUP(asb->sb_size, 
        !           406:                        BLOCKSIZE) / BLOCKSIZE);
        !           407:            }
        !           408:        }
        !           409:     } else if (f_append || f_create) {
        !           410:        switch (mode) {
        !           411: #ifdef S_IFLNK
        !           412:        case S_IFLNK:   /* This file is a symbolic link */
        !           413:            i = readlink(name, symnam, PATH_MAX - 1);
        !           414:            if (i < 0) {                /* Could not find symbolic link */
        !           415:                warn("can't read symbolic link", strerror());
        !           416:            } else {            /* Found symbolic link filename */
        !           417:                symnam[i] = '\0';
        !           418:                fprintf(msgfile, "a %s symbolic link to %s\n", name, symnam);
        !           419:            }
        !           420:            break;
        !           421: #endif
        !           422:        case S_IFREG:   /* It is a link or a file */
        !           423:            fprintf(msgfile, "a %s ", name);
        !           424:            if ((asb->sb_nlink > 1) && (link = islink(name, asb))) {
        !           425:                fprintf(msgfile, "link to %s\n", link->l_name); 
        !           426:            } else {
        !           427:                fprintf(msgfile, "%ld Blocks\n", 
        !           428:                        ROUNDUP(asb->sb_size, BLOCKSIZE) / BLOCKSIZE);
        !           429:            }
        !           430:            break;
        !           431:        }
        !           432:     } else if (f_list) {
        !           433:        if (f_verbose) {
        !           434:            atm = localtime(&asb->sb_mtime);
        !           435:            print_mode(asb->sb_mode);
        !           436:            fprintf(msgfile," %d/%d %6d %3s %2d %02d:%02d %4d %s",
        !           437:                    asb->sb_uid, asb->sb_gid, asb->sb_size,
        !           438:                    monnames[atm->tm_mon], atm->tm_mday, atm->tm_hour, 
        !           439:                    atm->tm_min, atm->tm_year + 1900, name);
        !           440:        } else {
        !           441:            fprintf(msgfile, "%s", name);
        !           442:        }
        !           443:        switch (mode) {
        !           444: #ifdef S_IFLNK
        !           445:        case S_IFLNK:   /* This file is a symbolic link */
        !           446:            i = readlink(name, symnam, PATH_MAX - 1);
        !           447:            if (i < 0) {                /* Could not find symbolic link */
        !           448:                warn("can't read symbolic link", strerror());
        !           449:            } else {            /* Found symbolic link filename */
        !           450:                symnam[i] = '\0';
        !           451:                fprintf(msgfile, " symbolic link to %s", symnam);
        !           452:            }
        !           453:            break;
        !           454: #endif
        !           455:        case S_IFREG:   /* It is a link or a file */
        !           456:            if ((asb->sb_nlink > 1) && (link = islink(name, asb))) {
        !           457:                fprintf(msgfile, " linked to %s", link->l_name);
        !           458:            }
        !           459:            break;              /* Do not print out directories */
        !           460:        }
        !           461:        fputc('\n', msgfile);
        !           462:     } else {
        !           463:        fprintf(msgfile, "? %s %ld blocks\n", name,
        !           464:                ROUNDUP(asb->sb_size, BLOCKSIZE) / BLOCKSIZE);
        !           465:     }
        !           466: }
        !           467: 
        !           468: 
        !           469: /* pax_entry - print a verbose cpio-style entry
        !           470:  *
        !           471:  * DESCRIPTION
        !           472:  *
        !           473:  *     Print_entry prints a single line of file information.  The format
        !           474:  *     of the line is the same as that used by the LS command.  
        !           475:  *     No error checking is done for bad or invalid data.
        !           476:  *
        !           477:  * PARAMETERS
        !           478:  *
        !           479:  *     char   *name            - pointer to name to print an entry for
        !           480:  *     Stat   *asb             - pointer to the stat structure for the file
        !           481:  */
        !           482: 
        !           483: #if __STDC__
        !           484: 
        !           485: static void pax_entry(char *name, Stat *asb)
        !           486: 
        !           487: #else
        !           488:     
        !           489: static void pax_entry(name, asb)
        !           490: char          *name;
        !           491: Stat          *asb;
        !           492: 
        !           493: #endif
        !           494: {
        !           495:     struct tm         *atm;
        !           496:     Link              *from;
        !           497:     struct passwd      *pwp;
        !           498:     struct group       *grp;
        !           499: 
        !           500:     if (f_list && f_verbose) {
        !           501:        print_mode(asb->sb_mode);
        !           502:        fprintf(msgfile, " %2d", asb->sb_nlink);
        !           503:        atm = localtime(&asb->sb_mtime);
        !           504:        if (pwp = getpwuid((int) USH(asb->sb_uid))) {
        !           505:            fprintf(msgfile, " %-8s", pwp->pw_name);
        !           506:        } else {
        !           507:            fprintf(msgfile, " %-8u", USH(asb->sb_uid));
        !           508:        }
        !           509:        if (grp = getgrgid((int) USH(asb->sb_gid))) {
        !           510:            fprintf(msgfile, " %-8s", grp->gr_name);
        !           511:        } else {
        !           512:            fprintf(msgfile, " %-8u", USH(asb->sb_gid));
        !           513:        }
        !           514:        switch (asb->sb_mode & S_IFMT) {
        !           515:        case S_IFBLK:
        !           516:        case S_IFCHR:
        !           517:            fprintf(msgfile, "\t%3d, %3d",
        !           518:                           major(asb->sb_rdev), minor(asb->sb_rdev));
        !           519:            break;
        !           520:        case S_IFREG:
        !           521:            fprintf(msgfile, "\t%8ld", asb->sb_size);
        !           522:            break;
        !           523:        default:
        !           524:            fprintf(msgfile, "\t        ");
        !           525:        }
        !           526:        fprintf(msgfile," %3s %2d %02d:%02d ",
        !           527:                monnames[atm->tm_mon], atm->tm_mday, 
        !           528:                atm->tm_hour, atm->tm_min);
        !           529:     }
        !           530:     fprintf(msgfile, "%s", name);
        !           531:     if ((asb->sb_nlink > 1) && (from = islink(name, asb))) {
        !           532:        fprintf(msgfile, " == %s", from->l_name);
        !           533:     }
        !           534: #ifdef S_IFLNK
        !           535:     if ((asb->sb_mode & S_IFMT) == S_IFLNK) {
        !           536:        fprintf(msgfile, " -> %s", asb->sb_link);
        !           537:     }
        !           538: #endif /* S_IFLNK */
        !           539:     putc('\n', msgfile);
        !           540: }
        !           541: 
        !           542: 
        !           543: /* print_mode - fancy file mode display
        !           544:  *
        !           545:  * DESCRIPTION
        !           546:  *
        !           547:  *     Print_mode displays a numeric file mode in the standard unix
        !           548:  *     representation, ala ls (-rwxrwxrwx).  No error checking is done
        !           549:  *     for bad mode combinations.  FIFOS, sybmbolic links, sticky bits,
        !           550:  *     block- and character-special devices are supported if supported
        !           551:  *     by the hosting implementation.
        !           552:  *
        !           553:  * PARAMETERS
        !           554:  *
        !           555:  *     ushort  mode    - The integer representation of the mode to print.
        !           556:  */
        !           557: 
        !           558: #if __STDC__
        !           559: 
        !           560: static void print_mode(ushort mode)
        !           561: 
        !           562: #else
        !           563:     
        !           564: static void print_mode(mode)
        !           565: ushort mode;
        !           566: 
        !           567: #endif
        !           568: {
        !           569:     /* Tar does not print the leading identifier... */
        !           570:     if (ar_interface != TAR) {
        !           571:        switch (mode & S_IFMT) {
        !           572:        case S_IFDIR: 
        !           573:            putc('d', msgfile); 
        !           574:            break;
        !           575: #ifdef S_IFLNK
        !           576:        case S_IFLNK: 
        !           577:            putc('l', msgfile); 
        !           578:            break;
        !           579: #endif /* S_IFLNK */
        !           580:        case S_IFBLK: 
        !           581:            putc('b', msgfile); 
        !           582:            break;
        !           583:        case S_IFCHR: 
        !           584:            putc('c', msgfile); 
        !           585:            break;
        !           586: #ifdef S_IFIFO
        !           587:        case S_IFIFO: 
        !           588:            putc('p', msgfile); 
        !           589:            break; 
        !           590: #endif /* S_IFIFO */ 
        !           591:        case S_IFREG: 
        !           592:        default:
        !           593:            putc('-', msgfile); 
        !           594:            break;
        !           595:        }
        !           596:     }
        !           597:     putc(mode & 0400 ? 'r' : '-', msgfile);
        !           598:     putc(mode & 0200 ? 'w' : '-', msgfile);
        !           599:     putc(mode & 0100
        !           600:         ? mode & 04000 ? 's' : 'x'
        !           601:         : mode & 04000 ? 'S' : '-', msgfile);
        !           602:     putc(mode & 0040 ? 'r' : '-', msgfile);
        !           603:     putc(mode & 0020 ? 'w' : '-', msgfile);
        !           604:     putc(mode & 0010
        !           605:         ? mode & 02000 ? 's' : 'x'
        !           606:         : mode & 02000 ? 'S' : '-', msgfile);
        !           607:     putc(mode & 0004 ? 'r' : '-', msgfile);
        !           608:     putc(mode & 0002 ? 'w' : '-', msgfile);
        !           609:     putc(mode & 0001
        !           610:         ? mode & 01000 ? 't' : 'x'
        !           611:         : mode & 01000 ? 'T' : '-', msgfile);
        !           612: }
        !           613: 
        !           614: 
        !           615: /* from_oct - quick and dirty octal conversion
        !           616:  *
        !           617:  * DESCRIPTION
        !           618:  *
        !           619:  *     From_oct will convert an ASCII representation of an octal number
        !           620:  *     to the numeric representation.  The number of characters to convert
        !           621:  *     is given by the parameter "digs".  If there are less numbers than
        !           622:  *     specified by "digs", then the routine returns -1.
        !           623:  *
        !           624:  * PARAMETERS
        !           625:  *
        !           626:  *     int digs        - Number to of digits to convert 
        !           627:  *     char *where     - Character representation of octal number
        !           628:  *
        !           629:  * RETURNS
        !           630:  *
        !           631:  *     The value of the octal number represented by the first digs
        !           632:  *     characters of the string where.  Result is -1 if the field 
        !           633:  *     is invalid (all blank, or nonoctal). 
        !           634:  *
        !           635:  * ERRORS
        !           636:  *
        !           637:  *     If the field is all blank, then the value returned is -1.
        !           638:  *
        !           639:  */
        !           640: 
        !           641: #if __STDC__
        !           642: 
        !           643: static long from_oct(int digs, char *where)
        !           644: 
        !           645: #else
        !           646: 
        !           647: static long from_oct(digs, where)
        !           648: int             digs;          /* number of characters to convert */
        !           649: char           *where;         /* character representation of octal number */
        !           650: 
        !           651: #endif
        !           652: {
        !           653:     long            value;
        !           654: 
        !           655:     while (isspace(*where)) {  /* Skip spaces */
        !           656:        where++;
        !           657:        if (--digs <= 0) {
        !           658:            return(-1);         /* All blank field */
        !           659:        }
        !           660:     }
        !           661:     value = 0;
        !           662:     while (digs > 0 && ISODIGIT(*where)) {     /* Scan til nonoctal */
        !           663:        value = (value << 3) | (*where++ - '0');
        !           664:        --digs;
        !           665:     }
        !           666: 
        !           667:     if (digs > 0 && *where && !isspace(*where)) {
        !           668:        return(-1);             /* Ended on non-space/nul */
        !           669:     }
        !           670:     return(value);
        !           671: }

unix.superglobalmegacorp.com

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