{ From: russell@alpha3.ersys.edmonton.ab.ca (Russell Schulz) using my tpserio from simtel and genericf from rnr123 on simtel: } program uushell; { accept a login and shell to uucico } { Russell Schulz - russell@alpha3.ersys.edmonton.ab.ca (940423) Copyright 1994 Russell Schulz this code is not in the Public Domain permission is granted to use these routines in any application regardless of commercial status as long as the author of these routines assumes no liability for any damages whatsoever for any reason. have fun. } {$M 16384,65536,65536} {$define consoleoverride} {$undef consoleoverride} {$define autoanswer} {$undef autoanswer} uses dos,crt,genericf; const version='v0.2'; defaultidpwfn='c:\etc\idpw'; defaultmsg='Authorized use only -- all others disconnect now'; defaultuucicocmd='uucico.exe'; defaultuucicoparams='-r_0_-u%A'; var console: boolean; port: integer; shadow: integer; eightbitclean: boolean; highcolor: integer; lowcolor: integer; readlnecho: boolean; idleminutes: integer; minstart: integer; minlastinput: integer; minutestorun: integer; didtimeout: boolean; speed: longint; delaytime: integer; idpwfn: string; msg: string; msgfn: string; uucicocmd: string; uucicoparams: string; verbose: boolean; {$undef debug} {$define debug} {$undef timeout} {$define timeout} {$undef timeoutreturnscr} {$define timeoutreturnscr} {$i serio.pas} procedure usage; begin writeln('uushell [-?] [-p port] [-s speed] [-d delaytime]'); writeln(' [-f file] [-m messagefile] [-c command] [-a arguments]'); writeln(' [-v]'); writeln; writeln(' -p 0=COM1, 1=COM2'); writeln(' -s 2400=2400, 9600=9600'); writeln(' -d delay delaytime/1000 seconds'); writeln(' -f file of id-space-password, one set per line'); writeln(' -m first line of this file will be shown to callers'); writeln(' -c command (default: ',defaultuucicocmd,')'); writeln(' the extension is necessary. if no path is given,'); writeln(' the PATH environment variable will be searched'); writeln(' -a arguments (default: ',defaultuucicoparams,')'); writeln(' underscores (_) will be changed to spaces'); writeln(' %A will be changed to the id'); writeln(' -v verbose'); writeln; writeln('russell@alpha3.ersys.edmonton.ab.ca (941106)'); halt(1); end; procedure execp(cmd,cmdline: string); var path: string; success: boolean; ncmd: string; nbase: string; npath: string; el: string; at: integer; function indir(cmd,dir: string): boolean; var fileinfo: searchrec; begin findfirst(dir+'\'+cmd,archive,fileinfo); indir := (doserror=0); end; begin success := false; ncmd := crepl(cmd,'/','\'); nbase := ncmd; {strip path from nbase} repeat at := pos(':',nbase); if at<>0 then nbase := copy(nbase,at+1,255); until at=0; repeat at := pos('\',nbase); if at<>0 then nbase := copy(nbase,at+1,255); until at=0; {chop off path. if trailing \, chop, unless root or drive:root (then add .)} npath := ''; if nbase<>ncmd then begin success := true; {so as to not look further than given path} npath := copy(ncmd,1,length(ncmd)-length(nbase)); if npath='\' then npath := npath+'.'; if pos(':\',npath)<>0 then if copy(npath,length(npath)-1,2)=':\' then npath := npath+'.'; if copy(npath,length(npath),1)='\' then npath := copy(npath,1,length(npath)-1); end; {if an explicit path, use it -- otherwise, just try '.'} if npath='' then npath := '.'; {if no extension, try com then exe} if pos('.',nbase)=0 then begin if indir(nbase+'.com',npath) then begin success := true; exec(npath+'\'+nbase+'.com',cmdline); end else if indir(nbase+'.exe',npath) then begin success := true; exec(npath+'\'+nbase+'.exe',cmdline); end end else if indir(nbase,npath) then begin success := true; exec(npath+'\'+nbase,cmdline); end; if not success then begin {not found in explicit path (or ., if no explicit path). try $PATH} path := getenv('PATH'); while not success and (path<>'') do begin if copy(path,length(path),255)<>';' then path := path+';'; at := pos(';',path); el := copy(path,1,at-1); path := copy(path,at+1,255); if pos('.',nbase)=0 then begin if indir(nbase+'.com',el) then begin success := true; exec(el+'\'+nbase+'.com',cmdline); end else if indir(nbase+'.exe',el) then begin success := true; exec(el+'\'+nbase+'.exe',cmdline); end; end else begin if indir(nbase,el) then begin success := true; exec(el+'\'+nbase,cmdline); end; end; end; end; end; procedure sendch(c: char); begin xwrites(c); if xkeypressed then write(xreadkey); if xkeypressed then write(xreadkey); if xkeypressed then write(xreadkey); if xkeypressed then write(xreadkey); if xkeypressed then write(xreadkey); delay(50); end; procedure outstrnocr(s: string); var i: integer; echo: string; anecho: boolean; begin if verbose then begin writeln('writing: ',s); writeln; end; echo := ''; for i := 1 to length(s) do begin xwrites(s[i]); if s[i]<>#13 then delay(4*delaytime); delay(delaytime); repeat anecho := xkeypressed; if anecho then echo := echo+xreadkey; delay(delaytime); until not anecho; end; if verbose then if echo<>'' then writeln('echo: ',echo); end; procedure outstr(s: string); begin outstrnocr(s+#13); end; procedure initmsg; var msgf: text; begin msg := defaultmsg; if msgfn<>'' then begin assign(msgf,msgfn); {$I-} reset(msgf); {$I+} if ioresult<>0 then begin writeln('! could not open message file ',msgfn); writeln('! using default message'); end else begin if not eof(msgf) then readln(msgf,msg); close(msgf); end; end; end; procedure initialize; var i: integer; code: word; s: string; begin speed := 2400; port := 0; delaytime := 500; idpwfn := defaultidpwfn; msgfn := ''; uucicocmd := defaultuucicocmd; uucicoparams := defaultuucicoparams; verbose := false; {$ifdef com2} port := 1; {$endif} i := 1; while i<=paramcount do begin if paramstr(i)='-p' then begin inc(i); if i<=paramcount then val(paramstr(i),port,code) else usage; end else if paramstr(i)='-s' then begin inc(i); if i<=paramcount then val(paramstr(i),speed,code) else usage; end else if paramstr(i)='-d' then begin inc(i); if i<=paramcount then val(paramstr(i),delaytime,code) else usage; end else if paramstr(i)='-f' then begin inc(i); if i<=paramcount then idpwfn := paramstr(i) else usage; end else if paramstr(i)='-m' then begin inc(i); if i<=paramcount then msgfn := paramstr(i) else usage; end else if paramstr(i)='-c' then begin inc(i); if i<=paramcount then uucicocmd := paramstr(i) else usage; end else if paramstr(i)='-a' then begin inc(i); if i<=paramcount then uucicoparams := paramstr(i) else usage; end else if paramstr(i)='-v' then begin verbose := true; end else usage; inc(i); end; portengage; portspeed(speed); console := false; shadow := 0; if verbose then shadow := 1; outstr('ATV1E1'); initmsg; end; procedure initmodem; var s: string; begin writeln('Initializing modem...'); delay(1000); outstr('AT'); outstr('ATZ'); outstr('AT'); {$ifdef autoanswer} outstr('ATS0=1'); {$endif} end; procedure shutdown; var s: string; begin writeln('Restoring modem settings...'); outstr('AT'); outstr('AT'); outstr('ATS0=0'); outstr('AT'); outstr('AT'); portdisengage; end; procedure hangup; begin delay(2000); outstrnocr('+++'); delay(2000); outstr('AT'); outstr('ATH'); end; function verify(id,pw: string): boolean; var result: boolean; s: string; idpwf: text; i: integer; begin result := false; assign(idpwf,idpwfn); {$I-} reset(idpwf); {$I+} if ioresult<>0 then begin writeln('! could not open id+password file ',idpwfn); writeln('! no logins will succeed'); end else begin while not eof(idpwf) do begin readln(idpwf,s); if chopfirstw(s)=id then if s=pw then result := true; end; close(idpwf); end; verify := result; end; function expandparams(oldparams: string; id: string): string; var result: string; begin result := ununderscore(oldparams); result := srepl(result,'%A',id); expandparams := result; end; procedure getlogin; var expandedparams: string; id: string; pw: string; begin console := false; shadow := 1; xwriteln; xwritelns('authorized use only.'); xwriteln; xwrites('login: '); readlnecho := true; xreadlns(id,80,false); xwriteln; xwrites('password: '); readlnecho := false; xreadlns(pw,80,false); xwriteln; if verbose then writeln('id: ',id,' pw: ',pw); if not verify(id,pw) then begin xwriteln; xwritelns('sorry'); end else begin writeln('disengaging communications port...'); portdisengage; writeln('running uucico for ',id); expandedparams := expandparams(uucicoparams,id); writeln(uucicocmd,' ',expandedparams); execp(uucicocmd,expandedparams); writeln('engaging communications port...'); portengage; portspeed(speed); end; if not verbose then shadow := 0; end; procedure getcalls; var done: boolean; ch: char; str: string; currmitoday: integer; begin write('Waiting for call...'); currmitoday := mitoday; done := false; str := ''; while not done do begin minlastinput := mitoday; if currmitoday<>mitoday then begin write('.'); currmitoday := mitoday; end; console := true; if keypressed then begin ch := readkey; if verbose then writeln(ch); if ch='q' then begin done := true; writeln; writeln('Quit...'); end else if ch='a' then begin write('Answering...'); outstr('ATA'); end else if ch='p' then begin write('Pausing...'); ch := readkey; write('Waiting...'); end else begin writeln; if (ord(ch)<32) or (ord(ch)>126) then writeln('unknown key ',ord(ch)) else writeln('unknown key ',ch); end; end; console := false; if xkeypressed then begin ch := xreadkey; if verbose then writeln(ch); if (ch<>#13) and (ch<>#10) then str := str+ch else begin if verbose then writeln('got: ',str); if str='RING' then begin write('Ring...'); {$ifndef autoanswer} outstr('ATA'); {$endif} end; if copy(str,1,7)='CONNECT' then begin writeln; writeln('Connected at: ',str); minlastinput := mitoday; getlogin; minlastinput := mitoday; hangup; initmodem; write('Waiting for call...'); end; str := ''; end; end; end; writeln; end; begin writeln('uushell ',version); writeln; console := true; port := 0; shadow := 0; eightbitclean := true; highcolor := 0; lowcolor := 0; idleminutes := 2; minutestorun := -1; didtimeout := false; minstart := mitoday; minlastinput := minstart; initialize; initmodem; getcalls; shutdown; end.