Intial commit
This commit is contained in:
1
prospero/app/.gitignore
vendored
Normal file
1
prospero/app/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Makefile
|
||||
4
prospero/app/FILES
Normal file
4
prospero/app/FILES
Normal file
@@ -0,0 +1,4 @@
|
||||
FILES
|
||||
Makefile
|
||||
cat.c
|
||||
ls.c
|
||||
84
prospero/app/Makefile.backup.backup
Executable file
84
prospero/app/Makefile.backup.backup
Executable file
@@ -0,0 +1,84 @@
|
||||
# There used to be separate makefiles, app/Makefile.pcompat and
|
||||
# app/Makefile.nopcompat. This is no longer the case; there's just one
|
||||
# app/Makefile. This makefile will not be invoked by the top-level makefile
|
||||
# unless the user wants the PCOMPAT library.
|
||||
|
||||
SOURCEBASE=..
|
||||
include $(SOURCEBASE)/Makefile.config
|
||||
|
||||
PROGS = cat ls
|
||||
|
||||
# Alternative programs.
|
||||
# MORE is not part of this distribution.
|
||||
OTHERPROGS = more
|
||||
|
||||
CFILES = \
|
||||
cat.c \
|
||||
cc.c \
|
||||
cp.c \
|
||||
dd.c \
|
||||
ed.c \
|
||||
grep.c \
|
||||
ld.c \
|
||||
ls.c \
|
||||
more.c \
|
||||
nice.c \
|
||||
od.c \
|
||||
strings.c \
|
||||
tail.c \
|
||||
wc.c
|
||||
|
||||
OBJECTS = \
|
||||
cat.o \
|
||||
cc.o \
|
||||
cp.o \
|
||||
dd.o \
|
||||
ed.o \
|
||||
grep.o \
|
||||
ld.o \
|
||||
ls.o \
|
||||
more.o \
|
||||
nice.o \
|
||||
od.o \
|
||||
strings.o \
|
||||
tail.o \
|
||||
wc.o
|
||||
|
||||
# no subdirectories of this one are used.
|
||||
SUBDIRS =
|
||||
|
||||
##
|
||||
## Now the rules.
|
||||
|
||||
all: ${PROGS}
|
||||
|
||||
install:
|
||||
-for i in ${PROGS} ; do \
|
||||
X ${INSTALL} -c -m 755 -o ${OWNER} -g ${GROUP} $${i} ${P_BINARIES}/$${i}${GENERATIONSUFFIX} ;\
|
||||
${GENERATION} ${P_BINARIES}/$${i} ;\
|
||||
done
|
||||
|
||||
# dependencies of all and OTHERPROGS
|
||||
more: ${CMP_LIBS_DEPENDENCIES} more.o
|
||||
${CC} ${CFLAGS} -o more more.o $(CMP_LIBS) -lcurses -ltermcap
|
||||
|
||||
|
||||
${PROGS}: $(CMP_LIBS_DEPENDENCIES)
|
||||
${CC} ${CFLAGS} -o $@ $@.o $(CMP_LIBS)
|
||||
|
||||
|
||||
cat: cat.o
|
||||
cc: cc.o
|
||||
cp: cp.o
|
||||
dd: dd.o
|
||||
ed: ed.o
|
||||
grep: grep.o
|
||||
ld: ld.o
|
||||
ls: ls.o
|
||||
nice: nice.o
|
||||
od: od.o
|
||||
strings: strings.o
|
||||
tail: tail.o
|
||||
wc: wc.o
|
||||
|
||||
# Dependencies
|
||||
90
prospero/app/Makefile.in
Executable file
90
prospero/app/Makefile.in
Executable file
@@ -0,0 +1,90 @@
|
||||
# There used to be separate makefiles, app/Makefile.pcompat and
|
||||
# app/Makefile.nopcompat. This is no longer the case; there's just one
|
||||
# app/Makefile. This makefile will not be invoked by the top-level makefile
|
||||
# unless the user wants the PCOMPAT library.
|
||||
|
||||
SOURCEBASE=..
|
||||
include $(SOURCEBASE)/Makefile.config
|
||||
|
||||
PROGS = cat ls
|
||||
|
||||
# Alternative programs.
|
||||
# MORE is not part of this distribution.
|
||||
OTHERPROGS = more
|
||||
|
||||
CFILES = \
|
||||
cat.c \
|
||||
cc.c \
|
||||
cp.c \
|
||||
dd.c \
|
||||
ed.c \
|
||||
grep.c \
|
||||
ld.c \
|
||||
ls.c \
|
||||
more.c \
|
||||
nice.c \
|
||||
od.c \
|
||||
strings.c \
|
||||
tail.c \
|
||||
wc.c
|
||||
|
||||
OBJECTS = \
|
||||
cat.o \
|
||||
cc.o \
|
||||
cp.o \
|
||||
dd.o \
|
||||
ed.o \
|
||||
grep.o \
|
||||
ld.o \
|
||||
ls.o \
|
||||
more.o \
|
||||
nice.o \
|
||||
od.o \
|
||||
strings.o \
|
||||
tail.o \
|
||||
wc.o
|
||||
|
||||
# no subdirectories of this one are used.
|
||||
SUBDIRS =
|
||||
|
||||
##
|
||||
## Now the rules.
|
||||
|
||||
all: ${PROGS}
|
||||
|
||||
install:
|
||||
-for i in ${PROGS} ; do \
|
||||
X ${INSTALL} -c -m 755 -o ${OWNER} -g ${GROUP} $${i} ${P_BINARIES}/$${i}${GENERATIONSUFFIX} ;\
|
||||
${GENERATION} ${P_BINARIES}/$${i} ;\
|
||||
done
|
||||
|
||||
# dependencies of all and OTHERPROGS
|
||||
more: ${CMP_LIBS_DEPENDENCIES} more.o
|
||||
${CC} ${CFLAGS} -o more more.o $(CMP_LIBS) -lcurses -ltermcap
|
||||
|
||||
|
||||
${PROGS}: $(CMP_LIBS_DEPENDENCIES)
|
||||
${CC} ${CFLAGS} -o $@ $@.o $(CMP_LIBS)
|
||||
|
||||
|
||||
cat: cat.o
|
||||
cc: cc.o
|
||||
cp: cp.o
|
||||
dd: dd.o
|
||||
ed: ed.o
|
||||
grep: grep.o
|
||||
ld: ld.o
|
||||
ls: ls.o
|
||||
nice: nice.o
|
||||
od: od.o
|
||||
strings: strings.o
|
||||
tail: tail.o
|
||||
wc: wc.o
|
||||
|
||||
# Dependencies
|
||||
cat.o : \
|
||||
../include/perrno.h \
|
||||
../include/pfs_threads.h ../include/pfs_utils.h
|
||||
ls.o : \
|
||||
../include/pcompat.h \
|
||||
../include/pfs_threads.h ../include/pfs_utils.h ../include/pmachine.h
|
||||
247
prospero/app/cat.c
Normal file
247
prospero/app/cat.c
Normal file
@@ -0,0 +1,247 @@
|
||||
/*
|
||||
* Derived from Berkeley source code. Those parts are
|
||||
* Copyright (c) 1989 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Kevin Fall.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that: (1) source distributions retain this entire copyright
|
||||
* notice and comment, and (2) distributions including binaries display
|
||||
* the following acknowledgement: ``This product includes software
|
||||
* developed by the University of California, Berkeley and its contributors''
|
||||
* in the documentation or other materials provided with the distribution
|
||||
* and in all advertising materials mentioning features or use of this
|
||||
* software. Neither the name of the University nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
char copyright[] =
|
||||
"@(#) Copyright (c) 1989 The Regents of the University of California.\n\
|
||||
All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)cat.c 5.11 (Berkeley) 5/31/90";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/file.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <perrno.h> /* For unixerrstr */
|
||||
#include <stdlib.h> /*For malloc*/
|
||||
|
||||
int bflag, eflag, nflag, sflag, tflag, vflag;
|
||||
int rval;
|
||||
char *filename;
|
||||
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
extern int optind;
|
||||
int ch;
|
||||
|
||||
while ((ch = getopt(argc, argv, "benstuv")) != EOF)
|
||||
switch (ch) {
|
||||
case 'b':
|
||||
bflag = nflag = 1; /* -b implies -n */
|
||||
break;
|
||||
case 'e':
|
||||
eflag = vflag = 1; /* -e implies -v */
|
||||
break;
|
||||
case 'n':
|
||||
nflag = 1;
|
||||
break;
|
||||
case 's':
|
||||
sflag = 1;
|
||||
break;
|
||||
case 't':
|
||||
tflag = vflag = 1; /* -t implies -v */
|
||||
break;
|
||||
case 'u':
|
||||
setbuf(stdout, (char *)NULL);
|
||||
break;
|
||||
case 'v':
|
||||
vflag = 1;
|
||||
break;
|
||||
case '?':
|
||||
(void)fprintf(stderr,
|
||||
"usage: cat [-benstuv] [-] [file ...]\n");
|
||||
exit(1);
|
||||
}
|
||||
argv += optind;
|
||||
|
||||
if (bflag || eflag || nflag || sflag || tflag || vflag)
|
||||
cook_args(argv);
|
||||
else
|
||||
raw_args(argv);
|
||||
exit(rval);
|
||||
}
|
||||
|
||||
cook_args(argv)
|
||||
char **argv;
|
||||
{
|
||||
register FILE *fp;
|
||||
|
||||
fp = stdin;
|
||||
filename = "-";
|
||||
do {
|
||||
if (*argv) {
|
||||
if (!strcmp(*argv, "-"))
|
||||
fp = stdin;
|
||||
else if (!(fp = fopen(*argv, "r"))) {
|
||||
(void)fprintf(stderr,
|
||||
"cat: %s: %s\n", *argv, unixerrstr());
|
||||
rval = 1;
|
||||
++argv;
|
||||
continue;
|
||||
}
|
||||
filename = *argv++;
|
||||
}
|
||||
cook_buf(fp);
|
||||
if (fp != stdin)
|
||||
(void)fclose(fp);
|
||||
} while (*argv);
|
||||
}
|
||||
|
||||
cook_buf(fp)
|
||||
register FILE *fp;
|
||||
{
|
||||
register int ch, gobble, line, prev;
|
||||
|
||||
line = gobble = 0;
|
||||
for (prev = '\n'; (ch = getc(fp)) != EOF; prev = ch) {
|
||||
if (prev == '\n') {
|
||||
if (ch == '\n') {
|
||||
if (sflag) {
|
||||
if (!gobble && putchar(ch) == EOF)
|
||||
break;
|
||||
gobble = 1;
|
||||
continue;
|
||||
}
|
||||
if (nflag && !bflag) {
|
||||
(void)fprintf(stdout, "%6d\t", ++line);
|
||||
if (ferror(stdout))
|
||||
break;
|
||||
}
|
||||
} else if (nflag) {
|
||||
(void)fprintf(stdout, "%6d\t", ++line);
|
||||
if (ferror(stdout))
|
||||
break;
|
||||
}
|
||||
}
|
||||
gobble = 0;
|
||||
if (ch == '\n') {
|
||||
if (eflag)
|
||||
if (putchar('$') == EOF)
|
||||
break;
|
||||
} else if (ch == '\t') {
|
||||
if (tflag) {
|
||||
if (putchar('^') == EOF || putchar('I') == EOF)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
} else if (vflag) {
|
||||
/* isascii() is not provided in POSIX, so we just do it here. */
|
||||
#ifndef isascii
|
||||
#define isascii(c) ((unsigned)(c)<=0177)
|
||||
#endif
|
||||
if (!isascii(ch)) {
|
||||
if (putchar('M') == EOF || putchar('-') == EOF)
|
||||
break;
|
||||
ch = toascii(ch);
|
||||
}
|
||||
if (iscntrl(ch)) {
|
||||
if (putchar('^') == EOF ||
|
||||
putchar(ch == '\177' ? '?' :
|
||||
ch | 0100) == EOF)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (putchar(ch) == EOF)
|
||||
break;
|
||||
}
|
||||
if (ferror(fp)) {
|
||||
(void)fprintf(stderr, "cat: %s: read error\n", filename);
|
||||
rval = 1;
|
||||
}
|
||||
if (ferror(stdout)) {
|
||||
clearerr(stdout);
|
||||
(void)fprintf(stderr, "cat: stdout: write error\n");
|
||||
rval = 1;
|
||||
}
|
||||
}
|
||||
|
||||
raw_args(argv)
|
||||
char **argv;
|
||||
{
|
||||
register int fd;
|
||||
|
||||
fd = fileno(stdin);
|
||||
filename = "-";
|
||||
do {
|
||||
if (*argv) {
|
||||
if (!strcmp(*argv, "-"))
|
||||
fd = fileno(stdin);
|
||||
else if ((fd = open(*argv, O_RDONLY, 0)) < 0) {
|
||||
(void)fprintf(stderr, "cat: %s: %s\n",
|
||||
*argv, unixerrstr());
|
||||
rval = 1;
|
||||
++argv;
|
||||
continue;
|
||||
}
|
||||
filename = *argv++;
|
||||
}
|
||||
rval |= raw_cat(fd);
|
||||
if (fd != fileno(stdin))
|
||||
(void)close(fd);
|
||||
} while (*argv);
|
||||
}
|
||||
|
||||
raw_cat(fd)
|
||||
register int fd;
|
||||
{
|
||||
register int nr, nw, off;
|
||||
static int bsize;
|
||||
static char *buf;
|
||||
struct stat sbuf;
|
||||
|
||||
if (!buf) {
|
||||
if (fstat(fileno(stdout), &sbuf)) {
|
||||
(void)fprintf(stderr, "cat: %s: %s\n", filename,
|
||||
unixerrstr());
|
||||
return(1);
|
||||
}
|
||||
bsize = MAX(sbuf.st_blksize, 1024);
|
||||
if (!(buf = malloc((u_int)bsize))) {
|
||||
(void)fprintf(stderr, "cat: %s: no memory.\n",
|
||||
filename);
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
while ((nr = read(fd, buf, bsize)) > 0)
|
||||
for (off = 0; off < nr;) {
|
||||
if ((nw = write(fileno(stdout), buf + off, nr)) < 0) {
|
||||
perror("cat: stdout");
|
||||
return(1);
|
||||
}
|
||||
off += nw;
|
||||
}
|
||||
if (nr < 0) {
|
||||
(void)fprintf(stderr, "cat: %s: %s\n", filename,
|
||||
unixerrstr());
|
||||
return(1);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
898
prospero/app/ls.c
Normal file
898
prospero/app/ls.c
Normal file
@@ -0,0 +1,898 @@
|
||||
/*
|
||||
* Derived from Berkeley source code. Those parts are
|
||||
* Copyright (c) 1989 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Michael Fischbein.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that: (1) source distributions retain this entire copyright
|
||||
* notice and comment, and (2) distributions including binaries display
|
||||
* the following acknowledgement: ``This product includes software
|
||||
* developed by the University of California, Berkeley and its contributors''
|
||||
* in the documentation or other materials provided with the distribution
|
||||
* and in all advertising materials mentioning features or use of this
|
||||
* software. Neither the name of the University nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
char copyright[] =
|
||||
"@(#) Copyright (c) 1989 The Regents of the University of California.\n\
|
||||
All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)ls.c 5.42 (Berkeley) 5/17/90";
|
||||
#endif /* not lint */
|
||||
|
||||
#define DAYSPERNYEAR (365)
|
||||
#define SECSPERDAY (24*60*60)
|
||||
#define UT_NAMESIZE 8
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#ifndef S_ISLNK /* On the sun, this is defined for us in
|
||||
/usr/include/sys/stat.h, but it must not be
|
||||
defined there on all machines, or Berkeley
|
||||
wouldn't have put this into ls.c, right?
|
||||
--swa@isi.edu */
|
||||
#define S_ISLNK(m) ((S_IFLNK & m) == S_IFLNK)
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
#include <utmp.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <pcompat.h>
|
||||
#include <pmachine.h>
|
||||
|
||||
#ifdef USE_SYS_DIR_H
|
||||
#include <sys/dir.h>
|
||||
#else
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
/* At the moment this program doesn't work under HP-UX, because the
|
||||
compatability library's version of opendir() fails under HP-UX.
|
||||
*/
|
||||
#ifdef HPUX
|
||||
#error "The program ls.c should not be compiled under HP-UX, since it will \
|
||||
not work. It relies upon the compatability library's version of opendir(), \
|
||||
which has not yet been ported to HP-UX. Please proceed with compiling the \
|
||||
rest of the Prospero clients."
|
||||
#endif
|
||||
|
||||
|
||||
char *user_from_uid();
|
||||
char *group_from_gid();
|
||||
|
||||
typedef struct _lsstruct {
|
||||
char *name; /* file name */
|
||||
int len; /* file name length */
|
||||
struct stat lstat; /* lstat(2) for file */
|
||||
} LS;
|
||||
|
||||
int (*sortfcn)(), (*printfcn)();
|
||||
int lstat();
|
||||
char *emalloc();
|
||||
|
||||
int termwidth = 80; /* default terminal width */
|
||||
|
||||
/* flags */
|
||||
int f_accesstime; /* use time of last access */
|
||||
int f_column; /* columnated format */
|
||||
int f_group; /* show group ownership of a file */
|
||||
int f_ignorelink; /* indirect through symbolic link operands */
|
||||
int f_inode; /* print inode */
|
||||
int f_kblocks; /* print size in kilobytes */
|
||||
int f_listalldot; /* list . and .. as well */
|
||||
int f_listdir; /* list actual directory, not contents */
|
||||
int f_listdot; /* list files beginning with . */
|
||||
int f_longform; /* long listing format */
|
||||
int f_needstat; /* if need to stat files */
|
||||
int f_newline; /* if precede with newline */
|
||||
int f_nonprint; /* show unprintables as ? */
|
||||
int f_nosort; /* don't sort output */
|
||||
int f_recursive; /* ls subdirectories also */
|
||||
int f_reversesort; /* reverse whatever sort is used */
|
||||
int f_singlecol; /* use single column output */
|
||||
int f_size; /* list size in short listing */
|
||||
int f_statustime; /* use time of last mode change */
|
||||
int f_dirname; /* if precede with directory name */
|
||||
int f_timesort; /* sort by time vice name */
|
||||
int f_total; /* if precede with "total" line */
|
||||
int f_type; /* add type character for non-regular files */
|
||||
|
||||
char *dummyargv[2] = {"", NULL};
|
||||
|
||||
#ifndef TIOCGWINSZ
|
||||
#include <sys/termio.h>
|
||||
#endif
|
||||
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
extern int optind, stat();
|
||||
struct winsize win;
|
||||
int ch;
|
||||
char *p, *getenv();
|
||||
int acccmp(), modcmp(), namecmp(), prcopy(), printcol();
|
||||
int printlong(), printscol(), revacccmp(), revmodcmp(), revnamecmp();
|
||||
int revstatcmp(), statcmp();
|
||||
|
||||
/* terminal defaults to -Cq, non-terminal defaults to -1 */
|
||||
if (isatty(1)) {
|
||||
f_nonprint = 1;
|
||||
if (ioctl(1, TIOCGWINSZ, &win) == -1 || !win.ws_col) {
|
||||
if (p = getenv("COLUMNS"))
|
||||
termwidth = atoi(p);
|
||||
}
|
||||
else
|
||||
termwidth = win.ws_col;
|
||||
f_column = 1;
|
||||
} else
|
||||
f_singlecol = 1;
|
||||
|
||||
/* root is -A automatically */
|
||||
if (!getuid())
|
||||
f_listdot = 1;
|
||||
|
||||
/* Print sizes in kilobytes by default */
|
||||
f_kblocks = 1;
|
||||
|
||||
while ((ch = getopt(argc, argv, "1ACFLRacdfgiklqrstu")) != EOF) {
|
||||
switch (ch) {
|
||||
/*
|
||||
* -1, -C and -l all override each other
|
||||
* so shell aliasing works right
|
||||
*/
|
||||
case '1':
|
||||
f_singlecol = 1;
|
||||
f_column = f_longform = 0;
|
||||
break;
|
||||
case 'C':
|
||||
f_column = 1;
|
||||
f_longform = f_singlecol = 0;
|
||||
break;
|
||||
case 'l':
|
||||
f_longform = 1;
|
||||
f_column = f_singlecol = 0;
|
||||
break;
|
||||
/* -c and -u override each other */
|
||||
case 'c':
|
||||
f_statustime = 1;
|
||||
f_accesstime = 0;
|
||||
break;
|
||||
case 'u':
|
||||
f_accesstime = 1;
|
||||
f_statustime = 0;
|
||||
break;
|
||||
case 'F':
|
||||
f_type = 1;
|
||||
break;
|
||||
case 'L':
|
||||
f_ignorelink = 1;
|
||||
break;
|
||||
case 'R':
|
||||
f_recursive = 1;
|
||||
break;
|
||||
case 'a':
|
||||
f_listalldot = 1;
|
||||
/* FALLTHROUGH */
|
||||
case 'A':
|
||||
f_listdot = 1;
|
||||
break;
|
||||
case 'd':
|
||||
f_listdir = 1;
|
||||
break;
|
||||
case 'f':
|
||||
f_nosort = 1;
|
||||
break;
|
||||
case 'g':
|
||||
f_group = 1;
|
||||
break;
|
||||
case 'i':
|
||||
f_inode = 1;
|
||||
break;
|
||||
case 'k':
|
||||
f_kblocks = 1;
|
||||
break;
|
||||
case 'q':
|
||||
f_nonprint = 1;
|
||||
break;
|
||||
case 'r':
|
||||
f_reversesort = 1;
|
||||
break;
|
||||
case 's':
|
||||
f_size = 1;
|
||||
break;
|
||||
case 't':
|
||||
f_timesort = 1;
|
||||
break;
|
||||
default:
|
||||
case '?':
|
||||
usage();
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
/* -d turns off -R */
|
||||
if (f_listdir)
|
||||
f_recursive = 0;
|
||||
|
||||
/* if need to stat files */
|
||||
f_needstat = f_longform || f_recursive || f_timesort ||
|
||||
f_size || f_type;
|
||||
|
||||
/* select a sort function */
|
||||
if (f_reversesort) {
|
||||
if (!f_timesort)
|
||||
sortfcn = revnamecmp;
|
||||
else if (f_accesstime)
|
||||
sortfcn = revacccmp;
|
||||
else if (f_statustime)
|
||||
sortfcn = revstatcmp;
|
||||
else /* use modification time */
|
||||
sortfcn = revmodcmp;
|
||||
} else {
|
||||
if (!f_timesort)
|
||||
sortfcn = namecmp;
|
||||
else if (f_accesstime)
|
||||
sortfcn = acccmp;
|
||||
else if (f_statustime)
|
||||
sortfcn = statcmp;
|
||||
else /* use modification time */
|
||||
sortfcn = modcmp;
|
||||
}
|
||||
|
||||
/* select a print function */
|
||||
if (f_singlecol)
|
||||
printfcn = printscol;
|
||||
else if (f_longform)
|
||||
printfcn = printlong;
|
||||
else
|
||||
printfcn = printcol;
|
||||
|
||||
if (argc) doargs(argc, argv);
|
||||
else doargs(1,dummyargv);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static char path[MAXPATHLEN + 1];
|
||||
static char *endofpath = path;
|
||||
|
||||
doargs(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
register LS *dstatp, *rstatp;
|
||||
register int cnt, dircnt, maxlen, regcnt;
|
||||
LS *dstats, *rstats;
|
||||
struct stat sb;
|
||||
int (*statfcn)(), stat(), lstat();
|
||||
char top[MAXPATHLEN + 1];
|
||||
u_long blocks;
|
||||
long r_st_btotal;
|
||||
long r_st_maxlen;
|
||||
|
||||
/*
|
||||
* walk through the operands, building separate arrays of LS
|
||||
* structures for directory and non-directory files.
|
||||
*/
|
||||
dstats = rstats = NULL;
|
||||
statfcn = (f_longform || f_listdir) && !f_ignorelink ? lstat : stat;
|
||||
for (dircnt = regcnt = 0; *argv; ++argv) {
|
||||
if (statfcn(*argv, &sb)) {
|
||||
if (statfcn != stat || lstat(*argv, &sb)) {
|
||||
(void)fflush(stdout);
|
||||
(void)fprintf(stderr, "ls: %s: %s\n", *argv,
|
||||
unixerrstr());
|
||||
if (errno == ENOENT)
|
||||
continue;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
if (S_ISDIR(sb.st_mode) && !f_listdir) {
|
||||
if (!dstats)
|
||||
dstatp = dstats = (LS *)emalloc((u_int)argc *
|
||||
(sizeof(LS)));
|
||||
dstatp->name = *argv;
|
||||
dstatp->lstat = sb;
|
||||
++dstatp;
|
||||
++dircnt;
|
||||
}
|
||||
else {
|
||||
if (!rstats) {
|
||||
rstatp = rstats = (LS *)emalloc((u_int)argc *
|
||||
(sizeof(LS)));
|
||||
blocks = 0;
|
||||
maxlen = -1;
|
||||
}
|
||||
rstatp->name = *argv;
|
||||
rstatp->lstat = sb;
|
||||
|
||||
/* save name length for -C format */
|
||||
rstatp->len = strlen(*argv);
|
||||
|
||||
if (f_nonprint)
|
||||
prcopy(*argv, *argv, rstatp->len);
|
||||
|
||||
/* calculate number of blocks if -l/-s formats */
|
||||
if (f_longform || f_size)
|
||||
blocks += sb.st_blocks;
|
||||
|
||||
/* save max length if -C format */
|
||||
if (f_column && maxlen < rstatp->len)
|
||||
maxlen = rstatp->len;
|
||||
|
||||
++rstatp;
|
||||
++regcnt;
|
||||
}
|
||||
}
|
||||
/* display regular files */
|
||||
if (regcnt) {
|
||||
displaydir("", rstats, regcnt, blocks, maxlen);
|
||||
f_newline = f_dirname = 1;
|
||||
}
|
||||
/* display directories */
|
||||
if (dircnt) {
|
||||
register char *p;
|
||||
|
||||
f_total = 1;
|
||||
if (dircnt > 1) {
|
||||
(void)getwd(top);
|
||||
qsort((char *)dstats, dircnt, sizeof(LS), sortfcn);
|
||||
f_dirname = 1;
|
||||
}
|
||||
for (cnt = 0; cnt < dircnt; ++dstats) {
|
||||
for (endofpath = path, p = dstats->name;
|
||||
*endofpath = *p++; ++endofpath);
|
||||
subdir("",dstats);
|
||||
f_newline = 1;
|
||||
if (++cnt < dircnt && chdir(top)) {
|
||||
(void)fprintf(stderr, "ls: %s: %s\n",
|
||||
top, unixerrstr());
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
displaydir(subdirname, stats, num, blocks, maxlen)
|
||||
char *subdirname;
|
||||
LS *stats;
|
||||
register int num;
|
||||
long blocks;
|
||||
long maxlen;
|
||||
{
|
||||
register char *p, *savedpath;
|
||||
LS *lp;
|
||||
|
||||
if (num > 1 && !f_nosort) {
|
||||
u_long save1, save2;
|
||||
qsort((char *)stats, num, sizeof(LS), sortfcn);
|
||||
}
|
||||
|
||||
printfcn(subdirname, stats, num, blocks, maxlen);
|
||||
|
||||
if (f_recursive) {
|
||||
savedpath = endofpath;
|
||||
for (lp = stats; num--; ++lp) {
|
||||
if (!S_ISDIR(lp->lstat.st_mode))
|
||||
continue;
|
||||
p = lp->name;
|
||||
if (p[0] == '.' && (!p[1] || p[1] == '.' && !p[2]))
|
||||
continue;
|
||||
if (endofpath != path && endofpath[-1] != '/')
|
||||
*endofpath++ = '/';
|
||||
for (; *endofpath = *p++; ++endofpath);
|
||||
f_newline = f_dirname = f_total = 1;
|
||||
subdir(subdirname,lp);
|
||||
*(endofpath = savedpath) = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
subdir(wdir,lp)
|
||||
char *wdir;
|
||||
LS *lp;
|
||||
{
|
||||
char sbdirname[MAXPATHLEN];
|
||||
LS *stats;
|
||||
int num;
|
||||
char *names;
|
||||
long blocks;
|
||||
int maxlen;
|
||||
|
||||
if(*wdir) sprintf(sbdirname,"%s/%s",wdir,lp->name);
|
||||
else strcpy(sbdirname,lp->name);
|
||||
|
||||
if (f_newline)
|
||||
(void)putchar('\n');
|
||||
if (f_dirname)
|
||||
(void)printf("%s:\n", path);
|
||||
|
||||
if (num = tabdir(sbdirname, lp, &stats, &names, &blocks, &maxlen)) {
|
||||
displaydir(sbdirname, stats, num, blocks, maxlen);
|
||||
(void)free((char *)stats);
|
||||
(void)free((char *)names);
|
||||
}
|
||||
}
|
||||
|
||||
tabdir(dirname, lp, s_stats, s_names, blocksp, maxlenp)
|
||||
char *dirname;
|
||||
LS *lp, **s_stats;
|
||||
char **s_names;
|
||||
u_long *blocksp;
|
||||
int *maxlenp;
|
||||
{
|
||||
register DIR *dirp;
|
||||
register int cnt, maxentry, maxlen;
|
||||
register char *p, *names;
|
||||
#define NAMES_BLSIZ 2048
|
||||
int names_len = 4*NAMES_BLSIZ;
|
||||
int names_off;
|
||||
struct dirent *dp;
|
||||
u_long blocks;
|
||||
LS *stats;
|
||||
char newfname[MAXPATHLEN];
|
||||
|
||||
|
||||
if (!(dirp = opendir(dirname))) {
|
||||
(void)fprintf(stderr, "ls: %s: %s\n", lp->name,
|
||||
unixerrstr());
|
||||
return(0);
|
||||
}
|
||||
blocks = maxentry = maxlen = 0;
|
||||
stats = NULL;
|
||||
assert(P_IS_THIS_THREAD_MASTER()); /* readdir is MT-Unsafe */
|
||||
for (cnt = 0; dp = readdir(dirp);) {
|
||||
/* this does -A and -a */
|
||||
p = dp->d_name;
|
||||
if (p[0] == '.') {
|
||||
if (!f_listdot)
|
||||
continue;
|
||||
if (!f_listalldot && (!p[1] || p[1] == '.' && !p[2]))
|
||||
continue;
|
||||
}
|
||||
if (cnt == maxentry) {
|
||||
if (!maxentry)
|
||||
*s_names = names = emalloc(names_len);
|
||||
|
||||
if((names_len - (names_off = names - *s_names))
|
||||
< (2*NAMES_BLSIZ)) {
|
||||
names_len += 2*NAMES_BLSIZ;
|
||||
*s_names = (char *) realloc(*s_names,names_len);
|
||||
names = *s_names + names_off;
|
||||
}
|
||||
#define DEFNUM 256
|
||||
maxentry += DEFNUM;
|
||||
|
||||
if (stats==NULL)
|
||||
*s_stats = stats =
|
||||
(LS *) emalloc((u_int)maxentry * sizeof (LS));
|
||||
else if (!(*s_stats = stats =
|
||||
(LS *) realloc((char *)stats,
|
||||
(u_int)maxentry * sizeof(LS))))
|
||||
nomem();
|
||||
}
|
||||
|
||||
if(*dirname) sprintf(newfname,"%s/%s",dirname,dp->d_name);
|
||||
else strcpy(newfname,dp->d_name);
|
||||
|
||||
if (f_needstat && lstat(newfname, &stats[cnt].lstat)) {
|
||||
/*
|
||||
* don't exit -- this could be an NFS mount that has
|
||||
* gone away. Flush stdout so the messages line up.
|
||||
*/
|
||||
(void)fflush(stdout);
|
||||
(void)fprintf(stderr, "ls: %s: %s\n",
|
||||
dp->d_name, unixerrstr());
|
||||
continue;
|
||||
}
|
||||
stats[cnt].name = names;
|
||||
|
||||
if (f_nonprint)
|
||||
prcopy(dp->d_name, names, (int)dp->d_namlen);
|
||||
else
|
||||
bcopy(dp->d_name, names, (int)dp->d_namlen);
|
||||
names += dp->d_namlen;
|
||||
*names++ = '\0';
|
||||
|
||||
/*
|
||||
* get the inode from the directory, so the -f flag
|
||||
* works right.
|
||||
*/
|
||||
stats[cnt].lstat.st_ino = dp->d_ino;
|
||||
|
||||
/* save name length for -C format */
|
||||
stats[cnt].len = dp->d_namlen;
|
||||
|
||||
/* calculate number of blocks if -l/-s formats */
|
||||
if (f_longform || f_size)
|
||||
blocks += stats[cnt].lstat.st_blocks;
|
||||
|
||||
/* save max length if -C format */
|
||||
if (f_column && maxlen < (int)dp->d_namlen)
|
||||
maxlen = dp->d_namlen;
|
||||
++cnt;
|
||||
}
|
||||
(void)closedir(dirp);
|
||||
|
||||
if (cnt) {
|
||||
*blocksp = blocks;
|
||||
*maxlenp = maxlen;
|
||||
} else if (stats) {
|
||||
(void)free((char *)stats);
|
||||
(void)free((char *)names);
|
||||
}
|
||||
return(cnt);
|
||||
}
|
||||
|
||||
printscol(dirname, stats, num, blocks, maxlen)
|
||||
char *dirname;
|
||||
register LS *stats;
|
||||
register int num;
|
||||
long blocks;
|
||||
long maxlen;
|
||||
{
|
||||
for (; num--; ++stats) {
|
||||
(void)printaname(stats);
|
||||
(void)putchar('\n');
|
||||
}
|
||||
}
|
||||
|
||||
printlong(dirname, stats, num , blocks, maxlen)
|
||||
char *dirname;
|
||||
LS *stats;
|
||||
register int num;
|
||||
u_long blocks;
|
||||
int maxlen ;
|
||||
{
|
||||
char modep[15];
|
||||
|
||||
if (f_total)
|
||||
(void)printf("total %lu\n", f_kblocks ?
|
||||
howmany(blocks, 2) :
|
||||
blocks);
|
||||
for (; num--; ++stats) {
|
||||
if (f_inode)
|
||||
(void)printf("%6lu ", stats->lstat.st_ino);
|
||||
if (f_size)
|
||||
(void)printf("%4ld ", f_kblocks ?
|
||||
howmany(stats->lstat.st_blocks, 2) :
|
||||
stats->lstat.st_blocks);
|
||||
(void)strmode(stats->lstat.st_mode, modep);
|
||||
(void)printf("%s %3u %-*s ", modep, stats->lstat.st_nlink,
|
||||
UT_NAMESIZE, user_from_uid((uid_t) stats->lstat.st_uid));
|
||||
if (f_group)
|
||||
(void)printf("%-*s ", UT_NAMESIZE,
|
||||
group_from_gid((gid_t) stats->lstat.st_gid));
|
||||
if (S_ISCHR(stats->lstat.st_mode) ||
|
||||
S_ISBLK(stats->lstat.st_mode))
|
||||
(void)printf("%3d, %3d ", major(stats->lstat.st_rdev),
|
||||
minor(stats->lstat.st_rdev));
|
||||
else
|
||||
(void)printf("%8ld ", stats->lstat.st_size);
|
||||
if (f_accesstime)
|
||||
printtime(stats->lstat.st_atime);
|
||||
else if (f_statustime)
|
||||
printtime(stats->lstat.st_ctime);
|
||||
else
|
||||
printtime(stats->lstat.st_mtime);
|
||||
(void)printf("%s", stats->name);
|
||||
if (f_type)
|
||||
(void)printtype(stats->lstat.st_mode);
|
||||
if (S_ISLNK(stats->lstat.st_mode))
|
||||
printlink(dirname,stats->name);
|
||||
(void)putchar('\n');
|
||||
}
|
||||
}
|
||||
|
||||
printcol(dirname, stats, num, blocks, maxlen)
|
||||
char *dirname;
|
||||
LS *stats;
|
||||
int num;
|
||||
u_long blocks;
|
||||
int maxlen;
|
||||
{
|
||||
extern int termwidth;
|
||||
register int base, chcnt, cnt, col, colwidth;
|
||||
int endcol, numcols, numrows, row;
|
||||
|
||||
colwidth = maxlen + 2;
|
||||
if (f_inode)
|
||||
colwidth += 6;
|
||||
if (f_size)
|
||||
colwidth += 5;
|
||||
if (f_type)
|
||||
colwidth += 1;
|
||||
|
||||
if (termwidth < 2 * colwidth) {
|
||||
printscol(dirname, stats, num, blocks, maxlen);
|
||||
return;
|
||||
}
|
||||
|
||||
numcols = termwidth / colwidth;
|
||||
numrows = num / numcols;
|
||||
if (num % numcols)
|
||||
++numrows;
|
||||
|
||||
if (f_size && f_total)
|
||||
(void)printf("total %lu\n", f_kblocks ?
|
||||
howmany(blocks, 2) : blocks);
|
||||
for (row = 0; row < numrows; ++row) {
|
||||
endcol = colwidth;
|
||||
for (base = row, chcnt = col = 0; col < numcols; ++col) {
|
||||
chcnt += printaname(stats + base);
|
||||
if ((base += numrows) >= num)
|
||||
break;
|
||||
while ((cnt = chcnt + 1) <= endcol) {
|
||||
(void)putchar(' ');
|
||||
chcnt = cnt;
|
||||
}
|
||||
endcol += colwidth;
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* print [inode] [size] name
|
||||
* return # of characters printed, no trailing characters
|
||||
*/
|
||||
printaname(lp)
|
||||
LS *lp;
|
||||
{
|
||||
int chcnt;
|
||||
|
||||
chcnt = 0;
|
||||
if (f_inode) {
|
||||
printf("%5lu ", lp->lstat.st_ino);
|
||||
chcnt += 6;
|
||||
}
|
||||
if (f_size) {
|
||||
printf("%4ld ", f_kblocks ?
|
||||
howmany(lp->lstat.st_blocks, 2) : lp->lstat.st_blocks);
|
||||
chcnt += 5;
|
||||
}
|
||||
printf("%s", lp->name);
|
||||
chcnt += strlen(lp->name);
|
||||
|
||||
if (f_type) chcnt += printtype(lp->lstat.st_mode);
|
||||
|
||||
return(chcnt);
|
||||
}
|
||||
|
||||
printtime(ftime)
|
||||
time_t ftime;
|
||||
{
|
||||
int i;
|
||||
char *longstring, *ctime();
|
||||
time_t time();
|
||||
|
||||
if(ftime == 0) fputs("- ",stdout);
|
||||
else {
|
||||
|
||||
DISABLE_PFS(longstring = ctime(&ftime));
|
||||
for (i = 4; i < 11; ++i)
|
||||
(void)putchar(longstring[i]);
|
||||
|
||||
#define SIXMONTHS ((DAYSPERNYEAR / 2) * SECSPERDAY)
|
||||
if (ftime + SIXMONTHS > time((time_t *)NULL))
|
||||
for (i = 11; i < 16; ++i)
|
||||
(void)putchar(longstring[i]);
|
||||
else {
|
||||
(void)putchar(' ');
|
||||
for (i = 20; i < 24; ++i)
|
||||
(void)putchar(longstring[i]);
|
||||
}
|
||||
(void)putchar(' ');
|
||||
}
|
||||
}
|
||||
|
||||
printtype(mode)
|
||||
mode_t mode;
|
||||
{
|
||||
switch(mode & S_IFMT) {
|
||||
case S_IFDIR:
|
||||
(void)putchar('/');
|
||||
return(1);
|
||||
case S_IFLNK:
|
||||
(void)putchar('@');
|
||||
return(1);
|
||||
case S_IFSOCK:
|
||||
(void)putchar('=');
|
||||
return(1);
|
||||
}
|
||||
if (mode & (S_IXUSR | S_IXGRP | S_IXOTH)) {
|
||||
(void)putchar('*');
|
||||
return(1);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
printlink(dirname, name)
|
||||
char *dirname;
|
||||
char *name;
|
||||
{
|
||||
char linkname[MAXPATHLEN];
|
||||
int lnklen;
|
||||
char path[MAXPATHLEN + 1];
|
||||
|
||||
if(*dirname) sprintf(linkname,"%s/%s",dirname, name);
|
||||
else strcpy(linkname,name);
|
||||
|
||||
if ((lnklen = readlink(linkname, path, MAXPATHLEN)) == -1) {
|
||||
fflush(stdout);
|
||||
(void)fprintf(stderr, "\nls: %s: %s", name, unixerrstr());
|
||||
fflush(stderr);
|
||||
return;
|
||||
}
|
||||
path[lnklen] = '\0';
|
||||
(void)printf(" -> %s", path);
|
||||
}
|
||||
|
||||
|
||||
prcopy(src, dest, len)
|
||||
register char *src, *dest;
|
||||
register int len;
|
||||
{
|
||||
register int ch;
|
||||
|
||||
while(len--) {
|
||||
ch = *src++;
|
||||
*dest++ = isprint(ch) ? ch : '?';
|
||||
}
|
||||
}
|
||||
|
||||
char
|
||||
*emalloc(size)
|
||||
u_int size;
|
||||
{
|
||||
char *retval, *malloc();
|
||||
|
||||
if (!(retval = malloc(size)))
|
||||
nomem();
|
||||
return(retval);
|
||||
}
|
||||
|
||||
nomem()
|
||||
{
|
||||
(void)fprintf(stderr, "ls: out of memory.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
usage()
|
||||
{
|
||||
(void)fprintf(stderr, "usage: ls [-1ACFLRacdfgiklqrstu] [file ...]\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
namecmp(a, b)
|
||||
LS *a, *b;
|
||||
{
|
||||
return(strcmp(a->name, b->name));
|
||||
}
|
||||
|
||||
revnamecmp(a, b)
|
||||
LS *a, *b;
|
||||
{
|
||||
return(strcmp(b->name, a->name));
|
||||
}
|
||||
|
||||
modcmp(a, b)
|
||||
LS *a, *b;
|
||||
{
|
||||
return(a->lstat.st_mtime < b->lstat.st_mtime);
|
||||
}
|
||||
|
||||
revmodcmp(a, b)
|
||||
LS *a, *b;
|
||||
{
|
||||
return(b->lstat.st_mtime < a->lstat.st_mtime);
|
||||
}
|
||||
|
||||
acccmp(a, b)
|
||||
LS *a, *b;
|
||||
{
|
||||
return(a->lstat.st_atime < b->lstat.st_atime);
|
||||
}
|
||||
|
||||
revacccmp(a, b)
|
||||
LS *a, *b;
|
||||
{
|
||||
return(b->lstat.st_atime < a->lstat.st_atime);
|
||||
}
|
||||
|
||||
int
|
||||
statcmp(a, b)
|
||||
LS *a, *b;
|
||||
{
|
||||
return(a->lstat.st_ctime < b->lstat.st_ctime);
|
||||
}
|
||||
|
||||
int
|
||||
revstatcmp(a, b)
|
||||
LS *a, *b;
|
||||
{
|
||||
return(b->lstat.st_ctime < a->lstat.st_ctime);
|
||||
}
|
||||
|
||||
void
|
||||
strmode(short mode,char *modestr)
|
||||
{
|
||||
strcpy(modestr,"----------");
|
||||
|
||||
if(mode & S_IFDIR) modestr[0] = 'd';
|
||||
if((mode & S_IFLNK) == S_IFLNK) modestr[0] = 'l';
|
||||
if(mode & S_IREAD) modestr[1] = 'r';
|
||||
if(mode & S_IWRITE) modestr[2] = 'w';
|
||||
if(mode & S_IEXEC) modestr[3] = 'x';
|
||||
if(mode & S_ISUID) modestr[3] = 's';
|
||||
if(mode & (S_IREAD>>3)) modestr[4] = 'r';
|
||||
if(mode & (S_IWRITE>>3)) modestr[5] = 'w';
|
||||
if(mode & (S_IEXEC>>3)) modestr[6] = 'x';
|
||||
if(mode & S_ISGID) modestr[6] = 's';
|
||||
if(mode & (S_IREAD>>6)) modestr[7] = 'r';
|
||||
if(mode & (S_IWRITE>>6)) modestr[8] = 'w';
|
||||
if(mode & (S_IEXEC>>6)) modestr[9] = 'x';
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
user_from_uid(uid)
|
||||
uid_t uid;
|
||||
{
|
||||
static char uidstring[10];
|
||||
struct passwd *pwent;
|
||||
|
||||
if(uid == (uid_t) -1) return("-");
|
||||
|
||||
assert(P_IS_THIS_THREAD_MASTER()); /*getpwuid unsafe */
|
||||
DISABLE_PFS(pwent = getpwuid(uid));
|
||||
|
||||
if (pwent == NULL) {
|
||||
sprintf(uidstring,"%d",uid);
|
||||
return(uidstring);
|
||||
}
|
||||
else return(pwent->pw_name);
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
group_from_gid(gid)
|
||||
gid_t gid;
|
||||
{
|
||||
static char gidstring[10];
|
||||
struct group *grent;
|
||||
|
||||
if(gid == (gid_t) -1) return("-");
|
||||
|
||||
assert(P_IS_THIS_THREAD_MASTER()); /*SOLARIS getgrgid MT-Unsafe */
|
||||
DISABLE_PFS(grent = getgrgid(gid));
|
||||
|
||||
if (grent == NULL) {
|
||||
sprintf(gidstring,"%d",gid);
|
||||
return(gidstring);
|
||||
}
|
||||
else return(grent->gr_name);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user