home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Crawly Crypt Collection 2
/
crawlyvol2.bin
/
apps
/
text_ed
/
elv16b2
/
st
/
shell.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-13
|
7KB
|
429 lines
/* shell.c */
/* Author:
* Guntram Blohm
* Buchenstrasse 19
* 7904 Erbach, West Germany
* Tel. ++49-7305-6997
* sorry - no regular network connection
*/
/*
* This file contains a minimal version of a shell for TOS. It allows the
* setting of an environment, calling programs, and exiting.
* If you don't have another one, this might be sufficient, but you should
* prefer *any* other shell.
* You may, however, want to set your SHELL environment variable to this
* shell: it implements the -c switch, which is required by Elvis, and
* not supported by most other atari shells.
*/
#include <stdio.h>
#include <string.h>
#include <osbind.h>
#ifdef __STDC__
#include <stdlib.h>
#else
extern char *getenv(), *malloc();
#endif
extern char **environ;
long _stksize=16384;
#if MINT
/* this is quite a bit MiNT library dependant... (although you
don't want to use this when actually _running_ under MiNT ->
use init.prg instead) */
#define USEARGV 1
/* ...especially it depends on system() no relying on $SHELL! */
#include <unistd.h>
int xsystem(const char *cmd)
{
static int ret;
/* GEMDOS redirection bugs department... */
switch (vfork())
{
case -1: /* error */
ret = -1;
break;
case 0: /* child */
ret = system(cmd);
exit(0);
default: /* parent */
wait((int *) NULL);
}
return ret;
}
#endif
#if USEARGV
#define INITBUFSIZ 0x400
#include <errno.h>
size_t bufsiz = INITBUFSIZ;
char *buf = (char *) NULL;
#ifndef __STDC__
extern char *putenv(), *realloc();
#endif
#else
#define MAXENV 50
struct
{
char *name;
char *value;
} myenv[MAXENV];
#endif
int cmd_set(), cmd_exit(), cmd_cd(), cmd_pwd();
char home[FILENAME_MAX];
struct buildins
{
char *name;
int (*func)();
} buildins[]=
{ "exit", cmd_exit,
"set", cmd_set,
"cd", cmd_cd,
"pwd", cmd_pwd,
0,
};
#if USEARGV
char *getbuf(needed)
size_t needed;
{
if (buf && bufsiz >= needed)
return buf;
while (bufsiz < needed)
bufsiz *= 2;
if (!(buf = realloc(buf, bufsiz)))
exit(-ENOMEM);
return buf;
}
char *bufgets(fp)
FILE *fp;
{
int c = EOF;
size_t p = 0, left = bufsiz-1;
while(((c = getc(fp)) != EOF)) {
if (!--left) {
buf = getbuf(bufsiz * 2);
left = bufsiz-p-1;
}
if((buf[p++] = c) == '\n')
break;
}
buf[p] = '\0';
if (!p && c == EOF)
return NULL;
return buf;
}
#endif
main(argc, argv)
int argc;
char **argv;
{
int i;
#if USEARGV
size_t p, clen;
int interactive = isatty(0);
char *ch;
(void) getbuf((size_t) 1);
#else
char buf[128];
for (i=0; environ[i] && strncmp(environ[i],"ARGV=",5); i++)
cmd_set(environ[i]);
#endif
if (ch = getenv("HOME")) {
strcpy(home, ch);
ch = buf + strlen(strcpy(buf, ch));
if (!strchr("\\/", ch[-1]))
*ch++ = '/';
strcpy(ch, "profile.sh");
script(buf);
} else {
getcwd(home, sizeof(home));
script("profile.sh");
}
if (argc>1 && !strcmp(argv[1], "-c"))
{
buf[0]='\0';
#if USEARGV
p = 0;
for (i=2; i<argc; i++)
{ if (i>2) {
buf[p++] = ' ';
buf[p] = '\0';
}
strcpy(getbuf(p+(clen=strlen(argv[i]))+2)+p, argv[i]);
p += clen;
}
i = execute(buf);
exit(i>=0 ? i : errno);
#else
for (i=2; i<argc; i++)
{ if (i>2)
strcat(buf, " ");
strcat(buf, argv[i]);
}
execute(buf);
#endif
}
else
#if USEARGV
while ((interactive ? fputs("$ ", stdout) : 0),
bufgets(stdin)) {
if ((ch=strchr(buf, '\n')) != 0)
*ch='\0';
errno = 0;
if (execute(buf) == -1 && interactive) {
if (errno == ENOENT)
printf("%s: not found\n", strtok(buf, " "));
else if (errno == ENOEXEC)
printf("%s: unable to exec\n", strtok(buf, " "));
}
}
#else
while (fputs("$ ", stdout), gets(buf))
execute(buf);
#endif
exit(0);
}
execute(buf)
char *buf;
{
char *scan=buf;
#if !USEARGV
char cmd[FILENAME_MAX];
char line[128];
char env[4096], *ep=env;
#endif
int i;
while (*scan==' ')
scan++;
if (!*scan)
return 0;
while (*scan && *scan!=' ')
scan++;
if (*scan)
*scan++='\0';
for (i=0; buildins[i].name; i++)
if (!strcmp(buf, buildins[i].name))
return (*buildins[i].func)(scan);
#if USEARGV
if (*scan && !scan[-1])
scan[-1] = ' ';
return xsystem(buf);
#else
if (!searchpath(buf, cmd))
{ printf("%s: not found\n", buf);
return -1;
}
strcpy(line+1, scan);
line[0]=strlen(scan);
for (i=0; i<MAXENV && myenv[i].name; i++)
{ strcpy(ep, myenv[i].name);
strcat(ep, "=");
strcat(ep, myenv[i].value);
ep+=strlen(ep)+1;
}
*ep='\0';
return Pexec(0, cmd, line, env);
#endif
}
#if !USEARGV
searchpath(from, to)
char *from, *to;
{
char *path="";
char *scan;
char *end;
char *q;
int i;
for (i=0; i<MAXENV && myenv[i].name; i++)
if (!strcmp(myenv[i].name,"PATH"))
path=myenv[i].value;
for (scan=from; *scan; scan++)
if (*scan==':' || *scan=='\\')
{ path=0;
break;
}
if (!path)
{ strcpy(to, from);
end=to+strlen(to);
strcpy(end, ".prg"); if (try(to)) return 1;
strcpy(end, ".ttp"); if (try(to)) return 1;
strcpy(end, ".tos"); if (try(to)) return 1;
*to='\0'; return 0;
}
for (scan=path; *scan; )
{
for (q=to; *scan && *scan!=';' && *scan!=','; scan++)
*q++=*scan;
if (*scan==';' || *scan==',')
scan++;
*q++='\\';
*q='\0';
strcpy(q, from);
end=q+strlen(q);
strcpy(end, ".prg"); if (try(to)) return 1;
strcpy(end, ".ttp"); if (try(to)) return 1;
strcpy(end, ".tos"); if (try(to)) return 1;
}
*to='\0';
return 0;
}
try(name)
char *name;
{
if (Fattrib(name, 0, 0) < 0)
return 0;
return 1;
}
#endif
cmd_cd(line)
char *line;
{
if (!*line)
line = home;
else
line = strtok(line, " ");
if (chdir(line) < 0) {
perror(line);
return 1;
}
return 0;
}
cmd_pwd()
{
char cwd[FILENAME_MAX];
getcwd(cwd, (int) sizeof(cwd));
puts(cwd);
return 0;
}
cmd_exit()
{
exit(0);
}
cmd_set(line)
char *line;
{
char *value;
#if USEARGV
char **ep;
#else
int i;
#endif
if (!*line)
{
#if USEARGV
if (environ)
for (ep = environ; *ep; ++ep) {
fputs(*ep, stdout);
fputs("\n", stdout);
}
#else
for (i=0; i<MAXENV && myenv[i].name; i++)
printf("%s=%s\n", myenv[i].name, myenv[i].value);
#endif
return 0;
}
for (value=line; *value && *value!='='; value++)
;
if (!*value)
{ printf("Usage: set name=var\n");
return -1;
}
#if USEARGV
if (!(line = strdup(line)))
exit(-ENOMEM);
return putenv(line);
#else
*value++='\0';
return doset(line, value);
#endif
}
#if !USEARGV
doset(line, value)
char *line, *value;
{
int i;
for (i=0; i<MAXENV && myenv[i].name && strcmp(myenv[i].name, line); i++)
;
if (i==MAXENV)
{ printf("No Space\n");
return -1;
}
if (!myenv[i].name)
{ myenv[i].name=malloc(strlen(line)+1);
strcpy(myenv[i].name, line);
}
if (myenv[i].value)
free(myenv[i].value);
myenv[i].value=malloc(strlen(value)+1);
strcpy(myenv[i].value, value);
return 0;
}
#endif
script(name)
char *name;
{
FILE *fp;
#if USEARGV
char *p;
#else
char buf[128], *p;
#endif
if ((fp=fopen(name, "r"))==0)
return;
#if USEARGV
while (bufgets(fp))
#else
while (fgets(buf, (int) sizeof buf, fp))
#endif
{
if ((p=strchr(buf, '\n'))!=0)
*p='\0';
execute(buf);
}
fclose(fp);
}