1 /****^  ***********************************************************
  2         *                                                         *
  3         * Copyright, (C) BULL HN Information Systems Inc., 1990   *
  4         *                                                         *
  5         * Copyright, (C) Honeywell Bull Inc., 1988                *
  6         *                                                         *
  7         * Copyright, (C) Honeywell Information Systems Inc., 1984 *
  8         *                                                         *
  9         *********************************************************** */
 10 
 11 
 12 
 13 /****^  HISTORY COMMENTS:
 14   1) change(1988-05-16,Huen), approve(1988-05-16,MCR7841),
 15      audit(1988-05-25,RWaters), install(1988-07-05,MR12.2-1054):
 16      Fix kermit 15, 16, 17, and 18.
 17   2) change(1989-01-02,Huen), approve(1989-01-02,MCR8027),
 18      audit(1989-01-25,Lee), install(1989-03-01,MR12.3-1020):
 19      Fix kermit bugs: PC_File_Transfer 18, 20, 23, 24.
 20   3) change(1990-09-20,Huen), approve(1990-09-20,MCR8203),
 21      audit(1990-09-25,Gray), install(1990-10-14,MR12.4-1039):
 22      phx21339 (pc_25): Change version to 1.4
 23   4) change(2018-05-26,Anthony), approve(2018-05-26,MCR10049),
 24      audit(2018-05-26,GDixon), install(2018-05-27,MR12.6g-0013):
 25      Bump version number for kermit buffer overrun error fix to 1.5.
 26                                                    END HISTORY COMMENTS */
 27 
 28 
 29 kermit: proc;
 30 
 31   /********************************************************************/
 32   /*                                                                  */
 33   /*n     Name:     kermit                                  external  */
 34   /*i     Input:    multics command line arguments                    */
 35   /*f     Function: sets up the subsystem environment and call ssu_   */
 36   /*f               to execute the kermit requests.                   */
 37   /*o     Ouptut:   none                                              */
 38   /*                                                                  */
 39   /*l     Written:  84-10-12  by Dean Elhard                          */
 40   /*l     Modified: 86-01-16  by Don Kozlowski - Change subsystem     */
 41   /*l                         version to 1.1 . (kermit 13)            */
 42   /*l     Modified: 86-10-09  by Don Kozlowski - Do not set "server"  */
 43   /*l                         and "transfer_modes_set" flags until    */
 44   /*l                         it is in server mode. (kermit 13)       */
 45   /*l     Modified: 86-06-12  by Don Kozlowski - Change subsystem     */
 46   /*l                         version to 1.2 . (kermit 16)            */
 47   /*l     Modified:87-07-22   by Don Kozlowski - Use vfile for debug  */
 48   /*l                         to allow for msf traces (kermit 17)     */
 49   /*l     Modified: 89-01-02  by S. Huen - Change subsystem version   */
 50   /*l                         to 1.3. (PC_18, 20, 23, 24)             */
 51   /*l     Modified: 90-09-24  by S. Huen - Change subsystem version   */
 52   /*l                         to 1.4. (PC_25)                         */
 53   /*                                                                  */
 54   /********************************************************************/
 55 
 56   /* constants */
 57 
 58   dcl true                    bit (1) static options (constant) init ("1"b);
 59   dcl false                   bit (1) static options (constant) init ("0"b);
 60 
 61   dcl Subsystem_Name          char (6) static options (constant)
 62                                    init ("kermit");
 63   dcl Subsystem_Version       char (3) static options (constant)
 64                                    init ("1.5");
 65   dcl Subsystem_Info_Dir      char (168) static options (constant)
 66                                    init (">doc>subsystem>kermit");
 67   dcl Default_prompt          char (29) static options (constant)
 68                                    init ("^/Multics-Kermit^[ (^d)^]:^2x");
 69 
 70   /* procedures */
 71 
 72   dcl com_err_                entry() options(variable);
 73   dcl cu_$arg_count_rel       entry (fixed bin, ptr, fixed bin(35));
 74   dcl cu_$arg_list_ptr        entry (ptr);
 75   dcl cu_$arg_ptr_rel         entry (fixed bin, ptr, fixed bin(21),
 76                                    fixed bin(35), ptr);
 77   dcl expand_pathname_        entry (char(*), char(*), char(*),
 78                                    fixed bin(35));
 79   dcl expand_pathname_$add_suffix
 80                               entry (char(*), char(*), char(*), char(*),
 81                                    fixed bin(35));
 82   dcl get_system_free_area_   entry() returns(ptr);
 83   dcl initiate_file_          entry (char(*), char(*), bit(*), ptr,
 84                                    fixed bin(24), fixed bin(35));
 85   dcl iox_$attach_name        entry (char (*), ptr, char (*), ptr, fixed bin (35));
 86   dcl iox_$close              entry (ptr, fixed bin (35));
 87   dcl iox_$detach_iocb        entry (ptr, fixed bin (35));
 88   dcl iox_$look_iocb          entry (char(*), ptr, fixed bin(35));
 89   dcl iox_$open               entry (ptr, fixed bin, bit (1) aligned, fixed bin (35));
 90   dcl pathname_               entry (char(*), char(*)) returns(char(168));
 91   dcl ssu_$add_request_table  entry (ptr, ptr, fixed bin, fixed bin(35));
 92   dcl ssu_$create_invocation  entry (char(*), char(*), ptr, ptr, char(*),
 93                                    ptr, fixed bin(35));
 94   dcl ssu_$destroy_invocation entry (ptr);
 95   dcl ssu_$execute_start_up   entry () options (variable);
 96   dcl ssu_$execute_string     entry (ptr, char(*), fixed bin(35));
 97   dcl ssu_$get_temp_segment   entry (ptr, char(*), ptr);
 98   dcl ssu_$listen             entry (ptr, ptr, fixed bin(35));
 99   dcl ssu_$release_temp_segment
100                               entry (ptr, ptr);
101   dcl ssu_$set_abbrev_info    entry (ptr, ptr, ptr, bit(1) aligned);
102   dcl ssu_$set_prompt         entry (ptr, char(64) var);
103   dcl ssu_$set_prompt_mode    entry (ptr, bit(*));
104   dcl unique_chars_           entry (bit (*)) returns (char (15));
105 
106   /* external */
107 
108   dcl error_table_$badopt     external fixed bin (35);
109   dcl error_table_$noarg      external fixed bin (35);
110   dcl error_table_$noentry    external fixed bin (35);
111   dcl iox_$user_input         ptr ext static;
112   dcl iox_$user_io            ptr ext static;
113   dcl kermit_requests_$requests
114                               bit(36) aligned external;
115   dcl ssu_et_$subsystem_aborted
116                               external fixed bin (35);
117   dcl ssu_request_tables_$standard_requests
118                               bit(36) aligned external;
119 
120   /* structures */
121 
122   dcl 01 info                 aligned like kermit_info;
123   dcl 01 kermit_args          aligned,
124        02 flags               aligned,
125         03 request_loop       bit (1) unaligned,
126         03 abbrev             bit (1) unaligned,
127         03 prompt             bit (1) unaligned,
128         03 start_up           bit (1) unaligned,
129         03 debug              bit (1) unaligned,
130         03 prompt_given       bit (1) unaligned,
131         03 profile_given      bit (1) unaligned,
132         03 switchname_given   bit (1) unaligned,
133         03 request_given      bit (1) unaligned,
134         03 pad                bit (27) unaligned,
135        02 prompt              char (64) varying,
136        02 profile             char (168),
137        02 switchname          char (32),
138        02 request             char (512) varying,
139        02 debug_path          char (168) unaligned;
140 
141   /* automatic */
142 
143   dcl arg_listp               ptr;
144   dcl ec                      fixed bin (35);
145 
146   /* conditions */
147 
148   dcl cleanup                 condition;
149 
150   /* builtin */
151 
152   dcl addr                    builtin;
153   dcl index                   builtin;
154   dcl null                    builtin;
155 
156   /* include files */
157 
158 %include access_mode_values;
159 ^L
160 %include iox_modes;
161 ^L
162 %include kermit_info;
163 ^L
164 %include kermit_dcls;
165 ^L
166 %include kermit_mode_info;
167 ^L
168 %include ssu_prompt_modes;
169 ^L
170 %include terminate_file;
171 
172 /*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *   */
173 ^L
174 /*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *   */
175 
176 
177   /* initialize the subsystem info structure prior to setting up      */
178   /* the cleanup handlers to free the kermit databases                */
179 
180   info.version = kermit_info_version;
181   info.sci_ptr     = null;
182   info.perm_modesp = null;
183   info.temp_modesp = null;
184   info.log_infop   = null;
185   info.comm_infop  = null;
186 
187   on cleanup call kermit_cleanup (addr (info));
188 
189   /* parse the command line arguments                                 */
190 
191   call cu_$arg_list_ptr (arg_listp);
192 
193   call parse_command_line (arg_listp, addr (kermit_args));
194 
195   /* set up the subsystem invocation                                  */
196 
197   call kermit_initialization (addr (kermit_args), addr (info));
198 
199   /* only enter the request loop if required                          */
200 
201   if kermit_args.request_loop
202     then call ssu_$listen (info.sci_ptr, iox_$user_input, ec);
203 
204   call kermit_cleanup (addr (info));
205 
206   return;
207 
208 /*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *   */
209 ^L
210 /*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *   */
211 
212 
213 parse_command_line: proc (arg_listp, argsp);
214 
215   /********************************************************************/
216   /*                                                                  */
217   /*n     Name:     parse_command_line                      internal  */
218   /*i     Input:    arg_list_ptr                                      */
219   /*f     Function: parses the control arguments detecting illegal    */
220   /*f               control args.                                     */
221   /*f               Legal control arguments are:                      */
222   /*f                  -abbrev, -ab                                   */
223   /*f                         specifies that abbrev processing by the */
224   /*f                         subsystem request processor is to be    */
225   /*f                         initially enabled.                      */
226   /*f                  -debug pathname, -db pathname                  */
227   /*f                         specifies the pathname of a segment in  */
228   /*f                         which to log packet traffic for use in  */
229   /*f                         debugging kermit.                       */
230   /*f                  -io_switch switchname, -iosw switchname        */
231   /*f                         specified the name of the io switch     */
232   /*f                         over which to perform the file          */
233   /*f                         transfer.  If not specified, the users  */
234   /*f                         login channel is used.                  */
235   /*f                  -no_abbrev, -nab                               */
236   /*f                         specified that abbrev processing by the */
237   /*f                         subsystem request processor is to be    */
238   /*f                         initially disabled. (default)           */
239   /*f                  -no_prompt, -npmt                              */
240   /*f                         specified that no prompting is to be    */
241   /*f                         done in the request loop.               */
242   /*f                  -no_start_up, -nsu, -ns                        */
243   /*f                         do not execute the kermit start_up.     */
244   /*f                  -profile pathname, -pf pathname                */
245   /*f                         specifies the name of the profile       */
246   /*f                         segment to be used as the default       */
247   /*f                         profile for abbrev processing.  If this */
248   /*f                         is not specified, the users default     */
249   /*f                         profile is used. NB. -profile implies   */
250   /*f                         -abbrev                                 */
251   /*f                  -prompt prompt_string                          */
252   /*f                         specifies the prompt string to be used. */
253   /*f                  -quit                                          */
254   /*f                         do not enter the subsystem request      */
255   /*f                         loop.  Quit the subsystem after         */
256   /*f                         executing the request_string, if any.   */
257   /*f                  -request request_string, -rq request_string    */
258   /*f                         execute request string as a subsystem   */
259   /*f                         request line entering the subsystem     */
260   /*f                         request loop                            */
261   /*f                  -request_loop, -rql                            */
262   /*f                         enters the subsystem request loop after */
263   /*f                         executing the request_string, if any.   */
264   /*f                         (default)                               */
265   /*f                  -start_up, -su                                 */
266   /*f                         The user's home directory, the project  */
267   /*f                         directory, and >site are searched in    */
268   /*f                         that order for a segment named          */
269   /*f                         start_up.kermit.  (default)             */
270   /*o     Output:   request_string, quit_flag, abbrev_flag,           */
271   /*o               profile_path, start_up_flag, debug_flag,          */
272   /*o               debug_path, switchname                            */
273   /*                                                                  */
274   /*l     Written:  84-10-12  by Dean Elhard                          */
275   /*l     Modified: 84-11-01  by Dean Elhard to trap missing request, */
276   /*l                         prompt, profile, and switchname strings */
277   /*l                         embedded in the arg list.               */
278   /*l     Modified: 84-11-08  to add -start_up and -no_start_up       */
279   /*l     Modified: 84-11-15  to add -debug                           */
280   /*                                                                  */
281   /********************************************************************/
282 
283   /* arguments */
284 
285   dcl arg_listp               ptr;
286   dcl argsp                   ptr;
287 
288   /* structures */
289 
290   dcl 01 args                 aligned like kermit_args based (argsp);
291 
292   /* based */
293 
294   dcl arg                     char (argl) based (argp);
295 
296   /* automatic */
297 
298   dcl argl                    fixed bin (21);
299   dcl argp                    ptr;
300   dcl debug_pending           bit (1);
301   dcl ec                      fixed bin (35);
302   dcl i                       fixed bin;
303   dcl nargs                   fixed bin;
304   dcl profile_pending         bit (1);
305   dcl prompt_pending          bit (1);
306   dcl request_pending         bit (1);
307   dcl switchname_pending      bit (1);
308 
309   /* initialize state to default before starting parse                */
310 
311   args.flags.request_loop     = true;
312   args.flags.abbrev           = false;
313   args.flags.prompt           = true;
314   args.flags.start_up         = true;
315   args.flags.debug            = false;
316   args.flags.prompt_given     = false;
317   args.flags.profile_given    = false;
318   args.flags.switchname_given = false;
319   args.flags.request_given    = false;
320   args.prompt                 = "";
321   args.profile                = "";
322   args.switchname             = "";
323   args.request                = "";
324   args.debug_path             = "";
325 
326   profile_pending             = false;
327   prompt_pending              = false;
328   request_pending             = false;
329   switchname_pending          = false;
330   debug_pending               = false;
331 
332   /* get the arg count                                                */
333 
334   call cu_$arg_count_rel (nargs, arg_listp, ec);
335   if ec ^= 0
336     then call abort (ec, "");
337 
338   do i = 1 to nargs;
339 
340     call cu_$arg_ptr_rel (i, argp, argl, ec, arg_listp);
341     if ec ^= 0
342       then call abort (ec, "");
343 
344   /* get the prompt text if the previous arg was -prompt              */
345 
346     if prompt_pending
347       then do;
348         if index (arg, "-") = 1
349           then call abort (error_table_$noarg, "Prompt string expected.");
350         prompt_pending = false;
351         args.flags.prompt_given = true;
352         args.prompt = arg;
353       end;
354 
355   /* get the profile pathname if the previous arg was -profile        */
356 
357     else if profile_pending
358       then do;
359         if index (arg, "-") = 1
360           then call abort (error_table_$noarg, "Profile pathname expected.");
361         profile_pending = false;
362         args.flags.profile_given = true;
363         args.flags.abbrev = true;
364         args.profile = arg;
365       end;
366 
367   /* get the request string if the previous arg was -request          */
368 
369     else if request_pending
370       then do;
371         if index (arg, "-") = 1
372           then call abort (error_table_$noarg, "Request expected.");
373         request_pending = false;
374         args.flags.request_given = true;
375         args.request = arg;
376       end;
377 
378   /* get the switchname if the previous arg was -io_switch            */
379 
380     else if switchname_pending
381       then do;
382         if index (arg, "-") = 1
383           then call abort (error_table_$noarg, "Switch name expected.");
384         switchname_pending = false;
385         args.flags.switchname_given = true;
386         args.switchname = arg;
387       end;
388 
389   /* get the debug pathname if the previous are was -debug            */
390 
391     else if debug_pending
392       then do;
393         if index (arg, "-") = 1
394           then call abort (error_table_$noarg, "Debug pathname expected.");
395         debug_pending = false;
396         args.flags.debug = true;
397         args.debug_path = arg;
398       end;
399 
400   /* enable abbrev processing                                         */
401 
402     else if arg = "-abbrev" | arg = "-ab"
403       then args.flags.abbrev = true;
404 
405   /* flag that the next arg should be a debug segment path            */
406 
407     else if arg = "-debug" | arg = "-db"
408       then debug_pending = true;
409 
410   /* flag that the next arg should be a switchname                    */
411 
412     else if arg = "-io_switch" | arg = "-iosw"
413       then switchname_pending = true;
414 
415   /* disable abbrev processing                                        */
416 
417     else if arg = "-no_abbrev" | arg = "-nab"
418       then args.flags.abbrev = false;
419 
420   /* disable subsystem prompting                                      */
421 
422     else if arg = "-no_prompt" | arg = "-npmt"
423       then args.flags.prompt = false;
424 
425   /* disable start_up.kermit execution                                */
426 
427     else if arg = "-no_start_up" | arg = "-nsu" | arg = "-ns"
428       then args.flags.start_up = false;
429 
430   /* flag that the next arg should be a profile pathname              */
431 
432     else if arg = "-profile" | arg = "-pfl"
433       then profile_pending = true;
434 
435   /* flag that the next arg should be a prompt string                 */
436 
437     else if arg = "-prompt" | arg = "-pmt"
438       then prompt_pending = true;
439 
440   /* disable request loop entry after processing the request str      */
441 
442     else if arg = "-quit" | arg = "-no_request_loop" | arg = "-nrql"
443       then args.flags.request_loop = false;
444 
445   /* flag that the next arg should be a request string                */
446 
447     else if arg = "-request" | arg = "-rq"
448       then request_pending = true;
449 
450   /* enable request loop entry after request processing               */
451 
452     else if arg = "-request_loop" | arg = "-rql"
453       then args.flags.request_loop = true;
454 
455   /* enable start_up.kermit execution                                 */
456 
457     else if arg = "-start_up" | arg = "-su"
458       then args.flags.start_up = true;
459 
460   /* otherwise complain since that is all the valid args              */
461 
462       else call abort (error_table_$badopt, arg);
463   end;
464 
465   /* if there were any supplementary args outstanding when we ran out */
466   /* of command line arguments, complain and abort the subsystem      */
467 
468   if request_pending
469     then call abort (error_table_$noarg, "Request expected.");
470   if profile_pending
471     then call abort (error_table_$noarg, "Profile pathname expected.");
472   if switchname_pending
473     then call abort (error_table_$noarg, "Switch name expected.");
474   if prompt_pending
475     then call abort (error_table_$noarg, "Prompt string expected.");
476   if debug_pending
477     then call abort (error_table_$noarg, "Debug path expected.");
478 
479 end parse_command_line;
480 
481 /*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *   */
482 ^L
483 /*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *   */
484 
485 
486 kermit_initialization: proc (argsp, infop);
487 
488   /********************************************************************/
489   /*                                                                  */
490   /*n     Name:     kermit_initialization                   internal  */
491   /*i     Input:    arg_info, info_ptr                                */
492   /*f     Function: initializes the subsystem_info structure, creates */
493   /*f               an ssu_ invocation, initializes the profile and   */
494   /*f               abbrev state depending on the abbrev_flag and     */
495   /*f               profile_path, and calls the ssu_ request          */
496   /*f               processor to execute the request_string.          */
497   /*o     Output:   none                                              */
498   /*                                                                  */
499   /*l     Written:  84-10-12  by Dean Elhard                          */
500   /*l     Modified: 84-11-01  by Dean Elhard to null iocbp in         */
501   /*l                         log_info immediately to reduce cleanup  */
502   /*l                         error window                            */
503   /*l     Modified: 84-11-08  by Dean Elhard to execute start_up      */
504   /*                                                                  */
505   /********************************************************************/
506 
507   /* arguments */
508 
509   dcl argsp                   ptr;
510   dcl infop                   ptr;
511 
512   /* based */
513 
514   dcl 01 args                 aligned like kermit_args based (argsp);
515   dcl 01 info                 aligned like kermit_info based (infop);
516   dcl 01 log_info             aligned like kermit_log_info
517                                    based (info.log_infop);
518   dcl 01 perm_modes           aligned like kermit_perm_modes
519                                    based (info.perm_modesp);
520   dcl 01 temp_modes           aligned like kermit_temp_modes
521                                    based (info.temp_modesp);
522   dcl 01 comm_info            aligned like kermit_comm_info
523                                    based (info.comm_infop);
524   dcl sys_area                area based (system_free_areap);
525 
526   /* automatic */
527 
528   dcl dname                   char (168);
529   dcl ec                      fixed bin (35);
530   dcl ename                   char (32);
531   dcl system_free_areap       ptr;
532   dcl profile_ptr             ptr;
533   dcl prompt_mode             bit (2);
534 
535   /* get the area to allocate the databases in                        */
536 
537   system_free_areap = get_system_free_area_ ();
538 
539   /* allocate the databases and set the version numbers               */
540 
541   allocate log_info in (sys_area);
542 
543   /* null iocb pointer to minimize error window                       */
544 
545   log_info.log_file.iocbp = null;
546   log_info.version = kermit_log_info_version;
547 
548   allocate perm_modes in (sys_area);
549   perm_modes.version = kermit_perm_modes_version;
550 
551   allocate temp_modes in (sys_area);
552   temp_modes.version = kermit_temp_modes_version;
553 
554   allocate comm_info in (sys_area);
555 
556   /* null input_buffer pointer to minimize error window               */
557 
558   comm_info.input_buffer.bufferp = null;
559   comm_info.debug_segp = null;
560   comm_info.version = kermit_comm_info_version;
561   comm_info.server = "0"b;             /* Initialize server flag      */
562   comm_info.transfer_modes_set = "0"b; /* Initialize transfer_modes_set flag */
563 
564   /* now create the ssu_ invocation                                   */
565 
566   call ssu_$create_invocation (Subsystem_Name, Subsystem_Version, infop,
567                     addr (ssu_request_tables_$standard_requests),
568                     Subsystem_Info_Dir, info.sci_ptr, ec);
569 
570   if ec ^= 0
571     then call abort (ec, "Unable to create subsystem invocation.");
572 
573   /* add our request table to the subsystem                           */
574 
575   call ssu_$add_request_table (info.sci_ptr, addr (kermit_requests_$requests),
576                     1, ec);
577 
578   /* set the prompt string if required and set up the prompt mode     */
579 
580   if ^args.flags.prompt_given
581     then args.prompt = Default_prompt;
582 
583   call ssu_$set_prompt (info.sci_ptr, args.prompt);
584 
585   if args.flags.prompt
586     then prompt_mode = PROMPT | PROMPT_AFTER_NULL_LINES;
587     else prompt_mode = DONT_PROMPT | PROMPT_AFTER_NULL_LINES;
588 
589   call ssu_$set_prompt_mode (info.sci_ptr, prompt_mode);
590 
591   /* find the profile if a non-standard profile was requested         */
592 
593   if args.flags.profile_given
594     then do;
595       call expand_pathname_$add_suffix ((args.profile), "profile", dname,
596                                         ename, ec);
597       if ec ^= 0
598         then call abort (ec, (args.profile));
599       call initiate_file_ (dname, ename, R_ACCESS, profile_ptr, (0), ec);
600       if profile_ptr = null
601         then if ec = error_table_$noentry
602           then call com_err_ (ec, Subsystem_Name, "^/^a does not exist.",
603                     pathname_ (dname, ename));
604           else call abort (ec, (args.profile));
605     end;
606     else profile_ptr = null;
607 
608   /* set the abbrev info regarding the profile use and initial state  */
609 
610   call ssu_$set_abbrev_info (info.sci_ptr, profile_ptr, profile_ptr,
611                     (args.flags.abbrev));
612 
613   /* if a switch was supplied, then make sure it exists and save      */
614   /* the iocb pointer for use by the communications stuff             */
615 
616   if args.flags.switchname_given
617     then do;
618       call iox_$look_iocb ((args.switchname), comm_info.ft_iocbp, ec);
619       if ec ^= 0
620         then call abort (ec, (args.switchname));
621     end;
622     else comm_info.ft_iocbp = iox_$user_io;
623 
624   /* set the default modes in the permanent and temporary modes dbs   */
625 
626   call kermit_mode_mgr_$store (infop, Permanent, Store_all,
627                               addr (Perm_defaults), ec);
628   call kermit_mode_mgr_$store (infop, Temporary, Store_all,
629                               addr (Temp_defaults), ec);
630 
631   /* set up the initial logging state                                 */
632 
633   log_info.flags.enabled = false;
634   log_info.flags.stats_valid = false;
635 
636   /* get a temp-seg for use as an input buffer                        */
637 
638   call ssu_$get_temp_segment (info.sci_ptr, "buffer", comm_info.bufferp);
639 
640   /* set up the rest of the communications status info                */
641 
642   comm_info.bufferl = 0;
643   comm_info.old_modes = "";
644   comm_info.old_framing_chars.start_char = "^@";
645   comm_info.old_framing_chars.end_char = "^@";
646   comm_info.old_wake_table.breaks (*) = false;
647   comm_info.old_wake_table.mbz = ""b;
648 
649   /* set up the debug file if necessary                               */
650 
651   if args.flags.debug
652     then do;
653       call expand_pathname_ (args.debug_path, dname, ename, ec);
654       if ec ^= 0
655         then call abort (ec, args.debug_path);
656       call iox_$attach_name ("kermit.debug." || unique_chars_ ("0"b),
657                comm_info.debug_segp, "vfile_ " || pathname_ (dname, ename),
658                null(), ec);
659           call iox_$open (comm_info.debug_segp, Stream_output, "0"b, ec);
660       if ec ^= 0
661         then call abort (ec, pathname_ (dname, ename));
662     end;
663 
664   /* execute the start_up if requested                                */
665 
666   if args.flags.start_up
667     then do;
668       call ssu_$execute_start_up (info.sci_ptr, ec);
669       if ec = ssu_et_$subsystem_aborted
670         then call abort (ec, "^/Abort occurred while executing start_up.");
671     end;
672 
673   /* lastly, execute the request string (if any)                      */
674 
675   if args.flags.request_given
676     then do;
677       call ssu_$execute_string (info.sci_ptr, (args.request), ec);
678       if ec = ssu_et_$subsystem_aborted
679         then args.request_loop = false;
680     end;
681 
682 end kermit_initialization;
683 
684 /*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *   */
685 ^L
686 /*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *   */
687 
688 
689 kermit_cleanup: proc (infop);
690 
691   /********************************************************************/
692   /*                                                                  */
693   /*n     Name:     kermit_cleanup                          internal  */
694   /*i     Input:    subsystem_info_ptr                                */
695   /*f     Function: frees the subsystem_info structure and destroys   */
696   /*f               the ssu_ invocation                               */
697   /*o     Output:   none                                              */
698   /*                                                                  */
699   /*l     Written:  84-10-12  by Dean Elhard                          */
700   /*l     Modified: 84-11-01  by Dean Elhard to close log_file on     */
701   /*l                         cleanup if open.                        */
702   /*                                                                  */
703   /********************************************************************/
704 
705   /* arguments */
706 
707   dcl infop                   ptr;
708 
709   /* structures */
710 
711   dcl 01 comm_info            aligned like kermit_comm_info
712                                    based (info.comm_infop);
713   dcl 01 info                 aligned like kermit_info based (infop);
714   dcl 01 log_info             aligned like kermit_log_info
715                                    based (info.log_infop);
716   dcl 01 perm_modes           aligned like kermit_perm_modes
717                                    based (info.perm_modesp);
718   dcl sys_area                area based (system_free_areap);
719   dcl 01 temp_modes           aligned like kermit_temp_modes
720                                    based (info.temp_modesp);
721 
722   /* automatic */
723 
724   dcl system_free_areap       ptr;
725 
726   /* find the area to free the stuff into                             */
727 
728   system_free_areap = get_system_free_area_ ();
729 
730   /* free each of the databases                                       */
731 
732   if info.comm_infop ^= null
733     then do;
734 
735   /* free the input buffer temp-seg                                   */
736 
737       if comm_info.input_buffer.bufferp ^= null
738         then call ssu_$release_temp_segment (info.sci_ptr,
739                               comm_info.input_buffer.bufferp);
740 
741   /* terminate and set the bit_count on the debug file                */
742 
743       if comm_info.debug_segp ^= null
744         then do;
745            call iox_$close (comm_info.debug_segp, ec);
746            call iox_$detach_iocb (comm_info.debug_segp, ec);
747         end;
748 
749   /* and then free the communications database                        */
750 
751       free comm_info in (sys_area);
752     end;
753 
754   if info.perm_modesp ^= null
755     then free perm_modes in (sys_area);
756   if info.temp_modesp ^= null
757     then free temp_modes in (sys_area);
758   if info.log_infop ^= null
759     then do;
760 
761   /* close and detach the log_file                                    */
762 
763       call kermit_log_mgr_$disable (infop, ec);
764       call kermit_log_mgr_$close_log (infop, ec);
765 
766   /* free the log_info database                                       */
767 
768       free log_info in (sys_area);
769     end;
770 
771   /* lastly, destroy the ssu_ invocation                              */
772 
773   if info.sci_ptr ^= null
774     then call ssu_$destroy_invocation (info.sci_ptr);
775 
776 end kermit_cleanup;
777 
778 /*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *   */
779 ^L
780 /*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *   */
781 
782 
783 abort: proc (code, message);
784 
785   /********************************************************************/
786   /*                                                                  */
787   /*n     Name:     abort                                   internal  */
788   /*i     Input:    error_code, message                               */
789   /*f     Function: prints a message constructed from the error code  */
790   /*f               and message and then aborts the subsystem         */
791   /*o     Output:   none                                              */
792   /*                                                                  */
793   /*l     Written:  84-10-14  by Dean Elhard                          */
794   /*                                                                  */
795   /********************************************************************/
796 
797   /* parameters */
798 
799   dcl code                    fixed bin (35);
800   dcl message                 char (*);
801 
802   /* cleanup the subsystem before we leave                            */
803 
804   call kermit_cleanup (addr (info));
805 
806   call com_err_ (code, Subsystem_Name, message);
807   goto ABORT;
808 
809 end abort;
810 
811 ABORT:
812   return;
813 
814 end kermit;