/*
** FPMurphy 2009-01-03
**
** License: Common Public License Version 1.0
**
*/
#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?Finnbarr P. Murphy fpm at hotmail.com ]"
"[-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);
}
You can embed a man page into the builtin as done in the above source code. Most, if not all, of the commands have such embedded man pages.
Here is the output from .
$ stat --help
Usage: stat [ options ] var file
$
$ stat --man
NAME
stat - get file status
SYNOPSIS
stat [ options ] var file
DESCRIPTION
stat creates the compound variable var corresponding to the file given
by the pathname file. The elements of var are the names of fields in the
stat structure with the st_ prefix removed, together with the basename
of file.
EXIT STATUS
0 Success.
>0 An error occurred.
SEE ALSO
stat(1),stat(2)
IMPLEMENTATION
version stat 2009-01-03
author Finnbarr P. Murphy fpm at hotmail.com
license http://www.opensource.org/licenses/cpl1.0.txt
$
$ stat fileinfo ./tksh
$ print $fileinfo
( atime=1231192796 ctime=1231192291 dev=2065 gid=500 ino=50897
mode='0100755 -rwxr-xr-x ---' mtime=1231192291 name=tksh nlink=1 size=2171604 uid=500 )
$ print ${fileinfo.atime}
1231192796
$ printf "%(%Y-%m-%d %H:%M:%S)T\n" "#${fileinfo.atime}"
2009-01-05 16:59:56
$
As always, email me if you have any questions.
0 comments:
Post a Comment