home *** CD-ROM | disk | FTP | other *** search
- /*
- * INTERNAL.C - command.com internal commands.
- *
- * Comments:
- *
- * 17/08/94 (Tim Norman) ---------------------------------------------------
- * started.
- *
- * 08/08/95 (Matt Rains) ---------------------------------------------------
- * i have cleaned up the source code. changes now bring this source into
- * guidelines for recommended programming practice.
- *
- * cd()
- * started.
- *
- * dir()
- * i have added support for file attributes to the DIR() function. the
- * routine adds "d" (directory) and "r" (read only) output. files with the
- * system attribute have the filename converted to lowercase. files with
- * the hidden attribute are not displayed.
- *
- * i have added support for directorys. now if the directory attribute is
- * detected the file size if replaced with the string "<dir>".
- *
- * ver()
- * started.
- *
- * md()
- * started.
- *
- * rd()
- * started.
- *
- * del()
- * started.
- *
- * does not support wildcard selection.
- *
- * todo: add delete directory support.
- * add recursive directory delete support.
- *
- * ren()
- * started.
- *
- * does not support wildcard selection.
- *
- * todo: add rename directory support.
- *
- * a general structure has been used for the cd, rd and md commands. this
- * will be better in the long run. it is too hard to maintain such diverse
- * functions when you are involved in a group project like this.
- *
- * 12/14/95 (Tim Norman) -----------------------------------------------------
- * fixed DIR so that it will stick \*.* if a directory is specified and
- * that it will stick on .* if a file with no extension is specified or
- * *.* if it ends in a \
- *
- * 1/6/96 (Tim Norman) -----------------------------------------------------
- * added an isatty call to DIR so it won't prompt for keypresses unless
- * stdin and stdout are the console.
- *
- * changed parameters to be mutually consistent to make calling the
- * functions easier
- *
- * rem()
- * started.
- *
- * doskey()
- * started.
- *
- */
-
- #include <stdlib.h>
- #include <dos.h>
- #include <stdio.h>
- #include <ctype.h>
- #include <string.h>
- #include <dir.h>
- #include <conio.h>
- #include <io.h>
-
- #define SHELLINFO "FreeDOS Command Line Interface"
- #define SHELLVER "version 0.50"
- #define BADCMDLINE "bad or incorrect commandline"
- #define USAGE "usage"
- #define CD "change to directory cd [d:][path]"
- #define MD "make directory md [d:]path"
- #define RD "remove directory rd [d:]path"
- #define DIR "display directory listing dir [d:][path][filespec]"
- #define VER "display shell version info ver"
- #define DEL "delete file del [d:][path]filespec"
- #define REN "rename file ren [d:][path]filespec1 [d:][path]filespec2"
- #define SETPROMPT "SET PROMPT="
-
- /*
- * set environment variables
- *
- *
- */
- #pragma argsused
- void set(int argc, char *argv[], char *commandline)
- {
- int r;
- unsigned char count;
- static char env_temp[128]; /* must be static to use putenv() */
- char *command;
-
- if (argc == 1)
- {
- void show_environment (void);
-
- show_environment ();
- return;
- }
-
- command = commandline;
-
- while(isspace(*command)) /* skip over "set" and whitespace */
- {
- command++;
- }
-
- while(!isspace(*command))
- {
- command++;
- }
-
- while(isspace(*command))
- {
- command++;
- }
-
- strcpy(env_temp, command);
- count = strlen (env_temp) - 1; /* remove trailing spaces */
-
- while(env_temp[count] == ' ')
- {
- env_temp[count--] = 0;
- }
-
- if(strstr(env_temp, "=") == NULL)
- {
- puts("Syntax error");
- return;
- }
-
- /* capitalize name of env. var. */
- for(count = 0; env_temp[count] != '=' && env_temp[count] != 0; count++)
- {
- env_temp[count] = toupper(env_temp[count]);
- }
-
- r = putenv(env_temp);
-
- if(r == -1)
- {
- puts("Environment error");
- }
-
- return;
- }
-
- /*
- * simple change to directory internal command.
- *
- *
- */
- #pragma argsused
- void cd(int args, char *p[128], char *commandline)
- {
- int errnum;
- char dir[128];
-
- if (args == 1)
- {
- strcpy (dir, &p[0][2]);
- }
- else if (args == 2)
- {
- strcpy (dir, p[1]);
- }
- else
- {
- printf("%s\n", BADCMDLINE);
- printf("%s: %s\n", USAGE, CD);
- return;
- }
-
- /* if no parameters given, print out the current directory */
- if (!dir[0])
- {
- char direc[128];
- char temp[128];
-
- direc[0] = getdisk() + 'A';
- direc[1] = ':';
- getcurdir(0, temp);
-
- if(temp[0] == '\\')
- {
- strcpy(&direc[2], temp);
- }
- else
- {
- direc[2] = '\\';
- strcpy(&direc[3], temp);
- }
-
- printf("%s\n", direc);
-
- return;
- }
-
- /* take off trailing \ if any... */
- if (strlen (dir) > 1 && dir[strlen (dir) - 1] == '\\')
- dir[strlen (dir) - 1] = 0;
-
- if((errnum = chdir(dir)) != 0)
- {
- printf("cd() : error %d\n\n", errnum);
- }
-
- return;
- }
-
- /*
- * simple make directory internal command.
- *
- *
- */
- #pragma argsused
- void md(int args, char *p[128], char *commandline)
- {
- int errnum;
- char dir[128];
-
- if (args == 1)
- {
- strcpy (dir, &p[0][2]);
- }
- else if (args == 2)
- {
- strcpy (dir, p[1]);
- }
- else
- {
- printf("%s\n", BADCMDLINE);
- printf("%s: %s\n", USAGE, MD);
- return;
- }
-
- if((errnum = mkdir(dir)) != 0)
- {
- printf("md() : error %d\n\n", errnum);
- }
- }
-
- /*
- * simple remove directory internal command.
- *
- *
- */
- #pragma argsused
- void rd(int args, char *p[128], char *commandline)
- {
- int errnum;
- char dir[128];
-
- if (args == 1)
- {
- strcpy (dir, &p[0][2]);
- }
- else if (args == 2)
- {
- strcpy (dir, p[1]);
- }
- else
- {
- printf("%s\n", BADCMDLINE);
- printf("%s: %s\n", USAGE, RD);
- return;
- }
-
- if((errnum = rmdir(dir)) != 0)
- {
- printf("rd() : error %d\n\n", errnum);
- }
- }
-
- /*
- * simple display directory internal command.
- *
- *
- */
- #pragma argsused
- void dir(int args, char *p[128], char *commandline)
- {
- struct ffblk file;
- union REGS regs;
-
- long bytes = 0;
- int count;
- int dirs = 0;
- int done;
- int files = 0;
- int i;
- int len;
- int wildcards;
- char fattrib[4];
- char fname[13];
- char searchname[128], lastchar;
-
- if(args > 2)
- {
- printf("%s\n", BADCMDLINE);
- printf("%s: %s\n", USAGE, DIR);
-
- return;
- }
-
- /* set up search name and see if we have wildcards */
- if (args == 1)
- {
- /* find all files if nothing specified */
- strcpy (searchname, "*.*");
- wildcards = 1;
- }
- else
- {
- /* get the filename specified and find the last character */
- strcpy (searchname, p[1]);
-
- len = strlen (searchname);
- lastchar = searchname[len - 1];
-
- wildcards = 0;
-
- /* search for wildcards */
- for (count = 0; count < len; count++)
- if (searchname[count] == '*' || searchname[count] == '?')
- {
- wildcards = 1;
- break;
- }
- }
-
- /* check if filename ends in : or \ */
- if (!wildcards && (lastchar == ':' || lastchar == '\\'))
- strcpy (&searchname[len], "*.*");
- else
- {
- /* see if this file is a directory */
- if (!wildcards)
- done = findfirst (searchname, &file, 0xff);
- else
- done = 1;
-
- /* if we found a directory */
- if (!done && (file.ff_attrib & 0x10))
- strcpy (&searchname[len], "\\*.*");
- else
- {
- /* search for a . before a \ */
- for (count = len - 1; count >= 0; count--)
- if (searchname[count] == '.' || searchname[count] == '\\')
- break;
-
- /* if the filename has no extension, add a .* */
- if (count < 0 || (count >= 0 && searchname[count] == '\\'))
- strcpy (&searchname[len], ".*");
- }
- }
-
- /* scan through all the files */
- done = findfirst(searchname, &file, 0xff);
-
- if (done)
- {
- printf ("File not found.\n");
- return;
- }
-
- do
- {
- /* check file attributes */
- fattrib[0] = file.ff_attrib & 0x10 ? 'd' : '-'; /* 'd' = directory */
- fattrib[1] = file.ff_attrib & 0x01 ? 'r' : '-'; /* 'r' = read only */
- fattrib[2] = 0; /* terminate string */
- fattrib[3] = file.ff_attrib & 0x02 ? 'h' : '-'; /* 'h' = hidden */
- fattrib[4] = file.ff_attrib & 0x04 ? 's' : '-'; /* 's' = system file */
-
- /* convert filename to lowercase if it has the system attribute */
- if(fattrib[4] == 's')
- {
- for(i = 0;i <= strlen(file.ff_name); i++)
- {
- fname[i] = tolower(file.ff_name[i]);
- }
- }
- else
- {
- strcpy(fname, file.ff_name);
- }
-
- /* honor hidden attribute by ignoring files with this attribute */
- /* why not just set the mask right in findfirst/findnext? */
- if(fattrib[3] != 'h')
- {
- if(fattrib[0] == 'd')
- {
- /* entry found is a directory */
- dirs++;
- printf("%s %-12s <dir>\n", fattrib, fname);
- }
- else
- {
- /* entry found is a file */
- files++;
- bytes += file.ff_fsize;
- printf("%s %-12s %15ld\n", fattrib, fname, file.ff_fsize);
- }
-
- /* only prompt for keypress if stdin & stdout are console */
- if(isatty (0) && isatty (1) && (files + dirs) % 20 == 0)
- {
- puts("[press any key to continue]");
- getch();
- }
- }
-
- done = findnext(&file);
- }
- while(!done);
-
- printf(" %d file%s\n", files, files == 1 ? "" : "s");
- printf(" %d dir%s\n", dirs, dirs == 1 ? "" : "s");
-
- /* get free bytes */
- regs.h.ah = 0x36;
- regs.h.dl = 0;
- int86(0x21, ®s, ®s);
-
- printf(" %15ld byte%s used\n", bytes, bytes == 1 ? "" : "s");
- printf(" %15ld bytes free\n", (long) regs.x.ax * regs.x.cx * regs.x.bx);
- }
-
- /*
- * display shell version info internal command.
- *
- *
- */
- #pragma argsused
- void ver(int args, char *p[128], char *commandline)
- {
- if(args != 1)
- {
- printf("%s\n", BADCMDLINE);
- printf("%s: %s\n", USAGE, VER);
- }
- else
- {
- printf("License:\n");
- printf(" This program is free software; you can redistribute it and/or modify\n");
- printf(" it under the terms of the GNU General Public License as published by\n");
- printf(" the Free Software Foundation; either version 2 of the License, or\n");
- printf(" (at your option) any later version.\n\n");
- printf(" This program is distributed in the hope that it will be useful,\n");
- printf(" but WITHOUT ANY WARRANTY; without even the implied warranty of\n");
- printf(" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n");
- printf(" GNU General Public License for more details.\n\n");
- printf(" You should have received a copy of the GNU General Public License\n");
- printf(" along with this program; if not, write to the Free Software\n");
- printf(" Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\n");
-
- printf("%s %s\n\n", SHELLINFO, SHELLVER);
-
- printf("developed by: Tim Norman\n");
- printf(" Matt Rains\n");
- printf(" Evan Jeffrey\n");
- printf(" Steffen Kaiser\n");
- }
-
- return;
- }
-
- /*
- *
- * simple file delete internal command.
- *
- */
- #pragma argsused
- void del(int args, char *p[128], char *commandline)
- {
- int errnum;
-
- if(args != 2)
- {
- printf("%s\n", BADCMDLINE);
- printf("%s: %s\n", USAGE, DEL);
- }
- else
- {
- if((errnum = remove(p[1])) != 0)
- {
- printf("del() : error %d\n\n", errnum);
- }
- }
-
- return;
- }
-
- /*
- *
- * simple file rename internal command.
- *
- */
- #pragma argsused
- void ren(int args, char *p[128], char *commandline)
- {
- int errnum;
-
- if(args == 1 || args >= 4)
- {
- printf("%s\n", BADCMDLINE);
- printf("%s: %s\n", USAGE, REN);
- }
- else
- {
- if((errnum = rename(p[1], p[2])) != 0)
- {
- printf("ren() : error %d\n\n", errnum);
- }
- }
-
- return;
- }
-
- extern char exitflag;
-
- /*
- *
- * set the exitflag to true
- *
- */
- #pragma argsused
- void internal_exit (int args, char *p[128], char *commandline)
- {
- exitflag = 1;
- }
-
- /*
- *
- * does nothing
- *
- */
- #pragma argsused
- void rem (int args, char *p[128], char *commandline)
- {
- }
-
- /*
- *
- * prints DOSKEY message... will soon emulate DOSKEY macros
- *
- */
- #pragma argsused
- void doskey (int args, char *p[128], char *commandline)
- {
- printf ("DOSKEY features are already enabled in the shell.\n");
- }
-
- /*
- *
- * changes the PROMPT env. var.
- *
- */
- #pragma argsused
- void prompt (int args, char *p[128], char *commandline)
- {
- char *from, *to, tempcommand[256];
-
- from = commandline;
- to = tempcommand + 11;
- strcpy(tempcommand, SETPROMPT);
-
- while(isspace(*from))
- {
- from++;
- }
-
- from += 6;
-
- while(isspace(*from))
- {
- from++;
- }
-
- if(*from == '=')
- {
- from++;
-
- while(isspace(*from))
- {
- from++;
- }
- }
-
- strcpy(to, from);
- set(2, p, tempcommand); /* force 2 so that SET won't dump environment */
- }
-