9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
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                    #
###################################################








             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).