1 lock_console: lkc: proc;
  2 
  3           /* This command locks up a user's console for a user-specified
  4              period of time.  The only way to thwart lock_console before
  5              the expiration of the time period is to hang up the terminal.
  6 
  7              Version 9 coded 16 Mar. 1974 */
  8 
  9           dcl
 10 
 11           lock_console$condition ext entry(bit(1) aligned),
 12           timer_manager_$sleep ext entry(fixed bin(71),bit(2)),
 13           (com_err_,ioa_,ioa_$ioa_stream) ext entry options(variable),
 14           get_password_ ext entry(char(*),char(*),fixed bin,char(*)),
 15           defer_messages ext entry(),
 16           immediate_messages ext entry,
 17           cu_$arg_count ext entry(fixed bin),
 18           cu_$arg_ptr ext entry(fixed bin,ptr,fixed bin,fixed bin),
 19           ios_$order ext entry(char(*),char(*),ptr,bit(72) aligned),
 20           ios_$resetread ext entry(char(*),bit(72) aligned),
 21           timer_manager_$alarm_call ext entry(fixed bin(71),bit(2),entry),
 22           timer_manager_$reset_alarm_call ext entry(entry),
 23           find_condition_info_ ext entry(ptr,ptr,fixed bin(35)),
 24           continue_to_signal_ ext entry(fixed bin(35)),
 25           cu_$cp ext entry(ptr,fixed bin,fixed bin(35)),
 26           (quit,cleanup,any_other) condition,
 27           logout ext entry(),
 28           cv_dec_check_ entry(char(*),fixed bin) returns(fixed bin(35)),
 29           clock_ ext entry() returns(fixed bin(71)),
 30           date_time_ ext entry(fixed bin(71),char(*)),
 31           (nargs,ix,argl,code) fixed bin,
 32           nsecs fixed bin(71) init(600),
 33           argp ptr,
 34           iostat bit(72) aligned,
 35           args char(argl) based(argp),
 36           (ppw_sw,bf_sw,ncs_sw,com_sw,npf_sw,spw_sw,dm_sw,nolog_sw,already_quat) bit(1) aligned init("0"b),
 37           initsw bit(1) static aligned init("0"b),
 38           password char(8) static,
 39           ttyid char(4),
 40           1 ttyinf aligned,
 41                     2 id char(4),
 42                     2 res char(8),
 43                     2 type fixed bin,
 44           grace fixed bin init(0),
 45           comline char(256) aligned,
 46           comlen fixed bin, code35 fixed bin(35),
 47           (cur_time,wakeup_time) fixed bin(71),
 48           inputpw char(8),
 49           datestr char(24),
 50           lkc char(12) static init("lock_console"),
 51           error_table_$badopt ext fixed bin(35),
 52           (null,addr,substr) builtin;
 53 
 54           /* process arguments */
 55 
 56           call cu_$arg_count(nargs);
 57           if nargs=0 then goto default_all;
 58           do ix=1 to nargs;
 59           call cu_$arg_ptr(ix,argp,argl,code);
 60           if args="-time" | args="-tm" then do;
 61                     ix=ix+1;
 62                     call cu_$arg_ptr(ix,argp,argl,code);
 63                     if code^=0 then goto bad_mins;
 64                     nsecs=cv_dec_check_(args,code) * 60;
 65                     if code^=0 then goto bad_mins;
 66                     end;
 67           else if args="-no_print_off" | args="-npf" then npf_sw="1"b;
 68           else if args="-no_logout" | args="-nol" then nolog_sw="1"b;
 69           else if args="-prev_pw" | args="-ppw" then ppw_sw="1"b;
 70           else if args="-defer_messages" | args="-dm" then dm_sw="1"b;
 71           else if args="-set_pw" | args="-spw" then do;
 72                     ix=ix+1;
 73                     call cu_$arg_ptr(ix,argp,argl,code);
 74                     if code^=0 then goto bad_pw;
 75                     if argl>8 then goto bad_pw;
 76                     password=args;
 77                     initsw,spw_sw="1"b;
 78                     /* note: set initsw because spw is equiv to pw input */
 79                     end;
 80           else if args="-brief" | args="-bf" then bf_sw="1"b;
 81           else if args="-no_catch_signals" | args="-ncs" then ncs_sw="1"b;
 82           else if args="-call" | args="-cl" then do;
 83                     ix=ix+1;
 84                     call cu_$arg_ptr(ix,argp,argl,code);
 85                     if code^=0 then goto bad_cl;
 86                     comline=args;
 87                     comlen=argl;
 88                     com_sw="1"b;
 89                     end;
 90           else if args="-grace" | args="-gr" then do;
 91                     ix=ix+1;
 92                     call cu_$arg_ptr(ix,argp,argl,code);
 93                     if code^=0 then goto bad_gr;
 94                     grace=cv_dec_check_(args,code);
 95                     if code^=0 then goto bad_gr;
 96                     if grace<0 then goto bad_gr;
 97                     end;
 98           else do;
 99                     call com_err_(error_table_$badopt,lkc,"^a",args);
100                     return;
101                     end;
102           end;  /* end of arg proc loop */
103 
104 default_all: if ^initsw & ppw_sw then do;
105                     call com_err_(0,lkc,"The ""-ppw"" argument is ignored in the initial invocation.");
106                     ppw_sw="0"b;
107                     end;
108           call ios_$order("user_output","info",addr(ttyinf),iostat);
109           ttyid=ttyinf.id;
110           if npf_sw then if ttyinf.type<3 then ttyinf.type=6;
111           else ttyinf.type=7;  /* make terminal look like TTY33 or IBM2741 */
112           if ^ppw_sw & ^spw_sw then do;
113                     call ios_$resetread("user_input",iostat);
114                     call get_password_("lock_console: Password:",ttyid,ttyinf.type,inputpw);
115                     password=inputpw;
116                     initsw="1"b;
117                     end;
118           call timer_manager_$alarm_call(10*60,"11"b,alarm_handler_);
119           on cleanup call timer_manager_$reset_alarm_call(alarm_handler_);
120 
121           /* sets up an interval timer that unblocks process every 10 minutes.
122              This will prevent Multics from logging out the terminal, in the
123              case where nmins>15. */
124 
125           /* if com_sw = "0"b, put process to sleep for requested delay,
126              which is cur_time + nsecs.  Else execute the comline, and when
127              it returns, put the process to sleep for the remainder of the
128              requested delay (if any).  When delay time arrives, put process
129              back to sleep for the grace period (if any).  On return from
130              this sleep call, call logout or return (per nolog_sw). */
131 
132           wakeup_time=clock_()+nsecs*1000000;
133           if dm_sw then call defer_messages;
134           on quit call quit_handler_;
135           if ^bf_sw then do;
136                     call date_time_(clock_(),datestr);
137                     call ioa_("^2/As of ^a:^/This console is in use and has been locked.
138 Please use another console.^2/",datestr);
139                     end;
140           if com_sw then do;
141                     if ^ncs_sw then on any_other call any_other_handler_;
142                     call cu_$cp(addr(comline),comlen,code35);
143                     com_sw="0"b; /* when cu_$cp returns, comline is done */
144                     if ^ncs_sw then revert any_other;
145                     end;
146           cur_time=clock_();
147           if cur_time<wakeup_time then call timer_manager_$sleep(wakeup_time,"00"b);
148           if ^bf_sw | grace>0 then do;
149                     call ioa_("^/********^/From lock_console: Specified lock time has been exceeded.");
150                     if grace>0 then call ioa_("The grace period will expire in ^d minutes.",grace);
151                     call ioa_("********^/");
152                     end;
153           if grace>0 then do;
154                     call timer_manager_$sleep(grace*60,"11"b);
155                     call ioa_("^/********^/From lock_console: Grace period has expired.^/********^/");
156                     end;
157           if nolog_sw then goto release_console;
158           else call logout; /* logout does not return */
159 
160           /* proc to handle the 10 minute interval timer */
161 
162 alarm_handler_: proc;
163 
164           call timer_manager_$alarm_call(10*60,"11"b,alarm_handler_);
165           return; /* just start a new timer and return */
166 
167           end alarm_handler_;
168 
169           /* proc to process quits */
170 
171 quit_handler_: proc;
172 
173           call ios_$resetread("user_input",iostat);
174           if already_quat then do;
175                     call ioa_(""); /* dummy i/o to clear things after the quit */
176                     call ios_$order("user_output","printer_on",null,iostat); /* in case printer off */
177                     call ioa_("lock_console: Quit ignored; password input pending.^2/");
178                     call ios_$order("user_output","printer_off",null,iostat); /* turn it back off */
179                     return;
180                     end;
181           already_quat="1"b;
182           call get_password_("lock_console: Password:",ttyid,ttyinf.type,inputpw);
183           if inputpw=password then
184              if ^com_sw then goto release_console; /* cause nonlocal transfer */
185              else do;
186                     call continue_to_signal_(code35);
187                     already_quat="0"b;
188                     return;
189                     end;
190           else do;
191                     call ioa_("lock_console: Password incorrect, console not unlocked.^2/");
192                     call ios_$order("user_i/o","start",null,iostat);
193                     already_quat="0"b;
194                     return;
195                     end;
196 
197           end quit_handler_;
198 
199           /* handler for condition any_other */
200 
201 any_other_handler_: proc;
202 
203           dcl
204 
205           1 ci aligned,
206                     2 mcptr ptr,
207                     2 ver fixed bin,
208                     2 cname char(32) var,
209                     2 infoptr ptr,
210                     2 wcptr ptr,
211                     2 loc_ptr ptr,
212                     2 flags aligned,
213                               3 crawl bit(1) unal,
214                               3 pad1 bit(35) unal,
215                     2 pad2 bit(36) aligned,
216                     2 user_loc_ptr ptr,
217                     2 pad(4) bit(36) aligned;
218 
219           call find_condition_info_(null,addr(ci),code35);
220           if ci.cname="alrm" | ci.cname="cput" | ci.cname="quit" then do;
221 cts:                call continue_to_signal_(code35);
222                     return;
223                     end;
224           else do;
225                     call ioa_$ioa_stream("error_output",
226 "^/********^/From lock_console: Condition ""^a"" has been signalled.
227 ********^/",ci.cname);
228                     call lock_console$condition(npf_sw);
229                     goto cts; /* when $condition returns, user has reclaimed terminal */
230                     end;
231 
232           end any_other_handler_;
233 
234           /* control comes here when console is to be unlocked */
235 
236 release_console: call timer_manager_$reset_alarm_call(alarm_handler_);
237           if dm_sw then call immediate_messages;
238           if ^bf_sw then call ioa_("^/lock_console: Console unlocked.");
239           return;
240 
241           /* This entry point is called by the any_other handler to wait
242              for the user to reclaim the terminal before letting the
243              condition signal through. */
244 
245 condition: entry(real_npf_sw);
246 
247           dcl real_npf_sw bit(1) aligned;
248 
249           npf_sw=real_npf_sw; /* propagate the npf_sw value */
250           nsecs= 24*3600;  /* set up the other parameters */
251           grace= 24*60;
252           bf_sw,ppw_sw,nolog_sw="1"b;
253           goto default_all;  /* rejoin main entry code */
254 
255 bad_mins: call com_err_(0,lkc,"Missing or invalid time period parameter.");
256           return;
257 
258 bad_pw:   call com_err_(0,lkc,"Missing or invalid password parameter.");
259           return;
260 
261 bad_gr:   call com_err_(0,lkc,"Missing or invalid grace parameter.");
262           return;
263 
264 bad_cl:   call com_err_(0,lkc,"Missing command line parameter.");
265           return;
266 
267           end lock_console;