⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 finfo.c

📁 UNIX下SH的实现源码
💻 C
字号:
/* * finfo - print file info */#include <sys/types.h>#include "posixstat.h"#include <stdio.h>#include <pwd.h>#include <grp.h>#include <errno.h>#include "shell.h"#include "builtins.h"#include "common.h"#ifndef errnoextern int	errno;#endifextern char	*strrchr();extern char	**make_builtin_argv ();static int	printst();static int	printsome();static int	printfinfo();static int	finfo_main();extern int	sh_optind;extern char	*sh_optarg;extern char	*this_command_name;static char	*prog;static int	pmask;#define OPT_UID		0x00001#define OPT_GID		0x00002#define OPT_DEV		0x00004#define OPT_INO		0x00008#define OPT_PERM	0x00010#define OPT_LNKNAM	0x00020#define OPT_FID		0x00040#define OPT_NLINK	0x00080#define OPT_RDEV	0x00100#define OPT_SIZE	0x00200#define OPT_ATIME	0x00400#define OPT_MTIME	0x00800#define OPT_CTIME	0x01000#define OPT_BLKSIZE	0x02000#define OPT_BLKS	0x04000#define OPT_FTYPE	0x08000#define OPT_PMASK	0x10000#define OPT_OPERM	0x20000#define OPT_ASCII	0x1000000#define OPTIONS		"acdgiflmnopsuACGMP:U"static intoctal(s)char	*s;{	int	r;	r = *s - '0';	while (*++s >= '0' && *s <= '7')		r = (r * 8) + (*s - '0');	return r;}static intfinfo_main(argc, argv)int	argc;char	**argv;{	register int	i;	int	mode, flags, opt;	sh_optind = 0;	/* XXX */	prog = base_pathname(argv[0]);	if (argc == 1) {		builtin_usage();		return(1);	}	flags = 0;	while ((opt = sh_getopt(argc, argv, OPTIONS)) != EOF) {		switch(opt) {		case 'a': flags |= OPT_ATIME; break;		case 'A': flags |= OPT_ATIME|OPT_ASCII; break;		case 'c': flags |= OPT_CTIME; break;		case 'C': flags |= OPT_CTIME|OPT_ASCII; break;		case 'd': flags |= OPT_DEV; break;		case 'i': flags |= OPT_INO; break;		case 'f': flags |= OPT_FID; break;		case 'g': flags |= OPT_GID; break;		case 'G': flags |= OPT_GID|OPT_ASCII; break;		case 'l': flags |= OPT_LNKNAM; break;		case 'm': flags |= OPT_MTIME; break;		case 'M': flags |= OPT_MTIME|OPT_ASCII; break;		case 'n': flags |= OPT_NLINK; break;		case 'o': flags |= OPT_OPERM; break;		case 'p': flags |= OPT_PERM; break;		case 'P': flags |= OPT_PMASK; pmask = octal(sh_optarg); break;		case 's': flags |= OPT_SIZE; break;		case 'u': flags |= OPT_UID; break;		case 'U': flags |= OPT_UID|OPT_ASCII; break;		default: builtin_usage (); return(1);		}	}	argc -= sh_optind;	argv += sh_optind;	if (argc == 0) {		builtin_usage();		return(1);	}	for (i = 0; i < argc; i++)		opt = flags ? printsome (argv[i], flags) : printfinfo(argv[i]);	return(opt);}static struct stat *getstat(f)char	*f;{	static struct stat st;	int	fd, r;	long	lfd;	if (strncmp(f, "/dev/fd/", 8) == 0) {		if (legal_number(f + 8, &lfd) == 0) {			builtin_error("%s: invalid fd", f + 8);			return ((struct stat *)0);		}		fd = lfd;		r = fstat(fd, &st);	} else		r = stat(f, &st);	if (r < 0) {		builtin_error("%s: cannot stat: %s", f, strerror(errno));		return ((struct stat *)0);	}	return (&st);}static intprintfinfo(f)char	*f;{	struct stat *st;	st = getstat(f);	return (st ? printst(st) : 1);}static intgetperm(m)int	m;{	return (m & (S_IRWXU|S_IRWXG|S_IRWXO|S_ISUID|S_ISGID));}static intperms(m)int	m;{	char ubits[4], gbits[4], obits[4];	/* u=rwx,g=rwx,o=rwx */	int i;	i = 0;	if (m & S_IRUSR)		ubits[i++] = 'r';	if (m & S_IWUSR)		ubits[i++] = 'w';	if (m & S_IXUSR)		ubits[i++] = 'x';	ubits[i] = '\0';	i = 0;	if (m & S_IRGRP)		gbits[i++] = 'r';	if (m & S_IWGRP)		gbits[i++] = 'w';	if (m & S_IXGRP)		gbits[i++] = 'x';	gbits[i] = '\0';	i = 0;	if (m & S_IROTH)		obits[i++] = 'r';	if (m & S_IWOTH)		obits[i++] = 'w';	if (m & S_IXOTH)		obits[i++] = 'x';	obits[i] = '\0';	if (m & S_ISUID)		ubits[2] = (m & S_IXUSR) ? 's' : 'S';	if (m & S_ISGID)		gbits[2] = (m & S_IXGRP) ? 's' : 'S';	if (m & S_ISVTX)		obits[2] = (m & S_IXOTH) ? 't' : 'T';	printf ("u=%s,g=%s,o=%s", ubits, gbits, obits);}static intprintmode(mode)int	mode;{	if (S_ISBLK(mode))		printf("S_IFBLK ");	if (S_ISCHR(mode))		printf("S_IFCHR ");	if (S_ISDIR(mode))		printf("S_IFDIR ");	if (S_ISREG(mode))		printf("S_IFREG ");	if (S_ISFIFO(mode))		printf("S_IFIFO ");	if (S_ISLNK(mode))		printf("S_IFLNK ");	if (S_ISSOCK(mode))		printf("S_IFSOCK ");#ifdef S_ISWHT	if (S_ISWHT(mode))		printf("S_ISWHT ");#endif	perms(getperm(mode));	printf("\n");}static int	printst(st)struct stat *st;{	struct passwd	*pw;	struct group	*gr;	char	*owner;	printf("Device (major/minor): %d (%d/%d)\n", (int) (st->st_dev & 0xFF),						     (int) major (st->st_dev),						     (int) minor (st->st_dev));	printf("Inode: %d\n", (int) st->st_ino);	printf("Mode: (%o) ", (int) st->st_mode);	printmode((int) st->st_mode);	printf("Link count: %d\n", (int) st->st_nlink);	pw = getpwuid(st->st_uid);	owner = pw ? pw->pw_name : "unknown";	printf("Uid of owner: %d (%s)\n", (int) st->st_uid, owner);	gr = getgrgid(st->st_gid);	owner = gr ? gr->gr_name : "unknown";	printf("Gid of owner: %d (%s)\n", (int) st->st_gid, owner);	printf("Device type: %d\n", (int) st->st_rdev);	printf("File size: %ld\n", (long) st->st_size);	printf("File last access time: %s", ctime (&st->st_atime));	printf("File last modify time: %s", ctime (&st->st_mtime));	printf("File last status change time: %s", ctime (&st->st_ctime));	fflush(stdout);	return(0);}static intprintsome(f, flags)char	*f;int	flags;{	struct stat *st;	struct passwd *pw;	struct group *gr;	int	p;	char	*b;	st = getstat(f);	if (st == NULL)		return (1);	/* Print requested info */	if (flags & OPT_ATIME) {		if (flags & OPT_ASCII)			printf("%s", ctime(&st->st_atime));		else			printf("%ld\n", st->st_atime);	} else if (flags & OPT_MTIME) {		if (flags & OPT_ASCII)			printf("%s", ctime(&st->st_mtime));		else			printf("%ld\n", st->st_mtime);	} else if (flags & OPT_CTIME) {		if (flags & OPT_ASCII)			printf("%s", ctime(&st->st_ctime));		else			printf("%ld\n", st->st_ctime);	} else if (flags & OPT_DEV)		printf("%d\n", st->st_dev);	else if (flags & OPT_INO)		printf("%d\n", st->st_ino);	else if (flags & OPT_FID)		printf("%d:%ld\n", st->st_dev, st->st_ino);	else if (flags & OPT_NLINK)		printf("%d\n", st->st_nlink);	else if (flags & OPT_LNKNAM) {#ifdef S_ISLNK		b = xmalloc(4096);		p = readlink(f, b, 4096);		if (p >= 0 && p < 4096)			b[p] = '\0';		else {			p = errno;			strcpy(b, prog);			strcat(b, ": ");			strcat(b, strerror(p));		}		printf("%s\n", b);		free(b);#else		printf("%s\n", f);#endif	} else if (flags & OPT_PERM) {		perms(st->st_mode);		printf("\n");	} else if (flags & OPT_OPERM)		printf("%o\n", getperm(st->st_mode));	else if (flags & OPT_PMASK)		printf("%o\n", getperm(st->st_mode) & pmask);	else if (flags & OPT_UID) {		pw = getpwuid(st->st_uid);		if (flags & OPT_ASCII)			printf("%s\n", pw ? pw->pw_name : "unknown");		else			printf("%d\n", st->st_uid);	} else if (flags & OPT_GID) {		gr = getgrgid(st->st_gid);		if (flags & OPT_ASCII)			printf("%s\n", gr ? gr->gr_name : "unknown");		else			printf("%d\n", st->st_gid);	} else if (flags & OPT_SIZE)		printf("%ld\n", st->st_size);	return (0);}#ifndef NOBUILTINfinfo_builtin(list)     WORD_LIST *list;{  int c, r;  char **v;  WORD_LIST *l;  v = make_builtin_argv (list, &c);  r = finfo_main (c, v);  free (v);  return r;}static char *finfo_doc[] = {  "Display information about each FILE.  Only single operators should",  "be supplied.  If no options are supplied, a summary of the info",  "available about each FILE is printed.  If FILE is of the form",  "/dev/fd/XX, file descriptor XX is described.  Operators, if supplied,",  "have the following meanings:",  "",  "	-a	last file access time",  "	-A	last file access time in ctime format",  "	-c	last file status change time",  "	-C	last file status change time in ctime format",  "	-m	last file modification time",  "	-M	last file modification time in ctime format",  "	-d	device",  "	-i	inode",  "	-f	composite file identifier (device:inode)",  "	-g	gid of owner",  "	-G	group name of owner",  "	-l	name of file pointed to by symlink",  "	-n	link count",  "	-o	permissions in octal",  "	-p	permissions in ascii",  "	-P mask permissions ANDed with MASK (like with umask)",  "	-s	file size in bytes",  "	-u	uid of owner",  "	-U	user name of owner",  (char *)0};struct builtin finfo_struct = {	"finfo",	finfo_builtin,	BUILTIN_ENABLED,	finfo_doc,	"finfo [-acdgiflmnopsuACGMPU] file [file...]",	0};#endif#ifdef NOBUILTIN#if defined (PREFER_STDARG)#  include <stdarg.h>#else#  if defined (PREFER_VARARGS)#    include <varargs.h>#  endif#endifchar *this_command_name;main(argc, argv)int	argc;char	**argv;{	this_command_name = argv[0];	exit(finfo_main(argc, argv));}voidbuiltin_usage(){	fprintf(stderr, "%s: usage: %s [-%s] [file ...]\n", prog, OPTIONS);}#ifndef HAVE_STRERRORchar *strerror(e)int	e;{	static char	ebuf[40];	extern int	sys_nerr;	extern char	*sys_errlist[];	if (e < 0 || e > sys_nerr) {		sprintf(ebuf,"Unknown error code %d", e);		return (&ebuf[0]);	}	return (sys_errlist[e]);}#endifchar *xmalloc(s)size_t	s;{	char	*ret;	extern char *malloc();	ret = malloc(s);	if (ret)		return (ret);	fprintf(stderr, "%s: cannot malloc %d bytes\n", prog, s);	exit(1);}char *base_pathname(p)char	*p;{	char	*t;	if (t = strrchr(p, '/'))		return(++t);	return(p);}intlegal_number (string, result)     char *string;     long *result;{  int sign;  long value;  sign = 1;  value = 0;  if (result)    *result = 0;  /* Skip leading whitespace characters. */  while (whitespace (*string))    string++;  if (!*string)    return (0);  /* We allow leading `-' or `+'. */  if (*string == '-' || *string == '+')    {      if (!digit (string[1]))        return (0);      if (*string == '-')        sign = -1;      string++;    }  while (digit (*string))    {      if (result)        value = (value * 10) + digit_value (*string);      string++;    }  /* Skip trailing whitespace, if any. */  while (whitespace (*string))    string++;  /* Error if not at end of string. */  if (*string)    return (0);  if (result)    *result = value * sign;  return (1);}int sh_optind;char *sh_optarg;int sh_opterr;extern int optind;extern char *optarg;intsh_getopt(c, v, o)int	c;char	**v, *o;{	int	r;	r = getopt(c, v, o);	sh_optind = optind;	sh_optarg = optarg;	return r;}#if defined (USE_VARARGS)void#if defined (PREFER_STDARG)builtin_error (const char *format, ...)#elsebuiltin_error (format, va_alist)     const char *format;     va_dcl#endif{  va_list args;  if (this_command_name && *this_command_name)    fprintf (stderr, "%s: ", this_command_name);#if defined (PREFER_STDARG)  va_start (args, format);#else  va_start (args);#endif  vfprintf (stderr, format, args);  va_end (args);  fprintf (stderr, "\n");}#elsevoidbuiltin_error (format, arg1, arg2, arg3, arg4, arg5)     char *format, *arg1, *arg2, *arg3, *arg4, *arg5;{  if (this_command_name && *this_command_name)    fprintf (stderr, "%s: ", this_command_name);  fprintf (stderr, format, arg1, arg2, arg3, arg4, arg5);  fprintf (stderr, "\n");  fflush (stderr);}#endif /* !USE_VARARGS */#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -