diff options
author | tcsullivan <tullivan99@gmail.com> | 2018-11-17 13:02:57 -0500 |
---|---|---|
committer | tcsullivan <tullivan99@gmail.com> | 2018-11-17 13:02:57 -0500 |
commit | c6ef89664b8c0d7aa85bddd5c7014aa6df82cbe7 (patch) | |
tree | d1f9d09412a46bdf4344fe30392455070a72993d /src/sash/sash.c | |
parent | db38c4b9dac461de0ed75bf6d079dacba1b31bc9 (diff) |
added pdclib, removed sash
Diffstat (limited to 'src/sash/sash.c')
-rw-r--r-- | src/sash/sash.c | 1373 |
1 files changed, 0 insertions, 1373 deletions
diff --git a/src/sash/sash.c b/src/sash/sash.c deleted file mode 100644 index 8c15711..0000000 --- a/src/sash/sash.c +++ /dev/null @@ -1,1373 +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. - * - * Stand-alone shell for system maintainance for Linux. - * This program should NOT be built using shared libraries. - */ - -#include <sys/types.h> -#include <sys/wait.h> -#include <signal.h> -#include <errno.h> - -#include "sash.h" - - -static const char * const version = "3.8"; - - -/* - * The special maximum argument value which means that there is - * no limit to the number of arguments on the command line. - */ -#define INFINITE_ARGS 0x7fffffff - - -/* - * One entry of the command table. - */ -typedef struct -{ - const char * name; - int (*func)(int argc, const char ** argv); - int minArgs; - int maxArgs; - const char * description; - const char * usage; -} CommandEntry; - - -/* - * The table of built-in commands. - * This is terminated wih an entry containing NULL values. - */ -static const CommandEntry commandEntryTable[] = -{ - { - "alias", do_alias, 1, INFINITE_ARGS, - "Define a command alias", - "[name [command]]" - }, - - { - "aliasall", do_aliasall, 1, 1, - "Define aliases for all of the build-in commands", - "" - }, - - { - "-ar", do_ar, 3, INFINITE_ARGS, - "Extract or list files from an AR file", - "[txp]v arFileName fileName ..." - }, - - { - "cd", do_cd, 1, 2, - "Change current directory", - "[dirName]" - }, - -#if HAVE_LINUX_ATTR - { - "-chattr", do_chattr, 3, INFINITE_ARGS, - "Change ext2 file attributes", - "[+i] [-i] [+a] [-a] fileName ..." - }, -#endif - - { - "-chgrp", do_chgrp, 3, INFINITE_ARGS, - "Change the group id of some files", - "gid fileName ..." - }, - - { - "-chmod", do_chmod, 3, INFINITE_ARGS, - "Change the protection of some files", - "mode fileName ..." - }, - - { - "-chown", do_chown, 3, INFINITE_ARGS, - "Change the owner id of some files", - "uid fileName ..." - }, - - { - "-cmp", do_cmp, 3, 3, - "Compare two files for equality", - "fileName1 fileName2" - }, - - { - "-cp", do_cp, 3, INFINITE_ARGS, - "Copy files", - "srcName ... destName" - }, - -#ifdef HAVE_LINUX_CHROOT - { - "-chroot", do_chroot, 2, 2, - "change root file system", - "new_root_dir" - }, -#endif - - { - "-dd", do_dd, 3, INFINITE_ARGS, - "Copy data between two files", - "if=name of=name [bs=n] [count=n] [skip=n] [seek=n]" - }, - - { - "-echo", do_echo, 1, INFINITE_ARGS, - "Echo the arguments", - "[args] ..." - }, - - { - "-ed", do_ed, 1, 2, - "Edit a fileName using simple line mode commands", - "[fileName]" - }, - - { - "exec", do_exec, 2, INFINITE_ARGS, - "Execute another program in place of this sash process", - "fileName [args]" - }, - - { - "exit", do_exit, 1, 2, - "Exit from sash", - "[exit value]" - }, - - { - "-file", do_file, 1, INFINITE_ARGS, - "Describe information about files", - "fileName ..." - }, - - { - "-find", do_find, 2, INFINITE_ARGS, - "Find files in a directory tree meeting some conditions", - "dirName [-xdev] [-type chars] [-name pattern] [-size minSize]" - }, - - { - "-grep", do_grep, 3, INFINITE_ARGS, - "Look for lines containing a word in some files", - "[-in] word fileName ..." - }, - -#if HAVE_GZIP - { - "-gunzip", do_gunzip, 2, INFINITE_ARGS, - "Uncompress files which were saved in GZIP or compress format", - "fileName ... [-o outputPath]" - }, - - { - "-gzip", do_gzip, 2, INFINITE_ARGS, - "Compress files into GZIP format", - "fileName ... [-o outputPath]" - }, -#endif - - { - "help", do_help, 1, 2, - "Print help about a command", - "[word]" - }, - - { - "-kill", do_kill, 2, INFINITE_ARGS, - "Send a signal to the specified process", - "[-sig] pid ..." - }, - -#ifdef HAVE_LINUX_LOSETUP - { - "-losetup", do_losetup, 3, 3, - "Associate a loopback device with a file", - "[-d] device\n -losetup device filename" - }, -#endif - - { - "-ln", do_ln, 3, INFINITE_ARGS, - "Link one fileName to another", - "[-s] srcName ... destName" - }, - - { - "-ls", do_ls, 1, INFINITE_ARGS, - "List information about files or directories", - "[-lidFC] fileName ..." - }, - -#if HAVE_LINUX_ATTR - { - "-lsattr", do_lsattr, 2, INFINITE_ARGS, - "List ext2 file attributes", - "fileName ..." - }, -#endif - - { - "-mkdir", do_mkdir, 2, INFINITE_ARGS, - "Create a directory", - "dirName ..." - }, - - { - "-mknod", do_mknod, 5, 5, - "Create a special type of file", - "fileName type major minor" - }, - - { - "-more", do_more, 2, INFINITE_ARGS, - "Type file contents page by page", - "fileName ..." - }, - - { - "-mount", do_mount, 3, INFINITE_ARGS, - "Mount or remount a filesystem on a directory", -#if HAVE_LINUX_MOUNT - "[-t type] [-r] [-s] [-e] [-m] devName dirName" -#elif HAVE_BSD_MOUNT - "[-t type] [-r] [-s] [-e] devName dirName" -#else - "[-t type] devName dirName" -#endif - }, - - { - "-mv", do_mv, 3, INFINITE_ARGS, - "Move or rename files", - "srcName ... destName" - }, - -#ifdef HAVE_LINUX_PIVOT - { - "-pivot_root", do_pivot_root, 3, 3, - "pivot the root file system", - "new_dir old_dir" - }, -#endif - - { - "-printenv", do_printenv, 1, 2, - "Print environment variables", - "[name]" - }, - - { - "prompt", do_prompt, 2, INFINITE_ARGS, - "Set the prompt string for sash", - "string" - }, - - { - "-pwd", do_pwd, 1, 1, - "Print the current working directory", - "" - }, - - { - "quit", do_exit, 1, 1, - "Exit from sash", - "" - }, - - { - "-rm", do_rm, 2, INFINITE_ARGS, - "Remove the specified files", - "fileName ..." - }, - - { - "-rmdir", do_rmdir, 2, INFINITE_ARGS, - "Remove the specified empty directories", - "dirName ..." - }, - - { - "setenv", do_setenv, 3, 3, - "Set an environment variable value", - "name value" - }, - - { - "source", do_source, 2, 2, - "Read commands from the specified file", - "fileName" - }, - - { - "-sum", do_sum, 2, INFINITE_ARGS, - "Calculate checksums of the specified files", - "fileName ..." - }, - - { - "-sync", do_sync, 1, 1, - "Sync the disks to force cached data to them", - "" - }, - - { - "-tar", do_tar, 2, INFINITE_ARGS, - "Create, extract, or list files from a TAR file", - "[cxtv]f tarFileName fileName ..." - }, - - { - "-touch", do_touch, 2, INFINITE_ARGS, - "Update times or create the specified files", - "fileName ..." - }, - - { - "umask", do_umask, 1, 2, - "Set the umask value for file protections", - "[mask]" - }, - - { -#if HAVE_BSD_MOUNT - "-umount", do_umount, 2, 3, - "Unmount a filesystem", - "[-f] fileName" -#else - "-umount", do_umount, 2, 2, - "Unmount a filesystem", - "fileName" -#endif - }, - - { - "unalias", do_unalias, 2, 2, - "Remove a command alias", - "name" - }, - - { - "-where", do_where, 2, 2, - "Type the location of a program", - "program" - }, - - { - NULL, 0, 0, 0, - NULL, - NULL - } -}; - - -/* - * The definition of an command alias. - */ -typedef struct -{ - char * name; - char * value; -} Alias; - - -/* - * Local data. - */ -static Alias * aliasTable; -static int aliasCount; - -static FILE * sourcefiles[MAX_SOURCE]; -static int sourceCount; - -static BOOL intCrlf = TRUE; -static char * prompt; - - -/* - * Local procedures. - */ -static void catchInt(int); -static void catchQuit(int); -static int readFile(const char * name); -static int command(const char * cmd); -static BOOL tryBuiltIn(const char * cmd); -static int runCmd(const char * cmd); -static void childProcess(const char * cmd); -static void showPrompt(void); -static void usage(void); -static Alias * findAlias(const char * name); -static void expandVariable(char * name); - - -/* - * Global interrupt flag. - */ -BOOL intFlag; - - -int -main(int argc, const char ** argv) -{ - const char * cp; - const char * singleCommand; - const char * commandFile; - BOOL quietFlag; - BOOL aliasFlag; - BOOL interactiveFlag; - char buf[PATH_LEN]; - - singleCommand = NULL; - commandFile = NULL; - quietFlag = FALSE; - aliasFlag = FALSE; - interactiveFlag = FALSE; - - /* - * Look for options. - */ - argv++; - argc--; - - while ((argc > 0) && (**argv == '-')) - { - cp = *argv++ + 1; - argc--; - - while (*cp) switch (*cp++) - { - case '-': - /* - * Ignore. This is so that we can be - * run from login. - */ - break; - - case 'c': - /* - * Execute specified command. - */ - if ((argc != 1) || singleCommand || interactiveFlag) - usage(); - - singleCommand = *argv++; - argc--; - - break; - - case 'f': - /* - * Execute commands from file. - * This is used for sash script files. - * The quiet flag is also set. - */ - if ((argc != 1) || commandFile) - usage(); - - quietFlag = TRUE; - commandFile = *argv++; - argc--; - - break; - - case 'i': - /* - * Be an interactive shell - * ..is a no-op, but some contexts require this - * ..interactiveFlag is to avoid -ic as a legacy - */ - if (singleCommand) - usage(); - - interactiveFlag = TRUE; - break; - - case 'p': - /* - * Set the prompt string. - */ - if ((argc <= 0) || (**argv == '-')) - usage(); - - if (prompt) - free(prompt); - - prompt = strdup(*argv++); - argc--; - - break; - - case 'q': - quietFlag = TRUE; - break; - - case 'a': - aliasFlag = TRUE; - break; - - case 'h': - case '?': - usage(); - break; - - default: - fprintf(stderr, "Unknown option -%c\n", cp[-1]); - - return 1; - } - } - - /* - * No more arguments are allowed. - */ - if (argc > 0) - usage(); - - /* - * Default our path if it is not set. - */ - if (getenv("PATH") == NULL) - putenv("PATH=/bin:/usr/bin:/sbin:/usr/sbin:/etc"); - - /* - * If the alias flag is set then define all aliases. - */ - if (aliasFlag) - do_aliasall(0, NULL); - - /* - * If we are to execute a single command, then do so and exit. - */ - if (singleCommand) - { - return command(singleCommand); - } - - /* - * Print a hello message unless we are told to be silent. - */ - if (!quietFlag && isatty(STDIN)) - { - printf("Stand-alone shell (version %s)\n", version); - - if (aliasFlag) - printf("Built-in commands are aliased to standard commands\n"); - } - - signal(SIGINT, catchInt); - signal(SIGQUIT, catchQuit); - - /* - * Execute the user's alias file if present. - */ - cp = getenv("HOME"); - - if (cp) - { - strcpy(buf, cp); - strcat(buf, "/"); - strcat(buf, ".aliasrc"); - - if ((access(buf, 0) == 0) || (errno != ENOENT)) - readFile(buf); - } - - /* - * Read commands from stdin or from a command file. - */ - return readFile(commandFile); - -} - - -/* - * Read commands from the specified file. - * A null name pointer indicates to read from stdin. - */ -static int -readFile(const char * name) -{ - FILE * fp; - int cc; - BOOL ttyFlag; - char buf[CMD_LEN]; - int r = 0; - - if (sourceCount >= MAX_SOURCE) - { - fprintf(stderr, "Too many source files\n"); - - return 1; - } - - fp = stdin; - - if (name) - { - fp = fopen(name, "r"); - - if (fp == NULL) - { - perror(name); - - return 1; - } - } - - sourcefiles[sourceCount++] = fp; - - ttyFlag = isatty(fileno(fp)); - - while (TRUE) - { - if (ttyFlag) - showPrompt(); - - if (intFlag && !ttyFlag && (fp != stdin)) - { - fclose(fp); - sourceCount--; - - return 1; - } - - if (fgets(buf, CMD_LEN - 1, fp) == NULL) - { - if (ferror(fp) && (errno == EINTR)) - { - clearerr(fp); - - continue; - } - - break; - } - - cc = strlen(buf); - - if (buf[cc - 1] == '\n') - cc--; - - while ((cc > 0) && isBlank(buf[cc - 1])) - cc--; - - buf[cc] = '\0'; - - r = command(buf); - } - - if (ferror(fp)) - { - perror("Reading command line"); - - if (fp == stdin) - exit(1); - } - - clearerr(fp); - - if (fp != stdin) - fclose(fp); - - sourceCount--; - - return r; -} - - -/* - * Parse and execute one null-terminated command line string. - * This breaks the command line up into words, checks to see if the - * command is an alias, and expands wildcards. - */ -static int -command(const char * cmd) -{ - const char * endCmd; - const Alias * alias; - char newCommand[CMD_LEN]; - char cmdName[CMD_LEN]; - - /* - * Rest the interrupt flag and free any memory chunks that - * were allocated by the previous command. - */ - intFlag = FALSE; - - freeChunks(); - - /* - * Skip leading blanks. - */ - while (isBlank(*cmd)) - cmd++; - - /* - * If the command is empty or is a comment then ignore it. - */ - if ((*cmd == '\0') || (*cmd == '#')) - return 0; - - /* - * Look for the end of the command name and then copy the - * command name to a buffer so we can null terminate it. - */ - endCmd = cmd; - - while (*endCmd && !isBlank(*endCmd)) - endCmd++; - - memcpy(cmdName, cmd, endCmd - cmd); - - cmdName[endCmd - cmd] = '\0'; - - /* - * Search for the command name in the alias table. - * If it is found, then replace the command name with - * the alias value, and append the current command - * line arguments to that. - */ - alias = findAlias(cmdName); - - if (alias) - { - strcpy(newCommand, alias->value); - strcat(newCommand, endCmd); - - cmd = newCommand; - } - - /* - * Expand simple environment variables - */ - while (strstr(cmd, "$(")) expandVariable((char *)cmd); - - /* - * Now look for the command in the builtin table, and execute - * the command if found. - */ - if (tryBuiltIn(cmd)) - return 0; /* This is a blatant lie */ - - /* - * The command is not a built-in, so run the program along - * the PATH list. - */ - return runCmd(cmd); -} - - -/* - * Try to execute a built-in command. - * Returns TRUE if the command is a built in, whether or not the - * command succeeds. Returns FALSE if this is not a built-in command. - */ -static BOOL -tryBuiltIn(const char * cmd) -{ - const char * endCmd; - const CommandEntry * entry; - int argc; - const char ** argv; - char cmdName[CMD_LEN]; - - /* - * Look for the end of the command name and then copy the - * command name to a buffer so we can null terminate it. - */ - endCmd = cmd; - - while (*endCmd && !isBlank(*endCmd)) - endCmd++; - - memcpy(cmdName, cmd, endCmd - cmd); - - cmdName[endCmd - cmd] = '\0'; - - /* - * Search the command table looking for the command name. - */ - for (entry = commandEntryTable; entry->name != NULL; entry++) - { - if (strcmp(entry->name, cmdName) == 0) - break; - } - - /* - * If the command is not a built-in, return indicating that. - */ - if (entry->name == NULL) - return FALSE; - - /* - * The command is a built-in. - * Break the command up into arguments and expand wildcards. - */ - if (!makeArgs(cmd, &argc, &argv)) - return TRUE; - - /* - * Give a usage string if the number of arguments is too large - * or too small. - */ - if ((argc < entry->minArgs) || (argc > entry->maxArgs)) - { - fprintf(stderr, "usage: %s %s\n", entry->name, entry->usage); - - return TRUE; - } - - /* - * Call the built-in function with the argument list. - */ - entry->func(argc, argv); - - return TRUE; -} - - -/* - * Execute the specified command either by forking and executing - * the program ourself, or else by using the shell. Returns the - * exit status, or -1 if the program cannot be executed at all. - */ -static int -runCmd(const char * cmd) -{ - const char * cp; - BOOL magic; - pid_t pid; - int status; - - /* - * Check the command for any magic shell characters - * except for quoting. - */ - magic = FALSE; - - for (cp = cmd; *cp; cp++) - { - if ((*cp >= 'a') && (*cp <= 'z')) - continue; - - if ((*cp >= 'A') && (*cp <= 'Z')) - continue; - - if (isDecimal(*cp)) - continue; - - if (isBlank(*cp)) - continue; - - if ((*cp == '.') || (*cp == '/') || (*cp == '-') || - (*cp == '+') || (*cp == '=') || (*cp == '_') || - (*cp == ':') || (*cp == ',') || (*cp == '\'') || - (*cp == '"')) - { - continue; - } - - magic = TRUE; - } - - /* - * If there were any magic characters used then run the - * command using the shell. - */ - if (magic) - return trySystem(cmd); - - /* - * No magic characters were in the command, so we can do the fork - * and exec ourself. - */ - pid = fork(); - - if (pid < 0) - { - perror("fork failed"); - - return -1; - } - - /* - * If we are the child process, then go execute the program. - */ - if (pid == 0) - childProcess(cmd); - - /* - * We are the parent process. - * Wait for the child to complete. - */ - status = 0; - intCrlf = FALSE; - - while (((pid = waitpid(pid, &status, 0)) < 0) && (errno == EINTR)) - ; - - intCrlf = TRUE; - - if (pid < 0) - { - fprintf(stderr, "Error from waitpid: %s", strerror(errno)); - - return -1; - } - - if (WIFSIGNALED(status)) - { - fprintf(stderr, "pid %ld: killed by signal %d\n", - (long) pid, WTERMSIG(status)); - - return -1; - } - - return WEXITSTATUS(status); -} - - -/* - * Here as the child process to try to execute the command. - * This is only called if there are no meta-characters in the command. - * This procedure never returns. - */ -static void -childProcess(const char * cmd) -{ - const char ** argv; - int argc; - - /* - * Close any extra file descriptors we have opened. - */ - while (--sourceCount >= 0) - { - if (sourcefiles[sourceCount] != stdin) - fclose(sourcefiles[sourceCount]); - } - - /* - * Break the command line up into individual arguments. - * If this fails, then run the shell to execute the command. - */ - if (!makeArgs(cmd, &argc, &argv)) - { - int status = trySystem(cmd); - - if (status == -1) - exit(99); - - exit(status); - } - - /* - * Try to execute the program directly. - */ - execvp(argv[0], (char **) argv); - - /* - * The exec failed, so try to run the command using the shell - * in case it is a shell script. - */ - if (errno == ENOEXEC) - { - int status = trySystem(cmd); - - if (status == -1) - exit(99); - - exit(status); - } - - /* - * There was something else wrong, complain and exit. - */ - perror(argv[0]); - exit(1); -} - - -int -do_help(int argc, const char ** argv) -{ - const CommandEntry * entry; - const char * str; - - str = NULL; - - if (argc == 2) - str = argv[1]; - - /* - * Check for an exact match, in which case describe the program. - */ - if (str) - { - for (entry = commandEntryTable; entry->name; entry++) - { - if (strcmp(str, entry->name) == 0) - { - printf("%s\n", entry->description); - - printf("usage: %s %s\n", entry->name, - entry->usage); - - return 0; - } - } - } - - /* - * Print short information about commands which contain the - * specified word. - */ - for (entry = commandEntryTable; entry->name; entry++) - { - if ((str == NULL) || (strstr(entry->name, str) != NULL) || - (strstr(entry->usage, str) != NULL)) - { - printf("%-10s %s\n", entry->name, entry->usage); - } - } - - return 0; -} - - -int -do_alias(int argc, const char ** argv) -{ - const char * name; - char * value; - Alias * alias; - int count; - char buf[CMD_LEN]; - - if (argc < 2) - { - count = aliasCount; - - for (alias = aliasTable; count-- > 0; alias++) - printf("%s\t%s\n", alias->name, alias->value); - - return 0; - } - - name = argv[1]; - - if (argc == 2) - { - alias = findAlias(name); - - if (alias) - printf("%s\n", alias->value); - else - { - fprintf(stderr, "Alias \"%s\" is not defined\n", name); - - return 1; - } - - return 0; - } - - if (strcmp(name, "alias") == 0) - { - fprintf(stderr, "Cannot alias \"alias\"\n"); - - return 1; - } - - if (!makeString(argc - 2, argv + 2, buf, CMD_LEN)) - return 1; - - value = malloc(strlen(buf) + 1); - - if (value == NULL) - { - fprintf(stderr, "No memory for alias value\n"); - - return 1; - } - - strcpy(value, buf); - - alias = findAlias(name); - - if (alias) - { - free(alias->value); - alias->value = value; - - return 0; - } - - if ((aliasCount % ALIAS_ALLOC) == 0) - { - count = aliasCount + ALIAS_ALLOC; - - if (aliasTable) - { - alias = (Alias *) realloc(aliasTable, - sizeof(Alias) * count); - } - else - alias = (Alias *) malloc(sizeof(Alias) * count); - - if (alias == NULL) - { - free(value); - fprintf(stderr, "No memory for alias table\n"); - - return 1; - } - - aliasTable = alias; - } - - alias = &aliasTable[aliasCount]; - - alias->name = malloc(strlen(name) + 1); - - if (alias->name == NULL) - { - free(value); - fprintf(stderr, "No memory for alias name\n"); - - return 1; - } - - strcpy(alias->name, name); - alias->value = value; - aliasCount++; - - return 0; -} - - -/* - * Build aliases for all of the built-in commands which start with a dash, - * using the names without the dash. - */ -int -do_aliasall(int argc, const char **argv) -{ - const CommandEntry * entry; - const char * name; - const char * newArgv[4]; - - for (entry = commandEntryTable; entry->name; entry++) - { - name = entry->name; - - if (*name != '-') - continue; - - newArgv[0] = "alias"; - newArgv[1] = name + 1; - newArgv[2] = name; - newArgv[3] = NULL; - - do_alias(3, newArgv); - } - - return 0; -} - - -/* - * Look up an alias name, and return a pointer to it. - * Returns NULL if the name does not exist. - */ -static Alias * -findAlias(const char * name) -{ - Alias * alias; - int count; - - count = aliasCount; - - for (alias = aliasTable; count-- > 0; alias++) - { - if (strcmp(name, alias->name) == 0) - return alias; - } - - return NULL; -} - - -int -do_source(int argc, const char ** argv) -{ - return readFile(argv[1]); -} - - -int -do_exec(int argc, const char ** argv) -{ - const char * name; - - name = argv[1]; - - while (--sourceCount >= 0) - { - if (sourcefiles[sourceCount] != stdin) - fclose(sourcefiles[sourceCount]); - } - - argv[argc] = NULL; - - execvp(name, (char **) argv + 1); - perror(name); - - return 1; -} - - -int -do_prompt(int argc, const char ** argv) -{ - char * cp; - char buf[CMD_LEN]; - - if (!makeString(argc - 1, argv + 1, buf, CMD_LEN)) - return 1; - - cp = malloc(strlen(buf) + 2); - - if (cp == NULL) - { - fprintf(stderr, "No memory for prompt\n"); - - return 1; - } - - strcpy(cp, buf); - strcat(cp, " "); - - if (prompt) - free(prompt); - - prompt = cp; - - return 0; -} - - -int -do_unalias(int argc, const char ** argv) -{ - Alias * alias; - - while (--argc > 0) - { - alias = findAlias(*++argv); - - if (alias == NULL) - continue; - - free(alias->name); - free(alias->value); - aliasCount--; - alias->name = aliasTable[aliasCount].name; - alias->value = aliasTable[aliasCount].value; - } - - return 0; -} - - -/* - * Display the prompt string. - */ -static void -showPrompt(void) -{ - const char * cp; - - cp = "> "; - - if (prompt) - cp = prompt; - - tryWrite(STDOUT, cp, strlen(cp)); -} - - -static void -catchInt(int val) -{ - signal(SIGINT, catchInt); - - intFlag = TRUE; - - if (intCrlf) - tryWrite(STDOUT, "\n", 1); -} - - -static void -catchQuit(int val) -{ - signal(SIGQUIT, catchQuit); - - intFlag = TRUE; - - if (intCrlf) - tryWrite(STDOUT, "\n", 1); -} - - -/* - * Print the usage information and quit. - */ -static void -usage(void) -{ - fprintf(stderr, "Stand-alone shell (version %s)\n", version); - fprintf(stderr, "\n"); - fprintf(stderr, "Usage: sash [-a] [-q] [-f fileName] [-c command] [-p prompt] [-i]\n"); - - exit(1); -} - - -/* - * Expand one environment variable: Syntax $(VAR) - */ -static void -expandVariable(char * cmd) -{ - char tmp[CMD_LEN]; - char *cp; - char *ep; - - strcpy(tmp, cmd); - cp = strstr(tmp, "$("); - if (cp) { - *cp++ = '\0'; - strcpy(cmd, tmp); - ep = ++cp; - while (*ep && (*ep != ')')) ep++; - if (*ep == ')') *ep++ = '\0'; - cp = getenv(cp); - if (cp) strcat(cmd, cp); - strcat(cmd, ep); - } - return; -} - -/* END CODE */ |