123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311 |
- /*
- * Copyright (c) 1993 by David I. Bell
- * Permission is granted to use, distribute, or modify this source,
- * provided that this copyright notice remains intact.
- *
- * The "ls" built-in command.
- */
- #include "sash.h"
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/sysmacros.h>
- #include <dirent.h>
- #include <pwd.h>
- #include <grp.h>
- #include <time.h>
- #define LISTSIZE 256
- #define COLWIDTH 20
- #ifdef S_ISLNK
- #define LSTAT lstat
- #else
- #define LSTAT stat
- #endif
- /*
- * Flags for the LS command.
- */
- #define LSF_LONG 0x01
- #define LSF_DIR 0x02
- #define LSF_INODE 0x04
- #define LSF_MULT 0x08
- #define LSF_ALL 0x10
- #define LSF_COMPACT 0x20
- static char **list;
- static int listsize;
- static int listused;
- static int linelen = 0;
- static void lsfile();
- void
- do_ls(argc, argv)
- int argc;
- char **argv;
- {
- char *cp;
- char *name;
- int flags;
- int i;
- DIR *dirp;
- BOOL endslash;
- char **newlist;
- struct dirent *dp;
- char fullname[PATHLEN];
- struct stat statbuf;
- static char *def[2];
- if (listsize == 0) {
- list = (char **) malloc(LISTSIZE * sizeof(char *));
- if (list == NULL) {
- fprintf(stderr, "No memory for ls buffer\n");
- return;
- }
- listsize = LISTSIZE;
- }
- listused = 0;
-
- flags = 0;
- if ((argc > 1) && (argv[1][0] == '-'))
- {
- argc--;
- cp = *(++argv) + 1;
- while (*cp) switch (*cp++) {
- case 'l': flags |= LSF_LONG; break;
- case 'd': flags |= LSF_DIR; break;
- case 'i': flags |= LSF_INODE; break;
- case 'a': flags |= LSF_ALL; break;
- case 'C': flags |= LSF_COMPACT; break;
- default:
- fprintf(stderr, "Unknown option -%c\n", cp[-1]);
- return;
- }
- }
- if ((flags & LSF_COMPACT) && (flags & ~LSF_COMPACT)) {
- fprintf(stderr, "Cannot do compact list with other options\n");
- return;
- }
- if (argc <= 1) {
- argc = 2;
- argv = def;
- argv[0] = "ls";
- argv[1] = ".";
- }
- if (argc > 2)
- flags |= LSF_MULT;
- while (argc-- > 1) {
- name = *(++argv);
- endslash = (*name && (name[strlen(name) - 1] == '/'));
- if (LSTAT(name, &statbuf) < 0) {
- perror(name);
- continue;
- }
- if ((flags & LSF_DIR) || (!S_ISDIR(statbuf.st_mode))) {
- lsfile(name, &statbuf, flags);
- continue;
- }
- /*
- * Do all the files in a directory.
- */
- dirp = opendir(name);
- if (dirp == NULL) {
- perror(name);
- continue;
- }
- if (flags & LSF_MULT)
- printf("\n%s:\n", name);
- while ((dp = readdir(dirp)) != NULL) {
-
- if ((dp->d_name[0] == '.') && !(flags & LSF_ALL))
- continue;
- fullname[0] = '\0';
- if ((*name != '.') || (name[1] != '\0')) {
- strcpy(fullname, name);
- if (!endslash)
- strcat(fullname, "/");
- }
- strcat(fullname, dp->d_name);
- if (listused >= listsize) {
- newlist = malloc((sizeof(char **)) * (listsize + LISTSIZE));
- if (newlist == NULL) {
- fprintf(stderr, "No memory for ls buffer\n");
- break;
- }
- memcpy(newlist, list, sizeof(char**) * listsize);
- free(list);
- listsize += LISTSIZE;
- }
- list[listused] = strdup(fullname);
- if (list[listused] == NULL) {
- fprintf(stderr, "No memory for filenames\n");
- break;
- }
- listused++;
- }
- closedir(dirp);
- /*
- * Sort the files.
- */
- qsort((char *) list, listused, sizeof(char *), namesort);
- /*
- * Now finally list the filenames.
- */
- for (i = 0; i < listused; i++) {
- name = list[i];
- if (LSTAT(name, &statbuf) < 0) {
- perror(name);
- free(name);
- continue;
- }
- cp = strrchr(name, '/');
- if (cp)
- cp++;
- else
- cp = name;
- lsfile(cp, &statbuf, flags);
- free(name);
- }
- listused = 0;
- }
- if (linelen)
- fputc('\n', stdout);
- }
- /*
- * Do an LS of a particular file name according to the flags.
- */
- static void
- lsfile(name, statbuf, flags)
- char *name;
- struct stat *statbuf;
- {
- char *cp;
- struct passwd *pwd;
- struct group *grp;
- int len;
- char buf[PATHLEN];
- static char username[12];
- static int userid;
- static BOOL useridknown;
- static char groupname[12];
- static int groupid;
- static BOOL groupidknown;
- cp = buf;
- *cp = '\0';
- if (flags & LSF_INODE) {
- sprintf(cp, "%5d ", statbuf->st_ino);
- cp += strlen(cp);
- }
- if (flags & LSF_LONG) {
- strcpy(cp, modestring(statbuf->st_mode));
- cp += strlen(cp);
- sprintf(cp, "%3d ", statbuf->st_nlink);
- cp += strlen(cp);
- if (!useridknown || (statbuf->st_uid != userid)) {
- /*pwd = getpwuid(statbuf->st_uid);
- if (pwd)
- strcpy(username, pwd->pw_name);
- else*/
- sprintf(username, "%d", statbuf->st_uid);
- userid = statbuf->st_uid;
- useridknown = TRUE;
- }
- sprintf(cp, "%-8s ", username);
- cp += strlen(cp);
- if (!groupidknown || (statbuf->st_gid != groupid)) {
- /*grp = getgrgid(statbuf->st_gid);
- if (grp)
- strcpy(groupname, grp->gr_name);
- else*/
- sprintf(groupname, "%d", statbuf->st_gid);
- groupid = statbuf->st_gid;
- groupidknown = TRUE;
- }
- sprintf(cp, "%-8s ", groupname);
- cp += strlen(cp);
- if (S_ISBLK(statbuf->st_mode) || S_ISCHR(statbuf->st_mode))
- sprintf(cp, "%3d, %3d ", major(statbuf->st_rdev),
- minor(statbuf->st_rdev));
- else
- sprintf(cp, "%8d ", statbuf->st_size);
- cp += strlen(cp);
- sprintf(cp, " %-12s ", timestring(statbuf->st_mtime));
- }
- fputs(buf, stdout);
- fputs(name, stdout);
- #ifdef S_ISLNK
- if ((flags & LSF_LONG) && S_ISLNK(statbuf->st_mode)) {
- len = readlink(name, buf, PATHLEN - 1);
- if (len >= 0) {
- buf[len] = '\0';
- printf(" -> %s", buf);
- }
- }
- #endif
- if (flags & LSF_COMPACT) {
- len = strlen(name);
- if (len < COLWIDTH) {
- for (; (len < COLWIDTH); len++)
- fputc(' ', stdout);
- linelen += COLWIDTH;
- } else {
- linelen = 80;
- }
- if (linelen >= 80) {
- fputc('\n', stdout);
- linelen = 0;
- }
- } else {
- fputc('\n', stdout);
- }
- }
- /* END CODE */
|