📄 shell.c
字号:
/***********************************************************************/
/* */
/* Module: shell.c */
/* Release: 2004.5 */
/* Version: 2004.3 */
/* Purpose: Implement the shell application */
/* */
/***********************************************************************/
#include <errno.h>
#include <limits.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <stdio.h>
#include "shellp.h"
#include "../../posix.h"
#include "../../ffs_stdio.h"
/***********************************************************************/
/* Symbol Definitions */
/***********************************************************************/
#define DISPLAY_WIDTH 80
#define MAX_ARG 51
#define MAX_LINE 301
#define PAGE_SIZE 512
#define TRUE 1
#define FALSE 0
/***********************************************************************/
/* Type Definitions */
/***********************************************************************/
typedef struct
{
char *cmd;
int (*func)(char *cmd_line);
char *help;
} ShellEntry;
/***********************************************************************/
/* Function Prototypes */
/***********************************************************************/
/*
** Shell Functions
*/
static int sh_append(char *cmd_line);
static int sh_cd(char *cmd_line);
static int sh_cp(char *cmd_line);
static int sh_create(char *cmd_line);
static int sh_dir(char *cmd_line);
static int sh_display(char *cmd_line);
static int sh_format(char *cmd_line);
static int sh_fstat(char *cmd_line);
static int sh_help(char *cmd_line);
static int sh_link(char *cmd_line);
static int sh_ls(char *cmd_line);
static int sh_mkdir(char *cmd_line);
static int sh_more(char *cmd_line);
static int sh_mount(char *cmd_line);
static int sh_mount_all(char *cmd_line);
static int sh_mv(char *cmd_line);
static int sh_pwd(char *cmd_line);
static int sh_rm(char *cmd_line);
static int sh_rmdir(char *cmd_line);
static int sh_stat(char *cmd_line);
static int sh_sortdir(char *cmd_line);
static int sh_time(char *cmd_line);
static int sh_trunc(char *cmd_line);
static int sh_unformat(char *cmd_line);
static int sh_unmount(char *cmd_line);
static int sh_vstat(char *cmd_line);
/*
** Auxiliary Functions
*/
static int get_arg(char *cmd_line, char *arg);
/***********************************************************************/
/* Global Variable Definitions */
/***********************************************************************/
static ShellEntry ShellFuncs[] =
{
/* command name function */
/* help string */
"append", sh_append,
"append [file] [text] - Appends text to a file\n",
"cd", sh_cd,
"cd [directory] - Change current working directory\n",
"cp", sh_cp,
"cp [file1] [file2] - Copy contents of file1 into file2\n",
"create", sh_create,
"create [file] [text] - Creates a file containing text\n",
"dir", sh_dir,
"dir [directory] - Lists contents of directory\n",
"display", sh_display,
"display [file] - Displays contents of file (no splits)\n",
"format", sh_format,
"format [device] - Formats device (volume)\n",
"fstat", sh_fstat,
"fstat [file] - Gets stats about an open file\n",
"help", sh_help,
"help - Displays a list of all availabel shell commnads\n",
"link", sh_link,
"link [file1] [file2] - Links file2 to file1\n",
"ls", sh_ls,
"ls [directory] - Lists contents of directory\n",
"mkdir", sh_mkdir,
"mkdir [directory] - Creates new directory\n",
"more", sh_more,
"more [file] - Displays contents of file\n",
"mount", sh_mount,
"mount [device] - Mounts device (volume)\n",
"mount_all", sh_mount_all,
"mount_all - Mounts all existing unmounted devices\n",
"mv", sh_mv,
"mv [loc1] [loc2] - Moves file/directory from loc1 to loc2\n",
"pwd", sh_pwd,
"pwd - Displays the current working directory\n",
"rm", sh_rm,
"rm [file] - Deletes file\n",
"rmdir", sh_rmdir,
"rmdir [directory] - Deletes directory, must be empty\n",
"stat", sh_stat,
"stat [file] - Displays statistics of file\n",
"sortdir", sh_sortdir,
"sortdir [directory] [sort] - Sort a directory\n"
"\t[directory] = directory_path\n"
"\t[sort] = 1 by name, 2 by size, 3 by fileno, 4 by mod time\n",
"time", sh_time,
"time [cmd] - Time any valid shell command\n",
"trunc", sh_trunc,
"trunc [file] [size] - Truncate file to size bytes\n",
"unformat", sh_unformat,
"unformat [device] - Unformats device\n",
"unmount", sh_unmount,
"unmount [device] - Unmounts device\n",
"vstat", sh_vstat,
"vstat [device] - Get statistics about a device (volume)\n",
NULL, NULL,
NULL, /* ends w/ name, func, and help == NULL */
};
/*
** Sort option for sortdir()
*/
static int SortDir = 1;
/***********************************************************************/
/* Local Function Definitions */
/***********************************************************************/
/***********************************************************************/
/* process_cmd: Execute shell command */
/* */
/* Returns: -1 upon exit request or I/O error. Otherwise, 0 */
/* */
/***********************************************************************/
static int process_cmd(char *cmd_line)
{
char cmd[MAX_ARG];
int i, curr;
/*-------------------------------------------------------------------*/
/* Get the command from the command line. */
/*-------------------------------------------------------------------*/
curr = get_arg(cmd_line, cmd);
/*-------------------------------------------------------------------*/
/* If a command was entered, execute it. */
/*-------------------------------------------------------------------*/
if (curr)
{
/*-----------------------------------------------------------------*/
/* If it's the 'quit', 'logout', or 'exit' command, stop. */
/*-----------------------------------------------------------------*/
if (!strcmp(cmd, "quit") || !strcmp(cmd, "logout") ||
!strcmp(cmd, "exit"))
return -1;
/*-----------------------------------------------------------------*/
/* Go through the list of commands and try to find it. */
/*-----------------------------------------------------------------*/
for (i = 0; ShellFuncs[i].func; ++i)
{
/*---------------------------------------------------------------*/
/* If the function is found stop. */
/*---------------------------------------------------------------*/
if (!strcmp(ShellFuncs[i].cmd, cmd))
break;
}
/*-----------------------------------------------------------------*/
/* If the function was found execute it, else output not found. */
/*-----------------------------------------------------------------*/
if (ShellFuncs[i].func)
{
/*---------------------------------------------------------------*/
/* Clear errno before calling function to test for errors. */
/*---------------------------------------------------------------*/
errno = 0;
/*---------------------------------------------------------------*/
/* If the function fails, but not because of an I/O error */
/* output error message. */
/*---------------------------------------------------------------*/
if (ShellFuncs[i].func(&cmd_line[curr]))
{
if (errno == EIO)
return -1;
else if (errno)
printf("shell: %s\n", strerror(errno));
else
printf("syntax error\n");
}
}
else
printf("shell: %s command not found\n", cmd);
}
/*-------------------------------------------------------------------*/
/* Return 0 to try next command. */
/*-------------------------------------------------------------------*/
return 0;
}
/***********************************************************************/
/* to_int: Convert a decimal string into its value */
/* */
/* Input: str = string to be converted */
/* */
/* Returns: value of string or -1 on error */
/* */
/***********************************************************************/
static int to_int(char *str)
{
int r_value = 0;
for (; *str != '\0'; ++str)
{
/*-----------------------------------------------------------------*/
/* If the current char is not a digit return -1. */
/*-----------------------------------------------------------------*/
if (!isdigit(*str))
return -1;
else
r_value = 10 * r_value + (*str - '0');
}
return r_value;
}
/***********************************************************************/
/* get_line: Get a whole command line from the user */
/* */
/* Input: cmd_line = place to store the line */
/* */
/* Returns: 0 on success, -1 on error */
/* */
/***********************************************************************/
static int get_line(char *cmd_line)
{
int i, ch;
/*-------------------------------------------------------------------*/
/* Interactive loop to edit command string. */
/*-------------------------------------------------------------------*/
for (i = 0;;)
{
/*-----------------------------------------------------------------*/
/* Get next key and return -1 if I/O error occurs. */
/*-----------------------------------------------------------------*/
ch = getchar();
if (ch == -1)
return -1;
/*-----------------------------------------------------------------*/
/* Process backspace key. */
/*-----------------------------------------------------------------*/
if (ch == '\b')
{
if (i)
{
--i;
printf("\b \b");
}
}
/*-----------------------------------------------------------------*/
/* Else if it's new line, output it, NULL terminate, and return. */
/*-----------------------------------------------------------------*/
else if (ch == '\n')
{
putchar('\n');
cmd_line[i] = '\0';
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -