home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 1: Amiga
/
FrozenFish-Apr94.iso
/
bbs
/
gnu
/
find-3.8-src.lha
/
src
/
amiga
/
find-3.8
/
lib
/
listfile.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-12-13
|
6KB
|
255 lines
/* listfile.c -- display a long listing of a file
Copyright (C) 1985, 1988, 1991 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifndef S_ISCHR
#define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
#endif
#ifndef S_ISBLK
#define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
#endif
#if defined(S_IFLNK) && !defined(S_ISLNK)
#define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
#endif
/* Extract or fake data from a `struct stat'.
ST_NBLOCKS: Number of 512-byte blocks in the file
(including indirect blocks). */
#ifdef _POSIX_SOURCE
#define ST_NBLOCKS(statp) (((statp)->st_size + 512 - 1) / 512)
#else /* !_POSIX_SOURCE */
#ifndef HAVE_ST_BLOCKS
#define ST_NBLOCKS(statp) (st_blocks ((statp)->st_size))
#else /* HAVE_ST_BLOCKS */
#if defined(hpux) || defined(__hpux__)
/* HP-UX, perhaps uniquely, counts st_blocks in 1024-byte units.
This loses when mixing HP-UX and 4BSD filesystems, though. */
#define ST_NBLOCKS(statp) ((statp)->st_blocks * 2)
#else /* !hpux */
#define ST_NBLOCKS(statp) ((statp)->st_blocks)
#endif /* hpux */
#endif /* HAVE_ST_BLOCKS */
#endif /* _POSIX_SOURCE */
/* Convert B 512-byte blocks to kilobytes if K is nonzero,
otherwise return it unchanged. */
#define convert_blocks(b, k) ((k) ? ((b) + 1) / 2 : (b))
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <pwd.h>
#include <grp.h>
#ifndef _POSIX_VERSION
struct passwd *getpwuid ();
struct group *getgrgid ();
#endif
#include <time.h>
#if defined(HAVE_STRING_H) || defined(STDC_HEADERS)
#include <string.h>
#else
#include <strings.h>
#endif
/* Since major is a function on SVR4, we can't use `ifndef major'. */
#ifdef MAJOR_IN_MKDEV
#include <sys/mkdev.h>
#define HAVE_MAJOR
#endif
#ifdef MAJOR_IN_SYSMACROS
#include <sys/sysmacros.h>
#define HAVE_MAJOR
#endif
#ifdef major /* Might be defined in sys/types.h. */
#define HAVE_MAJOR
#endif
#ifndef HAVE_MAJOR
#define major(dev) (((dev) >> 8) & 0xff)
#define minor(dev) ((dev) & 0xff)
#endif
#undef HAVE_MAJOR
#include <errno.h>
#ifdef STDC_HEADERS
#include <stdlib.h>
#else
char *getenv ();
extern int errno;
#endif
#if defined(S_ISLNK)
int readlink ();
#endif
char *xmalloc ();
void error ();
void mode_string ();
char *get_link_name ();
char *getgroup ();
char *getuser ();
void print_name_with_quoting ();
void
list_file (name, statp)
char *name;
struct stat *statp;
{
static int kilobytes = -1; /* -1 = uninitialized, 0 = 512, 1 = 1024. */
char modebuf[20];
char timebuf[40];
time_t current_time = time ((time_t *) 0);
if (kilobytes == -1)
kilobytes = getenv ("POSIXLY_CORRECT") == 0;
mode_string (statp->st_mode, modebuf);
modebuf[10] = '\0';
strcpy (timebuf, ctime (&statp->st_mtime));
if (current_time > statp->st_mtime + 6L * 30L * 24L * 60L * 60L /* Old. */
|| current_time < statp->st_mtime - 60L * 60L) /* In the future. */
{
/* The file is fairly old or in the future.
POSIX says the cutoff is 6 months old;
approximate this by 6*30 days.
Allow a 1 hour slop factor for what is considered "the future",
to allow for NFS server/client clock disagreement.
Show the year instead of the time of day. */
strcpy (timebuf + 11, timebuf + 19);
}
timebuf[16] = 0;
printf ("%6u ", statp->st_ino);
printf ("%4u ", convert_blocks (ST_NBLOCKS (statp), kilobytes));
/* The space between the mode and the number of links is the POSIX
"optional alternate access method flag". */
printf ("%s %3u ", modebuf, statp->st_nlink);
printf ("%-8.8s ", getuser (statp->st_uid));
printf ("%-8.8s ", getgroup (statp->st_gid));
if (S_ISCHR (statp->st_mode) || S_ISBLK (statp->st_mode))
#ifdef HAVE_ST_RDEV
printf ("%3u, %3u ", major (statp->st_rdev), minor (statp->st_rdev));
#else
printf (" ");
#endif
else
printf ("%8lu ", statp->st_size);
printf ("%s ", timebuf + 4);
print_name_with_quoting (name);
#ifdef S_IFLNK
if (S_ISLNK (statp->st_mode))
{
char *linkname = get_link_name (name, statp);
if (linkname)
{
fputs (" -> ", stdout);
print_name_with_quoting (linkname);
free (linkname);
}
}
#endif
putchar ('\n');
}
void
print_name_with_quoting (p)
register char *p;
{
register unsigned char c;
while ((c = *p++) != '\0')
{
switch (c)
{
case '\\':
printf ("\\\\");
break;
case '\n':
printf ("\\n");
break;
case '\b':
printf ("\\b");
break;
case '\r':
printf ("\\r");
break;
case '\t':
printf ("\\t");
break;
case '\f':
printf ("\\f");
break;
case ' ':
printf ("\\ ");
break;
case '"':
printf ("\\\"");
break;
default:
if (c > 040 && c < 0177)
putchar (c);
else
printf ("\\%03o", (unsigned int) c);
}
}
}
#ifdef S_IFLNK
char *
get_link_name (filename, statp)
char *filename;
struct stat *statp;
{
register char *linkbuf;
register int bufsiz = statp->st_size;
linkbuf = (char *) xmalloc (bufsiz + 1);
linkbuf[bufsiz] = 0;
if (readlink (filename, linkbuf, bufsiz) < 0)
{
error (0, errno, "%s", filename);
free (linkbuf);
return 0;
}
return linkbuf;
}
#endif