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 }