list.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 579 行 · 第 1/2 页

C
579
字号
                        break;
                case LF_BLK:
                        modes[0] = 'b';
                        break;
                case LF_CHR:
                        modes[0] = 'c';
                        break;
                case LF_FIFO:
                        modes[0] = 'f';
                        break;
                case LF_CONTIG:
                        modes[0] = '=';
                        break;
                }
#ifdef MSDOS
                if (convmode(xname) & O_TEXT)
                        modes[0] = 'a';
#endif

                demode((unsigned) phstat->st_mode, modes + 1);

                /* Timestamp */
                longie = phstat->st_mtime;
#ifdef MSDOS
                /* following is due to a bug in MSDOS's ctime() */
                if (longie < 0x10000000L) {
                    memset(blanks, ' ', sizeof(blanks)-1);
                    blanks[sizeof(blanks)-1] = '\0';
                    timestamp = blanks;
                }
                else
#endif
                    timestamp = ctime((unsigned long*)(&longie));
                timestamp[16] = '\0';
                timestamp[24] = '\0';

                /* User and group names */
                if (*head->header.uname && header_std)
                {
                        user = head->header.uname;
                }
                else
                {
                        user = uform;
                        (void) sprintf(uform, "%d", (int) phstat->st_uid);
                }
                if (*head->header.gname && header_std)
                {
                        group = head->header.gname;
                }
                else
                {
                        group = gform;
                        (void) sprintf(gform, "%d", (int) phstat->st_gid);
                }

                /* Format the file size or major/minor device numbers */
                switch (head->header.linkflag)
                {
                case LF_CHR:
                case LF_BLK:
#ifdef V7
                        (void) sprintf(size, "(%d, %d) %D",
#else
                        (void) sprintf(size, "%d, %d",
#endif
                                major(phstat->st_dev),
                                minor(phstat->st_dev),
                                /* size has meaning for Minix - JER */
                                (long)phstat->st_size);
                        break;

                default:
#ifdef V7
                        (void) sprintf(size, "%D", (long) phstat->st_size);
#else
                        (void) sprintf(size, "%ld", (long) phstat->st_size);
#endif
                }

                /* Figure out padding and print the whole line. */
                pad = strlen(user) + strlen(group) + strlen(size) + 1;
                if (pad > ugswidth)
                        ugswidth = pad;

                        printf("%s %s/%s ", modes, user, group);
                        for (i = ugswidth - pad; i > 0; i--) putchar(' ');
                        printf("%s %s %s %s", size, timestamp+4,
                                timestamp+20, head->header.name);
        }
        else
        {
                printf("%s", head->header.name);
        }
        if (strcmp(head->header.name, xname))
                printf(" (%s)", xname);

        if (f_verbose)
                switch (head->header.linkflag)
                {
                case LF_SYMLINK:
                        printf(" -> %s\n", head->header.linkname);
                        break;

                case LF_LINK:
                        printf(" link to %s\n", head->header.linkname);
                        break;

                default:
                        printf(" unknown file type '%c'\n", head->header.linkflag);
                        break;

                case LF_OLDNORMAL:
                case LF_NORMAL:
                case LF_CHR:
                case LF_BLK:
                case LF_DIR:
                case LF_FIFO:
                case LF_CONTIG:
                        putc('\n', stdout);
                        break;
                }
        else
        {
                putc('\n', stdout);
        }

        /* FIXME: we don't print major/minor device numbers */
}

/*
 * Print a similar line when we make a directory automatically.
 */
void pr_mkdir( char *pathname, int length, int mode )
{
        char            modes[11];

        if (f_verbose)
        {
                /* File type and modes */
                modes[0] = 'd';
                demode((unsigned) mode, modes + 1);

                annofile(stdout, (char *) NULL);
                printf("%s %*s %.*s\n",
                        modes,
                        ugswidth + DATEWIDTH,
                        "Creating directory:",
                        length,
                        pathname);
        }
}


/*
 * Skip over <size> bytes of data in records in the archive.
 */
void skip_file( long   size )
{
        union record   *x;

        while (size > 0)
        {
                x = findrec();
                if (x == NULL)
                {                                               /* Check it... */
                        annorec(stderr, tar);
                        fprintf(stderr, "Unexpected EOF on archive file\n");
                        exit(EX_BADARCH);
                }
                userec(x);
                size -= RECORDSIZE;
        }
}


/*
 * Decode the mode string from a stat entry into a 9-char string and a null.
 * This is good, portable coding, John!
 */
void demode( unsigned int mode, char *string )
{
        unsigned int    mask;
        char             *rwx = "rwxrwxrwx";

        for (mask = 0400; mask != 0; mask >>= 1)
        {
                if (mode & mask)
                        *string++ = *rwx++;
                else
                {
                        *string++ = '-';
                        rwx++;
                }
        }

#ifdef S_ISUID
        if (mode & S_ISUID)
                if (string[-7] == 'x')
                        string[-7] = 's';
                else
                        string[-7] = 'S';
#endif
#ifdef S_ISGID
        if (mode & S_ISGID)
                if (string[-4] == 'x')
                        string[-4] = 's';
                else
                        string[-4] = 'S';
#endif
#ifdef S_ISVTX
        if (mode & S_ISVTX)
                if (string[-1] == 'x')
                        string[-1] = 't';
                else
                        string[-1] = 'T';
#endif
        *string = '\0';
}

/*
 * Main loop for reading an archive.
 */
void read_and( void (*do_something)( char *dummy ) )
{
        int             status = 1;
        int             prev_status;
        char           *xname;

        name_gather();                          /* Gather all the names */
        open_archive(1);                        /* Open for reading */

        for (;;)
        {
                prev_status = status;
                status = read_header();
                switch (status)
                {

                case 1:                         /* Valid header */
                        /* We should decode next field (mode) first... */
                        /* Ensure incoming names are null terminated. */
                        head->header.name[NAMSIZ - 1] = '\0';
                        /* make a valid filename for this OS */
                        xname = fixname(head->header.name);

                        if (!name_match(head->header.name))
                        {
                                /* Skip past it in the archive */
                                userec(head);
                                /* Skip to the next header on the archive */
                                if (head->header.linkflag != LF_BLK &&
                                    head->header.linkflag != LF_CHR)
                                        skip_file((long) phstat->st_size);
                                continue;
                        }

                        (*do_something) (xname);
                        continue;

                        /*
                         * If the previous header was good, tell them that we are
                         * skipping bad ones.
                         */
                case 0:                         /* Invalid header */
        case0:
                        userec(head);
                        if (prev_status == 1)
                        {
                                annorec(stderr, tar);
                                fprintf(stderr,
                                        "Skipping to next file header...\n");
                        }
                        continue;

                case 2:                         /* Block of zeroes */
                        if (f_ignorez)
                                goto case0;             /* Just skip if asked */
                        /* FALL THRU */
                case EOF:                               /* End of archive */
                        break;
                }
                break;
        };

        close_archive();
        names_notfound();                       /* Print names not found */
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?