From: stephen sp106@unix.york.ac.uk
Subject: where is 'find'?
Date: Sun, 8 Oct 1995 15:17:56 -0400 [thread overview]
Message-ID: <19951008191756.3lKLLGaMI_rfOVXaQab4sal3Si2OvFWX7rTzvz5EAt8@z> (raw)
In article <199510050558.HAA02659@ns.stellar.zw> you wrote:
: On Sat, 30 Sep 1995 11:46:46 GMT, you wrote:
: I'd appreciate a copy of the sources
Just in case he didn't send you them here is a program I wrote a while ago
to do similar things.
/*
* stat : A program to tell you about files.
* usage:read the source.
*/
#include <grp.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/sysmacros.h>
#include <sys/types.h>
#include <time.h>
#include <ustat.h>
/*
* Points to argv[0].
*/
char *progname;
/*
* Return a string containing the representation of
* the time_t.
*/
#define MAX_TIME_LEN 128
char *datestring(time_t t)
{
static char buf[MAX_TIME_LEN];
cftime(buf, "%C", &t);
return buf;
}
char *shortdatestring(time_t t)
{
static char buf[MAX_TIME_LEN];
cftime(buf, "%D", &t);
return buf;
}
/*
* String used for the %E format specifier. A quick way to
* Find out everything about the file.
*/
char *everythingstring =
"Filename %f\n"
"Size %s\n"
"Mode %o (%l)\n"
"Inode number %i\n"
"Dir Device %d (%D)\n"
"Device number %r (%R)\n"
"Link number %n\n"
"UID %u (%U)\n"
"GID %g (%G)\n"
"Access time %a (%A)\n"
"Modification %m (%M)\n"
"Status change %c (%C)\n"
"Blocksize %z\n"
"No. blocks %b\n\n"
;
char filechar(mode_t m)
{
/*
* If it's a regular file check for execute permission. Of
* couse it may be executable but not by you ;-).
*/
if (S_ISREG(m))
return (m & S_IXUSR || m & S_IXGRP || m & S_IXOTH) ? '*' : ' ';
if (S_ISDIR(m)) return '/';
if (S_ISCHR(m)) return '>';
if (S_ISBLK(m)) return '#';
if (S_ISFIFO(m)) return '|';
}
/*
* Transform the numberic mode into a string.
* There is I think no better way.
*/
char *modestring(mode_t mode)
{
static char string[24];
char *p = string;
/*
* Type of file. These constants are bollocks.
*/
if (S_ISFIFO(mode)) *p++ = 'f';
if (S_ISCHR(mode)) *p++ = 'c';
if (S_ISBLK(mode)) *p++ = 'b';
if (S_ISREG(mode)) *p++ = 'o';
if (S_ISDIR(mode)) *p++ = 'd';
/*
* Sticky setuid and setgid.
*/
if (mode & S_ISUID) *p++ = 's';
if (mode & S_ISGID) *p++ = 'g';
if (mode & S_ISVTX) *p++ = 't';
*p++ = ':';
/*
* User protections.
*/
*p++ = (mode & S_IRUSR) ? 'r' : '-';
*p++ = (mode & S_IWUSR) ? 'w' : '-';
*p++ = (mode & S_IXUSR) ? 'x' : '-';
/*
* Group protections.
*/
*p++ = (mode & S_IRGRP) ? 'r' : '-';
*p++ = (mode & S_IWGRP) ? 'w' : '-';
*p++ = (mode & S_IXGRP) ? 'x' : '-';
/*
* Other protections.
*/
*p++ = (mode & S_IROTH) ? 'r' : '-';
*p++ = (mode & S_IWOTH) ? 'w' : '-';
*p++ = (mode & S_IXOTH) ? 'x' : '-';
*p = '\0';
return string;
}
void usage()
{
static char *spec =
"The format string consists of plain text and format specifiers. The text is\n"
"printed for each file with the format specifiers replaced with the file's\n"
"information.\n"
"Format specifiers:\n\n"
" %% Print one %.\n"
" %s Print file size.\n"
" %f Print filename.\n"
" %o Print file mode (in octal).\n"
" %l Print file mode as text.\n"
" %i Print Inode number.\n"
" %d Print device number (of device holding the "
"directory).\n"
" %D Print (major/minor) of device.\n"
" %r Print device number (if this is a special file).\n"
" %R Print (major/minor) of device.\n"
" %n Print number of links.\n"
" %(u|g) Print (user|group) id.\n"
" %(U|G) Print (user|group) name.\n"
" %(a|m|c) Print (access|modification|status change) time "
"(as integer).\n"
" %(A|M|C) Print times as strings.\n"
" %.(A|M|C) Print times as short strings.\n"
" %z Print blocksize for device.\n"
" %b Print number of blocks.\n"
" %E Print all file information.\n"
" %* Print character representing file type.\n"
" \\n End of line.\n"
" \\t Tab.\n"
;
fprintf(stderr, "Usage: %s format file [files]\n\n%s", progname, spec);
exit(EXIT_FAILURE);
}
void statfile(char *format, char *filename)
{
struct stat st;
if (-1 == stat(filename, &st)) {
fprintf(stderr, "Couldn't stat %s.\n", filename);
exit(EXIT_FAILURE);
}
/*
* Go through each letter in the format string.
*/
do {
switch (*format) {
case '%':
switch (*++format) {
case '%':
putchar('%');
break;
case 'f':
printf("%s", filename);
break;
case 'i':
printf("%ld", (long) st.st_ino);
break;
case 'o':
printf("%o", (int) st.st_mode);
break;
case 'd':
printf("%ld", (long) st.st_dev);
break;
case 'D':
printf("%d/%d", major(st.st_dev), minor(st.st_dev));
break;
case 'r':
printf("%ld", (long) st.st_rdev);
break;
case 'R':
printf("%d/%d", major(st.st_rdev), minor(st.st_rdev));
break;
case 'n':
printf("%ld", (long) st.st_nlink);
break;
case 'u':
printf("%ld", (long) st.st_uid);
break;
case 'U':
printf("%s", getpwuid(st.st_uid)->pw_name);
break;
case 'g':
printf("%ld", (long) st.st_gid);
break;
case 'G':
printf("%s", getgrgid(st.st_gid)->gr_name);
break;
case 's':
printf("%ld", (long) st.st_size);
break;
case 'a':
printf("%ld", (long) st.st_atime);
break;
case 'A':
printf("%s", datestring(st.st_atime));
break;
case 'm':
printf("%ld", (long) st.st_mtime);
break;
case 'M':
printf("%s", datestring(st.st_mtime));
break;
case 'c':
printf("%ld", (long) st.st_ctime);
break;
case 'C':
printf("%s", datestring(st.st_ctime));
break;
case 'z':
printf("%ld", st.st_blksize);
break;
case 'b':
printf("%ld", st.st_blocks);
break;
case 'l':
printf("%s", modestring(st.st_mode));
break;
case '*':
putchar(filechar(st.st_mode));
break;
case 'E': /* Everything. */
statfile(everythingstring, filename);
break;
case '.': /* Further options. */
switch(*++format) {
case 'A':
printf("%s", shortdatestring(st.st_atime));
break;
case 'M':
printf("%s", shortdatestring(st.st_mtime));
break;
case 'C':
printf("%s", shortdatestring(st.st_ctime));
break;
default:
printf("\n");
fprintf(stderr, "Unknow extra format specifier %%.%c.\n",
*format);
usage();
break;
}
break;
default:
printf("\n");
fprintf(stderr, "Unknown format specifier %%%c.\n",
*format);
usage();
break;
}
break;
case '\\':
switch (*++format) {
case 'n':
putchar('\n');
break;
case 't':
putchar('\t');
break;
}
break;
default:
putchar(*format);
break;
}
} while (*++format);
}
main(int argc, char **argv)
{
char *format = argv[1];
int i;
progname = argv[0];
if (argc < 3)
usage();
/*
* Jump over argv[0].
*/
++argv;
/*
* Process argv[2] to argv[argc-1].
*/
for (i = 2; i < argc; i++)
statfile(format, *++argv);
exit(EXIT_SUCCESS);
return EXIT_SUCCESS;
}
--
###################################################
# sp106@york.ac.uk # http://www.york.ac.uk/~sp106 #
# Shapes in the drink like Christ #
# Cracks in the pale blue wall #
###################################################
next reply other threads:[~1995-10-08 19:17 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
1995-10-08 19:17 stephen [this message]
-- strict thread matches above, loose matches on Subject: below --
1995-10-08 19:19 stephen
1995-10-04 14:19 Jeremy
1995-10-04 5:55 ME
1995-09-30 19:46 Martin
1995-09-30 17:27 Jeremy
1995-09-30 15:00 John
1995-09-30 4:30 Scott
1995-09-27 15:26 Steve
1995-09-27 13:06 presotto
1995-09-27 7:11 Kenji
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=19951008191756.3lKLLGaMI_rfOVXaQab4sal3Si2OvFWX7rTzvz5EAt8@z \
--to=9fans@9fans.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).