| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  | /* fileman.c - file manager example for readline library. */ | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  | /* Copyright (C) 1987-2009 Free Software Foundation, Inc.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    This file is part of the GNU Readline Library (Readline), a library for | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  |    reading lines of text with interactive input and history editing. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  |    Readline is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  |    it under the terms of the GNU General Public License as published by | 
					
						
							|  |  |  |    the Free Software Foundation, either version 3 of the License, or | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  |    (at your option) any later version. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  |    Readline is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |    but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  |    GNU General Public License for more details. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  |    You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |    along with Readline.  If not, see <http://www.gnu.org/licenses/>.
 | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | /* fileman.c -- A tiny application which demonstrates how to use the
 | 
					
						
							|  |  |  |    GNU Readline library.  This application interactively allows users | 
					
						
							|  |  |  |    to manipulate files and their modes. */ | 
					
						
							| 
									
										
										
										
											1997-06-05 14:59:13 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #ifdef HAVE_CONFIG_H
 | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | #  include <config.h>
 | 
					
						
							| 
									
										
										
										
											1997-06-05 14:59:13 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <sys/types.h>
 | 
					
						
							| 
									
										
										
										
											1997-06-05 14:59:13 +00:00
										 |  |  | #ifdef HAVE_SYS_FILE_H
 | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | #  include <sys/file.h>
 | 
					
						
							| 
									
										
										
										
											1997-06-05 14:59:13 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | #include <sys/stat.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | #ifdef HAVE_UNISTD_H
 | 
					
						
							|  |  |  | #  include <unistd.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <fcntl.h>
 | 
					
						
							| 
									
										
										
										
											1997-06-05 14:59:13 +00:00
										 |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | #include <errno.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined (HAVE_STRING_H)
 | 
					
						
							|  |  |  | #  include <string.h>
 | 
					
						
							|  |  |  | #else /* !HAVE_STRING_H */
 | 
					
						
							|  |  |  | #  include <strings.h>
 | 
					
						
							|  |  |  | #endif /* !HAVE_STRING_H */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | #ifdef HAVE_STDLIB_H
 | 
					
						
							|  |  |  | #  include <stdlib.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  | #include <time.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-06-05 14:59:13 +00:00
										 |  |  | #ifdef READLINE_LIBRARY
 | 
					
						
							|  |  |  | #  include "readline.h"
 | 
					
						
							|  |  |  | #  include "history.h"
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | #  include <readline/readline.h>
 | 
					
						
							|  |  |  | #  include <readline/history.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  | extern char *xmalloc PARAMS((size_t)); | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* The names of functions that actually do the manipulation. */ | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  | int com_list PARAMS((char *)); | 
					
						
							|  |  |  | int com_view PARAMS((char *)); | 
					
						
							|  |  |  | int com_rename PARAMS((char *)); | 
					
						
							|  |  |  | int com_stat PARAMS((char *)); | 
					
						
							|  |  |  | int com_pwd PARAMS((char *)); | 
					
						
							|  |  |  | int com_delete PARAMS((char *)); | 
					
						
							|  |  |  | int com_help PARAMS((char *)); | 
					
						
							|  |  |  | int com_cd PARAMS((char *)); | 
					
						
							|  |  |  | int com_quit PARAMS((char *)); | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* A structure which contains information on the commands this program
 | 
					
						
							|  |  |  |    can understand. */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | typedef struct { | 
					
						
							|  |  |  |   char *name;			/* User printable name of the function. */ | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  |   rl_icpfunc_t *func;		/* Function to call to do the job. */ | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  |   char *doc;			/* Documentation for this function.  */ | 
					
						
							|  |  |  | } COMMAND; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | COMMAND commands[] = { | 
					
						
							|  |  |  |   { "cd", com_cd, "Change to directory DIR" }, | 
					
						
							|  |  |  |   { "delete", com_delete, "Delete FILE" }, | 
					
						
							|  |  |  |   { "help", com_help, "Display this text" }, | 
					
						
							|  |  |  |   { "?", com_help, "Synonym for `help'" }, | 
					
						
							|  |  |  |   { "list", com_list, "List files in DIR" }, | 
					
						
							|  |  |  |   { "ls", com_list, "Synonym for `list'" }, | 
					
						
							|  |  |  |   { "pwd", com_pwd, "Print the current working directory" }, | 
					
						
							|  |  |  |   { "quit", com_quit, "Quit using Fileman" }, | 
					
						
							|  |  |  |   { "rename", com_rename, "Rename FILE to NEWNAME" }, | 
					
						
							|  |  |  |   { "stat", com_stat, "Print out statistics on FILE" }, | 
					
						
							|  |  |  |   { "view", com_view, "View the contents of FILE" }, | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  |   { (char *)NULL, (rl_icpfunc_t *)NULL, (char *)NULL } | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Forward declarations. */ | 
					
						
							|  |  |  | char *stripwhite (); | 
					
						
							|  |  |  | COMMAND *find_command (); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* The name of this program, as taken from argv[0]. */ | 
					
						
							|  |  |  | char *progname; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* When non-zero, this global means the user is done using this program. */ | 
					
						
							|  |  |  | int done; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | char * | 
					
						
							|  |  |  | dupstr (s) | 
					
						
							| 
									
										
										
										
											1997-06-05 14:59:13 +00:00
										 |  |  |      char *s; | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   char *r; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   r = xmalloc (strlen (s) + 1); | 
					
						
							|  |  |  |   strcpy (r, s); | 
					
						
							|  |  |  |   return (r); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | main (argc, argv) | 
					
						
							|  |  |  |      int argc; | 
					
						
							|  |  |  |      char **argv; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   char *line, *s; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   progname = argv[0]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   initialize_readline ();	/* Bind our completer. */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* Loop reading and executing lines until the user quits. */ | 
					
						
							|  |  |  |   for ( ; done == 0; ) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       line = readline ("FileMan: "); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (!line) | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       /* Remove leading and trailing whitespace from the line.
 | 
					
						
							|  |  |  |          Then, if there is anything left, add it to the history list | 
					
						
							|  |  |  |          and execute it. */ | 
					
						
							|  |  |  |       s = stripwhite (line); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (*s) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           add_history (s); | 
					
						
							|  |  |  |           execute_line (s); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       free (line); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   exit (0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Execute a command line. */ | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | execute_line (line) | 
					
						
							|  |  |  |      char *line; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   register int i; | 
					
						
							|  |  |  |   COMMAND *command; | 
					
						
							|  |  |  |   char *word; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* Isolate the command word. */ | 
					
						
							|  |  |  |   i = 0; | 
					
						
							|  |  |  |   while (line[i] && whitespace (line[i])) | 
					
						
							|  |  |  |     i++; | 
					
						
							|  |  |  |   word = line + i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   while (line[i] && !whitespace (line[i])) | 
					
						
							|  |  |  |     i++; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (line[i]) | 
					
						
							|  |  |  |     line[i++] = '\0'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   command = find_command (word); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!command) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       fprintf (stderr, "%s: No such command for FileMan.\n", word); | 
					
						
							|  |  |  |       return (-1); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* Get argument to command, if any. */ | 
					
						
							|  |  |  |   while (whitespace (line[i])) | 
					
						
							|  |  |  |     i++; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   word = line + i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* Call the function. */ | 
					
						
							|  |  |  |   return ((*(command->func)) (word)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Look up NAME as the name of a command, and return a pointer to that
 | 
					
						
							|  |  |  |    command.  Return a NULL pointer if NAME isn't a command name. */ | 
					
						
							|  |  |  | COMMAND * | 
					
						
							|  |  |  | find_command (name) | 
					
						
							|  |  |  |      char *name; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   register int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (i = 0; commands[i].name; i++) | 
					
						
							|  |  |  |     if (strcmp (name, commands[i].name) == 0) | 
					
						
							|  |  |  |       return (&commands[i]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return ((COMMAND *)NULL); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Strip whitespace from the start and end of STRING.  Return a pointer
 | 
					
						
							|  |  |  |    into STRING. */ | 
					
						
							|  |  |  | char * | 
					
						
							|  |  |  | stripwhite (string) | 
					
						
							|  |  |  |      char *string; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   register char *s, *t; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (s = string; whitespace (*s); s++) | 
					
						
							|  |  |  |     ; | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |   if (*s == 0) | 
					
						
							|  |  |  |     return (s); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   t = s + strlen (s) - 1; | 
					
						
							|  |  |  |   while (t > s && whitespace (*t)) | 
					
						
							|  |  |  |     t--; | 
					
						
							|  |  |  |   *++t = '\0'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return s; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* **************************************************************** */ | 
					
						
							|  |  |  | /*                                                                  */ | 
					
						
							|  |  |  | /*                  Interface to Readline Completion                */ | 
					
						
							|  |  |  | /*                                                                  */ | 
					
						
							|  |  |  | /* **************************************************************** */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  | char *command_generator PARAMS((const char *, int)); | 
					
						
							|  |  |  | char **fileman_completion PARAMS((const char *, int, int)); | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* Tell the GNU Readline library how to complete.  We want to try to complete
 | 
					
						
							|  |  |  |    on command names if this is the first word in the line, or on filenames | 
					
						
							|  |  |  |    if not. */ | 
					
						
							|  |  |  | initialize_readline () | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   /* Allow conditional parsing of the ~/.inputrc file. */ | 
					
						
							|  |  |  |   rl_readline_name = "FileMan"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* Tell the completer that we want a crack first. */ | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  |   rl_attempted_completion_function = fileman_completion; | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1996-12-23 17:02:34 +00:00
										 |  |  | /* Attempt to complete on the contents of TEXT.  START and END bound the
 | 
					
						
							|  |  |  |    region of rl_line_buffer that contains the word to complete.  TEXT is | 
					
						
							|  |  |  |    the word to complete.  We can use the entire contents of rl_line_buffer | 
					
						
							|  |  |  |    in case we want to do some simple parsing.  Return the array of matches, | 
					
						
							|  |  |  |    or NULL if there aren't any. */ | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | char ** | 
					
						
							|  |  |  | fileman_completion (text, start, end) | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  |      const char *text; | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  |      int start, end; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   char **matches; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   matches = (char **)NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* If this word is at the start of the line, then it is a command
 | 
					
						
							|  |  |  |      to complete.  Otherwise it is the name of a file in the current | 
					
						
							|  |  |  |      directory. */ | 
					
						
							|  |  |  |   if (start == 0) | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  |     matches = rl_completion_matches (text, command_generator); | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   return (matches); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Generator function for command completion.  STATE lets us know whether
 | 
					
						
							|  |  |  |    to start from scratch; without any state (i.e. STATE == 0), then we | 
					
						
							|  |  |  |    start at the top of the list. */ | 
					
						
							|  |  |  | char * | 
					
						
							|  |  |  | command_generator (text, state) | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  |      const char *text; | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  |      int state; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   static int list_index, len; | 
					
						
							|  |  |  |   char *name; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* If this is a new word to complete, initialize now.  This includes
 | 
					
						
							|  |  |  |      saving the length of TEXT for efficiency, and initializing the index | 
					
						
							|  |  |  |      variable to 0. */ | 
					
						
							|  |  |  |   if (!state) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       list_index = 0; | 
					
						
							|  |  |  |       len = strlen (text); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* Return the next name which partially matches from the command list. */ | 
					
						
							|  |  |  |   while (name = commands[list_index].name) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       list_index++; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (strncmp (name, text, len) == 0) | 
					
						
							|  |  |  |         return (dupstr(name)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   /* If no names matched, then return NULL. */ | 
					
						
							|  |  |  |   return ((char *)NULL); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* **************************************************************** */ | 
					
						
							|  |  |  | /*                                                                  */ | 
					
						
							|  |  |  | /*                       FileMan Commands                           */ | 
					
						
							|  |  |  | /*                                                                  */ | 
					
						
							|  |  |  | /* **************************************************************** */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* String to pass to system ().  This is for the LIST, VIEW and RENAME
 | 
					
						
							|  |  |  |    commands. */ | 
					
						
							|  |  |  | static char syscom[1024]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* List the file(s) named in arg. */ | 
					
						
							|  |  |  | com_list (arg) | 
					
						
							|  |  |  |      char *arg; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   if (!arg) | 
					
						
							|  |  |  |     arg = ""; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   sprintf (syscom, "ls -FClg %s", arg); | 
					
						
							|  |  |  |   return (system (syscom)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | com_view (arg) | 
					
						
							|  |  |  |      char *arg; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   if (!valid_argument ("view", arg)) | 
					
						
							|  |  |  |     return 1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | #if defined (__MSDOS__)
 | 
					
						
							|  |  |  |   /* more.com doesn't grok slashes in pathnames */ | 
					
						
							|  |  |  |   sprintf (syscom, "less %s", arg); | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  |   sprintf (syscom, "more %s", arg); | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  |   return (system (syscom)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | com_rename (arg) | 
					
						
							|  |  |  |      char *arg; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   too_dangerous ("rename"); | 
					
						
							|  |  |  |   return (1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | com_stat (arg) | 
					
						
							|  |  |  |      char *arg; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   struct stat finfo; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!valid_argument ("stat", arg)) | 
					
						
							|  |  |  |     return (1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (stat (arg, &finfo) == -1) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       perror (arg); | 
					
						
							|  |  |  |       return (1); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   printf ("Statistics for `%s':\n", arg); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-06-05 14:59:13 +00:00
										 |  |  |   printf ("%s has %d link%s, and is %d byte%s in length.\n", | 
					
						
							|  |  |  | 	  arg, | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  |           finfo.st_nlink, | 
					
						
							|  |  |  |           (finfo.st_nlink == 1) ? "" : "s", | 
					
						
							|  |  |  |           finfo.st_size, | 
					
						
							|  |  |  |           (finfo.st_size == 1) ? "" : "s"); | 
					
						
							|  |  |  |   printf ("Inode Last Change at: %s", ctime (&finfo.st_ctime)); | 
					
						
							|  |  |  |   printf ("      Last access at: %s", ctime (&finfo.st_atime)); | 
					
						
							|  |  |  |   printf ("    Last modified at: %s", ctime (&finfo.st_mtime)); | 
					
						
							|  |  |  |   return (0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | com_delete (arg) | 
					
						
							|  |  |  |      char *arg; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   too_dangerous ("delete"); | 
					
						
							|  |  |  |   return (1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Print out help for ARG, or for all of the commands if ARG is
 | 
					
						
							|  |  |  |    not present. */ | 
					
						
							|  |  |  | com_help (arg) | 
					
						
							|  |  |  |      char *arg; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   register int i; | 
					
						
							|  |  |  |   int printed = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (i = 0; commands[i].name; i++) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       if (!*arg || (strcmp (arg, commands[i].name) == 0)) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           printf ("%s\t\t%s.\n", commands[i].name, commands[i].doc); | 
					
						
							|  |  |  |           printed++; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (!printed) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       printf ("No commands match `%s'.  Possibilties are:\n", arg); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       for (i = 0; commands[i].name; i++) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |           /* Print in six columns. */ | 
					
						
							|  |  |  |           if (printed == 6) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |               printed = 0; | 
					
						
							|  |  |  |               printf ("\n"); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           printf ("%s\t", commands[i].name); | 
					
						
							|  |  |  |           printed++; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       if (printed) | 
					
						
							|  |  |  |         printf ("\n"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   return (0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Change to the directory ARG. */ | 
					
						
							|  |  |  | com_cd (arg) | 
					
						
							|  |  |  |      char *arg; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   if (chdir (arg) == -1) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       perror (arg); | 
					
						
							|  |  |  |       return 1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   com_pwd (""); | 
					
						
							|  |  |  |   return (0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Print out the current working directory. */ | 
					
						
							|  |  |  | com_pwd (ignore) | 
					
						
							|  |  |  |      char *ignore; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   char dir[1024], *s; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  |   s = getcwd (dir, sizeof(dir) - 1); | 
					
						
							| 
									
										
										
										
											1996-08-26 18:22:31 +00:00
										 |  |  |   if (s == 0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       printf ("Error getting pwd: %s\n", dir); | 
					
						
							|  |  |  |       return 1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   printf ("Current directory is %s\n", dir); | 
					
						
							|  |  |  |   return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* The user wishes to quit using this program.  Just set DONE non-zero. */ | 
					
						
							|  |  |  | com_quit (arg) | 
					
						
							|  |  |  |      char *arg; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   done = 1; | 
					
						
							|  |  |  |   return (0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Function which tells you that you can't do this. */ | 
					
						
							|  |  |  | too_dangerous (caller) | 
					
						
							|  |  |  |      char *caller; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   fprintf (stderr, | 
					
						
							|  |  |  |            "%s: Too dangerous for me to distribute.  Write it yourself.\n", | 
					
						
							|  |  |  |            caller); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Return non-zero if ARG is a valid argument for CALLER, else print
 | 
					
						
							|  |  |  |    an error message and return zero. */ | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | valid_argument (caller, arg) | 
					
						
							|  |  |  |      char *caller, *arg; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   if (!arg || !*arg) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       fprintf (stderr, "%s: Argument required.\n", caller); | 
					
						
							|  |  |  |       return (0); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return (1); | 
					
						
							|  |  |  | } |