Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 28 Jul 1999 15:46:54 -0400
From:      Keith Stevenson <k.stevenson@louisville.edu>
To:        freebsd-hackers@freebsd.org
Subject:   Was someone looking for a BSD licensed stat(1)?
Message-ID:  <19990728154654.A26747@homer.louisville.edu>

next in thread | raw e-mail | index | archive | help
I hacked this together last night.  The only GNU code I looked at was the
Linux stat(1u) man page.  (A man page is forthcoming, especially if there is
some interest in using this implementation.)  The code is also available at
http://www.kagekaze.org/stat.c

Regards,
--Keith Stevenson--

-- 
Keith Stevenson
System Programmer - Data Center Services - University of Louisville
k.stevenson@louisville.edu
PGP key fingerprint =  4B 29 A8 95 A8 82 EA A2  29 CE 68 DE FC EE B6 A0



/* stat.c: Human readable interface to stat(2) system call */
/*-
 * Copyright (c) 1999 Keith Stevenson
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *      $Id: stat.c,v 1.2 1999/07/28 19:33:10 ktstev01 Exp $
 */

#ifndef lint
static const char copyright[] =
	"Copyright (c) 1999\nKeith Stevenson.  All rights reserved.\n";
static const char rcsid[] =
	"$Id: stat.c,v 1.2 1999/07/28 19:33:10 ktstev01 Exp $";
#endif /* not lint */

#include <sys/types.h>
#include <sys/stat.h>

#include <errno.h>
#include <grp.h>
#include <pwd.h>
#include <stdio.h>
#include <string.h>
#include <sysexits.h>
#include <time.h>


/* stat:  Display the contents of an inode in a human friendly format. */
int
main(int argc, char *argv[])
{
	char	ftype[20];
	char	fmode[11];
	int	count;

	struct group	*gp;
	struct passwd	*pw;
	struct stat	inode;
	struct tm	*atime, *mtime, *ctime;

	for (count = 1; count < argc; count++) {

		if (lstat(argv[count], &inode) != -1) {

			/* Initialize */
			memset(fmode, '-', sizeof(fmode));
			fmode[10] = '\0';

			/* Interpret file type */
			switch (inode.st_mode & S_IFMT) {
			case S_IFIFO:
				strncpy(ftype, "FIFO", sizeof(ftype));
				fmode[0] = 'p';
				break;
			case S_IFCHR:
				strncpy(ftype, "Character Special",
				    sizeof(ftype));
				fmode[0] = 'c';
				break;
			case S_IFDIR:
				strncpy(ftype, "Directory", sizeof(ftype));
				fmode[0] = 'd';
				break;
			case S_IFBLK:
				strncpy(ftype, "Block Special", sizeof(ftype));
				fmode[0] = 'b';
				break;
			case S_IFREG:
				strncpy(ftype, "Regular", sizeof(ftype));
				break;
			case S_IFLNK:
				strncpy(ftype, "Symbolic Link", sizeof(ftype));
				fmode[0] = 'l';
				break;
			case S_IFSOCK:
				strncpy(ftype, "Socket", sizeof(ftype));
				fmode[0] = 's';
				break;
			case S_IFWHT:
				strncpy(ftype, "Whiteout", sizeof(ftype));
				fmode[0] = '?';
				break;
			default:
				strncpy(ftype, "Unknown", sizeof(ftype));
				fmode[0] = '?';
				break;
			}

			/* Interpret file mode */
			if (inode.st_mode & S_IRUSR)
				fmode[1] = 'r';
			if (inode.st_mode & S_IWUSR)
				fmode[2] = 'w';
			if (inode.st_mode & S_IXUSR)
				fmode[3] = 'x';
			if (inode.st_mode & S_ISUID) {
				if (inode.st_mode & S_IXUSR)
					fmode[3] = 's';
				else
					fmode[3] = 'S';
			}
			if (inode.st_mode & S_IRGRP)
				fmode[4] = 'r';
			if (inode.st_mode & S_IWGRP)
				fmode[5] = 'w';
			if (inode.st_mode & S_IXGRP)
				fmode[6] = 'x';
			if (inode.st_mode & S_ISGID) {
				if (inode.st_mode & S_IXGRP)
					fmode[6] = 's';
				else
					fmode[6] = 'S';
			}
			if (inode.st_mode & S_IROTH)
				fmode[7] = 'r';
			if (inode.st_mode & S_IWOTH)
				fmode[8] = 'w';
			if (inode.st_mode & S_IXOTH)
				fmode[9] = 'x';
			if (inode.st_mode & S_ISVTX) {
				if (inode.st_mode & S_IXOTH)
					fmode[9] = 't';
				else
					fmode[9] = 'T';
			}

			/* Get ownerships and times */
			pw = getpwuid(inode.st_uid);
			gp = getgrgid(inode.st_gid);
			atime = localtime(&inode.st_atime);
			mtime = localtime(&inode.st_mtime);
			ctime = localtime(&inode.st_ctime);

			/* Pretty print it*/
			printf("File: \"%s\"\n", argv[count]);
			printf("Size: %qu\t", inode.st_size);
			printf("Allocated Blocks: %qd\t", inode.st_blocks);
			printf("Filetype: %s\n", ftype);
			printf("Mode: (%.4o/%s)\t", (inode.st_mode & 07777),
			    fmode);
			if (pw != NULL)
				printf("Uid: (%hu/%s)\t", inode.st_uid,
				    pw->pw_name);
			else
				printf("Uid: (%hu/%hu)\t", inode.st_uid,
				    inode.st_uid);
			if (gp != NULL)
				printf("Gid: (%hu/%s)\n", inode.st_gid,
				    gp->gr_name);
			else
				printf("Gid: (%hu/%hu)\n", inode.st_gid,
				    inode.st_gid);
			printf("Device: %u\t", inode.st_dev);
			printf("Inode: %u\t", inode.st_ino);
			printf("Links: %hu\n", inode.st_nlink);
			printf("Access: %s", asctime(atime));
			printf("Modify: %s", asctime(mtime));
			printf("Change: %s\n", asctime(ctime));
		} else {
			switch(errno) {
			case ENOTDIR:
			case ENAMETOOLONG:
			case ELOOP:
				fprintf(stderr,
				    "Invalid file name specified.\n");
				exit(EX_SOFTWARE);
				break;
			case ENOENT:
				fprintf(stderr, "File not found.\n");
				exit(EX_SOFTWARE);
				break;
			case EACCES:
				fprintf(stderr, "Permission denied.\n");
				exit(EX_NOPERM);
				break;
			case EFAULT:
				fprintf(stderr, "Can't stat file.\n");
				exit(EX_SOFTWARE);
				break;
			case EIO:
				fprintf(stderr, "Can't stat file.\n");
				exit(EX_OSERR);
				break;
			default:
				fprintf(stderr, "Can't stat file.\n");
				exit(EX_SOFTWARE);
				break;
			}
			/* Not Reached */
			exit(EX_SOFTWARE);

		}
	}
	exit(EX_OK);
}


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19990728154654.A26747>