aboutsummaryrefslogtreecommitdiffstats
path: root/src/sash/cmd_find.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sash/cmd_find.c')
-rw-r--r--src/sash/cmd_find.c376
1 files changed, 0 insertions, 376 deletions
diff --git a/src/sash/cmd_find.c b/src/sash/cmd_find.c
deleted file mode 100644
index fde9006..0000000
--- a/src/sash/cmd_find.c
+++ /dev/null
@@ -1,376 +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 "find" built-in command.
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <dirent.h>
-#include <errno.h>
-
-#include "sash.h"
-
-
-#ifdef S_ISLNK
-#define LSTAT lstat
-#else
-#define LSTAT stat
-#endif
-
-
-#define MAX_NAME_SIZE (1024 * 10)
-
-
-/*
- * Items that can be specified to restrict the output.
- */
-static BOOL xdevFlag;
-static dev_t xdevDevice;
-static long fileSize;
-static const char * filePattern;
-static const char * fileType;
-
-
-/*
- * Recursive routine to examine the files in a directory.
- */
-static void examineDirectory(const char * path);
-static BOOL testFile(const char * fullName, const struct stat * statBuf);
-
-
-
-/*
- * Find files from the specified directory path.
- * This is limited to just printing their file names.
- */
-int
-do_find(int argc, const char ** argv)
-{
- const char * cp;
- const char * path;
- struct stat statBuf;
-
- argc--;
- argv++;
-
- xdevFlag = FALSE;
- fileType = NULL;
- filePattern = NULL;
- fileSize = 0;
-
- if ((argc <= 0) || (**argv == '-'))
- {
- fprintf(stderr, "No path specified\n");
-
- return 1;
- }
-
- path = *argv++;
- argc--;
-
- while (argc > 0)
- {
- argc--;
- cp = *argv++;
-
- if (strcmp(cp, "-xdev") == 0)
- xdevFlag = TRUE;
- else if (strcmp(cp, "-type") == 0)
- {
- if ((argc <= 0) || (**argv == '-'))
- {
- fprintf(stderr, "Missing type string\n");
-
- return 1;
- }
-
- argc--;
- fileType = *argv++;
- }
- else if (strcmp(cp, "-name") == 0)
- {
- if ((argc <= 0) || (**argv == '-'))
- {
- fprintf(stderr, "Missing file name\n");
-
- return 1;
- }
-
- argc--;
- filePattern = *argv++;
- }
- else if (strcmp(cp, "-size") == 0)
- {
- if ((argc <= 0) || (**argv == '-'))
- {
- fprintf(stderr, "Missing file size\n");
-
- return 1;
- }
-
- argc--;
- cp = *argv++;
-
- fileSize = 0;
-
- while (isDecimal(*cp))
- fileSize = fileSize * 10 + (*cp++ - '0');
-
- if (*cp || (fileSize < 0))
- {
- fprintf(stderr, "Bad file size specified\n");
-
- return 1;
- }
- }
- else
- {
- if (*cp != '-')
- fprintf(stderr, "Missing dash in option\n");
- else
- fprintf(stderr, "Unknown option\n");
-
- return 1;
- }
- }
-
- /*
- * Get information about the path and make sure that it
- * is a directory.
- */
- if (stat(path, &statBuf) < 0)
- {
- fprintf(stderr, "Cannot stat \"%s\": %s\n", path,
- strerror(errno));
-
- return 1;
- }
-
- if (!S_ISDIR(statBuf.st_mode))
- {
- fprintf(stderr, "Path \"%s\" is not a directory\n", path);
-
- return 1;
- }
-
- /*
- * Remember the device that this directory is on in case we need it.
- */
- xdevDevice = statBuf.st_dev;
-
- /*
- * If the directory meets the specified criteria, then print it out.
- */
- if (testFile(path, &statBuf))
- printf("%s\n", path);
-
- /*
- * Now examine the files in the directory.
- */
- examineDirectory(path);
-
- return 0;
-}
-
-
-/*
- * Recursive routine to examine the files in a directory.
- */
-static void
-examineDirectory(const char * path)
-{
- DIR * dir;
- BOOL needSlash;
- struct dirent * entry;
- struct stat statBuf;
- char fullName[MAX_NAME_SIZE];
-
- /*
- * Open the directory.
- */
- dir = opendir(path);
-
- if (dir == NULL)
- {
- fprintf(stderr, "Cannot read directory \"%s\": %s\n",
- path, strerror(errno));
-
- return;
- }
-
- /*
- * See if a slash is needed.
- */
- needSlash = (*path && (path[strlen(path) - 1] != '/'));
-
- /*
- * Read all of the directory entries and check them,
- * except for the current and parent directory entries.
- */
- while (!intFlag && ((entry = readdir(dir)) != NULL))
- {
- if ((strcmp(entry->d_name, ".") == 0) ||
- (strcmp(entry->d_name, "..") == 0))
- {
- continue;
- }
-
- /*
- * Build the full path name.
- */
- strcpy(fullName, path);
-
- if (needSlash)
- strcat(fullName, "/");
-
- strcat(fullName, entry->d_name);
-
- /*
- * Find out about this file.
- */
- if (LSTAT(fullName, &statBuf) < 0)
- {
- fprintf(stderr, "Cannot stat \"%s\": %s\n",
- fullName, strerror(errno));
-
- continue;
- }
-
- /*
- * If this file matches the criteria that was
- * specified then print its name out.
- */
- if (testFile(fullName, &statBuf))
- printf("%s\n", fullName);
-
- /*
- * If this is a directory and we are allowed to cross
- * mount points or the directory is still on the same
- * device, then examine it's files too.
- */
- if (S_ISDIR(statBuf.st_mode) &&
- (!xdevFlag || (statBuf.st_dev == xdevDevice)))
- {
- examineDirectory(fullName);
- }
- }
-
- closedir(dir);
-}
-
-
-/*
- * Test a file name having the specified status to see if it should
- * be acted on. Returns TRUE if the file name has been selected.
- */
-static BOOL
-testFile(const char * fullName, const struct stat * statBuf)
-{
- const char * cp;
- const char * entryName;
- BOOL wantType;
- int mode;
-
- mode = statBuf->st_mode;
-
- /*
- * Check the file type if it was specified.
- */
- if (fileType != NULL)
- {
- wantType = FALSE;
-
- for (cp = fileType; *cp; cp++)
- {
- switch (*cp)
- {
- case 'f':
- if (S_ISREG(mode))
- wantType = TRUE;
- break;
-
- case 'd':
- if (S_ISDIR(mode))
- wantType = TRUE;
-
- break;
-
- case 'p':
- if (S_ISFIFO(mode))
- wantType = TRUE;
-
- break;
-
- case 'c':
- if (S_ISCHR(mode))
- wantType = TRUE;
-
- break;
-
- case 'b':
- if (S_ISBLK(mode))
- wantType = TRUE;
-
- break;
-
- case 's':
- if (S_ISSOCK(mode))
- wantType = TRUE;
-
- break;
-
-#ifdef S_ISLNK
- case 'l':
- if (S_ISLNK(mode))
- wantType = TRUE;
-
- break;
-#endif
- default:
- break;
- }
- }
-
- if (!wantType)
- return FALSE;
- }
-
- /*
- * Check the file size if it was specified.
- * This check only lets regular files and directories through.
- */
- if (fileSize > 0)
- {
- if (!S_ISREG(mode) && !S_ISDIR(mode))
- return FALSE;
-
- if (statBuf->st_size < fileSize)
- return FALSE;
- }
-
- /*
- * Check the file name pattern if it was specified.
- */
- if (filePattern != NULL)
- {
- entryName = strrchr(fullName, '/');
-
- if (entryName)
- entryName++;
- else
- entryName = fullName;
-
- if (!match(entryName, filePattern))
- return FALSE;
- }
-
- /*
- * This file name is wanted.
- */
- return TRUE;
-}
-
-/* END CODE */