home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Dream 45
/
Amiga_Dream_45.iso
/
Atari
/
Magazine
/
Dossier
/
texutils
/
ms.arc
/
MS.C
< prev
next >
Wrap
C/C++ Source or Header
|
1988-10-17
|
12KB
|
677 lines
/*
* minimal shell for memory hogs on the atariST
* - MWC required (sort of)
*
* to configure:
* edit config.h
* to compile: (MWC)
* cc -O -o ms.tos -VSMALL -VPEEP -VGEM -DMWC ms.c -s -x
*
* note use of -VGEM to keep the size to a min. Stderr init. is
* done at the begining of main().
*
* Builtins:
* rm <list of files>
* cp <src> <dst> both <src> <dest> must be files
* WARNING: no checks for <src> <dst> being to same
* ls {<regular exp>} with no arg ls *.*
* cd {<dir>} with no arg cd $HOME
* md <dir>
* rd <dir>
* lo logout
* @ file read commands from file, then revert back to stdin.
* NO nested @'s allowed.
*
* Aliases, Path, Environment:
* see config.h
*
* ++jrb bammi@dsrgsun.ces.cwru.edu
*/
#include <osbind.h>
#ifdef __GNUC__
/* quick fix, this should be fixed in osbind.h and the library */
#undef Fforce
#define Fforce(Hstd,Hnew) trap_1_www(0x46,Hstd,Hnew)
int trap_1_www(args)
long args;
{
asm("movel a6@(16),d0"); /* copy w3 */
asm("movew d0,sp@-");
asm("movel a6@(12),d0"); /* copy w2 */
asm("movew d0,sp@-");
asm("movel a6@(8),d0"); /* copy w1 */
asm("movew d0,sp@-");
asm("trap #1"); /* do the trap */
asm("addl #6,sp"); /* pop junk off stack */
}
#endif
#ifdef NULL
#undef NULL
#endif
#define NULL 0L /* avoid stdio like the plague */
#define BSIZE 256 /* size of all purpose buffer */
#define PROMPT Bconws(cwd),Bconws("> ")
#define PRINTI(i) printi((short)i)
#define CRLF Bconws(_crlf)
#define REG
typedef struct
{
char st_sp1[21]; /* Junk */
char st_mode; /* File attributes */
short st_time; /* Mod Time */
short st_date; /* Mod date */
long st_size; /* File size */
char st_name[14]; /* File name */
} STAT;
#ifdef MWC
long _stksize = 128; /* don't trim this any further!! */
#else
#ifdef __GNUC__
long _stksize = 128; /* don't trim this any further!! */
#else /* alcyon */
long _STKSIZ = 128; /* don't trim this any further!! */
#endif
#endif
char *_crlf = "\r\n";
int rhandle = -10; /* some val < -5 */
char buf[BSIZE];
char cwd[64]; /* can tune this to your env */
STAT *stat;
#include "config.h" /* all the user configurable stuff in there */
/*
* Builtin commands
*
*/
#if __STDC__ || __GNUC__
void Bconws(char *);
void printi(int);
void setcwd();
char *nextarg(char **);
char *alltolower(char *);
int cd(char *);
int ls(char *);
void putls(STAT *, int);
int rm(char *);
int cp(char *);
int md(char *);
int rd(char *);
int lo();
int at(char *);
void read_at(char *);
int find_builtin(char *);
int find_alias(char *);
char *existf(char *, char *, char *);
char *find_ext(char *);
int do_command(char *, char *, char *);
int main();
extern char *strcpy(char *, char *);
extern char *strcat(char *, char *);
extern char *index(char *, char);
extern int strlen(char *);
#else
int ls(), rm(), cp(), cd(), md(), rd(), lo(), at();
extern char *strcpy();
extern char *strcat();
extern char *index();
extern int strlen();
#endif
typedef struct {
char *command; /* command string */
int (*routine)(); /* routine to invoke */
} BUILTIN;
BUILTIN builtin[] = {
{ "rm", rm },
{ "cp", cp },
{ "ls", ls },
{ "cd", cd },
{ "md", md },
{ "rd", rd },
{ "lo", lo },
{ "@", at },
{ (char *)NULL, (int (*)())NULL }
};
void Bconws(s)
REG char *s;
{
while(*s) Bconout(2, *s++);
}
void printi(val)
REG int val;
{
static short divisors[] = { 10000, 1000, 100, 10, 1 };
register short first = 0, div_idx = 0;
register short j;
/* Special Cases */
if (val == 0)
{
Bconout(2, '0');
}
else if (val == -32768)
{
Bconws("-32768");
}
else
{
/* Get digit for each power of 10 and print them, skip leading 0's */
if (val < 0)
{
Bconout(2, '-');
val = -val;
}
while( div_idx < 5 )
{
if(((j = val / divisors[div_idx]) != 0) || first != 0)
{
Bconout(2, j + '0');
first = 1;
}
val %= divisors[div_idx++];
}
}
}
void setcwd()
{
register short drive;
extern char *alltolower();
drive = Dgetdrv();
Dgetpath(&cwd[2],0);
cwd[0] = (char)(drive + 'a');
if(cwd[2] == '\0')
{
cwd[2] = '\\';
cwd[3] = '\0';
}
else (void) alltolower(&cwd[2]);
}
#define iswhite(c) ((c == ' ') || (c == '\t'))
/*
* return pointer to next arg, and advance q to char following next arg
*/
char *nextarg(q)
REG char **q;
{
register char *s = *q;
register char *p;
if(*s == '\0')
return (char *)NULL;
while(iswhite(*s)) s++;
p = s; s++;
while((!iswhite(*s)) && (*s != '\0')) s++;
if(*s != '\0')
{
*s = '\0';
*q = ++s;
}
else
*q = s;
return p;
}
#define isupper(c) ((c >= 'A') && (c <= 'Z'))
#define tolower(c) (c - 'A' + 'a')
char *alltolower(s)
REG char *s;
{
register char *p = s;
while(*p != '\0')
{
if(isupper(*p)) *p = tolower(*p);
p++;
}
return s;
}
int cd(s)
REG char *s;
{
register char *d, *path;
register int drive;
if(*s == '\0')
return cd(HOME);
if((d = index(s,':')) == (char *)NULL)
{
/* Drive was not specified, must mean the current drive */
path = s;
}
else
{
d--;
if(isupper(*d))
{
*d = tolower(*d);
}
drive = *d - 'a';
if(d[2] != '\\') /* just gave D: */
{
/* we will shove in the '\' */
d[1] = '\\';
path = &d[1];
}
else
path = &d[2];
/* Set the Drive */
if(Dsetdrv(drive) < 0)
{
Bconws("?drive: "); Bconout(2, *d); CRLF;
return 2;
}
}
/* Set the Path */
if(Dsetpath(path) != 0)
{
Bconws("?dir: "); Bconws(path); CRLF;
return 3;
}
setcwd();
return 0;
}
#define HASWILD(S) \
((index(S, '*') != (char *)NULL) || (index(S, '?') != (char *)NULL))
void putls(statbuf, count)
REG STAT *statbuf;
REG int count;
{
register int len = strlen(statbuf->st_name);
extern char *alltolower();
if((statbuf->st_mode) & 0x0010)
{
/* subtree */
Bconws(alltolower(statbuf->st_name));
Bconout(2, '/');
len++;
}
else
/* file */
Bconws(alltolower(statbuf->st_name));
if(!(count % 4))
CRLF;
else
{
len = 14 - len;
while(len--)
Bconout(2, ' ');
}
}
int ls(s)
REG char *s;
{
register short count;
if(*s == '\0')
return ls("*.*");
if(HASWILD(s))
(void) strcpy(buf, s);
else
{
if(s[(strlen(s) - 1)] != '\\')
{
(void) strcpy(buf, s);
(void) strcat(buf, "\\");
}
else
(void) strcpy(buf, s);
(void) strcat(buf, "*.*");
}
if(Fsfirst(buf, 0x0020 | 0x0010) != 0)
{
Bconws("?match: "); Bconws(buf); CRLF;
return 1;
}
count = 0;
if(!((strcmp(stat->st_name,".") == 0) ||
(strcmp(stat->st_name, "..") == 0)))
putls(stat, ++count);
while(Fsnext() == 0)
{
if(!((strcmp(stat->st_name,".") == 0) ||
(strcmp(stat->st_name, "..") == 0)))
putls(stat, ++count);
}
if((count % 4))
CRLF;
return 0;
}
int rm(s)
char *s;
{
register char *p;
register int status = 0;
extern char *nextarg();
while((p = nextarg(&s)) != (char *)NULL)
{
if(Fdelete(p) != 0)
{
Bconws("?file: "); Bconws(s); CRLF;
status = 1;
}
}
return status;
}
int cp(s)
char *s;
{
register char *p;
register int src, dst;
register long l, k;
extern char *nextarg();
if((p = nextarg(&s)) == (char *)NULL)
{
Bconws("?cp src dst"); CRLF;
return 1;
}
if((src = Fopen(p, 0)) < (-3))
{
Bconws("?src: "); Bconws(p); CRLF;
return src;
}
if((p = nextarg(&s)) == (char *)NULL)
{
Bconws("?cp src dst"); CRLF;
Fclose(src);
return 2;
}
if((dst = Fcreate(p, 0)) < (-3))
{
if((dst = Fopen(p, 1)) < (-3))
{
Bconws("?dst: "); Bconws(p); CRLF;
Fclose(src);
return dst;
}
}
while( (l = Fread(src, (long)BSIZE, buf)) > 0L)
{
if((k = Fwrite(dst, l, buf)) != l)
{
Bconws("?Write Fail\r\n");
Fclose(src);
Fclose(dst);
return (int)k;
}
}
Fclose(src);
Fclose(dst);
return 0;
}
int md(s)
char *s;
{
extern char *nextarg();
register char *p;
if((p = nextarg(&s)) == (char *)NULL)
{
Bconws("?md\r\n");
return 1;
}
return(Dcreate(p));
}
int rd(s)
char *s;
{
extern char *nextarg();
register char *p;
if((p = nextarg(&s)) == (char *)NULL)
{
Bconws("?rd\r\n");
return 1;
}
return(Ddelete(p));
}
int lo()
{
Pterm(0);
}
int at(s)
REG char *s;
{
if((s == (char *)NULL) || (*s == '\0')) /* dependency !! */
{
if(rhandle > (-3))
{
Fclose(rhandle);
rhandle = -10;
}
return 0;
}
if((rhandle = Fopen(s, 0)) < (-3))
{
Bconws("?file: "); Bconws(s); CRLF;
return 1;
}
return 0;
}
void read_at(buf)
char *buf;
{
char c;
register char *p;
p = &buf[2];
buf[1] = 0;
while(Fread(rhandle, 1L, &c) == 1L)
{
Bconout(2, c);
if(c == '\r')
{
Bconout(2, '\n');
*p = '\0';
buf[1] = strlen(&buf[2]);
Fread(rhandle, 1L, &c);
return;
}
*p++ = c;
}
Fclose(rhandle);
rhandle = -10;
CRLF;
}
int find_builtin(s)
REG char *s;
{
register short i;
for(i = 0; builtin[i].command != (char *)NULL; i++)
if(strcmp(s, builtin[i].command) == 0)
return i;
return -1;
}
int find_alias(s)
REG char *s;
{
register short i;
for(i = 0; alias[i].aname != (char *)NULL; i++)
if(strcmp(s, alias[i].aname) == 0)
return i;
return -1;
}
char *existf(name, pth, ex)
REG char *name, *pth, *ex;
{
register char *b = &buf[(BSIZE/2)];
if(*pth != '\0')
{
(void) strcpy(b, pth);
(void) strcat(b, name);
}
else
(void) strcpy(b, name);
if(*ex != '\0')
(void) strcat(b, ex);
if(Fsfirst(b, 0) == 0)
return b;
return (char *)NULL;
}
char *find_ext(s)
REG char *s;
{
register char *p;
register short i, j;
extern char *existf();
for(i = 0; path[i] != (char *)NULL; i++)
for(j = 0; ext[j] != (char *)NULL; j++)
if(( p = existf(s, path[i], ext[j])) != (char *)NULL)
return p;
return (char *)NULL;
}
int do_command(com, optarg, args)
char *com, *optarg, *args;
{
Bconws(com);
Bconout(2, ' ');
if(optarg != (char *)NULL)
{
Bconws(optarg);
Bconout(2, ' ');
}
Bconws(args); CRLF;
if(optarg != (char *)NULL)
{
buf[(BSIZE/2)] = strlen(optarg) + strlen(args) + 1;
(void)strcat(strcat(strcpy(&buf[(BSIZE/2+1)], optarg), " "),
args);
return (int)Pexec(0, com, &buf[(BSIZE/2)], env);
}
else
{
buf[0] = strlen(args);
(void) strcpy(&buf[1], args);
return (int)Pexec(0, com, buf, env);
}
}
int main()
{
register char *com, *args, *line;
register int i, status;
/* Set Up Stderr */
Fforce(2,(int)Fdup(1));
stat = (STAT *)Fgetdta();
cwd[1] = ':';
cd(HOME);
while(1)
{
PROMPT;
buf[0] = 127;
if(rhandle > (-3))
read_at(buf);
else
{
Cconrs(buf);
Bconout(2, '\n');
}
if(buf[1] == 0)
continue;
buf[(buf[1]+2)] = '\0';
line = &buf[2];
com = line;
/* pick up argv[0] */
while((*line != '\0') && (!iswhite(*line)))
line++;
if(*line != '\0')
{
*line++ = '\0';
}
args = line;
status = 0;
if((i = find_builtin(com)) >= 0)
status = (*(builtin[i].routine))(args);
else if ((i = find_alias(com)) >= 0)
status = do_command(alias[i].adef, alias[i].optarg,
args);
else if ((line = find_ext(com)) != (char *)NULL)
status = do_command(line, (char *)NULL, args);
else
{
Bconws(com);Bconws(" not found\r\n");
continue;
}
if(status != 0)
{
PRINTI(status); CRLF;
}
}
return 0;
}
/* -eof- */