/* maila.c */ #define MAILMASTER /* * Includes */ #include #include #include "vmail.h" #include "dfault.h" #include "evtdef.h" #include "hstdef.h" #include "prodef.h" #include "mailpi.h" #include "cliutl.h" #include "tsxutl.h" #include "kbdutl.h" #include "rtfile.h" #include "inicli.h" #include "suspnd.h" #include "usrblk.h" #include "rcdlck.h" #include "mailbx.h" #include "datime.h" /* * Internal routines */ extern VOID printtxt(); extern int finduniq(); extern int toggle(); extern VOID prnthelp(); extern int mailpi(); extern VOID more(); extern VOID mailexit(); extern int question(); extern int rtresp(); extern int tstbrk(); extern int loadpath(); extern VOID lcd(); extern VOID ldelete(); extern VOID ldelfil(); extern VOID lls(); extern VOID lmkdir(); extern VOID lprotect(); extern VOID setfilp(); extern VOID lrename(); extern VOID newname(); extern VOID lrmdir(); extern VOID rmdir(); extern VOID lunprotect(); extern VOID clrfilp(); extern VOID lsterr(); extern int mailgets(); extern int getword(); extern char *stptok(); extern char *stpblk(); extern int checkusps(); extern int Scompass(); extern VOID strlwr(); extern int strmatch(); extern VOID getinfo(); extern int wrtmsg(); extern VOID sendmail(); extern int send(); extern VOID lsendmail(); extern int lsend(); extern int lsend(); extern VOID scrnview(); extern VOID mailrsp(); extern int mailopen(); extern int mailreplies(); extern int rgetline(); extern int checkevent(); /* * Defines */ #define FALSE 0 #define TRUE 1 #define SUCCESS 2 #define HAVEDATA 4 #define ERROR -1 #define NONE -2 #define ABORT -3 #define INCOMPLETE -4 #define AMBIGUOUS -5 #define BUFFERS 2048 #define RSPSTRING 200 #define GENBUFR 200 /* * Global Variables For MAIL Control Channel */ int pswdreqd = 1; /* password required */ int fromtty = 1; /* tty / file input flag */ int hash = 0, /* hash mark flag */ verbose = 0, /* print mail transactions */ prompt = 1, /* prompt for answer */ wild = 1, /* wild cards enabled */ uflag = 0, /* username / password flag */ lflag = 0, /* local mail flag */ msgcnt = 0, /* number of unread mail messages */ msgflag = 0, /* created message flag */ mailcskt = -1; /* socket for outgoing mail */ /* * Global Buffers / Pointers */ #define INFO_LEN (80) #define HDR_R (0x0001) #define HDR_D (0x0002) #define HDR_F (0x0004) #define HDR_M (0x0008) #define HDR_T (0x0010) #define HDR_S (0x0020) struct mesginfo { char rcvd[INFO_LEN]; char date[INFO_LEN]; char from[INFO_LEN]; char mesgid[INFO_LEN]; char to[INFO_LEN]; char to_user[INFO_LEN]; char to_dest[INFO_LEN]; char to_host[INFO_LEN]; char subject[INFO_LEN]; char filename[INFO_LEN]; char expanded[INFO_LEN]; }; struct mesginfo header; /* message header information */ struct userblock user; /* usernames / passwords / mailboxes */ char xs[BUFFERS]; /* buffer space for incoming data */ /* and TSXUTL.C command files */ char ml_cmnd[GENBUFR], /* command string */ scratch[GENBUFR], /* scratch string */ rsp[RSPSTRING], /* response string */ filespec[GENBUFR], /* current file filespec */ mailspec[GENBUFR], /* mailbox file filespec */ username[USERPASSLEN+2], /* username */ password[USERPASSLEN+2], /* password */ mailpath[DIRPATHLEN+2], /* mailbox path */ lclmpath[DIRPATHLEN+2], /* local mail path */ uspspath[DIRPATHLEN+2], /* path returned by checkusps */ defpath[GENBUFR], /* default path */ pathname[GENBUFR]; /* space to keep path name */ char * ipadd = NULL; /* intermediate IP Address */ char * pass = "sy:paswrd.fil"; /* password file */ char fromfile[20] = ""; /* command file */ FILE *fromfp = NULL; /* command file */ /* * Debugging options * * bit 0 (0x01) debug internal events * bit 1 (0x02) debug mailpi() * bit 2 (0x04) debug checkusps() */ char *usetxt[] = { "", #ifdef DEBUGOPTION " MAIL [?] [-d level] [-fp filespec] [-i IP Address]", " ? List the Help Text and Exit MAIL", " d level Debug Level", " 1 - enable event printing", " 2 - enable mailpi() printing", " 4 - enable checkusps printing", #else " MAIL [?] [-fp filespec] [-i IP Address]", " ? List the Help Text and Exit MAIL", #endif " f filename Command File", " h Help list", " i IP Address Intermediate Host IP Address", " p filename Specify the Password Filespec", "", 0 }; /* * printout text */ VOID printtxt(txt) char **txt; { char **dp; for (dp = txt; *dp; dp++) { kb_puts(*dp); kb_nline(); } } main(argc,argv) int argc; char *argv[]; { int i,j,k; register char c; /* * Initialize for TSX+ clients */ inicli(); /* * Initialize kb handler * Set the break character to ^C */ kb_init(0x03); /* * identify self */ printtxt(vrstxt); /* * parse arguments */ for(i=1; i "); /* * read cmd from user */ mailgets(ml_cmnd,200,1); } } /* * finduniq: * * find name that is a unique prefix of one of the entries in * a list. Return position of the entry, * NONE if none, AMBIGUOUS if more than one. */ int finduniq(name,list,listsize) char *name, *list[]; int listsize; { int i,j,ilen; j = NONE; ilen = strlen(name); for(i=0; i=1 && n<=NCMDS+1) { if((mcmdfp = fopen("sy:maicmd.txt","r")) != NULL) { for(i=0; fgetss(txt,80,mcmdfp)!=NULL && i999) { kbprintf("\r\nInvalid Mail Index: #%d\r\n\r\n", j); break; } if(question(command,100,"To File: ")) break; /* * Mail Box Filespec */ sprintf(mailspec,"%-.6s.%03d", username,j); /* * Create a unique file name for temporary mail data */ sprintf(filespec,"wf:mailbx.%03d", tljobn); /* * Load directory path */ if(loadpath(mailpath)) break; if((inp = rtopen(mailspec,"rn",0,0)) == NULL) { kbprintf("\r\nNo Mail Message #%d\r\n\r\n", j); break; } else { /* * Open mail file */ if((oup = fopen(filespec, "wn")) == NULL) { rtclose(inp); kbprintf("Unable to Create File\r\n\r\n"); break; } /* * copy mail to a temporary file */ while((c = getc(inp)) != EOF) { putc(c,oup); } fclose(oup); rtclose(inp); } /* * Load directory path */ if(loadpath(defpath)) break; if((inp = fopen(filespec,"rn")) == NULL) { kbprintf("Unable to Read Temporary File\r\n\r\n"); break; } else { /* * Open new file */ if((oup = rtopen(command,"wn",0,0)) == NULL) { kbprintf("Unable to Create File\r\n\r\n"); fclose(inp); break; } /* * copy mail to a new file */ while((c = getc(inp)) != EOF) { putc(c,oup); } rtclose(oup); fclose(inp); } /* * Delete temporary file */ delete(filespec); break; #ifdef DEBUGOPTION case DEBUG: /* turn on/off debugging, optional level */ if(sscanf(command,"%d",&i)>0) { debug = i; kbprintf("Debugging on(debug=%d).\r\n",debug); } else { toggle(command,word,&debug, "Debugging on.\r\n", "Debugging off.\r\n"); } return; #else case DEBUG: /* no debugging */ kb_puts("Debugging not available.\r\n"); return; #endif case DELETE: /* * Message Number */ if(question(command,100,"Mail Message #: ")) break; sscanf(command,"%d", &j); if(j<1 || j>999) { kbprintf("\r\nInvalid Mail Message #%d\r\n\r\n", j); break; } kbprintf("Delete mail file #%d ? ", j); if(rtresp(answer,20)) break; strlwr(answer); if(strchr(answer,'y') == NULL) break; if(loadpath(mailpath)) break; sprintf(mailspec,"%-.6s.%03d", username,j); delfil(0,mailspec,0,0); lsterr(); modidx(username,j,CLR_RCVD|CLR_READ); break; case HASH: /* hash mark printing */ toggle(command,word,&hash, "Hash printing on(1024 bytes/hash mark).\r\n", "Hash printing off.\r\n"); break; case HOME: /* go to home directory */ kbprintf("Home directory is --> %s\r\n", gethome(defpath)); cd(defpath); lsterr(); break; case INDEX: /* * Load directory path */ if(loadpath(mailpath)) break; /* * List all received mail */ mailspec[0] = '\0'; for(i=1,lcnt=0,m=mailidx.mailid; i<1000; i++) { if(++m > 999) m = 1; if(mailidx.rcvd[m >> 3] & (1 << (m & 0x0007))) { sprintf(mailspec,"%-.6s.%03d", username,m); if((inp = rtopen(mailspec,"r",0,0)) == NULL) { modidx(username,m,CLR_RCVD|CLR_READ); } else { more(&lcnt,7); getinfo(HDR_F|HDR_S|HDR_D,inp); kbprintf( "#%3.3d %-36.36s %-.40s\r\n", m, header.from, header.date ); kbprintf( " %-.72s\r\n\r\n", header.subject ); rtclose(inp); } } if(tstbrk()) { kb_puts("___ Index Listing Aborted ___\r\n"); break; } } if(mailspec[0] == '\0') kb_puts("\r\nNo Received Mail\r\n\r\n"); break; case INTERACTIVE: /* turn on interactive prompting */ case NONINTERACTIVE: /* turn off interactive prompting */ case PROMPT: /* interactive prompting */ if(cmdno == INTERACTIVE) prompt = FALSE; /* will be toggled */ if(cmdno == NONINTERACTIVE) prompt = TRUE; /* will be toggled */ toggle(command,word,&prompt, "Interactive mode on.\r\n", "Interactive mode off.\r\n"); break; case LPWD: /* local working directory */ *command = '\0'; case LCD: /* change local directory */ /* * Load directory path */ if(loadpath(defpath)) break; if(*(stpblk(command))) { lcd(command); getpath(defpath); } /* * current directory */ kbprintf("Local directory is --> %s\r\n", defpath); return; case LRENAME: /* local RENAME */ /* * Load directory path */ if(loadpath(defpath)) break; if(question(command,100,"From: ")) return; getword(command,&scratch[0]); if(question(command,100,"To: ")) return; getword(command,&scratch[100]); lrename(); return; case LDELETE: /* local DEL */ case LDIR: /* local DIR */ case LLS: /* local DIR */ case LMKDIR: /* local MKDIR */ case LPROTECT: /* local PROTECT */ case LRMDIR: /* local RMDIR */ case LTYPE: /* local TYPE */ case LUNPROTECT: /* local UNPROTECT */ /* * Load directory path */ if(loadpath(defpath)) break; /* * Preprocessing */ if(!*(stpblk(command))) { switch(cmdno) { case LDELETE: case LPROTECT: case LTYPE: case LUNPROTECT: if(question(command,100,"File(s): ")) return; break; case LDIR: case LLS: lls(command); tstbrk(); return; case LRMDIR: case LMKDIR: if(question(command,100,"Directory(s): ")) return; break; } } /* * for each arg */ while(!tstbrk() && getword(command,word)) { /* * for each name */ switch(cmdno) { case LDELETE: ldelete(word); break; case LDIR: case LLS: lls(word); break; case LMKDIR: lmkdir(word); break; case LPROTECT: lprotect(word); break; case LRMDIR: lrmdir(word); break; case LTYPE: if((inp = rtopen(word,"r",0,0)) != NULL) { kbprintf("\r\nFile %s\r\n\r\n", word); while( fgetss(scratch, sizeof(scratch)-1, inp) != NULL && !tstbrk()) { kbprintf("%s\r\n", scratch); } rtclose(inp); } else { kbprintf("\r\nFile %s not found\r\n", word); } kb_puts("\r\n"); break; case LUNPROTECT: lunprotect(word); break; } } return; case DIR: case LIST: /* * Load directory path */ if(loadpath(mailpath)) break; sprintf(ml_cmnd,"newmail"); mailpi(ml_cmnd); if(!msgcnt) break; /* * List all unread mail */ mailspec[0] = '\0'; for(i=0,lcnt=0,m=mailidx.mailid; i<1000; i++) { if(++m > 999) m = 1; k = m >> 3; l = 1 << (m & 0x0007); if(mailidx.rcvd[k] & ~mailidx.read[k] & l) { sprintf(mailspec,"%-.6s.%03d", username,m); if((inp = rtopen(mailspec,"r",0,0)) == NULL) { modidx(username,m,CLR_RCVD|CLR_READ); } else { more(&lcnt,20); getinfo(HDR_F|HDR_S,inp); kbprintf( "#%3.3d %-36.36s %-.40s\r\n", m, header.from, header.subject ); rtclose(inp); } } if(tstbrk()) { kb_puts("___ Dir Listing Aborted ___\r\n"); break; } } if(mailspec[0] == '\0') kb_puts("No Unread Mail\r\n"); break; case MAIL: /* go to mail directory */ kbprintf("Mail directory is --> %s\r\n", mailpath); lcd(mailpath); getpath(defpath); break; case QMARK: case HELP: if(!command[0]) { kb_puts( "These valid commands may be abbreviated:\r\n"); /* * display command list */ scratch[0] = '\0'; for(i=0; i 999) m = 1; k = m >> 3; l = 1 << (m & 0x0007); if(mailidx.rcvd[k] & ~mailidx.read[k] & l) { j = m; break; } } } if(!j) { /* * Message Number */ if(question(command,100,"Mail Message #: ")) break; sscanf(command,"%d", &j); } if(j<1 || j>999) { kbprintf("\r\nInvalid Mail Message #%d\r\n\r\n", j); break; } /* * Load directory path */ if(loadpath(mailpath)) break; /* * Read selected mail file */ sprintf(mailspec,"%-.6s.%03d", username,j); if((inp = rtopen(mailspec,"r",0,0)) == NULL) { kbprintf("\r\nNo Mail Message #%d\r\n\r\n", j); modidx(username,j,CLR_RCVD|CLR_READ); } else { kbprintf("\r\nMail Message #%d [%s]\r\n",j,mailspec); lcnt = 0; while(fgetss(scratch,sizeof(scratch)-1,inp)!=NULL && !tstbrk()) { more(&lcnt,20); kbprintf("%s\r\n", scratch); } rtclose(inp); modidx(username,j,SET_RCVD|SET_READ); } break; case SCAN: kb_puts("Scanning. ... This will take a while ...\r\n"); /* * Load directory path */ if(loadpath(mailpath)) break; for(i=1; i<1000; i++) { sprintf(mailspec,"%-.6s.%03d", username,i); if((inp = rtopen(mailspec,"r",0,0)) == NULL) { modidx(username,i,CLR_READ|CLR_RCVD); } else { rtclose(inp); modidx(username,i,SET_RCVD); } if(tstbrk()) { kb_puts("___ Scan Aborted ___\r\n"); break; } } break; case SEND: /* * Check for a filespec */ getword(command,header.filename); command[0] = '\0'; loadpath(defpath); if(header.filename[0] != '\0') { if(strchr(header.filename,':')) { expand( header.expanded, header.filename); } else { expand( header.expanded, rtfile(header.filename,getdef())); } if((inp = rtopen(header.filename,"r",0,0)) == NULL) { kbprintf("No file %s\r\n", header.expanded); break; } else { rtclose(inp); } } /* * Received: */ sprintf(header.rcvd,"%s (TSX-Plus)", vrstxt[1]); /* * Date: */ strcpy(header.date,datime()); /* * From: */ strcpy(header.from,username); /* * To: */ if(question(command,INFO_LEN,"To: ")) break; getword(command,header.to); /* * To_User / To_Dest */ if((p = strrchr(header.to,':')) == NULL) { p = header.to - 1; } strcpy(header.to_dest,p+1); stptok(p+1,header.to_user,INFO_LEN,"@"); if(header.to_user[0] == '\0') { kb_puts("No User Specified\r\n"); break; } /* * To_Host */ lflag = 0; if((p = strchr(header.to,'@')) != NULL) { stptok(p+1,header.to_host,INFO_LEN,":@"); } else { header.to_host[0] = '\0'; } if(header.to_host[0] == '\0') { /* * Check Mail Privilege */ if(!(user.userflag[1] & LSMTP_PRIV)) { kb_puts("No Local MAIL Privilege\r\n"); break; } /* * Check local username */ strlwr(header.to_user); if(!checkusps(header.to_user,"",0)) { kb_puts("Unknown Local Username\r\n"); break; } strcpy(lclmpath,uspspath); lflag = 1; } else { /* * Check Mail Privilege */ if(!(user.userflag[1] & RSMTP_PRIV)) { kb_puts("No Remote MAIL Privilege\r\n"); break; } if((ipadd != NULL) && !streq(word,ipadd)) { strcpy(word,header.to); sprintf(header.to,"@%s:%s", ipadd, word); strcpy(header.to_host,ipadd); } } /* * Subject: */ kb_puts("Subject: "); if(rtresp(header.subject,INFO_LEN)) break; /* * Message */ if(wrtmsg()) break; /* * Send the Mail */ if(lflag) { lsendmail(); } else { sendmail(); } /* * Load directory path */ if(loadpath(mailpath)) break; /* * Reload mailidx */ sprintf(mailspec,"%-.6s.idx", username); if((inp = rtopen(mailspec,"rn",0,0)) != NULL) { fread(&mailidx,sizeof(mailidx),1,inp); rtclose(inp); } break; case STATUS: /* display status info */ kbprintf("User id: %s\r\n", username); if(ipadd == NULL) { kb_puts("No Intermediate Host\r\n"); } else { kbprintf("Intermediate Host: %s\r\n", ipadd); } #ifdef DEBUGOPTION if(debug) { kbprintf("Debugging on.(Debug=%d)\r\n",debug); } else { kb_puts("Debugging off.\r\n"); } #endif if(wild) { kb_puts("Filename wildcards enabled.\r\n"); } else { kb_puts("Filename wildcards disabled.\r\n"); } if(hash) { kb_puts("Hash-mark printing on.\r\n"); } else { kb_puts("Hash-mark printing off.\r\n"); } if(prompt) { kb_puts("Interactive prompting on.\r\n"); } else { kb_puts("Interactive prompting off.\r\n"); } if(verbose) { kb_puts("Verbose mode on.\r\n"); } else { kb_puts("Verbose mode off.\r\n"); } break; case USER: uflag = 0; /* * username */ if(question(command,100,"Username: ")) break; getword(command,word); username[0] = '\0'; strncat(username,word,USERPASSLEN); strlwr(username); /* * password */ if(!(*stpblk(command))) { if(pswdreqd) { kb_puts("Password: "); if(mailgets(command,100,0) == ABORT) break; } } getword(command,word); password[0] = '\0'; strncat(password,word,USERPASSLEN); strlwr(password); /* * Check username / password */ if(!checkusps(username,password,pswdreqd)) { kb_puts("Invalid Username / Password.\r\n"); break; } /* * Check Mail privileges */ if(!(user.userflag[1] & (LSMTP_PRIV | RSMTP_PRIV))) { kb_puts("No Privilege for MAIL.\r\n"); break; } strcpy(mailpath,uspspath); uflag = 1; case NEWMAIL: msgcnt = 0; /* * Load directory path */ if(loadpath(mailpath)) break; /* * Report number of messages waiting to be read */ sprintf(mailspec,"%-.6s.idx", username); if((inp = rtopen(mailspec,"rn",0,0)) == NULL) { kb_puts("\r\nNo Mail\r\n\r\n"); /* * Create index file if not opened */ if(!makidx(username)) { kb_puts( "?-MAIL-Failed to create index file\r\n"); } } else { fread(&mailidx,sizeof(mailidx),1,inp); rtclose(inp); for(i=0; i<1000; i++) { k = i >> 3; l = 1 << (i & 0x0007); if(mailidx.rcvd[k] & ~mailidx.read[k] & l) { msgcnt += 1; } } if(!msgcnt) { kb_puts("\r\nNo Mail\r\n\r\n"); } else { kbprintf("\r\n%d New Mail Message%s\r\n\r\n", msgcnt , (msgcnt==1) ? "" : "s"); } } break; case VERBOSE: /* display informative messages */ toggle(command,word,&verbose, "Verbose mode on.\r\n", "Verbose mode off.\r\n"); break; case VERSION: /* display current MAIL version */ printtxt(vrstxt); return; case WILD: /* wildcard expansion */ toggle(command,word,&wild, "Wildcards enabled.\r\n", "Wildcards disabled.\r\n"); break; default: break; } } /* * more */ VOID more(i,j) int *i,j; { *i += 1; if(*i%j == 0) { kb_puts( " ... more ... "); while(!fndbrk && tt_inp()!='\015') { suspnd(0); } kb_puts("\r \r"); } } /* * mailexit * * exit from mail */ VOID mailexit(i) int i; { if(i == ABORT) { kb_puts("\r\nMAIL session aborted by TCPIP\r\n"); } /* * close connection */ skclose(mailcskt); skrelease(mailcskt,1); suspnd(0); errhandle(); /* * Reset subdirectory specifications */ cd("dk:"); kb_puts("\r\nEscaping from MAIL\r\n"); exit(0); } /* * General looping question routine * loops until a response is given * returns 1 on ABORT * else 0 */ int question(cstr,clen,qstr) char *cstr,*qstr; int clen; { while(!(*(stpblk(cstr)))) { /* * get arg from user */ kb_puts(qstr); if(rtresp(cstr,clen)) return(1); } return(0); } /* * Routine to get a keyboard response * returns 1 on ABORT * else 0 */ int rtresp(st,ln) char *st; int ln; { return((mailgets(st,ln,1)==ABORT) ? 1 : 0); } /* * tstbrk * * if fndbrk is set then: * (1) terminate command file mode * (2) return(1) * else * return(0) */ int tstbrk() { if(fndbrk) { if(fromfp != NULL) { fclose(fromfp); fromfp = NULL; fromtty = TRUE; kb_puts("\r\nCommand File Input Aborted\r\n"); } fndbrk = 0; return(1); } else { return(0); } } /* * loadpath * * load the directory path if required */ int loadpath(str) char *str; { char str2[94]; if(!streq(str,getpath(str2))) { if(cd(str)) { lsterr(); cd(str2); return(1); } } return(0); } /* * Various routines that interface with the * TSXUTL.C utilities. */ VOID lcd(st) register char *st; { char path[100]; getpath(path); if(cd(st)) { lsterr(); cd(path); lsterr(); } } VOID ldelete(st) char *st; { VOID ldelfil(); dispatch(ldelfil,st); } VOID ldelfil(st) char *st; { delfil(0,st,prompt,wild); } VOID lls(st) char *st; { int dspdir(); dispatch(dspdir,st); } VOID lmkdir(st) char *st; { int mkdir(); dispatch(mkdir,st); } VOID lprotect(st) char *st; { VOID setfilp(); dispatch(setfilp,st); } VOID setfilp(st) char *st; { setclrp(st,1,wild); } VOID lrename() { VOID newname(); dispatch(newname,&scratch[0]); } VOID newname(st) char *st; { rename(st,&scratch[100],fromtty&&prompt,wild); } VOID lrmdir(st) char *st; { VOID rmdir(); dispatch(rmdir,st); } VOID rmdir(st) char *st; { delfil(1,st,prompt,wild); } VOID lunprotect(st) char *st; { VOID clrfilp(); dispatch(clrfilp,st); } VOID clrfilp(st) char *st; { setclrp(st,0,wild); } /* * This is the error print routine for TSXUTL.C * It will be called only if there is an internal error */ VOID lsterr() { if(*errstr) { kb_puts(errstr); kb_nline(); errstr[0] = '\0'; } } /* * mailgets * * read a line from the keyboard * returns ABORT if keyboard input aborted * or non-zero on success */ int mailgets(str,lim,echo) register char *str; /* where to put the line */ int lim,echo; /* max chars to read, echo? */ { register char *save; int c; save = str; /* beginning of line */ *save = '\0'; if(tstbrk()) { kb_puts("^C\r\n"); return(ABORT); } if(!fromtty) { if(fromfp != NULL) { if(fgetss(str,lim,fromfp) != NULL) { if(echo) { kb_puts(str); kb_nline(); } } else { fclose(fromfp); fromfp = NULL; fromtty = TRUE; kb_puts("[EOF]\r\n"); } return(strlen(str)); } else { fromtty = TRUE; } } while(1) { /* * build string from keyboard */ c = kb_gets(str,lim,echo); if(1 <= c && c <= 31) { kb_nline(); return(strlen(save)); } /* * check for abort */ if(tstbrk()) { *save = '\0'; kb_puts("^C\r\n"); return(ABORT); } suspnd(0); } } /* * getword: remove a word from a string. Things within quotes are * assumed to be one word. * return TRUE on success, FALSE on end of string */ int getword(string,word) char *string; register char *word; { register char *p; register int i; char *q; i = 0; /* * skip leading blanks */ p = stpblk(string); if(!(*p)) { /* * no words in string */ word[0] = '\0'; return(FALSE); } if(*p == '\"') { /* * word delimited by quotes */ while(p[++i] && p[i] != '\"') word[i-1] = p[i]; word[i-1] = '\0'; if(!p[i]) { /* * Missing \". Assumed at end of string. */ } else { i++; } q = p+i; } else { /* * get word, max len 79 */ q = stptok(p, word, 79, " \t\r\n"); } /* * remove trailing blanks */ p = stpblk(q); /* * remove extracted stuff */ strcpy(string,p); return(TRUE); } char *stptok( p, toword, ilen, delim) register char *p; char *toword; int ilen; char *delim; { register char *adv; register int i; int j,end; adv = toword; end = 0; j = strlen(delim); do { for(i=0; i= (toword+ilen-1)) end++; *adv++=*p++; } } while(!end); *adv='\0'; return(p); } char *stpblk(ch) register char *ch; { while(*ch == ' ' || *ch == '\t') ch++; return(ch); } /* * checkusps ( us, ps, pflag ) * * Check the password file for the user/password * combination. An inaccessable password file * results in an invalid return. * * If the user/password are validated then * the mail directory is accessed else the * default directory is accessed. An inaccessable * mail and default directory results in an invalid return. * * Returns valid(1)/invalid(0) */ int checkusps(us,ps,pflag) char *us,*ps; int pflag; { FILE *fp; if(NULL==(fp = rtopen(pass,"rn",0,0))) { #ifdef DEBUGOPTION if(debug&0x04) { kbprintf("checkusps(): password file not found: %s\r\n", pass); } #endif return(0); } while (NULL != fread(&user,sizeof(struct userblock),1,fp)) { /* * does username / password check ? */ if(!strncmp(us,&user.username,USERPASSLEN) && (!pflag || user.userflag[0]&PASSNOTREQUIRED || Scompass(ps,&user.password)) ) { rtclose(fp); /* * User found */ getpath(pathname); /* * Set Users Mailbox Directory */ if(user.mailbox.path[0]!='\0' && !cd(&user.mailbox.path)) { #ifdef DEBUGOPTION if(debug&0x04) { kbprintf("checkusps(): mailbox directory: %s\r\n", user.mailbox.path); } #endif getpath(uspspath); cd(pathname); return(1); } else /* * Set Users default directory */ if(user.defdir.path[0]!='\0' && !cd(&user.defdir.path)) { #ifdef DEBUGOPTION if(debug&0x04) { kbprintf("checkusps(): default directory: %s\r\n", user.defdir.path); } #endif getpath(uspspath); cd(pathname); return(1); } cd(pathname); return(0); } } rtclose(fp); #ifdef DEBUGOPTION if(debug&0x04) { kbprintf("checkusps(): Username not found.\r\n"); } #endif return(0); } /* * Scompass ( ps, en ) * * Compute and check the encrypted password */ int Scompass(ps,en) char *ps,*en; { int i,ck; char *p,c; ck = 0; p = ps; /* * checksum the string */ while (*p) ck += *p++; c = ck; /* * XOR with checksum */ i = USERPASSLEN; while (i--) { if((((*ps ^ c)|32)&127)!=*en) return(0); /* * increment checksum to hide length */ if(*ps) { ps++; } else { c++; } en++; } return(1); } VOID strlwr(st) register char *st; { while(*st) { *st = tolower(*st); *st++; } } int strmatch(s,t) char *s,*t; { int i,j; j = strlen(s); for(i=0; i']\r\n"); } else { kb_puts("Unable to open message file %s\r\n",header.expanded); return(1); } while(!rtresp(scratch,sizeof(scratch))) { if(streq(scratch,".")) { rtclose(fp); msgflag = 1; return(0); } fprintf(fp,"%s\r\n", scratch); } rtclose(fp); delfil(0,header.filename,1,0); lsterr(); return(1); }