Xinu7/contrib/ether.monitor/etc/mshell.c
/* mshell.c - mshell */
#include <conf.h>
#include <kernel.h>
#include <tty.h>
#include <slu.h>
#include <proc.h>
#include <deqna.h>
#include <ether.h>
#include <ctype.h>
#include "../h/tcp.h"
#include "../h/network.h"
#include "../h/mshell.h"
#include "../h/mshellc.h"
#include "../h/monitor.h"
Bool found;
Bool match;
int or;
struct epacket *epptr;
struct name table[] = {TABLE};
struct mcmdent mcmds[] = {CMDS}; /* shell commands (mshellc.h) */
struct mshvars Msh; /* globals used by pseudo shell */
LOCAL char errhd[] = "Syntax error\n";
LOCAL char fmt[] = "Cannot open %s\n";
struct name *lookup(list, nam)
struct name *list;
char *nam;
{
int len1, len2;
len1 = strlen(nam);
while(!blkequ(list->n_nam, ZERO, strlen(list->n_nam))){
len2 = strlen(list->n_nam);
if(blkequ(nam, list->n_nam, ((len1 >= len2)? len1 : len2))){
return list;
}else
list++;
}
return(SYSERR);
}
struct name *lookaddr(list, addr)
struct name *list;
char *addr;
{
int len1, len2;
len1 = strlen(addr);
while(!blkequ(list->n_nam, ZERO, strlen(list->n_nam))){
len2 = strlen(list->n_ipaddr);
if(blkequ(addr, list->n_ipaddr, ((len1 >= len2)? len1 : len2))){
return list;
}else
list++;
}
return(list);
}
struct sign *checkname(list, name)
register struct sign *list;
char *name;
{
int len1, len2;
len1 = strlen(name);
while(list->s_name){
len2 = strlen(list->s_name);
if(blkequ(name, list->s_name, ((len1 >= len2)? len1 : len2))){
return(list);
}
list++;
}
return(0);
}
struct sign *checknum(list, num)
register struct sign *list;
unsigned *num;
{
while(list->s_name){
if(list->s_number == num){
return(list);
}
list++;
}
return(list);
}
/*------------------------------------------------------------------------
* mshell - pseudo shell with a few hard-wired commands
*------------------------------------------------------------------------
*/
main(dev)
int dev;
{
int ntokens;
int i, j, k, len, length, num;
int com, recv, pool;
int stdin, stdout, stderr;
Bool flag;
char ch;
int child;
struct epacket *getbuf();
struct dcmd ercmd[2];
mtabinit(table);
minit();
Msh.mncmds = sizeof(mcmds)/sizeof(struct mcmdent);
stdin = stdout = stderr = dev = 0;
pool = mkpool(EMAXPAK,1);
while (TRUE) {
sleep(1);
fprintf(dev,"Enter command ## ");
if((len = read(dev,Msh.mshbuf,128)) ==0){
len = read(dev, Msh.mshbuf, 128);
}
if (len == EOF)
break;
Msh.mshbuf[len-1] = NULLCH;
control(dev, TCINT, getpid());
for(k=0, match=FALSE, found=FALSE; k<500 && found==FALSE; k++){
fprintf(dev,"\n",k);
fprintf(dev,"Packet %d\n",k);
if ( (ntokens=mparse(Msh.mshbuf)) == SYSERR) {
fprintf(dev, errhd);
continue;
} else if (ntokens == 0){
continue;
}
epptr = getbuf(pool);
while((length = meread(ETHER,ercmd,epptr,sizeof(*epptr)))== SYSERR){
continue;
}
/* scan tokens, handling '|' */
do {
flag = FALSE;
or = 0;
for (len=0, i=0 ; i<ntokens ;) {
if((ch=Msh.mtoktyp[i]) == '|'){
if(Msh.mtoktyp[i+1] != 'D' && Msh.mtoktyp[i+1] != 'd' && Msh.mtoktyp[i+1] != 'S' && Msh.mtoktyp[i+1] != 's'){
flag = TRUE;
num = ntokens-i;
ntokens = i;
break;
}else {
or++;
for(ntokens--,j=i; j<ntokens;j++){
Msh.mtoktyp[j]= Msh.mtoktyp[j+1];
Msh.mtokens[j]= Msh.mtokens[j+1];
}
continue;
}
}else {
len += strlen(Msh.mtokens[i++]);
continue;
}
}
for(com=0; com<Msh.mncmds; com++){
if(strcmp(mcmds[com].cmdnam,Msh.mtokens[0])==0)
break;
}
if (com >= Msh.mncmds){
fprintf(dev,"%s: not found\n",Msh.mtokens[0]);
found = TRUE;
freebuf(epptr);
break;
}
len += (ntokens+2)*(sizeof(int)+sizeof(char));
if(isodd(len))
len--;
/* create process to execute command */
if((child=create(mcmds[com].cproc,600,19,Msh.mtokens[0], (len/sizeof(int))+4,stdin,stdout,stderr,ntokens)) == SYSERR){
fprintf(dev,"Cannot create\n");
freebuf(epptr);
break;
}
maddarg(child,ntokens,len);
setnok(getpid(),child);
recvclr();
resume(child);
if(receive() == INTRMSG){
setnok(BADPID, child);
flag = FALSE;
found = TRUE;
}
if(found == TRUE)
break;
if (flag == FALSE){
break;
}
ntokens = num;
for(j=0; j<(ntokens-1); j++){
Msh.mtoktyp[j]=Msh.mtoktyp[j+i+1];
Msh.mtokens[j]=Msh.mtokens[j+i+1];
}
ntokens -= 1;
}while(flag == TRUE);
freebuf(epptr);
}
if(k>=500 && match==FALSE){
fprintf(dev,"Now! %d packets have arrived, but no address matches !\n", k);
}
}
return;
}
/* maddarg.c - maddarg */
/*------------------------------------------------------------------------
* maddarg - copy shell arguments to area reserved on process stack
*------------------------------------------------------------------------
*/
maddarg(pid, nargs, len)
int pid; /* process to receive arguments */
int nargs; /* number of arguments to copy */
int len; /* size of arg. area (in bytes) */
{
struct pentry *pptr;
int *fromarg;
int *toarg;
char *to;
if (isbadpid(pid) || (pptr= &proctab[pid])->pstate != PRSUSP)
return(SYSERR);
toarg = (int *) ( ((unsigned)pptr->pbase) - (unsigned)len );
to = (char *) (toarg + (nargs + 2));
*toarg++ = toarg + 1;
for (fromarg= &Msh.mtokens ; nargs > 0 ; nargs--) {
*toarg++ = to;
strcpy(to, *fromarg++);
to += strlen(to) + 1;
}
*toarg = 0;
return;
}
/* mparse.c - mparse */
/*------------------------------------------------------------------------
* mparse - simplistic, ad hoc parser for command line
*------------------------------------------------------------------------
*/
mparse(line)
char *line;
{
char **tokptr;
int ntok, i;
char *p;
char ch;
char *to;
to = &Msh.margstr;
tokptr = &Msh.mtokens[ntok = 0];
for (p=line; *p!='\n' && *p!='\0' && ntok<MMAXTOK; ){
while ( (ch = *p) == ' ') /* skip leading blanks */
p++;
if (ch=='\0' || ch=='\n') /* end of line or string */
return(ntok);
*tokptr++ = to;
Msh.mtoktyp[ntok++] = ch;
*to++ = *p++;
if (ch != '|'){
while ((ch = *p) != '\n' && ch != '\0' && ch != '|' && ch != ' ')
*to++ = *p++ ;
}
*to++ = NULLCH;
}
return(ntok);
}