summaryrefslogtreecommitdiff
path: root/Src/Modules
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2000-04-07 20:07:10 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2000-04-07 20:07:10 +0000
commitb4a2b47b64c9fbe9df1d80e84c5d08786bd29eac (patch)
tree952b6c06e878dae1b4454cfe3c65c49a40b87bea /Src/Modules
parent265f55fd58613ba968ced4ecc39c9ab77b0fb0cf (diff)
downloadzsh-b4a2b47b64c9fbe9df1d80e84c5d08786bd29eac.tar.gz
zsh-b4a2b47b64c9fbe9df1d80e84c5d08786bd29eac.zip
stat -o shows file modes in octal
Diffstat (limited to 'Src/Modules')
-rw-r--r--Src/Modules/stat.c148
1 files changed, 117 insertions, 31 deletions
diff --git a/Src/Modules/stat.c b/Src/Modules/stat.c
index 09245b52f..d0f80829c 100644
--- a/Src/Modules/stat.c
+++ b/Src/Modules/stat.c
@@ -34,18 +34,21 @@ enum statnum { ST_DEV, ST_INO, ST_MODE, ST_NLINK, ST_UID, ST_GID,
ST_RDEV, ST_SIZE, ST_ATIM, ST_MTIM, ST_CTIM,
ST_BLKSIZE, ST_BLOCKS, ST_READLINK, ST_COUNT };
enum statflags { STF_NAME = 1, STF_FILE = 2, STF_STRING = 4, STF_RAW = 8,
- STF_PICK = 16, STF_ARRAY = 32, STF_GMT = 64 };
+ STF_PICK = 16, STF_ARRAY = 32, STF_GMT = 64,
+ STF_HASH = 128, STF_OCTAL = 256 };
static char *statelts[] = { "device", "inode", "mode", "nlink",
"uid", "gid", "rdev", "size", "atime",
"mtime", "ctime", "blksize", "blocks",
"link", NULL };
+#define HNAMEKEY "name"
/**/
static void
statmodeprint(mode_t mode, char *outbuf, int flags)
{
if (flags & STF_RAW) {
- sprintf(outbuf, "%lu", (unsigned long)mode);
+ sprintf(outbuf, (flags & STF_OCTAL) ? "0%lo" : "%lu",
+ (unsigned long)mode);
if (flags & STF_STRING)
strcat(outbuf, " (");
}
@@ -64,6 +67,8 @@ statmodeprint(mode_t mode, char *outbuf, int flags)
*pm = 'c';
else if (S_ISDIR(mode))
*pm = 'd';
+ else if (S_ISDOOR(mode))
+ *pm = 'D';
else if (S_ISFIFO(mode))
*pm = 'p';
else if (S_ISLNK(mode))
@@ -85,6 +90,7 @@ statmodeprint(mode_t mode, char *outbuf, int flags)
for (i = 1; i <= 9; i++)
pm[i] = (mode & *mfp++) ? modes[i] : '-';
+ pm[10] = '\0';
if (mode & S_ISUID)
pm[3] = (mode & S_IXUSR) ? 's' : 'S';
@@ -210,7 +216,13 @@ statprint(struct stat *sbuf, char *outbuf, char *fname, int iwhich, int flags)
break;
case ST_INO:
+#ifdef INO_T_IS_64_BIT
+ convbase(optr, sbuf->st_ino, 0);
+#else
+ DPUTS(sizeof(sbuf->st_ino) > 4,
+ "Shell compiled with wrong ino_t size");
statulprint((unsigned long)sbuf->st_ino, optr);
+#endif
break;
case ST_MODE:
@@ -234,7 +246,13 @@ statprint(struct stat *sbuf, char *outbuf, char *fname, int iwhich, int flags)
break;
case ST_SIZE:
+#ifdef OFF_T_IS_64_BIT
+ convbase(optr, sbuf->st_size, 0);
+#else
+ DPUTS(sizeof(sbuf->st_size) > 4,
+ "Shell compiled with wrong off_t size");
statulprint((unsigned long)sbuf->st_size, optr);
+#endif
break;
case ST_ATIM:
@@ -286,6 +304,8 @@ statprint(struct stat *sbuf, char *outbuf, char *fname, int iwhich, int flags)
* file names are returned as a separate array element, type names as
* prefix to element. Note the formatting deliberately contains
* fewer frills when -A is used.
+ * -H hash: as for -A array, but returns a hash with the keys being those
+ * from stat -l
* -F fmt: specify a $TIME-like format for printing times; the default
* is the (CTIME-like) "%a %b %e %k:%M:%S". This option implies
* -s as it is not useful for numerical times.
@@ -304,6 +324,7 @@ static int
bin_stat(char *name, char **args, char *ops, int func)
{
char **aptr, *arrnam = NULL, **array = NULL, **arrptr = NULL;
+ char *hashnam = NULL, **hash = NULL, **hashptr = NULL;
int len, iwhich = -1, ret = 0, flags = 0, arrsize = 0, fd = 0;
struct stat statbuf;
int found = 0, nargs;
@@ -327,10 +348,10 @@ bin_stat(char *name, char **args, char *ops, int func)
iwhich = aptr - statelts;
}
if (found > 1) {
- zerrnam(name, "%s: ambiguous stat element", arg, 0);
+ zwarnnam(name, "%s: ambiguous stat element", arg, 0);
return 1;
} else if (found == 0) {
- zerrnam(name, "%s: no such stat element", arg, 0);
+ zwarnnam(name, "%s: no such stat element", arg, 0);
return 1;
}
/* if name of link requested, turn on lstat */
@@ -339,30 +360,40 @@ bin_stat(char *name, char **args, char *ops, int func)
flags |= STF_PICK;
} else {
for (; *arg; arg++) {
- if (strchr("glLnNrstT", *arg))
- ops[*arg] = 1;
+ if (strchr("glLnNorstT", *arg))
+ ops[STOUC(*arg)] = 1;
else if (*arg == 'A') {
if (arg[1]) {
arrnam = arg+1;
} else if (!(arrnam = *++args)) {
- zerrnam(name, "missing parameter name\n",
+ zwarnnam(name, "missing parameter name",
NULL, 0);
return 1;
}
flags |= STF_ARRAY;
break;
+ } else if (*arg == 'H') {
+ if (arg[1]) {
+ hashnam = arg+1;
+ } else if (!(hashnam = *++args)) {
+ zwarnnam(name, "missing parameter name",
+ NULL, 0);
+ return 1;
+ }
+ flags |= STF_HASH;
+ break;
} else if (*arg == 'f') {
char *sfd;
ops['f'] = 1;
if (arg[1]) {
sfd = arg+1;
} else if (!(sfd = *++args)) {
- zerrnam(name, "missing file descriptor\n", NULL, 0);
+ zwarnnam(name, "missing file descriptor", NULL, 0);
return 1;
}
fd = zstrtol(sfd, &sfd, 10);
if (*sfd) {
- zerrnam(name, "bad file descriptor\n", NULL, 0);
+ zwarnnam(name, "bad file descriptor", NULL, 0);
return 1;
}
break;
@@ -370,20 +401,29 @@ bin_stat(char *name, char **args, char *ops, int func)
if (arg[1]) {
timefmt = arg+1;
} else if (!(timefmt = *++args)) {
- zerrnam(name, "missing time format\n", NULL, 0);
+ zwarnnam(name, "missing time format", NULL, 0);
return 1;
}
/* force string format in order to use time format */
ops['s'] = 1;
break;
} else {
- zerrnam(name, "bad option: -%c", NULL, *arg);
+ zwarnnam(name, "bad option: -%c", NULL, *arg);
return 1;
}
}
}
}
+ if ((flags & STF_ARRAY) && (flags & STF_HASH)) {
+ /* We don't implement setting multiple variables at once */
+ zwarnnam(name, "both array and hash requested", NULL, 0);
+ return 1;
+ /* Alternate method would be to make -H blank arrnam etc etc *
+ * and so get 'silent loss' of earlier choice, which would *
+ * be similar to stat -A foo -A bar filename */
+ }
+
if (ops['l']) {
/* list types and return: can also list to array */
if (arrnam) {
@@ -423,18 +463,22 @@ bin_stat(char *name, char **args, char *ops, int func)
for (aptr = args; *aptr; aptr++)
nargs++;
+ if (ops['g']) {
+ flags |= STF_GMT;
+ ops['s'] = 1;
+ }
if (ops['s'] || ops['r'])
flags |= STF_STRING;
if (ops['r'] || !ops['s'])
flags |= STF_RAW;
if (ops['n'])
flags |= STF_FILE;
+ if (ops['o'])
+ flags |= STF_OCTAL;
if (ops['t'])
flags |= STF_NAME;
- if (ops['g'])
- flags |= STF_GMT;
- if (!arrnam) {
+ if (!(arrnam || hashnam)) {
if (nargs > 1)
flags |= STF_FILE;
if (!(flags & STF_PICK))
@@ -443,9 +487,20 @@ bin_stat(char *name, char **args, char *ops, int func)
if (ops['N'] || ops['f'])
flags &= ~STF_FILE;
- if (ops['T'])
+ if (ops['T'] || ops['H'])
flags &= ~STF_NAME;
+ if (hashnam) {
+ if (nargs > 1) {
+ zwarnnam(name, "only one file allowed with -H", NULL, 0);
+ return 1;
+ }
+ arrsize = (flags & STF_PICK) ? 1 : ST_COUNT;
+ if (flags & STF_FILE)
+ arrsize++;
+ hashptr = hash = (char **)zcalloc((arrsize+1)*2*sizeof(char *));
+ }
+
if (arrnam) {
arrsize = (flags & STF_PICK) ? 1 : ST_COUNT;
if (flags & STF_FILE)
@@ -469,16 +524,24 @@ bin_stat(char *name, char **args, char *ops, int func)
continue;
}
- if (flags & STF_FILE)
+ if (flags & STF_FILE) {
if (arrnam)
*arrptr++ = ztrdup(*args);
- else
+ else if (hashnam) {
+ *hashptr++ = ztrdup(HNAMEKEY);
+ *hashptr++ = ztrdup(*args);
+ } else
printf("%s%s", *args, (flags & STF_PICK) ? " " : ":\n");
+ }
if (iwhich > -1) {
statprint(&statbuf, outbuf, *args, iwhich, flags);
if (arrnam)
*arrptr++ = ztrdup(outbuf);
- else
+ else if (hashnam) {
+ /* STF_NAME explicitly turned off for ops['H'] above */
+ *hashptr++ = ztrdup(statelts[iwhich]);
+ *hashptr++ = ztrdup(outbuf);
+ } else
printf("%s\n", outbuf);
} else {
int i;
@@ -486,27 +549,40 @@ bin_stat(char *name, char **args, char *ops, int func)
statprint(&statbuf, outbuf, *args, i, flags);
if (arrnam)
*arrptr++= ztrdup(outbuf);
- else
+ else if (hashnam) {
+ /* STF_NAME explicitly turned off for ops['H'] above */
+ *hashptr++ = ztrdup(statelts[i]);
+ *hashptr++ = ztrdup(outbuf);
+ } else
printf("%s\n", outbuf);
}
}
if (ops['f'])
break;
- if (!arrnam && args[1] && !(flags & STF_PICK))
+ if (!arrnam && !hashnam && args[1] && !(flags & STF_PICK))
putchar('\n');
}
- if (arrnam)
- if (ret) {
- for (aptr = array; *aptr; aptr++)
- zsfree(*aptr);
- zfree(array, arrsize+1);
- } else {
+ if (arrnam) {
+ if (ret)
+ freearray(array);
+ else {
setaparam(arrnam, array);
if (errflag)
return 1;
}
+ }
+
+ if (hashnam) {
+ if (ret)
+ freearray(hash);
+ else {
+ sethparam(hashnam, hash);
+ if (errflag)
+ return 1;
+ }
+ }
return ret;
}
@@ -517,19 +593,29 @@ static struct builtin bintab[] = {
/**/
int
-boot_stat(Module m)
+setup_(Module m)
{
- return !addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
+ return 0;
}
-#ifdef MODULE
+/**/
+int
+boot_(Module m)
+{
+ return !addbuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
+}
/**/
int
-cleanup_stat(Module m)
+cleanup_(Module m)
{
deletebuiltins(m->nam, bintab, sizeof(bintab)/sizeof(*bintab));
return 0;
}
-#endif
+/**/
+int
+finish_(Module m)
+{
+ return 0;
+}