Code:
#pragma prototyped
#include "defs.h"
#include "builtins.h"
#include "path.h"
#include <tm.h>
/* macro to create subvariables */
#define CREATE_CVE(X,Y,Z) \
strcpy(b,(X)); \
np = nv_open(buf, shp->var_tree, NV_NOASSIGN|NV_VARNAME); \
nv_putval(np, (char*)(Y), (Z) ); \
nv_close(np)
static char strperms_buf[30];
static const
char sh_optstat[] =
"[-?\n@(#)$Id: stat 2009-01-03 $\n]"
"[-author?fpmurphy ]"
"[-license?http://www.opensource.org/licenses/cpl1.0.txt]"
"[+NAME? stat - get file status]"
"[+DESCRIPTION?\bstat\b creates the compound variable \avar\a corresponding"
" to the file given by the pathname \afile\a. The elements of \avar\a"
" are the names of fields in the \astat\a structure with the \bst_\b"
" prefix removed, together with the basename of \afile\a.]"
"\n"
"\nvar file\n"
"\n"
"[+EXIT STATUS?]{"
"[+0?Success.]"
"[+>0?An error occurred.]"
"}"
"[+SEE ALSO?\bstat\b(1),\bstat\b(2)]"
;
/* stringify the permission bits */
static char *
strperms(char * p, mode_t mode)
{
char ftype = '?';
if (S_ISBLK(mode)) ftype = 'b';
if (S_ISCHR(mode)) ftype = 'c';
if (S_ISDIR(mode)) ftype = 'd';
if (S_ISFIFO(mode)) ftype = '|';
if (S_ISLNK(mode)) ftype = 'l';
if (S_ISREG(mode)) ftype = '-';
sfsprintf(p, 30, "\\0%010lo %c%c%c%c%c%c%c%c%c%c %c%c%c\0",
mode, ftype,
mode & S_IRUSR ? 'r' : '-',
mode & S_IWUSR ? 'w' : '-',
mode & S_IXUSR ? 'x' : '-',
mode & S_IRGRP ? 'r' : '-',
mode & S_IWGRP ? 'w' : '-',
mode & S_IXGRP ? 'x' : '-',
mode & S_IROTH ? 'r' : '-',
mode & S_IWOTH ? 'w' : '-',
mode & S_IXOTH ? 'x' : '-',
mode & S_ISUID ? 'U' : '-',
mode & S_ISGID ? 'G' : '-',
mode & S_ISVTX ? 'S' : '-');
return(p);
}
int
b_stat(int argc, char *argv[], void *extra)
{
register Shell_t *shp = ((Shbltin_t*)extra)->shp;
register Namval_t *np;
register int n;
struct stat statb;
char buf[100];
char *b;
while (n = optget(argv, sh_optstat)) switch (n) {
case ':':
errormsg(SH_DICT, 2, "%s", opt_info.arg);
break;
case '?':
errormsg(SH_DICT, ERROR_usage(2), "%s", opt_info.arg);
break;
}
argc -= opt_info.index;
argv += opt_info.index;
if (argc!=2)
errormsg(SH_DICT, ERROR_usage(2), optusage((char*)0));
/* stat the file */
if (stat(argv[1], &statb) < 0)
errormsg(SH_DICT, ERROR_system(1), "%s: stat failed", argv[1]);
strcpy(buf, argv[0]);
b = buf;
while (*b) b++;
/* create compound variable */
np = nv_open(buf, shp->var_tree, NV_NOASSIGN|NV_VARNAME|NV_ARRAY );
if (!nv_isnull(np))
nv_unset(np);
nv_setvtree(np);
nv_close(np);
/* create compound variable elements */
CREATE_CVE(".name", path_basename(argv[1]) , NV_RDONLY);
CREATE_CVE(".atime", &statb.st_atime, NV_RDONLY|NV_INTEGER);
CREATE_CVE(".ctime", &statb.st_ctime, NV_RDONLY|NV_INTEGER);
CREATE_CVE(".mtime", &statb.st_mtime, NV_RDONLY|NV_INTEGER);
CREATE_CVE(".uid", &statb.st_uid, NV_RDONLY|NV_INTEGER);
CREATE_CVE(".gid", &statb.st_gid, NV_RDONLY|NV_INTEGER);
CREATE_CVE(".size", &statb.st_size, NV_RDONLY|NV_INTEGER|NV_LONG);
CREATE_CVE(".dev", &statb.st_dev, NV_RDONLY|NV_INTEGER);
CREATE_CVE(".ino", &statb.st_ino, NV_RDONLY|NV_INTEGER|NV_LONG);
CREATE_CVE(".nlink", &statb.st_nlink, NV_RDONLY|NV_INTEGER);
CREATE_CVE(".mode", strperms(strperms_buf, statb.st_mode), NV_RDONLY);
return(0);
}