|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T c
Length: 11449 (0x2cb9) Types: TextFile Names: »cmd.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987 └─⟦this⟧ »EUUGD18/General/Spacewar/cmd.c«
/* * Spacewar - get and process player commands doing character/line editing * * Copyright 1984 obo Systems, Inc. * Copyright 1984 Dan Rosenblatt */ #ifndef VMS #include <sys/types.h> #include <dbm.h> #else /* BSD SYSIII SYSV */ #include <types.h> #include "dbm.h" #endif /* VMS */ #include <errno.h> #include "spacewar.h" #include "universe.h" #include "login.h" #include "uio.h" #include "plyr.h" #include "mlbx.h" #ifdef VMS # include <iodef.h> # include <ssdef.h> short inmlbx; #endif /* VMS */ int doproctrap,doupdate; static struct login *getinp(); static VOID cmd2(); extern VOID prvcmd(); VOID cmd() { register struct login *plogin; #ifdef DEBUG DBG("cmd()\n"); #endif /* get and process a command */ if (!(plogin = getinp())) { #ifdef DEBUG VDBG("cmd return\n"); #endif return; } /* based on current major command */ #ifdef DEBUG VDBG("cmd: stat #%d '%c'\n",plogin-loginlst,plogin->ln_stat); #endif switch(plogin->ln_stat) { case 'M': /* Mail (Complain) */ doupdate = 0; mail(plogin); if (doupdate == 0) doupdate = 1; break; case 'B': /* reBuild */ doupdate = 0; build(plogin); if (doupdate == 0) doupdate = 1; break; case 'S': /* See */ doupdate = 0; see(plogin); if (doupdate == 0) doupdate = 1; break; case 'U': /* Usercmd */ doupdate = 0; usrcmd(plogin); if (doupdate == 0) doupdate = 1; break; case 'W': /* Who */ doupdate = 0; who(plogin); if (doupdate == 0) doupdate = 1; break; case 'P': /* Play */ doupdate = 0; play(plogin); if (doupdate == 0) doupdate = 1; break; default: /* not doing anything yet */ doupdate = 0; cmd2(plogin); if (doupdate == 0) doupdate = 1; break; } plogin->ln_input[0] = NULL; #ifdef DEBUG VDBG("cmd return\n"); #endif } static VOID cmd2(plogin) register struct login *plogin; { int inplen=strlen(plogin->ln_input); struct plyrkey getplkey; struct plyr getpldat; datum dbmkey,dbmdata; #ifdef DEBUG DBG("cmd2()\n"); #endif /********************/ /* response is name */ /********************/ if (!plogin->ln_name[0]) { /* no name */ #ifdef DEBUG VDBG("cmd2: #%d response is name\n",plogin-loginlst); #endif /* do again if too short or long */ if (inplen < 2 || inplen >= sizeof(plogin->ln_name)) { output(plogin,'C',0, "Name must be 2 to 8 characters\n\nWhat is your name?"); output(plogin,0,0,0); #ifdef DEBUG VDBG("cmd2 return\n"); #endif return; } /* insure no players playing more than once */ { int i; struct login *plgn; #ifdef DEBUG VDBG("cmd2: #%d checking for dup login (%s)\n", plogin-loginlst,plogin->ln_input); #endif for (i=MAXLOGIN,plgn=loginlst;i-- > 0;++plgn) { if (!strcmp(plogin->ln_input,plgn->ln_name)) { output(plogin,'C',0, "Someone is already playing that name.\n\n\ How about another name?"); output(plogin,0,0,0); #ifdef DEBUG VDBG("cmd2 return\n"); #endif return; } } } /* store name and prompt for password */ strcpy(plogin->ln_name,plogin->ln_input); output(plogin,'C',0,"Password:"); output(plogin,0,0,0); /* set up password state */ plogin->ln_stat = 'p'; plogin->ln_iomode = 'p'; /* no echo */ /************************/ /* response is password */ /************************/ } else if (plogin->ln_stat == 'p') { /* password state */ #ifdef DEBUG VDBG("cmd2: #%d (%s) response is password\n", plogin-loginlst,plogin->ln_name); #endif /* get player */ binit((char *)&getplkey,sizeof(getplkey)); getplkey.pl_plyrkey = PLYR; strcpy(getplkey.pl_name,plogin->ln_name); dbmkey.dptr = (char *)&getplkey; dbmkey.dsize = sizeof(getplkey); /* found; check password */ dbmdata = fetch(dbmkey); if (dbmdata.dptr) { #ifdef DEBUG VDBG("cmd2: #%d (%s) found, checking password\n", plogin-loginlst,plogin->ln_name); #endif bcopy((char *)&getpldat,dbmdata.dptr,sizeof(getpldat)); /* bad password */ if (strcmp(plogin->ln_input,getpldat.pl_passwd)) { output(plogin,'C',0,"Incorrect.\n\nPassword:"); output(plogin,0,0,0); /* good password; check for mail and give prompt */ } else { output(plogin,'C',0,"\n\n"); if (getpldat.pl_seenml < getpldat.pl_lstml) output(plogin,'C',0,"You have new mail\n"); output(plogin,'C',0,PROMPT); output(plogin,0,0,0); plogin->ln_stat = NULL; plogin->ln_iomode = NULL; /* update login info */ ++getpldat.pl_numlgn; time(&getpldat.pl_lstlgn); dbmdata.dptr = (char *)&getpldat; dbmdata.dsize = sizeof(getpldat); if (store(dbmkey,dbmdata)) perror("cmd2: can't update plyr"); } /* not found; insert new player */ } else { #ifdef DEBUG VDBG("cmd2: #%d (%s) not found, inserting\n", plogin-loginlst,plogin->ln_name); #endif /* do again if too short or long */ if (inplen < 2 || inplen >= sizeof(getpldat.pl_passwd)) { output(plogin,'C',0, "Password must be 2 to 8 characters\n\nPassword:"); output(plogin,0,0,0); #ifdef DEBUG VDBG("cmd2 return\n"); #endif return; } /* initialize new player login */ binit((char *)&getpldat,sizeof(getpldat)); strcpy(getpldat.pl_passwd,plogin->ln_input); getpldat.pl_numlgn = 1; time(&getpldat.pl_lstlgn); getpldat.pl_frstml = 1; /* insert new player */ dbmdata.dptr = (char *)&getpldat; dbmdata.dsize = sizeof(getpldat); if (store(dbmkey,dbmdata)) { output(plogin,'C',0, "(sigh) database collision - try another name\ \n\nWhat is your name?"); output(plogin,0,0,0); plogin->ln_name[0] = NULL; /* give prompt */ } else { output(plogin,'C',0,"\n\n"); output(plogin,'C',0,PROMPT); output(plogin,0,0,0); } plogin->ln_stat = NULL; plogin->ln_iomode = NULL; } /***********************/ /* response is command */ /***********************/ } else switch(plogin->ln_input[0]) { case 'L': case 'l': /* Logoff */ logoff(plogin); break; case 'B': case 'b': /* reBuild */ plogin->ln_stat = 'B'; plogin->ln_crft[0] = NULL; plogin->ln_substat = NULL; plogin->ln_input[0] = NULL; build(plogin); break; case 'I': case 'i': /* Information */ output(plogin,'C',0, "\nGet hold of and read the spacewar documentation\n"); output(plogin,'C',0,PROMPT); output(plogin,0,0,0); break; case 'C': case 'c': /* Complain -> Mail to Dan */ plogin->ln_stat = 'M'; plogin->ln_substat = NULL; strcpy(plogin->ln_input,SWMASTER); mail(plogin); break; case 'M': case 'm': /* Mail */ plogin->ln_stat = 'M'; plogin->ln_substat = NULL; plogin->ln_input[0] = NULL; mail(plogin); break; case 'U': case 'u': /* Usercmd */ plogin->ln_stat = 'U'; plogin->ln_substat = NULL; plogin->ln_input[0] = NULL; usrcmd(plogin); break; case 'S': case 's': /* See */ plogin->ln_stat = 'S'; plogin->ln_substat = NULL; plogin->ln_input[0] = NULL; see(plogin); break; case 'W': case 'w': /* Who */ plogin->ln_stat = 'W'; plogin->ln_substat = NULL; plogin->ln_input[0] = NULL; who(plogin); break; case 'P': case 'p': /* Play */ plogin->ln_stat = 'P'; plogin->ln_crft[0] = NULL; plogin->ln_substat = NULL; plogin->ln_input[0] = NULL; play(plogin); break; default: prvcmd(plogin); output(plogin,'C',0,PROMPT); output(plogin,0,0,0); break; } #ifdef DEBUG VDBG("cmd2 return\n"); #endif } /* get input; return a ptr to where a full command is */ static struct login *getinp() { struct uio inp; int i; register char *p; register char *input; extern int errno; #ifndef BSD #ifndef VMS # include "uio2.h" struct uio2 inp2; #endif /* VMS */ #endif /* BSD */ #ifdef DEBUG DBG("getinp()\n"); #endif /* DEBUG */ /* get player input allowing asynchronous */ /* trap processing; do echo and edit magic */ /* do all this until there is a full cmd */ for (;;) { /* get the uio header allowing asynch trap processing */ if (doproctrap < 0 || doupdate < 0) { #ifdef DEBUG VDBG("getinp return\n"); #endif return(NULL); } doproctrap = 1; #ifdef VMS inp.uio_lgn = (struct login *)-1; if ((i=sys$qiow(0,inmlbx,IO$_READVBLK,0,0,0,&inp,sizeof(inp), 0,0,0,0)) != SS$_NORMAL) { #ifdef DEBUG VDBG("getinp qiow(READVBLK)=%d errno=%d\n",i,errno); #endif if (errno != EINTR) perror("read mlbx uio"); continue; } if (inp.uio_lgn == (struct login *)-1) continue; #else /* BSD SYSIII SYSV */ if (read(0,&inp,sizeof(inp)) != sizeof(inp)) { if (errno != EINTR) perror("read uio"); continue; } #endif /* VMS BSD SYSIII SYSV */ doproctrap = 0; #ifdef DEBUG #ifndef BSD if (((int)inp.uio_lgn) >= 0 &&((int)inp.uio_lgn) <= 20) { #ifdef VMS VDBG("getinp: uio sig %d %s\n",(int)inp.uio_lgn, inp.uio_chrs); #else /* SYSIII SYSV */ bcopy((char *)&inp2,(char *)&inp,sizeof(inp2)); VDBG("getinp: uio sig %d %d %s\n",inp2.uio2sig, inp2.uio2pid,inp2.uio2tty); #endif /* VMS SYSIII SYSV */ } else #endif /* BSD */ { VDBG("getinp: uio #%d '",inp.uio_lgn-loginlst); for (p=inp.uio_chrs;*p;++p) VDBG((*p < ' ' || *p > '~') ? "\\%03o" : "%c",*p); VDBG("'\n"); } #endif /* DEBUG */ /* validate login pointer */ #ifndef BSD if (((int)inp.uio_lgn) >= 0 &&((int)inp.uio_lgn) <= 20) { #ifdef VMS proctrap(inp); #else /* SYSIII SYSV */ bcopy((char *)&inp2,(char *)&inp,sizeof(inp2)); proctrap(inp2); #endif /* VMS SYSIII SYSV */ continue; } #endif /* BSD */ if (inp.uio_lgn < loginlst || inp.uio_lgn >= loginlst+MAXLOGIN) { perror("uio_lgn out of range"); continue; } /* echo (based on iomode) and edit magic */ input = inp.uio_lgn->ln_input; input += strlen(input); for (p=inp.uio_chrs;*p;++p) { switch(*p) { case '\n': case '\r': *input = NULL; /* strip trailing blanks */ for (p=inp.uio_lgn->ln_input;--input >= p && *input == ' ';) *input = NULL; if (inp.uio_lgn->ln_iomode == 'm' || inp.uio_lgn->ln_iomode == 's') output(inp.uio_lgn,'C',0,"\r"); else output(inp.uio_lgn,'C',0,"\n"); output(inp.uio_lgn,0,0,0); #ifdef DEBUG VDBG("getinp return\n"); #endif /* DEBUG */ return(inp.uio_lgn); case '\025': /* control-U */ if (inp.uio_lgn->ln_iomode == 's') { output(inp.uio_lgn,'D',0,0); input = inp.uio_lgn->ln_input; } else { for (i=strlen(inp.uio_lgn->ln_input);i-- > 0;) { --input; output(inp.uio_lgn,'C',0,"\b \b"); } } break; case '\b': if (input > inp.uio_lgn->ln_input) { --input; output(inp.uio_lgn,'C',0,"\b \b"); } break; } /* ignore all non-printing chars */ if (*p < ' ' || *p > '~') continue; /* make sure buffer can't overflow */ if (input >= inp.uio_lgn->ln_input + sizeof(inp.uio_lgn->ln_input) - 1) { *input = NULL; if (inp.uio_lgn->ln_iomode == 'm' || inp.uio_lgn->ln_iomode == 's') output(inp.uio_lgn,'C',0,"\r"); else output(inp.uio_lgn,'C',0,"\n"); output(inp.uio_lgn,0,0,0); #ifdef DEBUG VDBG("getinp return\n"); #endif /* DEBUG */ return(inp.uio_lgn); } input[1] = NULL; *input = *p; output(inp.uio_lgn,'C',0,(inp.uio_lgn->ln_iomode == 'p') ? " " : input); /* space if password state, char otherwise */ ++input; } *input = NULL; output(inp.uio_lgn,0,0,0); } }