aboutsummaryrefslogtreecommitdiffstats
path: root/src/sash/cmd_ls.c
diff options
context:
space:
mode:
authortcsullivan <tullivan99@gmail.com>2018-11-17 13:02:57 -0500
committertcsullivan <tullivan99@gmail.com>2018-11-17 13:02:57 -0500
commitc6ef89664b8c0d7aa85bddd5c7014aa6df82cbe7 (patch)
treed1f9d09412a46bdf4344fe30392455070a72993d /src/sash/cmd_ls.c
parentdb38c4b9dac461de0ed75bf6d079dacba1b31bc9 (diff)
added pdclib, removed sash
Diffstat (limited to 'src/sash/cmd_ls.c')
-rw-r--r--src/sash/cmd_ls.c597
1 files changed, 0 insertions, 597 deletions
diff --git a/src/sash/cmd_ls.c b/src/sash/cmd_ls.c
deleted file mode 100644
index 41f31cc..0000000
--- a/src/sash/cmd_ls.c
+++ /dev/null
@@ -1,597 +0,0 @@
-/*
- * Copyright (c) 2014 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 "dirent.h"
-#include <pwd.h>
-#include <grp.h>
-
-
-#define LISTSIZE 8192
-
-
-#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_FLAG 0x10
-#define LSF_COLUMN 0x20
-#define LSF_NUMERIC 0x40
-
-
-/*
- * Data holding list of files.
- */
-static char ** list;
-static int listSize;
-static int listUsed;
-
-/*
- * Cached user and group name data.
- */
-static char userName[12];
-static int userId;
-static BOOL userIdKnown;
-static char groupName[12];
-static int groupId;
-static BOOL groupIdKnown;
-
-
-/*
- * Local procedures.
- */
-static void listFile(
- const char * name,
- const struct stat * statBuf,
- int flags,
- int width
-);
-
-static BOOL addListName(const char * fileName);
-static void listAllFiles(int flags, int displayWidth);
-static void clearListNames(void);
-
-
-int
-do_ls(int argc, const char ** argv)
-{
- const char * cp;
- const char * name;
- int flags;
- int i;
- int displayWidth;
- BOOL endSlash;
- DIR * dirp;
- struct dirent * dp;
- char fullName[PATH_LEN];
- struct stat statBuf;
- int r;
-
- static const char * def[] = {"."};
-
- /*
- * Reset for a new listing run.
- */
- clearListNames();
-
- userIdKnown = FALSE;
- groupIdKnown = FALSE;
-
- displayWidth = 0;
- flags = 0;
-
- /*
- * Handle options.
- */
- argc--;
- argv++;
-
- while ((argc > 0) && (**argv == '-'))
- {
- cp = *argv++ + 1;
- argc--;
-
- while (*cp) switch (*cp++)
- {
- case 'l': flags |= LSF_LONG; break;
- case 'n': flags |= LSF_NUMERIC; break;
- case 'd': flags |= LSF_DIR; break;
- case 'i': flags |= LSF_INODE; break;
- case 'F': flags |= LSF_FLAG; break;
- case 'C': flags |= LSF_COLUMN; break;
-
- default:
- fprintf(stderr, "Unknown option -%c\n", cp[-1]);
-
- return 1;
- }
- }
-
- /*
- * If long or numeric listing is specified then turn off column listing.
- */
- if (flags & (LSF_LONG | LSF_NUMERIC))
- flags &= ~LSF_COLUMN;
-
- /*
- * If column listing is specified then calculate the maximum
- * width available for the columns of file names.
- * This is settable using the COLS environment variable.
- */
- if (flags & LSF_COLUMN)
- {
- name = getenv("COLS");
-
- if (name)
- displayWidth = atoi(name);
-
- if (displayWidth <= 0)
- displayWidth = 80;
- }
-
- /*
- * If no arguments are given set up to show the current directory.
- */
- if (argc <= 0)
- {
- argc = 1;
- argv = def;
- }
-
- if (argc > 1)
- flags |= LSF_MULT;
-
- /*
- * Make one pass over the file names to collect together
- * all of the files which are not directories.
- * We will process them all as one list.
- */
- for (i = 0; i < argc; i++)
- {
- if ((flags & LSF_DIR) || !isDirectory(argv[i]))
- {
- if (!addListName(argv[i]))
- return 1;
- }
- }
-
- /*
- * List those file names, and then clear the list.
- */
- listAllFiles(flags, displayWidth);
- clearListNames();
-
- /*
- * If directories were being listed as themselves, then we are done.
- */
- if (flags & LSF_DIR)
- return r;
-
- /*
- * Now iterate over the file names processing the directories.
- */
- while (!intFlag && (argc-- > 0))
- {
- name = *argv++;
- endSlash = (*name && (name[strlen(name) - 1] == '/'));
-
- if (LSTAT(name, &statBuf) < 0)
- {
- perror(name);
- r = 1;
-
- continue;
- }
-
- /*
- * If this file name is not a directory, then ignore it.
- */
- if (!S_ISDIR(statBuf.st_mode))
- continue;
-
- /*
- * Collect all the files in the directory.
- */
- dirp = opendir(name);
-
- if (dirp == NULL)
- {
- perror(name);
-
- continue;
- }
-
- if (flags & LSF_MULT)
- printf("\n%s:\n", name);
-
- while (!intFlag && ((dp = readdir(dirp)) != NULL))
- {
- fullName[0] = '\0';
-
- if ((*name != '.') || (name[1] != '\0'))
- {
- strcpy(fullName, name);
-
- if (!endSlash)
- strcat(fullName, "/");
- }
-
- strcat(fullName, dp->d_name);
-
- /*
- * Save the file name in the list.
- */
- if (!addListName(fullName))
- {
- closedir(dirp);
-
- return 1;
- }
- }
-
- closedir(dirp);
-
- /*
- * List the files we collected in this directory,
- * and then clear the list.
- */
- listAllFiles(flags, displayWidth);
- clearListNames();
- }
-
- return r;
-}
-
-
-/*
- * List all of the files in the current list of files.
- * The files are displayed according to the specified flags,
- * in the specified display width.
- */
-static void
-listAllFiles(int flags, int displayWidth)
-{
- const char * name;
- const char * cp;
- int fileWidth;
- int column;
- int len;
- int i;
- struct stat statBuf;
-
- /*
- * Initialise width data until we need it.
- */
- fileWidth = 0;
- column = 0;
-
- /*
- * Sort the files in the list.
- */
- qsort((void *) list, listUsed, sizeof(char *), nameSort);
-
- /*
- * If we are showing the files in columns then calculate the
- * maximum width of all of the file names, taking into account
- * various factors.
- */
- if (flags & LSF_COLUMN)
- {
- for (i = 0; i < listUsed; i++)
- {
- len = strlen(list[i]);
-
- if (fileWidth < len)
- fileWidth = len;
- }
-
- if (flags & LSF_FLAG)
- fileWidth++;
-
- if (flags & LSF_INODE)
- fileWidth += 8;
-
- fileWidth += 2;
- }
-
- /*
- * Now list the fileNames.
- */
- for (i = 0; i < listUsed; i++)
- {
- name = list[i];
-
- if (LSTAT(name, &statBuf) < 0)
- {
- perror(name);
-
- continue;
- }
-
- cp = strrchr(name, '/');
-
- if (cp)
- cp++;
- else
- cp = name;
-
- /*
- * List the file in the next column or at the end
- * of a line depending on the width left.
- */
- if (column + fileWidth * 2 >= displayWidth)
- {
- listFile(cp, &statBuf, flags, 0);
- column = 0;
- }
- else
- {
- listFile(cp, &statBuf, flags, fileWidth);
- column += fileWidth;
- }
- }
-
- /*
- * Terminate the last file name if necessary.
- */
- if (column > 0)
- fputc('\n', stdout);
-}
-
-
-/*
- * Do a listing of a particular file name according to the flags.
- * The output is shown within the specified width if it is nonzero,
- * or on its own line if the width is zero.
- */
-static void
-listFile(
- const char * name,
- const struct stat * statBuf,
- int flags,
- int width
-)
-{
- char * cp;
- struct passwd * pwd;
- struct group * grp;
- int len;
- int mode;
- int flagChar;
- int usedWidth;
- char buf[PATH_LEN];
-
- mode = statBuf->st_mode;
-
- /*
- * Initialise buffers for use.
- */
- cp = buf;
- buf[0] = '\0';
- flagChar = '\0';
-
- /*
- * Show the inode number if requested.
- */
- if (flags & LSF_INODE)
- {
- sprintf(cp, "%7ld ", statBuf->st_ino);
- cp += strlen(cp);
- }
-
- /*
- * Create the long or numeric status line if requested.
- */
- if (flags & (LSF_LONG | LSF_NUMERIC))
- {
- strcpy(cp, modeString(mode));
- cp += strlen(cp);
-
- sprintf(cp, "%3ld ", (long) statBuf->st_nlink);
- cp += strlen(cp);
-
- if (!userIdKnown || (statBuf->st_uid != userId))
- {
- if (flags & LSF_NUMERIC)
- pwd = 0;
- else
- 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))
- {
- if (flags & LSF_NUMERIC)
- grp = 0;
- else
- 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(mode) || S_ISCHR(mode))
- {
- sprintf(cp, "%3lu, %3lu ",
- ((unsigned long) statBuf->st_rdev) >> 8,
- ((unsigned long) statBuf->st_rdev) & 0xff);
- }
- else
- sprintf(cp, "%8ld ", statBuf->st_size);
-
- cp += strlen(cp);
-
- sprintf(cp, " %-12s ", timeString(statBuf->st_mtime));
- }
-
- /*
- * Set the special character if the file is a directory or
- * symbolic link or executable and the display was requested.
- */
- if (flags & LSF_FLAG)
- {
- if (S_ISDIR(mode))
- flagChar = '/';
-#ifdef S_ISLNK
- else if (S_ISLNK(mode))
- flagChar = '@';
-#endif
- else if ((mode & 0111) != 0)
- flagChar = '*';
- }
-
- /*
- * Print the status info followed by the file name.
- */
- fputs(buf, stdout);
- fputs(name, stdout);
-
- if (flagChar)
- fputc(flagChar, stdout);
-
- /*
- * Calculate the width used so far.
- */
- usedWidth = strlen(buf) + strlen(name);
-
- if (flagChar)
- usedWidth++;
-
- /*
- * Show where a symbolic link points.
- */
-#ifdef S_ISLNK
- if ((flags & LSF_LONG) && S_ISLNK(mode))
- {
- len = readlink(name, buf, PATH_LEN - 1);
-
- if (len >= 0)
- {
- buf[len] = '\0';
- printf(" -> %s", buf);
- }
-
- usedWidth += strlen(buf) + 4;
- }
-#endif
-
- /*
- * If no width was given then just end the line with a newline.
- */
- if (width == 0)
- {
- fputc('\n', stdout);
-
- return;
- }
-
- /*
- * There is a width given.
- * Print as many spaces as it takes to reach that width.
- */
- while (usedWidth++ < width)
- fputc(' ', stdout);
-}
-
-
-/*
- * Save a file name to the end of the static list, reallocating if necessary.
- * The file name is copied into allocated memory owned by the list.
- * Returns TRUE on success.
- */
-static BOOL
-addListName(const char * fileName)
-{
- char ** newList;
-
- /*
- * Reallocate the list if necessary.
- */
- if (listUsed >= listSize)
- {
- newList = realloc(list,
- ((sizeof(char **)) * (listSize + LISTSIZE)));
-
- if (newList == NULL)
- {
- fprintf(stderr, "No memory for file name buffer\n");
-
- return FALSE;
- }
-
- list = newList;
- listSize += LISTSIZE;
- }
-
- /*
- * Copy the file name into the next entry.
- */
- list[listUsed] = strdup(fileName);
-
- if (list[listUsed] == NULL)
- {
- fprintf(stderr, "No memory for file name\n");
-
- return FALSE;
- }
-
- /*
- * Increment the amount of space used.
- */
- listUsed++;
-
- return TRUE;
-}
-
-
-/*
- * Free all of the names from the list of file names.
- */
-static void
-clearListNames(void)
-{
- while (listUsed > 0)
- {
- listUsed--;
-
- free(list[listUsed]);
- }
-}
-
-/* END CODE */