$TITLE ('SRVCTL - PROCESS MISCELLANEOUS REMOTE SERVER COMMANDS') srvctl$module: /* COPYRIGHT (C) 1985, Trustees of Columbia University in the City of New */ /* York. Permission is granted to any individual or institution to use, */ /* copy, or redistribute this software so long as it is not sold for */ /* profit, provided this copyright notice is retained. /* /* Contains the following public routines: */ /* bye, byehelp, cwd, cwdhelp, finhelp, finish, loghelp, and logout */ do; declare true literally '0FFH'; declare false literally '00H'; declare null literally '000H'; declare cr literally '0DH'; declare lf literally '0AH'; declare bel literally '007H'; declare del literally '07FH'; declare ctly literally '025H'; declare state byte external; /* FSM last state */ declare tries byte external; /* max number of retries */ declare maxtry byte external; /* the number of retries to attempt */ declare debug byte external; declare taking byte external; /* TRUE if TAKE in effect */ declare pksize literally '94'; declare packet(pksize) byte external; declare gencmd(40) byte; /* text of generic command */ newline: procedure external; end newline; ci: procedure byte external; end ci; co: procedure (char) external; declare char byte; end co; nout: procedure (num) external; declare num address; end nout; token: procedure address external; end token; prerrpkt: procedure (pkt) external; declare pkt address; end prerrpkt; tochar: procedure(char) byte external; declare char byte; end tochar; print: procedure(string) external; declare string address; end print; spack: procedure(type, pknum, length, packet) external; declare (type, pknum, length, packet) address; end spack; rpack: procedure(length, pknum, packet) byte external; declare (length, pknum, packet) address; end rpack; takeline: procedure(buffer) external; declare buffer address; end takeline; /* BLDLEN: Make a length-encoded string and suffix it to the generic */ /* command string */ bldlen: procedure(arg, dest) address; declare (arg, dest) address; declare destptr address; declare srcchr based arg byte; declare destchr based destptr byte; declare len byte; declare lastdest address; len = 0; destptr = dest + 1; /* Point to the 1st destination byte */ do while (srcchr <> null); /* Copy the string */ destchr = srcchr; /* Copy a byte */ arg = arg + 1; destptr = destptr + 1; len = len + 1; end; destchr = null; lastdest = destptr; /* Save final ptr for the return */ destptr = dest; /* Point to the length field */ destchr = tochar(len); return lastdest; end bldlen; /* SETGEN: Construct a generic command */ setgen: procedure(type, arg1, arg2, arg3) byte; declare type byte; declare (arg1, arg2, arg3) address; declare (genstart, genptr) address; declare genchr based genptr byte; genstart = .gencmd; genptr = genstart; genchr = type; /* Store the command type */ genptr = genptr + 1; genchr = null; if (arg1 <> 0) then do; genptr = bldlen(arg1, genptr); /* Add 1st arg */ if (arg2 <> 0) then do; genptr = bldlen(arg2, genptr); /* Add 2nd */ if (arg3 <> 0) then genptr = bldlen(arg3, genptr); /* Add 3rd */ end; end; if debug then do; call print(.('gencmd=$')); call print(.gencmd); call newline; end; return (genptr - genstart); end setgen; /* SENDGEN: Manage the sending of a generic server command packet */ /* Note: This state process does not implement all of the possible */ /* states which can result from the "send generic command" state. */ sendgen: procedure (cmd, cmdlen); declare cmd address; /* the command to be sent */ declare cmdlen byte; /* length of generic command */ declare (num, length) byte; if debug then call print(.('sendgen...\$')); tries = 0; state = 'G'; do while (state <> 'C' and state <> 'A'); if debug then do; call print(.('state=$')); call co(state); call newline; end; if state = 'G' then do; call spack('G', 0, cmdlen, cmd); state = rpack(.length, .num, .packet); end; else if state = 'Y' then do; if packet(0) > 0 then do; /* print reply text */ call print(.packet); call newline; end; state = 'C'; end; else if (state = 'N' or state = false) then do; tries = tries + 1; if tries <= maxtry then state = 'G'; else do; call spack('E', .num, 20, .('Retry count exceeded')); call print(.('Retry count exceeded\$')); state = 'A'; end; end; else if state = 'E' then do; call prerrpkt(.packet); state = 'A'; end; else state = 'A'; end; end sendgen; /* Display help for the BYE command */ byehelp: procedure public; call print(.('\BYE\\$')); call print(.(' The BYE command causes Kermit to shut down and $')); call print(.('log out the remote server\$')); call print(.('and return to ISIS.\\$')); call print(.('Syntax:\\$')); call print(.(' BYE\\$')); end byehelp; /* Display help for the CWD command */ cwdhelp: procedure public; call print(.('\CWD\\$')); call print(.(' The CWD command causes the remote server Kermit $')); call print(.('to change to the specified\$')); call print(.('working directory. If no directory name is $')); call print(.('provided, the server will change\$')); call print(.('to the default directory.\\$')); call print(.('Syntax:\\$')); call print(.(' CWD [remote-directory]\\$')); end cwdhelp; /* Display help for the FINISH command */ finhelp: procedure public; call print(.('\FINISH\\$')); call print(.(' The FINISH command causes Kermit to shut down the $')); call print(.('remote server\$')); call print(.('without logging it out.\\$')); call print(.('Syntax:\\$')); call print(.(' FINISH\\$')); end finhelp; /* Display help for the LOGOUT command */ loghelp: procedure public; call print(.('\LOGOUT\\$')); call print(.(' The LOGOUT command causes Kermit to shut down and $')); call print(.('log out the remote server.\\$')); call print(.('Syntax:\\$')); call print(.(' LOGOUT\\$')); end loghelp; /* BYE: Process a BYE command */ bye: procedure public; call sendgen(.('L'),1); end bye; /* CWD: Process a (remote) CWD command */ cwd: procedure public; declare (rdir, passwd) address; declare passmax literally '20'; declare passchr(passmax) byte; declare passndx byte; declare len byte; passwd = 0; rdir = token; if rdir <> 0 then /* If directory name given */ do; /* get password */ if taking then do; /* from "TAKE" file */ call takeline(.passchr); if not taking then do; /* Takeline reached end of file */ call print(.('take file ends prematurely in $')); call print(.('"cwd"\$')); return; end; end; else do; /* from terminal */ call print(.('Password:$')); passndx = 0; passchr(passndx) = ci; do while (passchr(passndx) <> cr and passchr(passndx) <> lf); if passchr(passndx) = del then /* back up */ if passndx > 0 then passndx = passndx - 1; else call co(bel); /* none left */ else if passchr(passndx) = ctly then /* start over */ passndx = 0; else do; passndx = passndx + 1; if passndx >= passmax then do; /* too long */ passndx = passndx - 1; call co(bel); end; end; passchr(passndx) = ci; end; call newline; passchr(passndx) = null; end; if debug then do; call print(.('password=$')); call print(.passchr); call newline; end; if passchr(0) <> null then passwd = .passchr; end; len = setgen('C',rdir,passwd,0); call sendgen(.gencmd,len); end cwd; /* FINISH: Process a FINISH command */ finish: procedure public; call sendgen(.('F'),1); end finish; /* LOGOUT: Process a LOGOUT command */ logout: procedure public; call sendgen(.('L'),1); end logout; end srvctl$module;