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 + -
显示快捷键?