1 /* ********************************************
  2    *                                          *
  3    * Copyright, (C) Honeywell Bull Inc., 1987 *
  4    *                                          *
  5    ******************************************** */
  6 
  7 /* HISTORY COMMENTS:
  8   1) change(86-10-31,Rohs), approve(87-07-13,MCR7580), audit(87-07-13,Leskiw),
  9      install(87-08-07,MR12.1-1072):
 10      Created.
 11   2) change(87-10-04,Flegel), approve(87-10-04,MCR7787),
 12      audit(88-01-26,DGHowe), install(88-02-24,MR12.2-1028):
 13      Implemented multiple queue entry strategy with Multics as the controller.
 14                                                    END HISTORY COMMENTS */
 15 
 16 /* COMPILER: Lattice C, V2.15 */
 17 
 18 /**************************************************************
 19 
 20      SUBRS.C
 21 
 22      This file contains the various support routines for BFT.
 23 
 24 ***************************************************************/
 25 
 26 #include <stdio.h>
 27 #include <dos.h>
 28 #include <mowse.h>
 29 #include <bft.h>
 30 
 31 /* DOS Function calls */
 32 
 33 #define DOS_GET_DRIVE     0x1900               /* Get current drive */
 34 #define DEFAULT_DRIVE     0x4700               /* Default drive mask */
 35 
 36 /* Masks */
 37 
 38 #define CHAR_MASK         0xFF                 /* Zero non-char bits */
 39 
 40 /*^L*/
 41 /***************************************************************
 42 
 43      ADDTOKEN
 44 
 45      PARAMETERS: ARGLIST   - a pointer to a string into which the token is
 46                              to be placed. (input,output)
 47                  ARGLEN    - current length of arg string. If 0, then assume
 48                              NULL terminated.  (input)
 49                  TOKEN     - a pointer to a string in which the input token
 50                              resides. (input)
 51                  TOKEN_LEN - length of token.  If 0, then assume NULL
 52                              terminated.  (input)
 53 
 54      FUNCTION:   Places a token at the end of the arglist followed by
 55                  the DELIMITER character and returns the length of the
 56                  arglist.
 57 
 58 ***************************************************************/
 59 
 60 addtoken (p_arglist, p_arg_len, p_token, p_token_len)
 61 
 62 char *p_arglist;       /* pointer to string to add the token to */
 63 int  p_arg_len;        /* length of arg_list */
 64 char *p_token;         /* pointer string where token is placed */
 65 int  p_token_len;      /* length of token */
 66 {
 67 int arg_pos;           /* append position in arg_list */
 68 int token_len;         /* actual length of token */
 69 int i;
 70 
 71 /* Determine actual lengths */
 72 
 73   arg_pos = (p_arg_len > 0) ? p_arg_len : strlen (p_arglist);
 74   token_len = (p_token_len > 0) ? p_token_len : strlen (p_token);
 75 
 76 /* Append the token to the arg_list */
 77 
 78   for (i = 0; i < token_len; i++, arg_pos++)
 79     p_arglist[arg_pos] = p_token[i];
 80 
 81 /* Append the delimeter */
 82 
 83   for (i = 0; i < strlen (DELIMITER); i++, arg_pos++)
 84     p_arglist[arg_pos] = DELIMITER[i];
 85   p_arglist[arg_pos] = 0;
 86 
 87 /* Return the next position */
 88 
 89   return (arg_pos);
 90 }
 91 /*^L*/
 92 /***************************************************************
 93 
 94      BFTCAN
 95 
 96      PARAMETERS: ID    - request identifier of cancellation
 97                        - either PATH or ID
 98                  ID_SW - PATH_ID || TIME_ID || ENTRY_ID
 99 
100      FUNCTION:   Performs the call to execute capability for
101                  the cancel command.
102 
103 *****************************************************************/
104 
105 bftcan (p_id_sw, p_id)
106 
107 int  p_id_sw;                           /* ID Type */
108 char *p_id;                             /* ID string */
109 {
110 char arg_string[MAXARGSTRING];          /* Message */
111 int  arg_len;                           /* Message length */
112 char token[PATHNAMESIZE];               /* Message portion */
113 char id_sw;                             /* Character version of ID type */
114 
115 /* Verify the request id type */
116 
117   id_sw = (char)p_id_sw;
118   if (!((id_sw == BFT_PATH_ID) || (id_sw == BFT_TIME_ID) || (id_sw == BFT_ENTRY_ID)))
119     return (BFT_BAD_REQUEST_ID);
120 
121 /* If the request type is a path, then expand the pathname */
122 
123   strncpy (token, p_id, PATHNAMESIZE);
124   if (id_sw == BFT_PATH_ID)
125     getpath (token);
126 
127 /* make the arglist for the cancel operation: ID; */
128 
129   arg_string[0] = 0;
130   arg_len = 0;
131   arg_len = addtoken (arg_string, arg_len, &id_sw, 1);
132   arg_len = addtoken (arg_string, arg_len, token, 0);
133 
134 /* execute the CANCEL_REQUEST capability */
135 
136   return (execute (CANCEL_REQUEST, WSREMOTE, arg_string, arg_len));
137 }
138 /*^L*/
139 /***************************************************************
140 
141      BFTFETCH
142 
143      PARAMETERS: MU_PATH  - source file name (input)
144                  PC_PATH  - destination file name (input)
145                  FLAGS    - transfer modes
146                  PRIORITY - transfer priority
147 
148      FUNCTION:   Performs the call to execute capability for
149                  the fetch command.
150 
151 *****************************************************************/
152 
153 bftfetch (p_mu_path, p_pc_path, p_flags, p_priority)
154 
155 char *p_mu_path;                      /* source file name */
156 char *p_pc_path;                      /* destination file name */
157 long p_flags;                         /* Transfer modes */
158 int  p_priority;                      /* Transfer priority */
159 {
160 char arg_string[MAXARGSTRING];        /* holds arguments to be passed to execap  */
161 int  arg_len;                         /* length of the argument string */
162 char priority;                        /* Character representation of priority */
163 char flags[4];                        /* Character representation of flags */
164 char full_path[PATHNAMESIZE];         /* PC full pathname */
165 int  i;
166 int  j;
167 
168 
169 /* Verify the priority level */
170 
171   if ((p_priority < BFT_MIN_PRIORITY) || (p_priority > BFT_MAX_PRIORITY))
172      return (BFT_INVALID_PRIORITY);
173 
174   priority = (char) p_priority;
175   long2char (flags, &p_flags);
176 
177 /* Expand the PC path to an absolute */
178 
179   strncpy (full_path, p_pc_path, PATHNAMESIZE);
180   getpath (full_path);
181 
182 /* make the arglist for the fetch operation: MU_PATH;PC_PATH;FLAGS;PRIORITY */
183 
184   arg_string[0] = 0;
185   arg_len = 0;
186   arg_len = addtoken (arg_string, arg_len, p_mu_path, 0);
187   arg_len = addtoken (arg_string, arg_len, full_path, 0);
188   arg_len = addtoken (arg_string, arg_len, flags, 4);
189   arg_len = addtoken (arg_string, arg_len, &priority, 1);
190 
191 /* execute the ADD_TO_STORE_QUEUE capability (store is in respect to Multics) */
192 
193   return (execute (ADD_TO_STORE_QUEUE, WSREMOTE, arg_string, arg_len));
194 }
195 /*^L*/
196 /***************************************************************
197 
198      BFTRECFE
199 
200      PARAMETERS: None.
201 
202      FUNCTION:   Performs the call to execute capability for
203                  the recover fetch command.
204 
205 *****************************************************************/
206 
207 bftrecfe ()
208 {
209 
210 /* execute the RECOVER_STORE capability to recover PC_to_MULTICS transfers */
211 
212   return (execute (REC_STORE, WSREMOTE, NULL, 0));
213 }
214 /*^L*/
215 /***************************************************************
216 
217      BFTRECST
218 
219      PARAMETERS: none.
220 
221      FUNCTION:   Performs the call to execute capability for
222                  the recover store command.
223 
224 *****************************************************************/
225 
226 bftrecst ()
227 {
228 
229 /* execute the RECOVER_FETCH capability to recover MULTICS_to_PC transfers */
230 
231   return (execute (REC_FETCH, WSREMOTE, NULL, 0));
232 }
233 /*^L*/
234 /***************************************************************
235 
236      BFTSTORE
237 
238      PARAMETERS: PC_PATH  - source file name (input)
239                  MU_PATH  - destination file name (input)
240                  FLAGS    - transfer modes
241                  PRIORITY - transfer priority
242 
243      FUNCTION:   Performs the call to execute capability for
244                  the store command.
245 
246 *****************************************************************/
247 
248 bftstore (p_pc_path, p_mu_path, p_flags, p_priority)
249 
250 char *p_pc_path;                      /* source file name */
251 char *p_mu_path;                      /* destination file name */
252 long p_flags;                         /* Transfer modes */
253 int  p_priority;                      /* Transfer priority */
254 {
255 char arg_string[MAXARGSTRING];        /* holds arguments to be passed to execap  */
256 int  arg_len;                         /* length of the argument string */
257 char priority;                        /* Character representation of priority */
258 char flags[4];                        /* Character representation of flags */
259 char full_path[PATHNAMESIZE];         /* PC full pathname */
260 int  i;
261 int  j;
262 
263 
264 /* Verify the priority level */
265 
266   if ((p_priority < BFT_MIN_PRIORITY) || (p_priority > BFT_MAX_PRIORITY))
267      return (BFT_INVALID_PRIORITY);
268 
269   priority = (char) p_priority;
270   long2char (flags, &p_flags);
271 
272 /* Expand the PC path to an absolute */
273 
274   strncpy (full_path, p_pc_path, PATHNAMESIZE);
275   getpath (full_path);
276 
277 /* make the arglist for the fetch operation */
278 
279   arg_string[0] = 0;
280   arg_len = 0;
281   arg_len = addtoken (arg_string, arg_len, p_mu_path, 0);
282   arg_len = addtoken (arg_string, arg_len, full_path, 0);
283   arg_len = addtoken (arg_string, arg_len, flags, 4);
284   arg_len = addtoken (arg_string, arg_len, &priority, 1);
285 
286 /* execute the ADD_TO_FETCH_QUEUE capability (fetch is in respect to Multics) */
287 
288   return (execute (ADD_TO_FETCH_QUEUE, WSREMOTE, arg_string, arg_len));
289 }
290 /*^L*/
291 /***************************************************************
292 
293      BFTUNLD
294 
295      PARAMETERS: none
296 
297      FUNCTION:   Unloads BFT from the PC
298 
299 *****************************************************************/
300 
301 bftunld ()
302 {
303 
304 /* execute the BFT_SHUT_DOWN capability */
305 
306   return (execute (BFT_SHUT_DOWN, WSLOCAL, NULL, 0));
307 }
308 /* ^L */
309 /*******************************************************************
310 
311      EXECUTE
312 
313      PARAMETERS: MINOR      - Minor capability number to execute
314                  SYSTEM     - the system of the capability
315                  ARG_STRING - The arguments passed to the minor
316                  ARG_LEN    - The length of the argument string
317 
318      FUNCTION:   Executes the specified minor capability on the
319                  remote system with the specified arguments.
320 
321 **********************************************************************/
322 
323 execute (p_minor,p_system,p_arg_string,p_arg_len)
324 
325 int  p_minor;                  /* minor capability number to call */
326 int  p_system;                 /* system to execute on */
327 char p_arg_string[];           /* string containing the arguments */
328 int  p_arg_len;                /* length of the arg string */
329 {
330 mcb *mcb_ptr;                  /* pointer to the mowse control block */
331 int bftarghandler();
332 int majnum;
333 int bft_major;
334 int code;
335 
336 /* Find the appropriate bft capability */
337 
338   bft_major = 0;
339   if (p_system = WSLOCAL)
340   {
341     if ((code = findnumb ("BFT", WSLOCAL, &bft_major)) != 0)
342       return (code);
343   }
344   else
345   {
346     if ((code = findnumb ("bft_main_", WSREMOTE, &bft_major)) != 0)
347       return (code);
348   }
349 
350 /* create the bft arg analyser instance */
351 
352   if ((code = cretinst ("BFT_ARG", bftarghandler, MAXARGSTRING, MAXARGSTRING, 0, &mcb_ptr)) != 0)
353     return (code);
354 
355 /* check to see if BFT_ARG is on the local system */
356 
357   majnum = 0;
358   if ((code = findnumb ("BFT_ARG", WSLOCAL, &majnum)) != 0)
359   {
360     destinst (&mcb_ptr);
361     return (code);
362   }
363 
364 /* execute the capability */
365 
366   if ((code = execap (bft_major, p_minor, p_arg_string, p_arg_len, mcb_ptr)) != 0)
367   {
368     destinst (&mcb_ptr);
369     return (code);
370   }
371 
372   destinst (&mcb_ptr);
373   return (0);
374 }
375 /*^L*/
376 /************************************************************
377 
378      BFTARGHANDLER
379 
380      PARAMETERS: none.
381 
382      FUNCTION:   This is the internal minor capability handler
383                  for the BFT argument capability.  It is a NULL
384                  routine as nothing is expected of it.
385 
386 *************************************************************/
387 
388 bftarghandler ()
389 {
390 }
391 /* ^L */
392 /********************************************************************
393 
394      CHAR2LONG
395 
396      PARAMETERS: STRING - character string with long in it.
397                  FLAGS  - long to be coppied into.
398 
399      FUNCTION:   Copy the 4 character string into a long.
400 
401 **********************************************************************/
402 
403 char2long (p_string, p_flags)
404 
405 char *p_string;
406 long *p_flags;
407 {
408 int  i;
409 int  j;
410 char *flags_ptr;
411 
412 /* Copy into flags; NOTE that the characters must be coppied in backwards
413    as the HIGH character is the LEAST significant */
414 
415   flags_ptr = (char *)(p_flags);
416   for (i = 0, j = 3; i < 4; i++, j--)
417     flags_ptr[j] = p_string[i];
418 }
419 /*^L*/
420 /***********************************************************
421 
422      NAME:       GETPATH
423 
424      PARAMETERS: RELPATH- A pointer to a string which
425                           contains the relative pathname
426                           (input,output)
427 
428      FUNCTION:   Expands the relative pathname into an
429                  absolute pathname.
430 *************************************************************/
431 
432 getpath (relpath)
433 char *relpath;                            /* relative pathname to be made absolute */
434 {
435 union REGS inregs;                        /* input registers for DOS calls  */
436 union REGS outregs;                       /* output registers for DOS calls */
437 char abspath[PATHNAMESIZE+ENTRYNAMESIZE]; /* absolute pathname */
438 char tok[PATHNAMESIZE];                   /* token parsed out of the relative path */
439 char *parseptr;                           /* pointer to path while parsing */
440 char *stptok();                           /* token stripping routine */
441 int  relindex;                            /* pointer to characters in the pathname */
442 
443 
444 /* Set the drive spec */
445 
446   if (relpath[1] != ':')
447   {
448     relindex = 0;
449     inregs.x.dx = 0;
450     inregs.x.ax = DOS_GET_DRIVE;
451     intdos (&inregs,&outregs);
452     abspath[0] = (char) ((outregs.x.ax & CHAR_MASK)+ (int)'A');
453     abspath[1] = ':';
454   }
455   else
456   {
457     strncpy(abspath,relpath,2);
458     outregs.x.ax = toupper(relpath[0]) - (int)'A';
459     relindex=2;
460   }
461 
462 /* set the pathname, user may have already given an absolute one */
463 
464   if (relpath[relindex]=='\\')
465     strcpy (abspath+2,&relpath[relindex]);
466 
467   else
468   {
469 
470 /* Set the absolute path to the current working dir */
471 
472     abspath[2] = '\\';
473     inregs.x.dx = (outregs.x.ax & CHAR_MASK) + 1;
474     inregs.x.ax = DEFAULT_DRIVE;
475     inregs.x.si = (short) (&abspath[3]);
476     intdos (&inregs,&outregs);
477 
478 /* Traverse each name in the relative path figuring out what to do with the absolute path */
479 
480     parseptr = &(relpath[relindex]);
481     while ((parseptr < (relpath + strlen (relpath)))&&(strlen (abspath) < PATHNAMESIZE))
482     {
483       parseptr = stptok (parseptr, tok, PATHNAMESIZE, "\\") + 1;
484 
485 /* if the token is not ".." then tack the dir to the end of the abspath, else back up */
486 
487       if (strcmp (tok, ".."))
488       {
489         if (abspath[strlen (abspath) - 1] != '\\')
490           strcat (abspath, "\\");
491 
492         strncat (abspath, tok, strlen(tok));
493       }
494       else
495       {
496         relindex = strlen(abspath) - 1;
497         while ((abspath[--relindex] != '\\')&&(relindex != 2));
498         abspath[relindex]=0;
499       }
500     }
501   }
502 
503 /* make the pathname uppercase */
504 
505   for (relindex = 0; relindex < strlen (abspath); abspath[relindex] = toupper(abspath[relindex++]));
506 
507 /* copy the absolute path back to the relative path for return */
508 
509   strncpy (relpath, abspath, PATHNAMESIZE);
510 }
511 /*^L*/
512 /***********************************************************
513 
514      LONG2CHAR
515 
516      PARAMETERS: STRING - character string to put into.
517                  NUM    - long to copy
518 
519      FUNCTION:   Copy into num into string, NOTE that the
520                  characters must be coppied in backwards
521                  as the HIGH character is the LEAST significant.
522 
523 *************************************************************/
524 
525 long2char (p_string, p_num)
526 
527 char *p_string;
528 long *p_num;
529 {
530 char *num_ptr;
531 int  i;
532 int  j;
533 
534   num_ptr = (char *)(p_num);
535   for (i = 0, j = 3; i < 4; i++, j--)
536     p_string[i] = num_ptr[j];
537 }
538 /*^L*/
539 /***********************************************************
540      NAME:       STRIPQUOTE
541 
542      PARAMETERS: STRING - a pointer to a string from which
543                           the quotes are to be stripped
544                           (input)
545 
546      FUNCTION:   If there are leading and trailing quotes
547                  on a string then they are removed and a pointer to
548                  the new string is returned.
549 *************************************************************/
550 
551 char *stripquote (string)
552 
553 char *string;                         /* input string */
554 {
555 char tempstr[PATHNAMESIZE];           /* temporary string */
556 
557 /* if there are leading and trailing quotes then remove them */
558 
559   if (string[0]=='"' && string[strlen(string)-1]=='"')
560   {
561     strcpy (tempstr,string);
562     strncpy(string,tempstr+1,strlen(tempstr)-2);
563   }
564 
565   return(string);
566 }
567 /*^L*/
568 /***********************************************************
569 
570      STRIPTOK
571 
572      PARAMETERS: STRING - a pointer to a string from which
573                           the token is to be parsed from.
574                           (input)
575                  TOKEN  - a pointer to a string in which the
576                           parsed token is placed. (output)
577 
578      FUNCTION:   Gets the next token out of a string (which
579                  is separated by the DELIMITER character) and
580                  returns a pointer to the character after the
581                  delimiter.
582 
583 *************************************************************/
584 
585 char *striptok (string, token)
586 
587 char *string;                         /* input string */
588 char *token;                          /* string where token is placed */
589 {
590 int i;                                /* counter variable */
591 
592 /* find position of delimiter in the source string */
593 
594   for (i = 0; string[i] != DELIMITER[0]; i++)
595     token[i] = string[i];
596 
597   token[i] = 0;
598 
599 /* return the address of the character after the delimiter */
600 
601   return (string + i + 1);
602 }
603 /*^L*/
604 /***********************************************************
605 
606      SYSTEM SHUTDOWN
607 
608      PARAMETERS: None.
609 
610      FUNCTION:   Crash the system.
611 
612 *************************************************************/
613 
614 system_shutdown()
615 {
616   fprintf (stderr, "\nBFT:  Fatal error encountered.\n");
617 }