bcdmp.pl1 09/09/83 1357.7rew 09/09/83 1006.5 48906 /* *********************************************************** * * * Copyright, (C) Honeywell Information Systems Inc., 1982 * * * *********************************************************** */ bcdmp: proc (seg_ptr); /* Procedure to dump a GCOS segment, printing less information than dump_segment. Entry bcdmp prints bcw, then for each record, the rcw and its offset, and the BCD or ASCII contents (BCD translated to ASCII for printing). Binary card records just have their rcw and offset printed. Entry gcdmp prints just bcw and rcws, and their offsets. No record contents are printed. Entry set_max_line_len gives the line length of the terminal, and by implication, the number of rcw-offset pairs that will fit on a line (20 chars per). The segment and offset to be dumped are specified by a pointer argument. Dumping always begins at the beginning of a GCOS block (on a 320-word boundary). If the offset in the pointer does not specify such an address, it will be rounded DOWN, so dumping will begin at the start of the block in which the offset falls. This procedure can be called as a subroutine, or from db: :=bcdmp(segno|offset) or by the dump_gcos (dgc) command, which accepts a pathname, offset, line length, and -bcd (or -ch) argument. WRITTEN BY T. CASEY, JULY 1974 */ dcl gcos_cv_gebcd_ascii_ ext entry (ptr, fixed bin, ptr); dcl (command_query_ , ioa_, ioa_$nnl , com_err_ , db ) ext entry options (variable); %include query_info_; dcl word bit (36) aligned based; dcl char_string char (200) based; dcl 1 bcw aligned based (block_ptr), 2 bsn bit (18) unaligned, 2 length bit (18) unaligned; dcl 1 rcw aligned based (record_ptr), 2 length bit (18) unaligned, 2 eof bit (6) unaligned, 2 zeros bit (2) unaligned, 2 media_code bit (4) unaligned, 2 report_code bit (6) unaligned; dcl (seg_ptr, block_ptr, record_ptr) ptr; dcl offset fixed bin (35); dcl (block_len, record_len, cur_line_len, i, medium) fixed bin; dcl max_line_len fixed bin int static init (80); dcl reply char (4) varying; dcl me char (5); dcl ascii_line char (200); dcl bcdsw bit (1) aligned init ("1"b); dcl (addr, addrel, fixed, index, rel, substr) builtin; me = "bcdmp"; start: block_ptr = seg_ptr; offset = fixed (rel (block_ptr)); cur_line_len = 0; i = mod (offset, 320); if i ^= 0 then do; offset = offset - i; block_ptr = addrel (block_ptr, -i); call com_err_ (0, me, "will start at offset: ^6o", offset); end; start_block: block_len = fixed (bcw.length); if cur_line_len ^= 0 then do; call ioa_ (""); cur_line_len = 0; end; call ioa_ ("^/^6o ^w", offset, block_ptr -> word); if block_ptr -> word = (36)"0"b then do; call com_err_ (0, me, "bcw = 0; aborting dump"); goto exit; end; if block_len = 0 then goto next_block; offset = offset + 1; record_ptr = addrel (block_ptr, 1); next_record: record_len = fixed (rcw.length); if record_len > block_len then do; call com_err_ (0, me, "bad rcw:"); goto new_line; end; if bcdsw then do; if record_len = 0 then goto new_line; ascii_line = ""; medium = fixed (rcw.media_code); if medium >= 5 then /* ascii */ ascii_line = substr (addrel (record_ptr, 1) -> char_string, 1, record_len*4); else if medium = 1 then /* binary card */ ascii_line = "BINARY CARD"; else do; /* else assume bcd */ call gcos_cv_gebcd_ascii_ (addrel (record_ptr, 1), record_len*6, addr (ascii_line)); /* COMMENT OUT: so we can see the !1 or !2 or whatever, at the end of the last word substr (ascii_line, 1+index (ascii_line, "!")) = ""; /* END COMMENT OUT */ substr (ascii_line, 1+record_len*6) = ""; /* but blank out the garbage after the last word */ end; call ioa_ ("^6o ^w ^a", offset, record_ptr -> word, ascii_line); end; else do; if cur_line_len = 0 then goto new_line; if cur_line_len + 20 > max_line_len then new_line: do; call ioa_$nnl ("^/^6o ^w", offset, record_ptr -> word); cur_line_len = 20; end; else do; call ioa_$nnl (" ^6o ^w", offset, record_ptr -> word); cur_line_len = cur_line_len + 20; end; end; if rcw.eof = "001111"b then do; query_info.yes_or_no_sw = "1"b; call command_query_ (addr (query_info), reply, me, "eof in rcw; do you wish to continue?"); if reply = "no" then goto exit; end; offset = offset + record_len + 1; record_ptr = addrel (record_ptr, record_len+1); block_len = block_len - record_len - 1; if block_len < 0 then do; call com_err_ (0, me, "warning - remaining block length went negative - calling db"); call db; end; if block_len <= 0 then next_block: do; block_ptr = addrel (block_ptr, 320); offset = fixed (rel (block_ptr)); goto start_block; end; goto next_record; exit: /* terminate the seg here, if we add code to initiate it later */ call com_err_ (0, me, "returning to caller"); return; /* Entry to request printing of just block and record control words */ gcdmp: entry (seg_ptr); me = "gcdmp"; bcdsw = "0"b; goto start; /* Entry to set max_line_length */ set_max_line_len: entry (ll); dcl ll fixed bin; max_line_len = ll; return; end bcdmp;  dump_gcos.pl1 09/09/83 1357.7rew 09/09/83 1006.5 59211 /* *********************************************************** * * * Copyright, (C) Honeywell Information Systems Inc., 1982 * * * * Copyright (c) 1972 by Massachusetts Institute of * * Technology and Honeywell Information Systems, Inc. * * * *********************************************************** */ dump_gcos: dgc: proc; /* Command to dump a GCOS standard system format file, doing less printing than dump_segment or dump_segment -bcd. USAGE: dgc pathname -octal_offset- -bcd -line_length (-ll) n If octal offset is omitted, it defaults to zero. If it is given, it is rounded DOWN to the beginning of the 320 (decimal) word block in which it falls. Dumping always begins on a 320-word boundary. Dumping will proceed until the user QUIT's, or until an end of file (octal 17) is found (in which case the user will be given the choice of quitting or continuing), or a block control word of all zeros is found, which always terminates the dump. If -bcd (or -ch) is given, the contents of BCD or ASCII records is printed (the BCD being converted to ASCII for printing), preceeded by the rcw and its offset. For binary card records, the offset and rcw, and the words BINARY CARD are printed. If -bcd is not given, just bcw and rcws (and their offsets) are printed. The -line_length n argument may be used to control the number of rcws placed on each line. The default is 80, which is room for 4 rcws and their offsets. Once set, the line length is remembered in internal static for the remainder of the process. WRITTEN BY T. Casey July 1974 MODIFIED BY S. Akers September 1981 Changed error_table_$badarg to error_table_$badopt. Fixed "USAGE" error to prevent garbage in error message. */ /* D E C L A R A T I O N S */ /* External Entries */ dcl cu_$arg_count entry (fixed bin); dcl cu_$arg_ptr entry (fixed bin, ptr, fixed bin, fixed bin (35)); dcl (cv_dec_check_, cv_oct_check_) entry (char (*), fixed bin (35)) returns (fixed bin); dcl (ioa_, com_err_) entry options (variable); dcl hcs_$initiate_count entry (char (*), char (*), char (*), fixed bin (24), fixed bin (2), ptr, fixed bin (35)); dcl hcs_$terminate_noname entry (ptr, fixed bin (35)); dcl (bcdmp, bcdmp$gcdmp) entry (ptr); dcl bcdmp$set_max_line_len entry (fixed bin); dcl expand_path_ entry (ptr, fixed bin, ptr, ptr, fixed bin (35)); /* Work Variables */ dcl argp ptr; dcl argl fixed bin; dcl arg char (argl) based (argp); dcl (argno, nargs) fixed bin; dcl code fixed bin (35); dcl err_msg char (200) varying; dcl err_arg char (168); dcl numeric_arg fixed bin; dcl given_path char (168) init (""); dcl dirname char (168); dcl ename char (32); dcl offset fixed bin init (0); dcl (bcdsw, expecting_ll) bit (1) aligned init ("0"b); dcl (error_table_$noarg, error_table_$badopt) ext fixed bin (35); dcl plen fixed bin; dcl segptr ptr init (null); dcl bitcount fixed bin (24); dcl callptr ptr; dcl (addr, divide, null, ptr) builtin; dcl cleanup condition; /* P R O C E D U R E */ on condition (cleanup) begin; if segptr ^= null then call hcs_$terminate_noname (segptr, code); end; call cu_$arg_count (nargs); if nargs = 0 then do; code = 0; err_msg = "USAGE: dgc path offset -bcd -line_length n"; call_com_err: call com_err_ (code, "dump_gcos", err_msg, err_arg, numeric_arg); exit: if segptr ^= null then do; call hcs_$terminate_noname (segptr, code); if code ^= 0 then do; err_msg = "from hcs_$terminate_noname ^a"; segptr = null; /* avoid infinite loop */ show_expanded_path: /* come here from below */ err_arg = substr (dirname, 1, index (dirname, " ")-1) || ">" || substr (ename, 1, index (ename, " ")-1); goto call_com_err; end; end; return; end; arg_loop: do argno = 1 to nargs; call cu_$arg_ptr (argno, argp, argl, code); if code ^= 0 then do; err_msg = "from cu_$arg_ptr ^s^d"; numeric_arg = argno; goto call_com_err; end; if expecting_ll then do; expecting_ll = "0"b; numeric_arg = cv_dec_check_ (arg, code); if code ^= 0 then do; code = 0; /* not an error_table_ code */ err_msg = "bad line length argument: ^a"; err_arg = arg; end; call bcdmp$set_max_line_len (numeric_arg); end; else if substr (arg, 1, 1) = "-" then do; /* control */ if arg = "-bcd" | arg = "-ch" then bcdsw = "1"b; else if arg = "-ll" | arg = "-line_length" then expecting_ll = "1"b; else do; code = error_table_$badopt; err_arg = arg; err_msg = "^a"; goto call_com_err; end; end; /* end control arg */ else do; /* path or offset */ numeric_arg = cv_oct_check_ (arg, code); if code ^= 0 then do; /* not an octal number */ if given_path = "" then do; /* if path not already given */ given_path = arg; /* assume this is it */ plen = argl; /* for expand_path_ */ end; else do; if offset ^= 0 then /* if offset given already */ err_msg = "unknown argument: ^a"; err_arg = arg; goto call_com_err; end; end; /* end code ^= 0 */ else offset = numeric_arg; end; end arg_loop; if expecting_ll then do; err_msg = "line length, after ^a"; err_arg = arg; noarg: code = error_table_$noarg; goto call_com_err; end; if given_path = "" then do; err_msg = "pathname of file to be dumped"; goto noarg; end; call expand_path_ (addr (given_path), plen, addr (dirname), addr (ename), code); if code ^= 0 then do; err_msg = "from expand_path_ ^a"; err_arg = given_path; goto call_com_err; end; call hcs_$initiate_count (dirname, ename, "", bitcount, 0, segptr, code); if segptr = null then do; err_msg = "from hcs_$initiate_count ^a"; goto show_expanded_path; end; else code = 0; /* clear possible segknown */ bitcount = divide (bitcount-1, 36, 17, 0); /* compute offset of last word, from bitcount */ if offset > bitcount then do; call com_err_ (0, "dump_gcos", "offset (^o) is past last word (^o); last block will be dumped.", offset, bitcount); offset = bitcount; end; callptr = ptr (segptr, offset); if bcdsw then call bcdmp (callptr); else call bcdmp$gcdmp (callptr); goto exit; end dump_gcos;  gcos_build_library.pl1 09/09/83 1357.7rew 09/09/83 1006.5 142308 /* *********************************************************** * * * Copyright, (C) Honeywell Information Systems Inc., 1982 * * * *********************************************************** */ gcos_build_library: gcbl: build: proc; /* This procedure builds a catalog for a GCOS system-loadable file. The catalog contains 2 words per module: program name (in BCD), and offset (of the preface record preceeding the module). This format is similar to the "GECALL TABLE" that is kept in core by the real GCOS, and it differs from the format of the catalog produced by SYSEDIT for a random system loadable file (commonly used for ** files). WARNING: This command can not be used to manipulate a random system loadable file. See the GCOS PLM (AN77 for a detailed description of the differences between a random system loadable file, a tape system loadable file, and a simulator format software library. NOTE: THERE IS NO SUCH PLM. The catalog occupies the first 1000 words of the file, and has room for 499 name-offset pairs. Usage: gcbl input_path output_path -brief -append append_path input_path is the pathname of the input file. This file may or may not already have a catalog. The file may have been created by this procedure (in which case it has a catalog), or by gcos_extract_module or gcos_pull_tapefile (in which case it does NOT have a catalog). output_path is the pathname of the file into which the modules in the input file (plus those in the optional append file) are to be copied, preceeded by a catalog. If this file already exists, it will be overwritten with no warning. append_path is the pathname of a file whose contents are to be appended to those of the input file (i.e., copied to the end of the output file) before the new catalog is built. This file is optional. If it is given, the pathname must be preceeded by one of the two control arguments: -append, or -append_cat, depending on whether or not the file TO BE APPENDED has a catalog. The following is no longer the case but is kept for historical reference. NOTE that when an append file is given, either with or without a catalog, the input file is assumed to have a catalog, and otherwise the input file is assumed NOT to have a catalog. This might appear at first to be an arbitrary and unwise assumption, but use of earlier versions of this procedure has shown that the appending function is always used to add modules to a library that is already being used by the simulator (and thus has a catalog). (End of not true.) NOTE that existing modules are NOT replaced by the appending function. The only way to replace an existing module with a different version of itself is to extract from the existing library, into a new file, all the modules EXCEPT the one(s) to be replaced, extract the new versions of those modules into the new file (they will be appended to those previously extracted into the file), and then build a catalog for the new file. WRITTEN BY DICK SNYDER .... 1971 MODIFIED BY T. CASEY JUNE 1974, AUGUST 1974 Modified: Ron Barstad 2.0 83-02-28 Added dcl precision to conform to standards Added version (start with 2.0) Modified: Ron Barstad 2.1 83-04-20 Removed catalog-nocatalog restriction */ /* D E C L A R A T I O N S */ /* External Entries */ dcl ios_$detach ext entry (char (*), char (*), char (*), bit (72)); dcl ios_$attach ext entry (char (*), char (*), char (*), char (*), bit (72)); dcl ios_$seek ext entry (char (*), char (*), char (*), fixed bin(24), bit (72)); dcl (ios_$read, ios_$write) ext entry (char (*), pointer, fixed bin(24), fixed bin(24), fixed bin(24), bit (72)); dcl ios_$setsize ext entry (char (*), fixed bin(24), bit (72)); dcl (ioa_, com_err_) ext entry options (variable); dcl (elindex, offset) fixed bin(24); dcl progname char (6); dcl gcos_cv_gebcd_ascii_ ext entry (pointer, fixed bin(24), pointer, fixed bin(24)); dcl cu_$arg_count entry (fixed bin, fixed bin(35)); dcl cu_$arg_ptr ext entry (fixed bin(24), ptr, fixed bin(24), fixed bin(35)); /* Work Variables */ dcl nargs fixed bin(17); dcl argp ptr; dcl argl fixed bin(24); dcl arg char (argl) based (argp); dcl argno fixed bin(24); dcl cleanup condition; dcl err_msg char (200) varying; dcl cat char (4000) aligned init (" "); /* place to build catalog */ dcl buffer char (4000) aligned init (" "); /* buffer */ dcl first_word fixed bin(35) based (addr(buffer)); /* first word of buffer */ dcl 1 catblk aligned based (catp), /* catalog image */ 2 nxt fixed bin(24), /* pointer to next cat blk */ 2 no_ent fixed bin(24), /* no. of entries in this cat blk */ 2 elblock (499), /* room for 499 entries */ 3 element bit (36) unaligned, /* prog name */ 3 address fixed bin(24); /* offset in file */ dcl catp pointer; dcl (i, j, k) fixed bin(24); /* temps */ dcl st bit (72); /* ios status */ dcl (load_origin, pgm_length, transfer_addr, load_increment, reloc_len) fixed bin(24); /* temps */ dcl 1 status aligned based (addr (st)), /* overlay for ios_ status */ 2 code fixed bin (35), /* standard error code */ 2 fill bit (9) unaligned, 2 eof bit (1) unaligned; /* eof bit */ dcl 1 gecall aligned based (callp), /* overlay for gecall parameters */ 2 prog_name bit (36) unaligned, /* bcd pgm name */ 2 origin bit (18) unaligned, /* place to begin loading */ 2 filler bit (18) unaligned, 2 xfer_addr bit (18) unaligned; /* transfer address */ dcl callp pointer; dcl 1 preface aligned based (prefp), /* model of preface record */ 2 data_check fixed bin(24), /* checksum of following data words */ 2 rel_check fixed bin(24), /* checksum of following reloc. words */ 2 rel_abs fixed bin(24), /* 0=absolute|^0=relocatable */ 2 name bit (36) unaligned, /* name of pgm */ 2 entry bit (18) unaligned, /* entry address */ 2 origin bit (18) unaligned, /* origin */ 2 reloc_words fixed bin (17) unaligned, /* no. of relocation words */ 2 data_words fixed bin (17) unaligned, /* no. of data words */ 2 dcws (ndcw) bit (36) unaligned; /* dcw(s) to load following data records */ dcl prefp pointer; dcl ndcw fixed bin(24); dcl 1 dcw_model aligned based (dcwp), /* model of dcw */ 2 data_addr bit (18) unaligned, 2 zero bit (3) unaligned, 2 action bit (3) unaligned, 2 count bit (12) unaligned; /* number of words to xfer */ dcl dcwp pointer; dcl checker (pgm_length) bit (36) aligned based (ptr); /* overlay for computing chksum */ dcl ptr pointer; dcl reloc_bits (size) bit (2) based (prefp); /* overlay for relocation record */ dcl 1 gecos_reloc (size) aligned based (ptr), /* overlay for each word of loaded pgm */ 2 upper bit (18) unaligned, 2 lower bit (18) unaligned; dcl size fixed bin(24); /* size of pgm overlay arrays */ dcl accum fixed bin (71); /* checksum accumulator */ dcl (input_path, output_path, append_path, err_path) char (168); dcl me char (24) int static options (constant) init ("gcos_build_library (2.1)"); dcl stream_names (2) char (12) int static init ( "gcbl_input", "gcbl_output"); dcl (briefsw , catalogsw , appendsw , append_cat_sw , append_path_sw , ineof , usage_sw ) bit (1) aligned init ("0"b); dcl path_counter fixed bin(24)init (0); dcl (error_table_$badopt, error_table_$noarg) ext fixed bin (35); dcl (addr, divide, mod, substr) builtin; /* */ /* P R O C E D U R E */ on condition (cleanup) call cleanup_proc; call cu_$arg_count (nargs, code); if nargs < 2 & code = 0 then code = error_table_$noarg; if code ^= 0 then do; call com_err_ (code, me); print_usage: call ioa_ ("Usage: gcbl INPUT_PATH OUTPUT_PATH {-brief} {-append APPEND_PATH}"); exit: call cleanup_proc; return; end; arg_loop: do argno = 1 to nargs; call cu_$arg_ptr (argno, argp, argl, code); if code ^= 0 then do; err_msg = arg; call_com_err: call com_err_ (code, me, err_msg, err_path); if usage_sw then goto print_usage; else goto exit; end; err_path = arg; /* in case of error in argument processing */ if substr (arg, 1, 1) ^= "-" then /* if not control argument */ get_path: do; /* must be a pathname */ /* which one is it? */ if append_path_sw then /* if previous argument was -append or -append_cat */ get_append: do; append_path = arg; /* save path */ append_path_sw = "0"b; /* remember we got it */ end get_append; else if path_counter = 0 then /* if we have no paths */ get_input: do; /* has to be input_path */ input_path = arg; /* save it */ path_counter = 1; /* remember we got it */ end get_input; else if path_counter = 1 then /* if we have input path */ get_output: do; /* this has to be output */ output_path = arg; /* save it */ path_counter = 2; /* remember we got it */ end get_output; else do; /* if we have both, this is garbage */ usage_sw = "1"b; /* tell user how to use command */ err_msg = "unidentified non-control argument: ^a"; code = 0; goto call_com_err; end; end get_path; else if arg = "-bf" | arg = "-brief" then briefsw = "1"b; else if arg = "-append" then do; append_arg: appendsw, catalogsw = "1"b; append_path_sw = "1"b; end; else if arg = "-append_cat" then do; append_cat_sw = "1"b; goto append_arg; end; else do; code = error_table_$badopt; err_msg = "^a"; goto call_com_err; end; end arg_loop; if path_counter ^= 2 then do; /* complain if required paths missing */ err_msg = ""; noarg_err: code = error_table_$noarg; usage_sw = "1"b; /* show user required args */ goto call_com_err; end; if append_path_sw then do; /* if we were waiting for append path and it was not there, complain */ err_msg = "append_path"; goto noarg_err; end; err_path = output_path; /* in case of error initializing output file */ call ios_$attach ("gcbl_output", "file_", output_path, "", st); if code ^= 0 then do; attach_err: err_msg = "from ios_$attach ^a"; goto call_com_err; end; call ios_$setsize ("gcbl_output", 36, st); if code ^= 0 then do; setsize_err: err_msg = "from ios_$setsize ^a"; goto call_com_err; end; call ios_$seek ("gcbl_output", "last", "first", 1000, st); if code ^= 0 then do; err_msg = "from ios_$seek last 1000 ^a"; goto call_com_err; end; call ios_$seek ("gcbl_output", "write", "first", 1000, st); if code ^= 0 then do; err_msg = "from ios_$seek write 1000 ^a"; goto call_com_err; end; /* copy entire input (or append) file into output file */ attach_input: /* come here to attach input or append file for reading */ err_path = input_path; /* in case of error while reading */ call ios_$attach ("gcbl_input", "file_", input_path, "r", st); if code ^= 0 then goto attach_err; call ios_$setsize ("gcbl_input", 36, st); if code ^= 0 then goto setsize_err; /*** The input or append library is determined to have or not have a catalog by inspection. If the first word is 0, then it is a simulator library and has a catalog. If the first word not=0, then the lib does not have a catalog and is a native gcos lib. Neither catalogsw, nor append_cat_sw is examined. */ call ios_$read ("gcbl_input", addr (buffer), 0, 1000, j, st); if code ^= 0 then goto read_err; if first_word ^= 0 then goto no_skip_cat; else skip_catalog: do; call ios_$seek ("gcbl_input", "read", "first", 1000, st); if code ^= 0 then do; seek_read_err: err_msg = "from ios_$seek read 1000 ^a"; goto call_com_err; end; end skip_catalog; /* Come here to read next 1000 words from input or append file */ loop: call ios_$read ("gcbl_input", addr (buffer), 0, 1000, j, st); if code ^= 0 then do; read_err: err_msg = "from ios_$read ^a"; goto call_com_err; end; no_skip_cat: if status.eof then ineof = "1"b; /* remember end of file, since we clear status by writing */ call ios_$write ("gcbl_output", addr (buffer), 0, j, k, st); if code ^= 0 then do; write_err: err_msg = "from ios_$write ^a"; err_path = output_path; goto call_com_err; end; if ^ineof then go to loop; /* go read next block, if not end of file */ if appendsw then do; /* eof on input...append now?? */ ineof = "0"b; appendsw = "0"b; /* after next eof we won't append again */ catalogsw = append_cat_sw; /* if append file has catalog, skip over it */ call ios_$detach ("gcbl_input", "", "", st); /* detach input file */ if code ^= 0 then do; err_msg = "from ios_$detach ^a"; goto call_com_err; end; input_path = append_path; goto attach_input; /* go attach and read append file */ end; /* Fall thru here to start reading thru output file and building catalog */ err_path = output_path; /* in case of error on output file */ call ios_$seek ("gcbl_output", "read", "first", 1000, st); /* seek to first preface record for reading */ if code ^= 0 then goto seek_read_err; call ios_$seek ("gcbl_output", "write", "first", 0, st); /* seek to start of empty catalog for writing */ if code ^= 0 then do; err_msg = "from ios_$seek write first ^a"; goto call_com_err; end; catp = addr (cat); /* place to build catalog */ prefp = addr (buffer); /* place to read preface records into */ catblk.nxt = 0; /* clear rel ptr to next catalog block (there never is another catalog block) */ elindex = 1; /* first modue - first catalog position */ offset = 1000; /* offset of its preface record */ read: call ios_$read ("gcbl_output", prefp, 0, 1000, j, st); /* read the preface record */ if code ^= 0 then goto read_err; elblock (elindex).element = preface.name; /* copy name */ elblock (elindex).address = offset; /* copy preface offset */ elindex = elindex + 1; /* bump index */ if elindex = 500 then do; code = 0; err_msg = "catalog overflow - more than 499 modules in file: ^a"; goto call_com_err; end; if ^briefsw then do; /* unless told not to, print name and offset */ call gcos_cv_gebcd_ascii_ (addr (preface.name), 6, addr (progname), j); call ioa_ ("^a ^o", progname, offset); end; /* Count DCWs, by looking for one with action code = "000"b */ do ndcw = 1 to 58 /* there may be up to 58 of them in a block */ while (substr (preface.dcws (ndcw), 22, 3) ^= "000"b); end; offset = offset+6+ndcw+preface.data_words+preface.reloc_words; /* compute offset of next preface record */ call ios_$seek ("gcbl_output", "read", "first", offset, st); /* seek to it */ if code ^= 0 then do; err_msg = "from ios_$seek read next_preface ^a"; goto call_com_err; end; if ^eof then go to read; /* if not end of file on seek, go read it */ call ioa_ ("end of file"); catblk.no_ent = elindex-1; /* compute total elements in catalog */ call ios_$write ("gcbl_output", addr (cat), 0, 1000, j, st); /* write catalog into file */ if code ^= 0 then goto write_err; goto exit; /* all done */ cleanup_proc: proc; do i = 1 to 2; call ios_$detach (stream_names (i), "", "", st); end; return; end cleanup_proc; end gcos_build_library;  gcos_build_patchfile.pl1 09/09/83 1357.7rew 09/09/83 1006.5 114084 /* *********************************************************** * * * Copyright, (C) Honeywell Information Systems Inc., 1982 * * * * Copyright (c) 1972 by Massachusetts Institute of * * Technology and Honeywell Information Systems, Inc. * * * *********************************************************** */ /* ******************************************************************************************** ******************************************************************************************** * * * G C O S B U I L D P A T C H F I L E * * * The gcos_build_patchfile command is used to build a patch file to be used by the * GCOS Environment Simulator. The arguments to the command are the name of the * Multics ASCII segment containing the patches and the name of the resulting * patchfile. In order to have the patches applied by MME GECALL the patchfile * must be called gcos_system_software_patchfile_ and must be locatable by the * search rules. * * * Written by M. R. Jordan, September 1977 * ******************************************************************************************** ******************************************************************************************** */ gcos_build_patchfile: gbp: proc (); dcl ME char (20) static internal options (constant) init ("gcos_build_patchfile"); dcl NL char (1) static internal options (constant) init (" "); dcl aclinfo_ptr ptr init (null ()); dcl addr builtin; dcl arg char (arg_len) based (arg_ptr); dcl arg_len fixed bin; dcl arg_num fixed bin; dcl arg_ptr ptr; dcl ascii_module_name char (6); dcl bit_count fixed bin (24); dcl cleanup condition; dcl code fixed bin (35); dcl com_err_ entry options (variable); dcl cu_$arg_count entry (fixed bin); dcl cu_$arg_ptr entry (fixed bin, ptr, fixed bin, fixed bin (35)); dcl cv_oct_check_ entry (char (*), fixed bin (35)) returns (fixed bin (35)); dcl divide builtin; dcl dummy fixed bin; dcl end_of_info bit (1); dcl error_table_$bad_arg fixed bin (35) ext; dcl error_table_$badopt fixed bin (35) ext; dcl error_table_$noarg fixed bin (35) ext; dcl error_table_$too_many_names fixed bin (35) ext; dcl error_table_$translation_failed fixed bin (35) ext; dcl expand_pathname_ entry (char (*), char (*), char (*), fixed bin (35)); dcl fixed builtin; dcl gcos_cv_ascii_gebcd_ entry (ptr, fixed bin, ptr, fixed bin); dcl get_temp_segments_ entry (char (*), (*)ptr, fixed bin (35)); dcl hbound builtin; dcl hcs_$initiate_count entry (char (*), char (*), char (*), fixed bin (24), fixed bin (2), ptr, fixed bin (35)); dcl highest_severity fixed bin init (0); dcl i fixed bin; dcl in_dirname char (168); dcl in_ename char (32); dcl in_line char (in_line_len) based (in_line_ptr); dcl in_line_len fixed bin (20); dcl in_line_num fixed bin; dcl in_line_ptr ptr; dcl in_seg char (in_seg_len) based (in_seg_ptr); dcl in_seg_len fixed bin (20); dcl in_seg_offset fixed bin (20); dcl in_seg_ptr ptr; dcl index builtin; dcl ioa_ entry options (variable); dcl last_name bit (36); dcl length builtin; dcl n fixed bin; dcl nargs fixed bin; dcl null builtin; dcl number_of_patches fixed bin; dcl out_dirname char (168); dcl out_ename char (32); dcl out_seg_bit_count fixed bin (24); dcl out_seg_ptr ptr init (null ()); dcl patch_ptr ptr; dcl rel builtin; dcl release_temp_segments_ entry (char (*), (*)ptr, fixed bin (35)); dcl search builtin; dcl substr builtin; dcl table_ptr ptr; dcl temp_ptr (2) ptr init ((2)null ()); dcl temp_segments_cleanup_needed bit (1) aligned init ("0"b); dcl tssi_$clean_up_segment entry (ptr); dcl tssi_$finish_segment entry (ptr, fixed bin (24), bit (36) aligned, ptr, fixed bin (35)); dcl tssi_$get_segment entry (char (*), char (*), ptr, ptr, fixed bin (35)); dcl tssi_cleanup_needed bit (1) aligned init ("0"b); dcl 1 patch (number_of_patches+1) aligned based (patch_ptr), 2 location fixed bin (17), 2 content fixed bin (35); dcl 1 patch_file aligned based (out_seg_ptr), 2 version fixed bin, 2 number_of_names fixed bin, 2 module (130560), 3 name bit (36), 3 first_patch_offset bit (18) unal, 3 number_of_patches fixed bin (17) unal; dcl 1 table (87040) aligned based (table_ptr), 2 name bit (36), 2 location fixed bin (17), 2 content fixed bin (35) ; /* Make sure there are at least enough arguments to get started. */ call cu_$arg_count (nargs); if nargs < 2 then do; call com_err_ (error_table_$noarg, ME, "^/Usage is: gcos_build_patchfile patches patchfile"); return; end; on cleanup call Cleanup (); /* Process the pathname of the input file containing patches. */ call cu_$arg_ptr (1, arg_ptr, arg_len, code); if code ^= 0 then do; call com_err_ (code, ME, "referencing argument 1."); return; end; call Process_Input_Pathname (); if code ^= 0 then return; /* Process the patchfile pathname. */ call cu_$arg_ptr (2, arg_ptr, arg_len, code); if code ^= 0 then do; call com_err_ (code, ME, "referencing argument 2."); return; end; call Process_Output_Pathname (); if code ^= 0 then return; /* Process the remaining arguments. These should all be control arguments. */ do arg_num = 3 to nargs; call cu_$arg_ptr (arg_num, arg_ptr, arg_len, code); if code ^= 0 then do; call com_err_ (code, ME, "referencing argument ^d.", arg_num); return; end; call Process_Argument (); if code ^= 0 then return; end; temp_segments_cleanup_needed = "1"b; call get_temp_segments_ (ME, temp_ptr, code); if code ^= 0 then do; call com_err_ (code, ME); return; end; table_ptr = temp_ptr (1); call Process_Patch_Cards (); if code ^= 0 then return; if highest_severity < 3 then do; call Sort_Patches (); if code ^= 0 then return; call Generate_Patch_File (); if code ^= 0 then return; end; else call com_err_ (error_table_$translation_failed, ME); give_up: call tssi_$finish_segment (out_seg_ptr, out_seg_bit_count, "110"b, aclinfo_ptr, code); tssi_cleanup_needed = "0"b; call release_temp_segments_ (ME, temp_ptr, code); temp_segments_cleanup_needed = "0"b; return; Process_Input_Pathname: proc (); call expand_pathname_ (arg, in_dirname, in_ename, code); if code ^= 0 then do; call com_err_ (code, ME, """^a""", arg); return; end; call hcs_$initiate_count (in_dirname, in_ename, "", bit_count, 0, in_seg_ptr, code); if in_seg_ptr = null () then do; call com_err_ (code, ME, """^a^[>^]^a""", in_dirname, (in_dirname ^= ">"), in_ename); return; end; else code = 0; in_seg_len = divide (bit_count, 9, 20, 0); in_seg_offset = 1; in_line_len = 0; in_line_num = 0; in_line_ptr = null (); return; end Process_Input_Pathname; Process_Output_Pathname: proc (); call expand_pathname_ (arg, out_dirname, out_ename, code); if code ^= 0 then do; call com_err_ (code, ME, """^a""", arg); return; end; tssi_cleanup_needed = "1"b; call tssi_$get_segment (out_dirname, out_ename, out_seg_ptr, aclinfo_ptr, code); if code ^= 0 then do; call com_err_ (code, ME, """^a^[>^]^a""", out_dirname, (out_dirname ^= ">"), out_ename); return; end; return; end Process_Output_Pathname; Process_Argument: proc (); code = error_table_$badopt; call com_err_ (code, ME, """^a""", arg); return; end Process_Argument; Get_Input_Line: proc (); dcl in_char (in_seg_len) char (1) based (in_seg_ptr) unal; /* Make sure we still have text to process. If not, quit while we're ahead. */ loop: if in_seg_offset >= in_seg_len then do; end_of_info = "1"b; return; end; else end_of_info = "0"b; /* Get the next line from the source. */ in_line_ptr = addr (in_char (in_seg_offset)); in_line_len = index (substr (in_seg, in_seg_offset), NL)-1; if in_line_len < 0 then in_line_len = in_seg_len-in_seg_offset+1; in_line_num = in_line_num+1; /* Now update the offset of the next line. */ in_seg_offset = in_seg_offset+in_line_len+1; if in_line_len < 78 then do; call Error (3, "1"b, "Missing or incomplete program name.", ""); goto loop; end; if substr (in_line, 7, 9) ^= " octal " & substr (in_line, 7, 9) ^= " OCTAL " then do; call Error (3, "1"b, "Source is not an ""octal"" line.", ""); goto loop; end; return; end Get_Input_Line; Octal_Value: proc (text)returns (fixed bin (35)); dcl i fixed bin; dcl result fixed bin (35); dcl text char (*); i = search (text, " ,")-1; if i < 0 then i = length (text); else if substr (text, i+1, 1) = "," then do; call Error (3, "1"b, "Bad delimiter in octal field. ""^a""", substr (text, i+1, 1)); return (0); end; result = cv_oct_check_ (substr (text, 1, i), code); if code ^= 0 then do; call Error (3, "1"b, "Bad octal value. ""^a""", substr (text, 1, i)); return (0); end; return (result); end Octal_Value; Process_Patch_Cards: proc (); end_of_info = "0"b; number_of_patches = 0; do i = 1 to hbound (table, 1) while (^end_of_info); call Get_Input_Line (); ascii_module_name = substr (in_line, 73, 6); call gcos_cv_ascii_gebcd_ (addr (ascii_module_name), 6, addr (table (i).name), n); table (i).location = Octal_Value (substr (in_line, 1, 7)); table (i).content = Octal_Value (substr (in_line, 16, 13)); number_of_patches = number_of_patches+1; end; if ^end_of_info then do; code = error_table_$too_many_names; call com_err_ (code, ME, "Too many patches."); return; end; return; end Process_Patch_Cards; Sort_Patches: proc (); dcl i fixed bin; dcl j fixed bin; dcl 1 R (number_of_patches) aligned based (table_ptr), 2 K bit (36), 2 data1 fixed bin (17), 2 data2 fixed bin (35) ; dcl 1 Record aligned, 2 Key bit (36), 2 data1 fixed bin (17), 2 data2 fixed bin (35) ; do j = 2 to number_of_patches; i = j-1; Record = R (j); l: if Key < K (i) then do; R (i+1) = R (i); i = i-1; if i>0 then goto l; end; R (i+1) = Record; end; return; end Sort_Patches; Generate_Patch_File: proc (); patch_file.version = 1; n = 0; last_name = (36)"0"b; do i = 1 to number_of_patches; if table (i).name ^= last_name then do; n = n+1; last_name = table (i).name; patch_file.module (n).name = table (i).name; patch_file.module (n).first_patch_offset = (18)"0"b; patch_file.module (n).number_of_patches = 0; end; end; patch_file.number_of_names = n; patch_ptr = addr (patch_file.module (n+1)); n = 0; last_name = (36)"0"b; do i = 1 to number_of_patches; if table (i).name ^= last_name then do; last_name = table (i).name; n = n+1; patch_file.module (n).first_patch_offset = rel (addr (patch (i))); end; patch_file.module (n).number_of_patches = patch_file.module (n).number_of_patches+1; patch (i).location = table (i).location; patch (i).content = table (i).content; end; out_seg_bit_count = fixed (rel (addr (patch (number_of_patches+1))), 18)*36; return; end Generate_Patch_File; Cleanup: proc (); if tssi_cleanup_needed then do; call tssi_$clean_up_segment (aclinfo_ptr); tssi_cleanup_needed = "0"b; end; if temp_segments_cleanup_needed then do; call release_temp_segments_ (ME, temp_ptr, code); temp_segments_cleanup_needed = "0"b; end; return; end Cleanup; Error: proc (severity, print_source, message, arg); dcl arg char (*); dcl message char (*); dcl print_source bit (1) aligned; dcl severity fixed bin; dcl HEADING (4) char (16) init ( "WARNING", "ERROR SEVERITY 2", "ERROR SEVERITY 3", "ERROR SEVERITY 4"); call ioa_ ("^/^a, LINE ^d.", HEADING (severity), in_line_num); call ioa_ (message, arg); if print_source then call ioa_ ("SOURCE:^/^a", in_line); if severity>highest_severity then highest_severity = severity; if severity = 4 then goto give_up; return; end Error; end gcos_build_patchfile;  gcos_extract_module.pl1 09/09/83 1357.7rew 09/09/83 1006.5 131193 /* *********************************************************** * * * Copyright, (C) Honeywell Information Systems Inc., 1982 * * * *********************************************************** */ gcos_extract_module: gcem: extract: proc; /* This procedure extracts one or more modules from a (tape format) GCOS system loadable file, or a simulator format software library, placing them in an output file. The names of the modules are given in a control file. WARNING: This command can not be used to manipulate a random system loadable file. For a detailed description of the differences between a random system loadable file, a tape system loadable file, and a simulator format software library see the simulator manual (AN05) and the GCOS System Editor manual (DD30). USAGE: gcem control_path input_path output_path -brief control_path is the pathname of a segment containing the names of the modules to be extracted, in lower case ascii, each on a separate line. (Such a segment can be created by the gcos_library_summary command, using the -brief control argument, and preceeding it by the file_output command, and then editing the resulting segment to remove the names of unwanted modules; or the segment can be created directly by any of the Multics editors.) input_path is the pathname of a file containing gcos modules. It may be a file copied from a GCOS total system tape, or it may be a simulator library, beginning with a simulator-format catalog of the module names and locations. The file is determined to be a native GCOS or simulator format file by inspection. The -no_catalog arg is no longer necessary. output_path is the pathname of the output file into which the extracted modules are to be written. If the file already exists, it will be appended to, enabling the construction of a single library from several smaller ones. The names of each module copied will be printed on user_output, unless the -brief control argument is given. The names of any requested modules that are not found in the input file will be printed on error_output. WRITTEN BY DICK SNYDER .... 1971 MODIFIED BY T. CASEY JUNE 1974, AUGUST 1974 Change: Ron Barstad 2.0 83-07-29 Repaired obsolete hcs_$initiate_count call Removed need for -no_catalog */ /* D E C L A R A T I O N S */ /* External Entries */ dcl ios_$read ext entry (char (*) aligned, pointer, fixed bin, fixed bin, fixed bin, bit (72) aligned); dcl ios_$write ext entry (char (*), pointer, fixed bin, fixed bin, fixed bin, bit (72) aligned); dcl ios_$detach ext entry (char (*), char (*), char (*), bit (72) aligned); dcl expand_path_ ext entry (pointer, fixed bin, pointer, pointer, fixed bin (35)); dcl hcs_$initiate_count ext entry (char (*), char (*), char (*), fixed bin, fixed bin, pointer, fixed bin (35)); dcl delete_$ptr ext entry (ptr, bit (6), char (*), fixed bin (35)); dcl (ioa_, ioa_$nnl, ioa_$rsnnl, com_err_) ext entry options (variable); dcl ios_$attach ext entry (char (*), char (*), char (*), char (*), bit (72) aligned); dcl ios_$setsize ext entry (char (*), fixed bin, bit (72) aligned); dcl ios_$seek ext entry (char (*), char (*), char (*), fixed bin(21), bit (72) aligned); dcl gcos_cv_gebcd_ascii_ ext entry (pointer, fixed bin, pointer, fixed bin); dcl cu_$arg_count ext entry (fixed bin); dcl cu_$arg_ptr ext entry (fixed bin, ptr, fixed bin, fixed bin (35)); dcl get_temp_segment_ entry (char(*), ptr, fixed bin(35)); dcl release_temp_segment_ entry (char(*), ptr, fixed bin(35)); /* Work Variables */ dcl nargs fixed bin; dcl argp ptr; dcl argl fixed bin; dcl arg char (argl) based (argp); dcl argno fixed bin; dcl cleanup condition; dcl err_msg char (200) varying; dcl (i1, i2, i3, i4, pref_data, pref_reloc) fixed bin; dcl (i, j, word_no, bc, segl, doff) fixed bin; /* temps */ dcl k fixed bin (21); dcl control char (segl) based (temp_segp); dcl temp_segp pointer; dcl control_orig char (segl) based (segp); dcl segp pointer; dcl word_one fixed bin (35); /* first word of input file */ dcl ename char (32); dcl dir char (168); dcl string char (6); dcl st bit (72) aligned ; /* ios status */ dcl 1 status aligned based (addr (st)), /* overlay for ios_ status */ 2 code fixed bin (35), /* standard error code */ 2 fill bit (9) unaligned, 2 eof bit (1) unaligned; /* eof bit */ dcl 1 preface aligned based (prefp), /* model of preface record */ 2 data_check fixed bin, /* checksum of following data words */ 2 rel_check fixed bin, /* checksum of following reloc. words */ 2 rel_abs fixed bin, /* 0=absolute|^0=relocatable */ 2 name bit (36) unaligned, /* name of pgm */ 2 entry bit (18) unaligned, /* entry address */ 2 origin bit (18) unaligned, /* origin */ 2 reloc_words fixed bin (17) unaligned, /* no. of relocation words */ 2 data_words fixed bin (17) unaligned, /* no. of data words */ 2 dcws (ndcw) bit (36) unaligned; /* dcw(s) to load following data records */ dcl prefp pointer; dcl ndcw fixed bin; dcl (control_path, input_path, output_path, err_path) char (168); dcl (briefsw /* omit printing of names of extracted modules */ , nocatsw /* file does not begin with a catalog */ , usage_sw /* print usage message if error on command line */ ) bit (1) aligned init ("0"b); dcl path_counter fixed bin init (0); dcl me char (25) int static init ("gcos_extract_module (2.0)"); dcl ascii_newline char (1) int static init (" "); dcl (error_table_$badopt, error_table_$noarg) ext fixed bin (35); /* NOTE: Declaration of buffer should be last declaration in case */ /* buffer should overflow. */ dcl buffer bit (131400); /* preface and relocation blk buffer */ dcl (addr, divide, index, mod, null, substr, translate) builtin; /* */ /* P R O C E D U R E */ on condition (cleanup) call cleanup_proc; segp, temp_segp = null; call cu_$arg_count (nargs); /* IF WRONG NUMBER OF ARGS, PRINT USAGE MESSAGE AND QUIT */ if nargs < 3 then print_usage: do; call ioa_ ("Usage: gcem CONTROL_PATH INPUT_PATH OUTPUT_PATH {-brief}"); exit: call cleanup_proc; return; end print_usage; arg_loop: do argno = 1 to nargs; call cu_$arg_ptr (argno, argp, argl, code); if code ^= 0 then do; err_msg = arg; call_com_err: call com_err_ (code, me, err_msg, err_path); if usage_sw then goto print_usage; else goto exit; end; err_path = arg; /* in case of error, be ready */ if substr (arg, 1, 1) ^= "-" then /* if not control argument */ get_path: do; /* must be pathname */ if path_counter = 0 then /* which pathname? how many do we have already? */ get_control: do; /* if none, first one is control file */ call expand_path_ (argp, argl, addr (dir), addr (ename), code); if code ^= 0 then do; err_msg = "from expand_path_ ^a"; goto call_com_err; end; call ioa_$rsnnl ("^a>^a", control_path, bc, dir, ename); /* put pathname together */ call hcs_$initiate_count (dir, ename, "", bc, 0, segp, code); if segp = null then do; err_path = control_path; err_msg = "from hcs_$initiate_count ^a"; goto call_com_err; end; segl = divide (bc, 9, 17, 0); call get_temp_segment_(me, temp_segp, code); if code ^= 0 then do; call com_err_(code, me, "Unable to make temporary copy of input_path."); goto exit; end; control = control_orig; /* make a working copy */ path_counter = 1; /* remember that we have control_path */ end get_control; else if path_counter = 1 then /* if we already have control_path */ get_input: do; /* this must be input_path */ input_path = arg; call ios_$attach ("gcem_input", "file_", input_path, "r", st); if code ^= 0 then do; attach_err: err_msg = "from ios_$attach ^a"; goto call_com_err; end; call ios_$setsize ("gcem_input", 36, st); if code ^= 0 then do; setsize_err: err_msg = "from ios_$setsize ^a"; goto call_com_err; end; path_counter = 2; /* remember that we have input_path */ end get_input; else if path_counter = 2 then /* but if we have input path already */ get_output: do; /* this must be output_path */ output_path = arg; call ios_$attach ("gcem_output", "file_", output_path, "", st); if code ^= 0 then goto attach_err; call ios_$setsize ("gcem_output", 36, st); if code ^= 0 then goto setsize_err; path_counter = 3; /* remember that we have all 3 pathnames */ end get_output; else do; /* can't be a pathname - must be garbage */ usage_sw = "1"b; /* tell user how to use command */ err_msg = "unidentified non-control argument: ^a"; code = 0; goto call_com_err; end; end get_path; else if arg = "-bf" | arg = "-brief" then briefsw = "1"b; else if arg = "-no_catalog" then nocatsw = "1"b; else do; code = error_table_$badopt; err_msg = "^a"; goto call_com_err; end; end arg_loop; if path_counter ^= 3 then do; /* complain if all 3 pathnames not given */ code = error_table_$noarg; err_msg = ""; usage_sw = "1"b; goto call_com_err; end; /* initialize */ prefp = addr (buffer); /* pointer to buffer for ios_ */ k = 0; /* offset of first preface record (relative to doff) */ err_path = input_path; /* higher probablility of input errors */ /* determine if the input file has a catalog: if the first word of the file =0 then this is a simulator file with a catalog if the first word not=0 then this is a native GCOS file without a catalog */ call ios_$seek ("gcem_input", "read", "first", 0, st); if code ^= 0 then do; err_msg = "from ios_$seek read first word: ^a"; goto call_com_err; end; call ios_$read ("gcem_input", addr(word_one), 0, 1, j, st); if code ^= 0 then do; err_msg = "from ios_$read of word one: ^a"; goto call_com_err; end; if word_one = 0 then doff = 1000; /* has catalog */ else doff = 0; %page; /* Main loop begins here */ seek_preface: call ios_$seek ("gcem_input", "read", "first", k+doff, st); if code ^= 0 then do; seek_err: err_msg = "from ios_$seek read start-of-preface ^a"; goto call_com_err; end; if status.eof then do; /* check for end of file */ call ioa_ ("^/end of file"); control = translate (control, "", " "); /* translate blanks to fill (177) chars */ call com_err_ (0, me, "Following modules not found in ^a^/^a", input_path, control); goto exit; end; read: call ios_$read ("gcem_input", prefp, 0, 3650, j, st); /* read preface record */ if code ^= 0 then do; read_err: err_msg = "from ios_$read ^a"; goto call_com_err; end; /* Count DCWs, by looking for one with action code = "000"b */ do ndcw = 1 to 58 /* there may be up to 58 of them in a block */ while (substr (preface.dcws (ndcw), 22, 3) ^= "000"b); end; pref_reloc = preface.reloc_words; /* copy data from preface */ pref_data = preface.data_words; i4 = pref_data + pref_reloc + 6 + ndcw; /* compute number of words to copy */ /* (or to skip over, if this one not to be copied) */ /* NOTE that this number includes the preface record, which is copied along with the data */ call gcos_cv_gebcd_ascii_ (addr (preface.name), 6, addr (string), i); /* convert prog name to ascii */ /* and see if that name is in the control file */ i1 = index (string, " "); /* find the end of it */ if i1 = 0 then i1 = 7; /* if no trailing blank, must be 6 chars */ i3 = 1; /* start search from beginning */ search_control: i2 = index (substr (control, i3), substr (string, 1, i1-1)); /* look for the name in the control file */ if i2 ^= 0 then do; /* if its there, extract the module - maybe */ /* Aviod extracting module "b" because "abc" occurs in the control file. Check that name in control file is delimited by blanks or newlines (or beginning of file) */ if substr (control, i2+i1-1, 1) ^= ascii_newline then /* name must end in newline */ if substr (control, i2+i1-1, 1) ^= " " then /* or blank */ goto keep_searching; /* or we do not copy it */ if i2 ^= 1 then /* except for first name in control file */ if substr (control, i2-1, 1) ^= ascii_newline then /* name must begin with newline */ if substr (control, i2-1, 1) ^= " " then /* or blank */ keep_searching: do; /* or we do not copy it */ i3 = i2 + i1 - 1; /* move search pointer past this name */ if i3 + i1 - 1 > segl then /* if name is longer than remainder of file */ goto next_preface; /* give up and go look at next preface record */ else goto search_control; /* else keep looking for it */ end; if ^briefsw then /* print name unless asked not to */ call ioa_ ("^a will be copied", string); substr (control, i2, i1) = ""; /* blank out name and trailing blank or newline */ call ios_$seek ("gcem_input", "read", "read", -j, st); /* move read pointer back to beginning of preface */ if code ^= 0 then goto seek_err; copyloop: if i4 < 3650 then i3 = i4; else i3 = 3650; call ios_$read ("gcem_input", prefp, 0, i3, j, st); if code ^= 0 then goto read_err; if i4 > j then i2 = j; else i2 = i4; call ios_$write ("gcem_output", prefp, 0, i2, i1, st); if code ^= 0 then do; err_path = output_path; err_msg = "from ios_$write ^a"; goto call_com_err; end; i4 = i4 -i1; if i4 > 0 then go to copyloop; end; if control = "" then do; /* if all requested modules copied, quit */ call ioa_ ("^/all requested modules copied"); goto exit; end; next_preface: k = k+6+ndcw+pref_data+pref_reloc; /* compute offset of next preface block */ goto seek_preface; /* go seek to it */ cleanup_proc: proc; call ios_$detach ("gcem_input", "", "", st); call ios_$detach ("gcem_output", "", "", st); if temp_segp ^= null then call release_temp_segment_(me, temp_segp, code); return; end cleanup_proc; end gcos_extract_module;  gcos_library_summary.pl1 09/09/83 1357.7rew 09/09/83 1006.5 102159 /* *********************************************************** * * * Copyright, (C) Honeywell Information Systems Inc., 1982 * * * *********************************************************** */ gcos_library_summary: gcls: summary: proc; /* This procedure prints a summary of the contents of a GCOS tape-format system-loadable file, or a simulator format software library, or a gcos format system-loadable file. USAGE: gcls pathname {-control_args} -control_args are: -brief | -preface | -no_catalog | -gcos If no control arguments are given, the file is assumed to begin with a catalog (containing the name and offset of each module in the file), and the catalog is printed. If -preface is given, a catalog is assumed to be present, and it is skipped over, and the preface record at the beginning of each module is printed. If -no_catalog is given, the file is assumed to begin with the first preface record, and the preface records are printed. If -brief is given, only the names of the modules are printed, whether catalog or preface record printing was specified. -gcos arg will cause the pathname to be interpreted as a Gcos format file and its contents will be listed. Written by Dick Snyder .... 1971 Modified by T. Casey JUNE 1974, AUGUST 1974 Modified: Ron Barstad 02/04/83 To work on Gcos format files with -gcos arg Add version indicator, start with 2.0 */ /* D E C L A R A T I O N S */ /* External Entries */ dcl ios_$detach ext entry (char (*), char (*), char (*), bit (72) aligned); dcl ios_$read ext entry (char (*), pointer, fixed bin(24), fixed bin(24), fixed bin(24), bit (72) aligned); dcl (ioa_, ioa_$nnl, com_err_) ext entry options (variable); dcl ios_$attach ext entry (char (*), char (*), char (*), char (*), bit (72) aligned); dcl ios_$setsize ext entry (char (*), fixed bin(24), bit (72) aligned); dcl ios_$seek ext entry (char (*), char (*), char (*), fixed bin(24), bit (72) aligned); dcl gcos_cv_gebcd_ascii_ ext entry (pointer, fixed bin(24), pointer, fixed bin(24)); dcl cu_$arg_count ext entry (fixed bin); dcl cu_$arg_ptr ext entry (fixed bin(24), ptr, fixed bin(24), fixed bin(35)); /* Work Variables */ dcl nargs fixed bin(17); dcl argp ptr; dcl argl fixed bin(24); dcl arg char (argl) based (argp); dcl argno fixed bin(24); dcl cleanup condition; dcl err_msg char (200) varying; dcl (i1, i2, i3, i4) fixed bin(24); dcl (i, j, k, word_no) fixed bin(24); /* temps */ dcl doff fixed bin(24)init (0); dcl string char (6); dcl word_one fixed bin (35); /* first word of input file */ dcl st bit (72) aligned ; /* ios status */ dcl seek_save fixed bin(24); /* holds seek offset */ dcl 1 status aligned based (addr (st)), /* overlay for ios_ status */ 2 code fixed bin (35), /* standard error code */ 2 fill bit (9) unaligned, 2 eof bit (1) unaligned; /* eof bit */ dcl 1 preface aligned based (prefp), /* model of preface record */ 2 data_check fixed bin(24), /* checksum of following data words */ 2 rel_check fixed bin(24), /* checksum of following reloc. words */ 2 rel_abs fixed bin(24), /* 0=absolute|^0=relocatable */ 2 name bit (36) unaligned, /* name of pgm */ 2 entry bit (18) unaligned, /* entry address */ 2 origin bit (18) unaligned, /* origin */ 2 reloc_words fixed bin (17) unaligned, /* no. of relocation words */ 2 data_words fixed bin (17) unaligned, /* no. of data words */ 2 dcws (ndcw) bit (36) unaligned; /* dcw(s) to load following data records */ dcl prefp pointer; dcl ndcw fixed bin(24); dcl 1 catalog based (prefp), 2 fill fixed bin(24), 2 no_ent fixed bin(24), 2 elements (499), 3 name bit (36) aligned, 3 address fixed bin(24); dcl me char (20) init ("gcos_library_summary"); dcl version char (4) init ("2.1"); dcl (briefsw /* print names only */ , prefsw /* skip over catalog and print preface records */ , nocatsw /* no catalog - print preface records */ , usage_sw /* print usage message if error on command line */ ) bit (1) aligned init ("0"b); dcl pathname char (168) init (""); dcl (error_table_$badopt, error_table_$noarg) ext fixed bin (35); dcl (addr, divide, fixed, mod, substr) builtin; dcl 1 gcatlog aligned based (prefp), 2 gav fixed bin (17) unal, 2 gcat fixed bin (17) unal, 2 g2fil bit(36) unal, 2 gentry (15) unal, 3 gname bit(36), 3 gfill (3) bit (36), 2 g3fill bit (36) unal; dcl gcosw bit (1) init ("0"b); /* NOTE: Declaration of buffer should be last declaration in case */ /* buffer should overflow. */ dcl buffer bit (131400); /* preface and relocation blk buffer */ %page; /* P R O C E D U R E */ call ioa_ ("^a (^a)",me,version); on condition (cleanup) call cleanup_proc; call cu_$arg_count (nargs); /* IF NO ARGS, PRINT USAGE MESSAGE AND QUIT */ if nargs = 0 then do; print_usage: call ioa_ ("Usage: gcls PATH {-control_args}"); return; end; arg_loop: do argno = 1 to nargs; call cu_$arg_ptr (argno, argp, argl, code); if code ^= 0 then do; err_msg = arg; call_com_err: call com_err_ (code, me, err_msg); call cleanup_proc; if usage_sw then goto print_usage; return; end; if substr (arg, 1, 1) ^= "-" then do; if pathname ^= "" then do; err_msg = "unidentified non-control argument: " || arg; goto call_com_err; end; err_msg, pathname = arg; /* don't bother with expand_path_ since file dim does */ end; else if arg = "-bf" | arg = "-brief" then briefsw = "1"b; else if arg = "-preface" then prefsw = "1"b; else if arg = "-no_catalog" then /* ignored */ nocatsw = "1"b; else if arg = "-gc" | arg = "-gcos" then do; gcosw = "1"b; end; else do; code = error_table_$badopt; err_msg = arg; goto call_com_err; end; end arg_loop; if pathname = "" then do; /* complain if pathname not given */ code = error_table_$noarg; err_msg = ""; usage_sw = "1"b; /* print usage message after complaining */ goto call_com_err; end; prefp = addr (buffer); call ios_$attach ("gcls_input", "file_", pathname, "r", st); if status.code ^= 0 then do; err_msg = err_msg || " from ios_$attach"; goto call_com_err; end; call ios_$setsize ("gcls_input", 36, st); if status.code ^= 0 then do; err_msg = err_msg || " from ios_$setsize"; goto call_com_err; end; %page; /* gcos ** file */ if gcosw then do; call ioa_ ("Gcos ** file catalog list for ^a", pathname); get_nextg: call ios_$read ("gcls_input", prefp, 0, 64, j, st); if status.code ^= 0 then do; err_msg = err_msg || " from GCOS ios_$read"; go to call_com_err; end; do j = 1 to 15; if gcatlog.gentry (j).gname ^= "000000000000000000"b then do; call gcos_cv_gebcd_ascii_ (addr (gcatlog.gentry (j).gname), 6, addr (string), i); call ioa_ ("^a", string); end; end; if gcatlog.gcat = 0 then do; call ioa_ ("^/end of catalog."); call cleanup_proc; return; end; call ios_$seek ("gcls_input", "read", "first", gcatlog.gcat * 64, st); if status.code ^= 0 then do; err_msg = err_msg || " from GCOS ios_$seek"; go to call_com_err; end; go to get_nextg; end; %page; /* determine if the input file has a catalog: if the first word of the file =0 then this is a simulator file with a catalog if the first word not=0 then this is a native GCOS file without a catalog */ call ios_$seek ("gcls_input", "read", "first", 0, st); if code ^= 0 then do; err_msg = "from ios_$seek read first word: ^a"; goto call_com_err; end; call ios_$read ("gcls_input", addr(word_one), 0, 1, j, st); if code ^= 0 then do; err_msg = "from ios_$read of word one: ^a"; goto call_com_err; end; if word_one = 0 then nocatsw = "0"b; /* has catalog */ else nocatsw = "1"b; call ios_$seek ("gcls_input", "read", "first", 0, st); if code ^= 0 then do; err_msg = "from ios_$seek read first word: ^a"; goto call_com_err; end; %page; /* not gcos ** file */ if ^nocatsw then do; /* if file has a catalog (the default) */ if ^prefsw then do; /* and we were not requested to print preface records */ /* then print the catalog */ call ios_$read ("gcls_input", prefp, 0, 1000, j, st); /* read catalog */ if status.code ^= 0 then do; err_msg = err_msg || " from ios_$read"; goto call_com_err; end; do j = 1 to catalog.no_ent; call gcos_cv_gebcd_ascii_ (addr (catalog.elements (j).name), 6, addr (string), i); /* get name in ascii */ if briefsw then call ioa_ ("^a", string); /* print name only, if -brief given */ else call ioa_ ("^a^-^o", string, catalog.elements (j).address); /* else print name and offset */ end; call ioa_ ("^/end of catalog"); call cleanup_proc; return; end; /* END OF "PRINT CATALOG" DO GROUP */ else /* we want to skip over the catalog */ doff = 1000; /* which is exactly 1000 words long */ end; /* END OF "THERE IS A CATALOG" DO GROUP */ else doff = 0; /* no catalog to skip over */ k = 0; /* offset of first preface record (relative to doff) */ seek_preface: call ios_$seek ("gcls_input", "read", "first", k+doff, st); /* seek to start of next preface record */ if status.code ^= 0 then do; /* error ? */ err_msg = err_msg || " from ios_$seek"; goto call_com_err; end; if status.eof then do; call ioa_ ("^/end of file"); call cleanup_proc; return; end; read: call ios_$read ("gcls_input", prefp, 0, 3650, j, st); /* read preface record */ if status.code ^= 0 then do; err_msg = err_msg || " from ios_$read"; goto call_com_err; end; /* Count DCWs, by looking for one with action code = "000"b */ do ndcw = 1 to 58 /* there may be up to 58 of them in a block */ while (substr (preface.dcws (ndcw), 22, 3) ^= "000"b); end; call gcos_cv_gebcd_ascii_ (addr (preface.name), 6, addr (string), i); /* convert prog name to ascii */ if briefsw then do; /* if -brief given, print name only - and not rest of contents of preface record */ call ioa_ ("^a", string); goto next_preface; end; call ioa_ ("preface of ^a", string); i1 = fixed (preface.entry, 18); i2 = fixed (preface.origin, 18); /* convert interesting data */ i3 = preface.reloc_words; i4 = preface.data_words; call ioa_ ("entry ^w, origin ^w, reloc_words ^w, data_words, ^w", i1, i2, i3, i4); do i = 1 to ndcw; /* loop to print dcws */ i1 = fixed (preface.dcws (i)); call ioa_$nnl ("^w ", i1); end; call ioa_ ("^2/"); /* get offset of next preface record and seek to it */ next_preface: k = k+6+ndcw+preface.data_words+preface.reloc_words; /* offset of next preface block */ goto seek_preface; /* go seek to it */ cleanup_proc: proc; call ios_$detach ("gcls_input", "", "", st); return; end cleanup_proc; end gcos_library_summary;  gcos_list_patchfile.pl1 09/09/83 1357.7rew 09/09/83 1006.5 56475 /* *********************************************************** * * * Copyright, (C) Honeywell Information Systems Inc., 1982 * * * * Copyright (c) 1972 by Massachusetts Institute of * * Technology and Honeywell Information Systems, Inc. * * * *********************************************************** */ /* ******************************************************************************************* ******************************************************************************************* * * * Written by M. R. Jordan, September 1977 * ******************************************************************************************* ******************************************************************************************* */ gcos_list_patchfile: glp: proc (); dcl ME char (19) static internal options (constant) init ("gcos_list_patchfile"); dcl addr builtin; dcl arg char (arg_len) based (arg_ptr); dcl arg_index fixed bin; dcl arg_len fixed bin; dcl arg_ptr ptr; dcl ascii_module_name char (6); dcl bcd_to_ascii_ entry (bit (*), char (*)); dcl code fixed bin (35); dcl com_err_ entry options (variable); dcl cu_$arg_count entry (fixed bin); dcl cu_$arg_ptr entry (fixed bin, ptr, fixed bin, fixed bin (35)); dcl dirname char (168); dcl ename char (32); dcl error_table_$bigarg fixed bin (35) ext; dcl error_table_$improper_data_format fixed bin (35) ext; dcl error_table_$noarg fixed bin (35) ext; dcl expand_pathname_ entry (char (*), char (*), char (*), fixed bin (35)); dcl gcos_cv_ascii_gebcd_ entry (ptr, fixed bin, ptr, fixed bin); dcl hcs_$initiate entry (char (*), char (*), char (*), fixed bin (1), fixed bin (2), ptr, fixed bin (35)); dcl i fixed bin; dcl ioa_ entry options (variable); dcl ioa_$rsnnl entry options (variable); dcl length builtin; dcl module_name bit (36); dcl module_name_index fixed bin; dcl nargs fixed bin; dcl null builtin; dcl number_of_patches fixed bin; dcl patch_file_ptr ptr; dcl patch_location char (12) varying; dcl patch_ptr ptr; dcl ptr builtin; dcl substr builtin; dcl 1 patch (number_of_patches) aligned based (patch_ptr), 2 location fixed bin (17), 2 content fixed bin (35); dcl 1 patch_file aligned based (patch_file_ptr), 2 version fixed bin, 2 number_of_names fixed bin, 2 module (130560), 3 name bit (36) unal, 3 first_patch_offset bit (18) unal, 3 number_of_patches fixed bin (17) unal; call cu_$arg_count (nargs); if nargs < 1 then do; call com_err_ (error_table_$noarg, ME, "^/Usage is: gcos_list_patchfile patchfile {modulename ...}"); return; end; call cu_$arg_ptr (1, arg_ptr, arg_len, code); if code ^= 0 then do; call com_err_ (code, ME, "referencing argument 1"); return; end; call Process_Patchfile_Name (); if code ^= 0 then return; if nargs = 1 then call Print_Patch_Cards (); else do; call ioa_ ("^2/_m_o_d_u_l_e _l_o_c_a_t_i_o_n _c_o_n_t_e_n_t"); do arg_index = 2 to nargs; call cu_$arg_ptr (arg_index, arg_ptr, arg_len, code); if code ^= 0 then do; call com_err_ (code, ME, "referencing argument ^d", arg_index); return; end; if length (arg) > length (ascii_module_name) then do; code = error_table_$bigarg; call com_err_ (code, ME, """^a""", arg); end; ascii_module_name = arg; call gcos_cv_ascii_gebcd_ (addr (ascii_module_name), 6, addr (module_name), i); call Get_Module_Name_Index (); call List_Patches (); end; end; return; Process_Patchfile_Name: proc (); call expand_pathname_ (arg, dirname, ename, code); if code ^= 0 then do; call com_err_ (code, ME, """^a""", arg); return; end; call hcs_$initiate (dirname, ename, "", 0, 0, patch_file_ptr, code); if patch_file_ptr = null () then do; call com_err_ (code, ME, """^a^[>^]^a""", dirname, (dirname ^= ">"), ename); return; end; else code = 0; if patch_file.version ^= 1 then do; code = error_table_$improper_data_format; call com_err_ (code, ME, "patchfile version number is bad"); return; end; return; end Process_Patchfile_Name; Print_Patch_Cards: proc (); do module_name_index = 1 to patch_file.number_of_names; call bcd_to_ascii_ (patch_file.module (module_name_index).name, ascii_module_name); patch_ptr = ptr (patch_file_ptr, patch_file.module (module_name_index).first_patch_offset); number_of_patches = patch_file.module (module_name_index).number_of_patches; do i = 1 to number_of_patches; call ioa_$rsnnl ("^w", patch_location, 0, patch (i).location); patch_location = substr (patch_location, 7, 6); call ioa_ ("^6a^1xoctal^3x^w^45x^6a", patch_location, patch (i).content, ascii_module_name); end; end; return; end Print_Patch_Cards; Get_Module_Name_Index: proc (); dcl l fixed bin; dcl u fixed bin; dcl floor builtin; dcl divide builtin; l = 1; u = patch_file.number_of_names; do while (u >= l); module_name_index = floor (divide ((l+u), 2, 17)); if module_name < patch_file.module (module_name_index).name then u = module_name_index-1; else if module_name > patch_file.module (module_name_index).name then l = module_name_index+1; else return; end; module_name_index = 0; return; end Get_Module_Name_Index; List_Patches: proc (); if module_name_index > patch_file.number_of_names | module_name_index < 1 then do; call ioa_ ("^2/^6a^3xNO PATCHES", ascii_module_name); return; end; patch_ptr = ptr (patch_file_ptr, patch_file.module (module_name_index).first_patch_offset); number_of_patches = patch_file.module (module_name_index).number_of_patches; call ioa_ ("^2/^6a^3x^6o^3x^w", ascii_module_name, patch (1).location, patch (1).content); do i = 2 to number_of_patches; call ioa_ ("^9x^6o^3x^w", patch (i).location, patch (i).content); end; return; end List_Patches; end gcos_list_patchfile;  gcos_pull_tapefile.pl1 09/09/83 1357.7rew 09/09/83 1006.6 289944 /* *********************************************************** * * * Copyright, (C) Honeywell Information Systems Inc., 1982 * * * *********************************************************** */ gcos_pull_tapefile: gcpt: pull: proc; /* This command copies files from a GCOS tape into the Multics storage system. Since it was designed to read files from a total system tape, from which the gcos simulator libraries are built, it accepts records longer than 320 words. It reads the header label preceeding each file, prints the name and file sequence number, and asks the user if the file is to be copied. If the answer is yes, it asks for a pathname, and copies the file into it. Then it continues with the next file. This process is terminated either by a reply of "cancel", or "quit", or "q" to the question, or an end-of-reel label or partial label being encountered on the tape. USAGE: gcpt tape_number {-control_args} tape_number is a character string used in the mount message to the Multics operator. It need not match any field in the tape labels. See -attached, below. -attached, -att may be given in place of tape_number to indicate that the tape has been retained (see -retain, below) from a previous use of this command, and is therefore already mounted. -retain, -ret causes the tape to remain mounted when processing by this command is completed. This saves work for the Multics operator, if several attempts to read the tape are to be made. -detach, -det causes the tape to be detached and dismounted, before any attempt is made to attach the currently specified tape. If this is the only argument given, the tape will be detached and no other processing will take place. -skip n causes n files to be skipped over before the user is asked if files are to be copied. (Questioning starts with the n+1st file.) -gsr Allows standard size (320 word or less) records to be copied into the Multics storage system in a format readable by other Multics tools that manipulate GCOS files. Records shorter than 320 words are padded out to 320 words, allowing a read of 320 words to obtain exectly one record. This argument should not be used when reading a total system tape. -dcw Requests program to assume files are tape format System Loadable Files, as produced by SYSEDIT, and to interpret the DCW blocks, verifying their consistency with the data records, and adjusting record lengths, if necessary, before writing them to the output file. -no_label, -nl Indicates that there are no header or trailer labels, and that every file is to be treated as data. -brief, -bf Causes certain warning messages and informative messages not to be printed. -long, -lg Causes hardware status, labels, and length and first word of all data records, to be printed on the terminal. -long_brief, -lb Causes hardware status and labels, but NOT length and first word of data records, to be printed on the terminal. -debug, -db Causes db to be called after the call to com_err_ and before the call to cleanup_proc, when any errors occur. -block n Allows tape buffer size to be increased from the default of 3842 words, up to a maximum of 4096 words. -density Allows tape density to be specified. Default is 1600. WRITTEN BY T. CASEY AUGUST 1974 MODIFIED BY T.CASEY NOVEMBER 1974 TO FIX BUGS Modified: Ron Barstad 2.0 83-02-28 Changed incl query_info_ to query_info Added version indicator (start with 2.0) Modified: Ron Barstad 2.1 83-04-15 Added -density, -block and changed defaults. */ %page; /* D E C L A R A T I O N S */ %include query_info; /* External Entries */ dcl com_err_ ext entry options (variable); dcl command_query_ ext entry options (variable); dcl cu_$arg_count ext entry (fixed bin); dcl cu_$arg_ptr ext entry (fixed bin, ptr, fixed bin, fixed bin (35)); dcl cv_dec_check_ ext entry (char (*), fixed bin (35)) returns (fixed bin); dcl db ext entry; dcl decode_nstd_status_ ext entry (bit (72) aligned, char (*) varying); dcl gcos_cv_gebcd_ascii_ ext entry (ptr, fixed bin, ptr, fixed bin(21)); dcl ioa_ ext entry options (variable); dcl ios_$attach ext entry (char (*) aligned, char (*) aligned, char (*) aligned, char (*) aligned, bit (72) aligned); dcl ios_$detach ext entry (char (*) aligned, char (*) aligned, char (*) aligned, bit (72) aligned); dcl ios_$order ext entry (char (*) aligned, char (*) aligned, ptr, bit (72) aligned); dcl ios_$read ext entry (char (*) aligned, ptr, fixed bin(21), fixed bin(21), fixed bin(21), bit (72) aligned); dcl ios_$seek ext entry (char (*) aligned, char (*) aligned, char (*) aligned, fixed bin, bit (72) aligned); dcl ios_$setsize ext entry (char (*) aligned, fixed bin, bit (72) aligned); dcl ios_$tell ext entry (char (*) aligned, char (*) aligned, char (*) aligned, fixed bin(21), bit (72) aligned); dcl ios_$write ext entry (char (*) aligned, ptr, fixed bin(21), fixed bin(21), fixed bin(21), bit (72) aligned); dcl (error_table_$noarg, error_table_$badopt, error_table_$inconsistent, error_table_$ioname_not_found, error_table_$bad_arg) ext static fixed bin (35); /* Work Variables */ /* Argument processing */ dcl nargs fixed bin; dcl argp ptr; dcl argl fixed bin; dcl arg char (argl) based (argp); dcl argno fixed bin; /* Character strings */ dcl buf_arg char (32) varying; dcl buffer char (16384) aligned; /* 4096 words */ dcl den_arg char (32) varying; dcl err_msg char (200) varying; dcl pname char (168) aligned; /* pathname to copy into, given by user */ dcl err_path char (168) varying; dcl answer char (168) varying; dcl intape char (32) varying; /* tape number to read from */ dcl tape_request char (64) aligned; dcl me char (24) int static options(constant) init ("gcos_pull_tapefile (2.1)"); dcl ascii_name char (12) aligned; dcl valid_den (5) char (4) int static options(constant) init ("200", "556", "800", "1600", "6250"); /* Switches - init off */ dcl ( longsw /* print codes or labels or length and word one */ , long_brief /* do not print length and wordone */ ) bit (1) aligned int static init ("0"b); /* keep for -attach invocation */ dcl ( attached /* -attached given */ , briefsw /* -brief given */ , debugsw /* -debug given - call db if any errors occur */ , dcwsw /* -dcw given - interpret dcw blocks and delete extra words */ , detach /* -detach given */ , eorsw /* end of reel, or user said "quit" */ , gsr /* -gsr given */ , no_label /* no_label given: tape has no labels */ , notdcw /* on after inconsistent dcw block found in file */ , out_of_synch /* on if initial tape position not at header label */ , print_hdwr_status /* hardware status returned from nstd_ */ , retain /* -retain given */ , skipit /* user said -skip n and we are not yet at file n+1 */ , tape_is_attached /* either -attached given, or we attached a tape */ ) bit (1) aligned init ("0"b); /* Fixed bin */ dcl bufsize fixed bin (21); dcl ( /* fixed bin init (0) */ dcw_block_len /* computed length of dcw or data block */ , dcw_index /* index of current dcw in block */ , dcw_word_count /* sum of dcw.counts */ , expected_arg /* says which of -skip n or -block n was given */ , filecount /* which file are we at */ , i /* just an index counter */ , in_elements /* elements read from input */ , out_elements /* elements written to output */ , ndcw /* number of dcws in block */ , numeric_arg /* value of n after -skip or -block */ , read_count /* to help get back into synch */ , rec_count /* counter for tape records in one file */ , skipcount /* number of files user said to skip */ , word_count /* sum of reloc and data word counts in dcw block */ )fixed bin (21) init (0); /* To keep track of what we are expecting next from the tape */ dcl (expected_input, next_expected_input, unexpected_input) fixed bin; /* Names for things we are expecting, for program readability */ dcl ( data_to_be_copied init (1) , header_label init (2) , trailer_label init (3) , eof_after_header init (4) , eof_after_trailer init (5) , eof_after_forward_file init (6) , eof init (7) , label init (8) , data init (9) , next_file init (10) )fixed bin int static options(constant); /* Bit string */ dcl st bit (72) aligned; /* Based */ dcl code fixed bin (35) aligned based (addr (st)); dcl 1 stat_word based (addr (st)), 2 hdwr_status bit (1) unaligned, 2 fill bit (25) unaligned, 2 major bit (4) unaligned, 2 minor bit (6) unaligned, 2 word2 bit (36) aligned; /* to allow printing of second half */ dcl 1 label_model aligned based (buffp), 2 filler (8) fixed bin, 2 filename bit (72); dcl 1 partial_label aligned based (buffp), 2 fill (4) bit (36) aligned, 2 zero_words (6) bit (36) aligned, /* if all zero, this is a partial label */ 2 fill2 (4) bit (36) aligned; dcl 1 preface aligned based (buffp), /* dcw block - called preface for historical reasons */ 2 (data_check, rel_chekc, rel_abs) fixed bin (35), 2 name bit (36), 2 (entry, origin) bit (18) unaligned, 2 (reloc_words, data_words) fixed bin (17) unaligned, 2 dcw (ndcw), 3 data_addr bit (18) unaligned, 3 zero bit (3) unaligned, 3 action bit (3) unaligned, 3 count bit (12) unaligned; dcl w (4096) bit (36) aligned based (buffp); dcl wordone bit (36) aligned based (buffp); /* overlay for first word of buffer */ /* Pointer */ dcl buffp pointer; /* Builtin */ dcl (addr, divide, fixed, hbound, mod, null, rtrim, substr, unspec) builtin; dcl cleanup condition; %page; /* P R O C E D U R E */ buffp = addr (buffer); on condition (cleanup) call cleanup_proc; call cu_$arg_count (nargs); /* Initialize */ den_arg = "1600"; buf_arg = "3842"; bufsize = 3842; intape = ""; tape_request = ""; /* IF NO ARGS, PRINT USAGE MESSAGE AND QUIT */ if nargs = 0 then do; code = error_table_$noarg; err_msg = "Usage: gcpt REEL_NUMBER OR -attached {-control_args}"; goto call_com_err; end; arg_loop: do argno = 1 to nargs; call cu_$arg_ptr (argno, argp, argl, code); if code ^= 0 then do; err_msg = arg; call_com_err: call com_err_ (code, me, err_msg, err_path, numeric_arg); if print_hdwr_status then call ioa_ ("(^a)", answer); if debugsw then do; call ioa_ ("CALLING DB:"); call db; end; clean_out: call cleanup_proc; return; end; err_path = arg; /* in case of arg error */ code = 0; if expected_arg ^= 0 then do; numeric_arg = cv_dec_check_ (arg, code); if expected_arg = 1 then do; /* -skip n */ expected_arg = 0; if code ^= 0 then do; code = error_table_$bad_arg; /* cv_dec_check_ does not return an error_table_ code */ err_msg = "bad skip count: ^a"; goto call_com_err; end; skipcount = numeric_arg; end; else if expected_arg = 2 then do; /* -block n */ expected_arg = 0; if code ^= 0 then do; code = error_table_$bad_arg; bad_buf_size: err_msg = "bad buffer size: ^a"; goto call_com_err; end; if numeric_arg > 4096 then goto bad_buf_size; bufsize = numeric_arg; buf_arg = arg; end; else if expected_arg = 3 then do; /* -density n */ den_arg = ""; expected_arg = 0; if code ^= 0 then do; code = error_table_$bad_arg; err_msg = "tape density missing or contains non-numerics: ^a"; goto call_com_err; end; do i = 1 to hbound(valid_den,1); if arg = valid_den(i) then den_arg = arg; end; if den_arg = "" then do; code = error_table_$bad_arg; err_msg = "not a known tape density: ^a"; goto call_com_err; end; end; else do; err_msg = "program bug"; goto call_com_err; end; end; /* end of expected arg do group */ else if substr (arg, 1, 1) ^= "-" then do; /* must be tape number */ if intape ^= "" then do; /* if it was already given */ err_msg = "unknown non-control argument: ^a"; goto call_com_err; end; intape = arg; end; /* end of tape number do group */ else do; /* control arg */ if arg = "-att" | arg = "-attached" then do; attached = "1"b; tape_is_attached = "1"b; end; else if arg = "-bk" | arg = "-block" then expected_arg = 2; else if arg = "-db" | arg = "-debug" then debugsw = "1"b; else if arg = "-den" | arg = "-density" then expected_arg = 3; else if arg = "-dcw" then dcwsw = "1"b; else if arg = "-det" | arg = "-detach" then detach = "1"b; else if arg = "-gsr" then gsr = "1"b; else if arg = "-lg" | arg = "-long" then do; longsw = "1"b; long_brief = "0"b; end; else if arg = "-lb" | arg = "-long_brief" then longsw, long_brief = "1"b; else if arg = "-nl" | arg = "-no_label" | arg = "-no_labels" then no_label = "1"b; else if arg = "-ret" | arg = "-retain" then retain = "1"b; else if arg = "-skip" then expected_arg = 1; else if arg = "-bf" | arg = "-brief" then briefsw = "1"b; else do; code = error_table_$badopt; err_msg = "^a"; goto call_com_err; end; end; /* end control arg do group */ end arg_loop; /* Check correctness of args */ if expected_arg ^= 0 then do; err_msg = "after ^a"; code = error_table_$noarg; goto call_com_err; end; if attached then do; /* tape attached already */ if intape ^= "" then do; /* can't give tape number too */ err_msg = "tape_number and -attached"; inconsistent: code = error_table_$inconsistent; goto call_com_err; end; if detach then do; err_msg = "-detach and -attached"; goto inconsistent; end; end; /* end tape attached do group */ else do; /* tape not already attached */ if detach then do; call ios_$detach ("gcpt_input", "", "", st); if code ^= 0 then if code ^= error_table_$ioname_not_found then do; /* don't blow up if there was no tape attached */ err_msg = "from ios_$detach the previously retained tape"; goto tape_error; end; if nargs = 1 then return; /* if that's all there is to do */ detach = "0"b; /* don't detach the next tape */ end; if intape = "" then do; /* tape number must be given */ err_msg = "tape_number"; code = error_table_$noarg; goto call_com_err; end; end; /* end tape not attached do group */ /* Attach input tape */ if ^attached then do; tape_request = rtrim(intape||",den="||den_arg||",block="||buf_arg); err_path = "tape " || intape; /* for error messages */ call ios_$attach ("gcpt_input", "nstd_", tape_request, "r", st); if code ^= 0 then do; err_msg = "from ios_$attach ^a"; tape_error: /* come here from other tape errors */ if hdwr_status then do; call decode_nstd_status_ (st, answer); print_hdwr_status = "1"b; /* rember to print it after main error message */ end; else if code = error_table_$ioname_not_found then tape_is_attached = "0"b; /* tell cleanup_proc that tape was not there */ goto call_com_err; end; /* end code ^= 0 do group */ tape_is_attached = "1"b; /* for the information of cleanup_proc */ end; /* end ^attached do group */ else /* tape is attached */ err_path = "the retained tape"; /* best we can do for error messages */ /* Initialize */ /* Initialize */ query_info.suppress_name_sw = "1"b; if no_label then /* if tape has no labels */ expected_input = next_file; /* first record will be data */ else expected_input = header_label; /* otherwise it will be a header label */ /* Main read and write loop */ copyloop: do while (^eorsw); /* keep reading until end of reel or until user says "quit" */ if expected_input = eof_after_forward_file then /* if user does not want file copied */ call ios_$order ("gcpt_input", "forward_file", null, st); /* skip over all data records at once, to save time */ else do; call ios_$read ("gcpt_input", buffp, 0, bufsize, in_elements, st); /* else read data or label record */ read_count = read_count + 1; /* count reads, to help get into synch, in case initial tape position is not at header label */ end; if longsw then do; if code ^= 0 then do; call decode_nstd_status_ (st, answer); call ioa_ ("status = ^w ^w (^a)", code, word2, answer); end; else do; if in_elements ^= 14 then do; /* if not a label */ if ^long_brief then /* let user turn this off separately */ call dumper (1); /* print length and bcw of record */ end; else call dumper (2); /* this is probably a label - dump 14 words */ end; end; if code ^= 0 then do; if hdwr_status /* is it hadrware status */ & major = "0100"b /* is it an end of file mark */ & (minor = "001111"b /* eof 7track (17 octal) */ | minor = "010011"b) then do; /* eof 9track (23 octal) */ /* it was end of file */ if expected_input = eof_after_header then expected_input = next_expected_input; /* either data_to_be_copied, or eof_after_forward_file, depending on user's reply */ else if expected_input = eof_after_trailer then expected_input = header_label; else if expected_input = eof_after_forward_file then do; if no_label then /* if tape has no labels */ expected_input = next_file; /* next record will be first of next file */ else expected_input = trailer_label; /* otherwise it will be a trailer label */ end; else if expected_input = data_to_be_copied then do; /* eof after data records */ call ios_$tell ("gcpt_output", "write", "first", out_elements, st); /* see how much we wrote */ if code ^= 0 then do; err_msg = "from ios_$tell write ^a"; goto file_error; end; if mod (out_elements, 1024) ^= 0 then out_elements = out_elements+1024; /* get it in pages */ out_elements = divide (out_elements, 1024, 17, 0); /* tell user */ call ioa_ ("^d tape records read, ^d Multics records (pages) written", rec_count, out_elements); rec_count = 0; /* reset it for next file */ call ios_$detach ("gcpt_output", "", "", st); /* detach output file */ if code ^= 0 then do; err_msg = "from ios_$detach ^a"; goto file_error; end; if no_label then /* if tape has no labels */ expected_input = next_file; /* next record will be first of next file */ else expected_input = trailer_label; /* otherwise it will be trailer label */ end; else if expected_input = header_label then do; if read_count = 1 then do; /* first read - tape was not at header to start */ call ioa_ ("^a: Filemark encountered when header label expected.", me); unexpected_input = eof; tape_out_of_synch: out_of_synch = "1"b; call ioa_ ("Initial tape position was incorrect. Answer ""no"" to the following question to request search for next header label. Answer ""quit"" to terminate processing."); goto ask; end; else if out_of_synch then if unexpected_input = eof then goto double_eof; end; else if expected_input = trailer_label | expected_input = next_file then do; double_eof: call com_err_ (0, me, "Consecutive end of file marks encountered. Enter ""no"" to continue reading tape, or ""quit"" to stop."); goto ask; end; end; /* end of end-of-file do group */ /* Since nstd_ retries reads 10 times after errors, before returning to the caller, there is no point in our retrying again. It is hopeless. */ else do; if expected_input = eof_after_forward_file then err_msg = "From ios_$order forward_file ^a"; else err_msg = "From ios_$read ^a"; goto tape_error; end; end; /* end of code ^= 0 do group */ else if in_elements >= bufsize then do; err_msg = "record too long on tape ^a (^d words)"; numeric_arg = in_elements; goto call_com_err; end; else if expected_input = eof_after_header | expected_input = eof_after_trailer then do; /* if it had been there, we would have detected it above, as hardware status */ err_msg = "no filemark after label record on tape ^a"; goto tape_error; end; else if expected_input = next_file then do; /* no labels on tape */ skipit = "0"b; /* duplicate some of header label processing code */ filecount = filecount + 1; if filecount <= skipcount then skipit = "1"b; if ^skipit then do; call ioa_ ("File ^d.", filecount); if ^longsw then /* if user has seen nothing about file yet */ call dumper (3); /* print everything */ else do; /* user has seen dump, if 14 word record, or length and bcw, if ^14words and ^long_brief */ if long_brief then do; /* user has not seen length */ if in_elements ^= 14 then /* and not dump either */ call dumper (3); /* so print both */ end; /* dump without header implies 14 word length */ else do; /* user has seen something */ if in_elements ^= 14 then /* it was length and bcw */ call dumper (2); /* so dump first 14 words */ end; end; /* having told user something about the file */ goto ask_copy; /* go ask if it should be copied */ end; /* end ^skipit do group */ end; /* end expecting next file do group */ else if expected_input = header_label then do; /* if expecting header label */ check_for_header: if in_elements = 14 & wordone = "010111010101010000010000000110000000"b then do; /* (GE/b/b60) */ out_of_synch = "0"b; /* just in case it was on */ expected_input = eof_after_header; /* translate filename to ascii */ call gcos_cv_gebcd_ascii_ (addr (label_model.filename), 12, addr (ascii_name), out_elements); skipit = "0"b; filecount = filecount+1; /* bump file number */ if unspec (partial_label.zero_words) = ""b then do; skipit, eorsw = "1"b; /* partial label indicates end of tape */ call ioa_ ("Partial label (end of tape)."); end; if filecount <= skipcount then skipit = "1"b; if ^briefsw | ^skipit then if ^eorsw then call ioa_ ("File ^d. is ""^a""", filecount, ascii_name); /* Ask user if he wants to copy this file */ if ^skipit then do; ask_copy: err_msg = "Copy?"; ask: call command_query_ (addr (query_info), answer, me, err_msg); end; if skipit | answer = "no" | answer = "n" then do; if no_label then /* if unlabeled tape */ expected_input = eof_after_forward_file; /* skip to next file */ else next_expected_input = eof_after_forward_file; /* else get past eof after header first */ end; else if answer = "cancel" | answer = "quit" | answer = "q" then eorsw = "1"b; /* pretend we hit end of reel */ else if answer ^= "yes" & answer ^= "y" then do; err_msg = "Please answer ""yes"", ""no"", or ""quit"":"; goto ask; end; else do; next_expected_input = data_to_be_copied; if dcwsw then do; /* initialize dcw processing for new file */ notdcw = "0"b; ndcw = 0; end; call command_query_ (addr (query_info), answer, me, "Pathname of file to copy to:"); pname = answer; /* varying string to fixed length string */ call ios_$attach ("gcpt_output", "file_", pname, "", st); /* attach file */ if code ^= 0 then do; err_msg = "from ios_$attach ^a"; file_error: /* come here from other output file errors */ err_path = pname; goto call_com_err; end; call ios_$setsize ("gcpt_output", 36, st); /* set element size to 1 word */ if code ^= 0 then do; err_msg = "from ios_$setsize 36 ^a"; goto file_error; end; call ios_$seek ("gcpt_output", "last", "first", 0, st); /* start at beginning of file */ if code ^= 0 then do; err_msg = "from ios_$seek last first ^a"; goto file_error; end; if no_label then /* if no labels, we have the first data record */ goto copy_data; /* so go copy it */ end; /* end answer = yes */ end; /* end header label given */ else do; /* expected header label not found */ if read_count = 1 then do; if in_elements = 14 then unexpected_input = label; else unexpected_input = data; call ioa_ ("^a: Unknown record (^d words) encountered when header label expected.", me, in_elements); goto tape_out_of_synch; end; else if ^out_of_synch then call ioa_ (" ^a: Expected header label not found; will read until found", me); else if in_elements ^= 14 then /* if not some kind of label record */ expected_input = eof_after_forward_file; /* then forward space to save time */ end; end; /* end header label expected */ else if expected_input = trailer_label then do; /* if eof after file was read */ /* then we are expecting and EOF or EOR label record */ if in_elements = 14 & wordone = "010000010101100110010110010000010000"b then do; /* "/bEOF/b/b"? */ call ioa_ ("End of File"); expected_input = eof_after_trailer; end; else if in_elements = 14 & wordone = "010000010101100110101001010000010000"b then do; /* "/bEOR/b/b"? */ call ioa_ ("End of Reel"); eorsw = "1"b; /* remember eor */ end; else do; /* neither EOR nor EOF - what is it? */ if out_of_synch then do; if in_elements = 14 then /* might be header label! */ goto check_for_header; else expected_input = eof_after_forward_file; end; else call ioa_ ("^a trailer label missing. processing continues.", me); end; end; /* end trailer label expected */ else if expected_input = data_to_be_copied then do; /* if we were expecting a data record, copy it */ copy_data: rec_count = rec_count + 1; /* count tape records copied to file */ if gsr then /* if user so requested */ if in_elements < 320 then /* we will pad short records */ in_elements = 320; /* out to 320 words */ /* When the argument -dcw is given, this code assumes a tape format system loadable file, as produced by SYSEDIT, determines what the record lengths should be by looking at the dcw blocks, and whenever it finds an input record one word longer than it should be, it subtracts 1 from the length before writing it. */ if dcwsw /* if user said -dcw */ then if ^notdcw /* and we have not found inconsistencies already */ then do; /* then interpret dcw blocks */ if ndcw = 0 then do; /* if we are expecting a dcw block */ dcw_index = 1; if in_elements > 64 then do; /* too long to be a dcw block */ call ioa_ ("not dcw block: ^d words.", in_elements); goto not_dcw_block; end; else do; /* length ok for dcw block */ dcw_word_count = 0; /* sum of dcw.counts */ do ndcw = 1 to 58; /* max of 58 dcws, plus 6 others, for 64 word max */ dcw_word_count = dcw_word_count + fixed (dcw (ndcw).count); if dcw (ndcw).action = "000"b then goto end_dcw_list; end; end_dcw_list: dcw_block_len = ndcw + 6; if in_elements ^= dcw_block_len then do; if in_elements = dcw_block_len + 1 /* the case we are looking for */ then in_elements = dcw_block_len; /* fix it */ else do; /* otherwise we don't know what's happening */ call ioa_ ("not dcw block: actual block length = ^d, computed block length = ^d (^d dcws)", in_elements, dcw_block_len, ndcw); goto not_dcw_block; end; end; word_count = preface.reloc_words + preface.data_words; if dcw_word_count ^= word_count then do; call ioa_ ("not dcw block: sum of dcw.counts = ^d, but reloc + data words = ^d (^d + ^d)", dcw_word_count, word_count, preface.reloc_words, preface.data_words); goto not_dcw_block; end; end; end; else do; /* expecting data block */ dcw_block_len = fixed (dcw (dcw_index).count); if in_elements ^= dcw_block_len then do; if in_elements = dcw_block_len + 1 then /* the case we are looking for */ in_elements = dcw_block_len; else do; /* ??? */ call ioa_ ("record length = ^d, dcw.count = ^d", in_elements, dcw_block_len); goto not_dcw_block; end; end; dcw_index = dcw_index + 1; if dcw_index > ndcw then /* if we just used the last dcw */ ndcw = 0; /* expect a dcw block next */ end; /* end expecting data block */ goto write_output; not_dcw_block: notdcw = "1"b; call ioa_ ("will continue copying with no further attempts to interpret dcws"); end; /* end of entire dcw block interpreting code */ write_output: call ios_$write ("gcpt_output", buffp, 0, in_elements, out_elements, st); /* write out record into file */ if code ^= 0 then do; err_msg = "from ios_$write ^a"; goto file_error; end; if in_elements ^= out_elements then do; err_msg = "wrong number of words written to ^a (^d words)"; numeric_arg = out_elements; goto file_error; end; end; /* end of copy record do group */ else call ioa_ ("Program bug."); /* can't be else, unless the programmer blew it */ end copyloop; /* end of main loop */ /* We fall thru here when eorsw is "1"b - i.e. an end of reel record was read (or the user said to quit and we turned it on before the end of the tape) */ if retain then call ioa_ ("^a: input tape will remain attached.", me); else do; call ios_$detach ("gcpt_input", "", "", st); if code ^= 0 then do; err_msg = "from ios_$detach ^a"; goto tape_error; end; end; return; /* normal return */ /* END OF MAIN PROCEDURE */ cleanup_proc: proc; /* called on cleanup condition, and after any error in argument processing or I/O */ if retain then do; /* if user said retain */ if tape_is_attached then /* and we do have a tape attached */ call ioa_ ("^a: input tape will remain attached", me); /* let him know it's there */ end; /* and don't detach it */ else call ios_$detach ("gcpt_input", "", "", st); call ios_$detach ("gcpt_output", "", "", st); return; end cleanup_proc; dumper: proc (sw); dcl sw fixed bin; if sw = 1 | sw = 3 then /* print length and bcw */ call ioa_ ("reclen = ^d, wordone = ^w", in_elements, wordone); if sw = 2 | sw = 3 then /* dump first 14 words of record */ call ioa_ ("^3(^4(^w ^)^/^)^w ^w", w (1), w (2), w (3), w (4), w (5), w (6), w (7), w (8), w (9), w (10), w (11), w (12), w (13), w (14)); return; end dumper; /* Allow user to hit QUIT, change the long or long_brief mode, and resume processing */ gcpt_long: gcptlg: entry; dcl state char (8) aligned; buffp = addr (buffer); long_brief = "0"b; longsw = ^longsw; if longsw then do; state = "on"; end; else do; set_off: state = "off"; end; print_state: call ioa_ ("gcpt long mode set to ^a", state); return; gcpt_long_brief: gcptlb: entry; buffp = addr (buffer); long_brief = ^long_brief; if long_brief then do; longsw = "1"b; state = "brief"; goto print_state; end; else do; longsw = "0"b; goto set_off; end; end gcos_pull_tapefile;  gcos_reformat_syslib.pl1 09/09/83 1357.7rew 09/09/83 1006.6 80766 /* *********************************************************** * * * Copyright, (C) Honeywell Information Systems Inc., 1982 * * * *********************************************************** */ gcos_reformat_syslib: gcrs: ssyfix: proc; /* This command reformats the softw-syslib file (the library used by GELOAD) from the total system tape, so that it can be read by the simulator. As read from the total system tape, the file contains 321 word blocks. The first appears to be a block control word, and the next 320 make up a block that GELOAD interprets itself. If read from a 7 track MTS500, the word count is rounded up to the next even number, 322, so a word at the end must also be discarded. The number of words to be read is therefore an optional argument, with the default being 321. The first word is discarded, and the next 320 words are always retained. THe first word (the bcw) is checked for sequential bsn's, and block lengths of 320 or less, to verify that the correct record length was used for reading, and that the words being discarded are really bcw's. NOTE that this method of making the file readable by the simulator was arrived at experimentally, and is not based on any knowledge of the format of the subroutine library or the operation of GELOAD in real GCOS. If either of those changes, this command may also have to be changed. USAGE: gcrs input_path -output_path- -record_length- If output_path is not given, the modifications will be made to the input file. Since a temporary is not used, quitting and releasing while updating the input file will leave it in an inconsistent state, from which recovery is almost impossible. If record_length is not given the default is 321. Record_length is distinguished from out_path by the fact that it must be numeric. It may preceed or follow output_path, and output_path need not be given when record_length is given. WRITTEN BY T.CASEY AUGUST 1973 MODIFIED BY T. CASEY AUGUST 1974 */ /* D E C L A R A T I O N S */ dcl ioa_ ext entry options (variable); dcl com_err_ ext entry options (variable); dcl cv_dec_check_ ext entry (char (*), fixed bin (35)) returns (fixed bin); dcl ios_$attach ext entry (char (*) aligned, char (*) aligned, char (*) aligned, char (*) aligned, bit (72) aligned); dcl ios_$detach ext entry (char (*) aligned, char (*) aligned, char (*) aligned, bit (72) aligned); dcl ios_$read ext entry (char (*) aligned, ptr, fixed bin, fixed bin, fixed bin, bit (72) aligned); dcl ios_$seek ext entry (char (*) aligned, char (*) aligned, char (*) aligned, fixed bin, bit (72) aligned); dcl ios_$setsize ext entry (char (*) aligned, fixed bin, bit (72) aligned); dcl ios_$write ext entry (char (*) aligned, ptr, fixed bin, fixed bin, fixed bin, bit (72) aligned); dcl cu_$arg_count ext entry (fixed bin); dcl cu_$arg_ptr ext entry (fixed bin, ptr, fixed bin, fixed bin (35)); /* Work Variables */ dcl nargs fixed bin; dcl argp ptr; dcl argl fixed bin; dcl arg char (argl) based (argp); dcl argno fixed bin; dcl err_msg char (200) varying; dcl err_path char (168) varying; dcl eofbit bit (1) aligned; dcl buffer char (1600) aligned; /* 400 words */ dcl blkp ptr; dcl 1 block aligned based (blkp), 2 bcw, 3 bsn bit (18) unaligned, 3 count bit (18) unaligned; dcl old_bsn fixed bin init (0); /* bsns must begin with 1 */ dcl new_bsn fixed bin; dcl rec_len fixed bin init (321); dcl (i, j, k) fixed bin; /* temporaries */ dcl status bit (72) aligned init (""b); dcl code fixed bin (35) aligned based (addr (status)); dcl (inpath, outpath) char (168) aligned init (""); dcl (instream, outstream) char (32) aligned init (""); dcl me char (20) int static aligned init ("gcos_reformat_syslib"); dcl rw char (1) aligned; dcl (addr, fixed, substr) builtin; dcl cleanup condition; /* P R O C E D U R E */ blkp = addr (buffer); on condition (cleanup) call cleanup_proc; call cu_$arg_count (nargs); /* IF WRONG NUMBER OF ARGS, PRINT USAGE MESSAGE AND QUIT */ if nargs = 0 | nargs > 3 then do; err_msg = "USAGE: gcrs input_path -output_path-"; goto call_com_err; end; arg_loop: do argno = 1 to nargs; call cu_$arg_ptr (argno, argp, argl, code); if code ^= 0 then do; err_msg = arg; call_com_err: call com_err_ (code, me, err_msg, err_path); call cleanup_proc; return; end; err_path = arg; if argno = 1 then do; /* default is to update input file */ inpath, outpath = arg; instream, outstream = "gcrs_i/o"; rw = " "; /* equivalent to "rw" for ios_$attach */ end; else do; /* see if output_path or record len */ i = cv_dec_check_ (arg, code); if code ^= 0 then do; /* non numeric */ code = 0; /* clear it - its not an error_table_ code */ if outpath ^= inpath then do; /* outpath already given */ err_msg = "Unknown argument: ^a"; goto call_com_err; end; /* end outpath given */ else do; /* outpath not given - assume this is it */ outpath = arg; outstream = "gcrs_output"; instream = "gcrs_input"; rw = "r"; /* attach input file for read only */ end; /* end assume outpath */ end; /* end non numeric */ else rec_len = i; /* numeric - assume rec_len */ end; /* end not firt arg */ end arg_loop; /* Initialize and attach files */ err_path = inpath; /* in case of error */ call ios_$attach (instream, "file_", inpath, rw, status); if code ^= 0 then do; attach_error: err_msg = "from ios_$attach ^a"; goto call_com_err; end; call ios_$setsize (instream, 36, status); if code ^= 0 then do; setsize_error: err_msg = "from ios_$setsize 36 ^a"; goto call_com_err; end; err_path = outpath; /* more possibilities of output errors now */ if outstream ^= instream then do; /* if separate output file */ call ios_$attach (outstream, "file_", outpath, "", status); if code ^= 0 then goto attach_error; call ios_$setsize (outstream, 36, status); if code ^= 0 then goto setsize_error; end; /* whether or not input and output are the same, seek the output write pointer to the beginning of the file */ call ios_$seek (outstream, "write", "first", 0, status); if code ^= 0 then do; err_msg = "from ios_$seek write first ^a"; goto call_com_err; end; /* Main loop */ read: call ios_$read (instream, blkp, 0, rec_len, i, status); eofbit = substr (status, 46, 1); /* remember end of file indicator */ if code ^= 0 then do; err_msg = "from ios_$read ^a"; input_error: err_path = inpath; goto call_com_err; end; new_bsn = fixed (bsn); if new_bsn ^= old_bsn + 1 then call ioa_ ("^a: block serial number error: previous bsn = ^d, current bsn = ^d.Processing continues", me, old_bsn, new_bsn); old_bsn = new_bsn; k = fixed (bcw.count); if k > 320 then call ioa_ ("^a: bad bcw count: ^d in block ^d. Processing continues.", me, k, new_bsn); if i = rec_len then i = 320; /* throw away the rcw */ else call ioa_ ("^a: short block read: ^d words in block ^d. Processing continues.", me, i, new_bsn); call ios_$write (outstream, blkp, 1, i, j, status); /* the offset of 1 is what gets rid of the rcw */ if code ^= 0 then do; err_msg = "from ios_$write ^a"; goto call_com_err; end; if i ^= j then do; err_msg = "wrong number of words written to ^a"; goto call_com_err; end; if ^eofbit then goto read; /* go read next record if there is one */ else do; /* end of file */ call ioa_ ("^a: Normal end of file on ^a", me, inpath); if instream = outstream then do; /* if updating input file */ call ios_$seek (instream, "last", "write", 0, status); /* get rid of garbage at end */ if code ^= 0 then do; err_msg = "from ios_$seek last write ^a"; goto call_com_err; end; end; call ios_$detach (instream, "", "", status); if code ^= 0 then do; err_msg = "from ios_$detach ^a"; goto input_error; end; if instream ^= outstream then do; /* if separate output file, detach it too */ call ios_$detach (outstream, "", "", status); if code ^= 0 then do; err_msg = "from ios_$detach ^a"; goto call_com_err; end; end; return; end; /* end of end of file do group */ cleanup_proc: proc; call ios_$detach (instream, "", "", status); call ios_$detach (outstream, "", "", status); if code = 0 then /* if this is cleanup handler */ if instream = outstream then if instream ^= "" then call ioa_ ("^a: WARNING: ^a may have been left in an inconsistent state", me, inpath); return; end cleanup_proc; end gcos_reformat_syslib;  gcos_tss_build_library.pl1 04/09/85 1704.7r w 04/08/85 1131.8 401940 /* *********************************************************** * * * Copyright, (C) Honeywell Information Systems Inc., 1983 * * * *********************************************************** */ /* format: style1,^inddcls,ind4 */ gcos_tss_build_library: gtbl: proc; /**** Build or update the GTSS fast load software library from all or selected parts of GCOS software files (native or GES) and update the GTSS program descriptors. Based on the command "gcos_lib_obtain_modules" or "glom" Usage: gtbl INPUT_LIBS {-control_args} INPUT_LIBS are paths of one or more gcos software files the files may be either native GCOS or simulator format -control_args := -module_file PATH, -mf PATH a segment containing a list of modules to be moved from INPUT_LIBS to output -modules STR..., -mods STR... names of modules to be moved -program_descriptors PATH, -prgdes PATH path of a gtss_prgdes_alm_.incl.alm to be updated -output_library PATH, -olb PATH path of the gtss_fast_library_ -print_catalog, -prcat print contents of GES format INPUT_LIBS -brief, -bf don't print catalog or modules moved Created: Dave Ward 78-04-18 As glom Modified: Ron Barstad 83-03-03 1.0 Changed name to gtbl, added version 1.0 Changed to standard or current conventions Changed command line -cf to -module_file -nm to -modules -ol to -output_library -no_cat to -format added -program_descriptors deleted -olli Changed reference to XIO to gcos_xio_ Changed reference to HASH to gfms_hash_ Moved inits from dcl to procedure Changed gtss_bcd_ascii_ calls to gfms_bcd_ascii_ Fixed msf boundry bug, each object wholly contained in a segment. Added prgdes update functionality Modified: Ron Barstad 83-04-14 1.1 Removed need for -format, determine this by inspection */ %page; /**** P R O C E D U R E */ call cu_$arg_count (nargs, e); if e = 0 & nargs < 1 then e = error_table_$noarg; if e ^= 0 then do; call com_err_ (e, ME, "^/Usage: gtbl INPUT_LIBS {-control_args}"); return; end; on condition (cleanup) call closer; /**** Initialize */ /* format: off */ all_mods = TRUE; brief = FALSE; get_mod_name = FALSE; need_1_mod_name = FALSE; no_cat = FALSE; prgdes = FALSE; open_prgdes = FALSE; have_output_lib = FALSE; process_mf = FALSE; process_ol = FALSE; pr_cat = FALSE; catl = 1000; /* length of catalog at front of GES format lib. */ catl_parm = 0; cc = -1; copy_names.start = 0; dcwbc = 0; init_nm = 0; libc = 0; msw = sys_info$max_seg_size; ndcw = 1; obj_num = 0; outc = -1; outl = 0; wdl = 0; copy_names.nm = 0; lib_stack.libn = 0; input_lib_path = "NONE"; output_lib_path = "NONE"; path = "NONE"; prgdes_path = "NO_PRGDES"; mf_fcbp = null(); lib_fcbp = null(); out_fcbp = null(); prgdes_fcbp = null(); outp = null(); dcwbp = null(); eo_word_loc = null(); reloc_word_loc = null(); rd_word_loc = null(); dcw_loc = null(); call date_time_ (clock_(), run_date); /* format: on */ %page; /* Process command line */ do arg_num = 1 to nargs; call cu_$arg_ptr (arg_num, ap, al, e); if e ^= 0 then do; call com_err_ (e, ME, "Argument ^i", arg_num); goto close_files; end; if al < 1 then do; call com_err_ (error_table_$bad_arg, ME, "Zero length parameter (^i). Quitting.", arg_num); goto close_files; end; if substr (arg, 1, 1) = "-" then get_mod_name = FALSE; if get_mod_name then do; need_1_mod_name = FALSE; /* Regulates reporting name missing. */ call next_mod_name (ap, al); end; else if process_mf then call get_module_file; /* Obtain control file and names therein. */ else if process_ol then call get_out_lib; /* Obtain output file. */ else if open_prgdes then call get_prgdes_file; else if (arg = "-prgdes") | (arg = "-program_descriptors") then open_prgdes = TRUE; else if (arg = "-bf") | (arg = "-brief") then brief = TRUE; else if (arg = "-module_file") | (arg = "-mf") then process_mf = TRUE; else if (arg = "-output_library") | (arg = "-olb") then process_ol = TRUE; else if (arg = "-print_catalog") | (arg = "-prcat") then pr_cat = TRUE; else if (arg = "-modules") | (arg = "-mods") | (arg = "-module") | (arg = "-mod") then get_mod_name, need_1_mod_name = TRUE; else if substr (arg, 1, 1) = "-" then do; call com_err_ (error_table_$badopt, ME, "Unknown option ""^a"". Quitting.", arg); goto close_files; end; else call stack_lib_path; end; %page; /**** Verify that caller's parameters are acceptable. */ if libn < 1 then do; call com_err_ (error_table_$noarg, ME, "At least one input library must be specified. Quitting."); goto close_files; end; if need_1_mod_name then do; call com_err_ (error_table_$noarg, ME, "Missing module name for -modules. Quitting."); goto close_files; end; if open_prgdes then do; call com_err_ (error_table_$noarg, ME, "No path supplied for -prgdes. Quitting."); goto close_files; end; if process_mf then do; call com_err_ (error_table_$noarg, ME, "No module path supplied for -module_file. Quitting."); goto close_files; end; if process_ol then do; call com_err_ (error_table_$noarg, ME, "Missing output path for -output_library. Quitting."); goto close_files; end; /**** check for some possibly incompatable parameters */ if prgdes & ^have_output_lib then call ioa_$ioa_stream ("error_output", "^/Warning: no output library was specified, the program descriptors will not be updated."); else if ^prgdes & have_output_lib then call ioa_$ioa_stream ("error_output", "^/Warning: the output library will be updated but no program descriptor file was specified."); /**** give run date_time */ if prgdes then call ioa_ ("Updated program descriptors will be labeled ""^a"".", run_date); %page; /**** Process input libraries. */ max_dcw_count = 2 ** length (addr (i) -> dcw.count);/* Constant => if count=0. */ init_nm = nm; if nm > 0 then all_mods = FALSE; /* Specific modules selected. */ libc = 0; /* Current library. */ next_input_library: ; libc = libc + 1; if libc > libn then do; /* All input libraries processed. */ if nm > 0 then do; if nm = 1 then call ioa_$ioa_stream ("error_output", "Specified module not found on input libraries."); else call ioa_$ioa_stream ("error_output", "^i specified modules not found on input libraries.", nm); if ^brief then do; j = 0; do k = 1 to init_nm; if link (k) > -1 then do; j = j + 1; call ioa_$ioa_stream ("error_output", "^4i. ""^a""", j, mod_name (k)); end; end; end; end; goto close_files; end; if get_input_lib () then goto next_input_library; /* Could not obtain it. */ /*** look at the first word of the library to see if it is native gcos or simulator format */ if cp (0) -> just_a_word = "0"b then catl = 1000; /* simulator library */ else catl = 0; /* native gcos format */ if pr_cat then call print_catalog; if (brief) & (out_fcbp = null ()) & (nm = 0) then goto next_input_library; next_dcw_block: ; fw = fw + obj_len; rl = rl - obj_len; if rl > 0 then dcwbp = addrel (dcwbp, obj_len); else if word (catl + fw, dcwbp, rl, cc) then goto next_input_library; /*** Obtain pointer to relocation bit word (3). */ call get_dcw_block_word (3, reloc_word_loc); /*** Locate name field on dcw block record. (4th word). */ call get_dcw_block_word (4, name_loc); call gfms_bcd_ascii_ (name_loc, 6, addr (name_chars)); dcwbc = dcwbc + 1; /* Count of dcw blocks. */ nl = search (name_chars, " ") - 1; if nl < 0 then nl = length (name_chars); call calculate_object_length (obj_len, total_dcw_count, initial_load_address); if obj_len < 1 then do; if (fw = 1) & (catl ^= 0) then do; call ioa_$ioa_stream ("error_output", "Attempting native GCOS format for ""^a"".", input_lib_path); rl, obj_len, catl = 0; goto next_dcw_block; end; call com_err_ (error_table_$improper_data_format, ME, "Object length calculation negative for ""^a"". Library ""^a"" skipped.", name_chars, input_lib_path); goto next_input_library; end; if all_mods then f = TRUE; else f = lookup (obj_name); if f then do; /* Object named in input library is a module caller specified. */ if ^have_output_lib then do; if ^brief then call ioa_ ("Found module ""^a"" in ^a.", name_chars, input_lib_path); end; else do; /* have output lib */ if ^prgdes then call copy_obj; else do; /* have prgdes */ if 0 = index (substr (prgdes_seg, start_prgdes, end_prgdes - start_prgdes), "," || obj_name) then do; /* but prgdes doesn't have module */ if ^brief then call ioa_ ( "Call name ""^a"" not found in ^a. Did not add module to ^a.", name_chars, prgdes_path, output_lib_path); end; else /* have out lib, prgdes, and call name */ call copy_obj; end; end; /**** debug */ if Debug then do; obj_num = obj_num + 1; if obj_num = 1 then do; /* Output header. */ call ioa_ ( "^15xOBJECT DATA RELOC"); call ioa_ ( "^7xNAME^3x^3( WORDS^)^3xDCWS OBJECT COMP REMAIN PATH"); end; call ioa_ ( "^4i. ""^a""^vx^7(^1x^6i^) ^a" , obj_num /** Count of objects found. */ , name_chars /** Name of object. */ , max (0, 6 - nl) /** Align next field. */ , obj_len /** No. words in object. */ , data_wds /** No. data words. */ , reloc_wds /** No. relocation words. */ , ndcw /** No. DCW's. */ , dcwbc /** Which object on library. */ , cc /** Which msf component of library. */ , rl /** Words remaining in component. */ , input_lib_path /** Multics file name of library. */ ); end; end; if all_mods then goto next_dcw_block; if nm > 0 then goto next_dcw_block; close_files: ; call closer; return; %page; db: entry; Debug = ^Debug; return; dcl Debug bit (1) static int init ("0"b); %page; /**** Command line processing procedures */ get_module_file: proc; e = open_file (arg, mf_fcbp); if mf_fcbp ^= null () then call msf_manager_$get_ptr (mf_fcbp, 0, USE_EXISTING_COMPONENTS, mfp, mfl, e); if e ^= 0 then do; call com_err_ (e, ME, "Module file ""^a"". Quitting.", path); goto close_files; end; mfl = divide (mfl, 9, 24, 0); /* Number characters in control file. */ process_mf = FALSE; j = 1; do while (j <= mfl); k = search (substr (mf, j), NL); if k < 1 then k = mfl - j + 2; if k > 1 then call next_mod_name (addr (mfa (j)), k - 1); j = j + k; end; end get_module_file; %page; get_prgdes_file: proc; if prgdes then do; call com_err_ (error_table_$inconsistent, ME, "File ""^a"" already open for prgdes. Quitting.", prgdes_path); goto close_files; end; prgdes_path = arg; call expand_pathname_ (prgdes_path, prgdes_dir, prgdes_entry, e); if e ^= 0 then goto bad_prgdes_path; call initiate_file_ (prgdes_dir, prgdes_entry, RW_ACCESS, prgdes_seg_ptr, prgdes_bit_count, e); if e ^= 0 then do; bad_prgdes_path: call com_err_ (e, ME, "^/Program descriptor file ""^a"" not available. Quitting.", prgdes_path); goto close_files; end; prgdes_seg_size = divide (prgdes_bit_count, 9, 24); start_prgdes = index (prgdes_seg, "Program descriptor 1.") + 22; end_prgdes = index (prgdes_seg, "Program descriptor end."); reverse_PRGDES = reverse ("PRGDES "); reverse_prog_desc = reverse ("Program descriptor "); open_prgdes = FALSE; prgdes = TRUE; return; end get_prgdes_file; %page; get_out_lib: proc; if out_fcbp ^= null () then do; call com_err_ (error_table_$inconsistent, ME, "Output library ""^a"" already open. Quitting.", output_lib_path); goto close_files; end; process_ol = FALSE; have_output_lib = TRUE; e = open_file (arg, out_fcbp); output_lib_path = path; if e ^= 0 then if e = error_table_$noentry then do; /* New output. */ outc = -1; /* so first output component will be 0 */ call next_out_comp; outp -> fast_lib_header.id = "gtssflib"; outp -> fast_lib_header.num_objects = 0; outl = FAST_LIB_HEADER_LENGTH; /* Position past the header. */ return; end; else do; out_fail: ; call com_err_ (e, ME, "Could not obtain output ""^a"". Quitting.", output_lib_path); goto close_files; end; last_outc, outc = 0; /* init output msf component */ e = 0; do while (e = 0); /* Position to the end of the output library. */ call msf_manager_$get_ptr (out_fcbp, outc, USE_EXISTING_COMPONENTS, outp, outl, e); if outc = 0 then if outp -> fast_lib_header.id ^= "gtssflib" then do; call com_err_ (error_table_$improper_data_format, ME, "Output library ""^a"" header not ""gtssflib"". Quitting.", output_lib_path); goto close_files; end; if e = 0 then do; last_outc = outc; last_outl = outl; last_outp = outp; outc = outc + 1; end; else if e ^= error_table_$noentry then goto out_fail; end; outc = last_outc; outp = last_outp; outl = last_outl; if mod (outl, 36) ^= 0 then do; call com_err_ (e, ME, "Component ^i of msf ""^a"" bit count (^i) not modulo 36. Quitting.", outc, output_lib_path, outl); goto close_files; end; outl = divide (outl, 36, 24, 0); return; dcl e fixed bin (35); /* error code */ dcl last_outc fixed bin (24); dcl last_outl fixed bin (24); dcl last_outp ptr; end get_out_lib; %page; stack_lib_path: proc; /**** Stack pointer to and length of library pathname. */ libn = libn + 1; if libn > hbound (input_lib, 1) then do; if (libn - 1) = hbound (input_lib, 1) then call com_err_ (error_table_$too_many_names, ME, "Only provision for ^i input libraries. None starting with ""^a"" used.", hbound (input_lib, 1), arg); end; else do; lib_name_loc (libn) = ap; lib_name_len (libn) = al; end; return; end stack_lib_path; %page; /**** Main procedures */ calculate_object_length: proc (ol, tc, da); /**** Set parameter (ol) to the total length of the next input library object, i.e., length of dcw block (6 + number of dcw's) plus the length of object data words and relocation words. Set parameter (tc) to the total of the dcw count fields values. Set parameter (da) to data address in first DCW. */ dcl ol fixed bin (24) parm; /* object length */ dcl tc fixed bin (24) parm; /* total count, dcw content fields */ dcl da fixed bin (24) parm; /* data address */ call get_dcw_block_word (6, rd_word_loc); /* Obtain pointer to reloc/data words. */ ndcw = 0; /* Count of DCW's. */ t = 0; /* Totoal of DCW counts. */ done_with_dcws = FALSE; do dcw_index = 1 to 58 while (done_with_dcws = FALSE); call get_dcw_block_word (6 + dcw_index, dcw_loc); ndcw = ndcw + 1; if count then t = t + fixed (count); else t = t + max_dcw_count; if dcw_index = 1 then da = fixed (data_address); if action = "000"b then done_with_dcws = TRUE; end; tc = t; ol = 6 + reloc_wds + data_wds + ndcw; return; dcl dcw_index fixed bin (24); dcl done_with_dcws bit (1); dcl t fixed bin (24); /* total count */ end calculate_object_length; %page; closer: proc; /**** Release spaces for file control blocks and terminate files. */ if lib_fcbp ^= null () then call msf_manager_$close (lib_fcbp); if out_fcbp ^= null () then do; /*** Set count of objects in file header. */ call msf_manager_$get_ptr (out_fcbp, 0, USE_EXISTING_COMPONENTS, outp, (outl), e); if e ^= 0 then call com_err_ (e, ME, "Unable to store number of objects (^i) in header.", obj_num); else outp -> fast_lib_header.num_objects = outp -> fast_lib_header.num_objects + obj_num; call msf_manager_$adjust (out_fcbp, outc, outl * 36, "111"b, e); if e ^= 0 then call com_err_ (e, ME, "Setting bit count to ^i words for ""^a"", component ^i", outl, output_lib_path, outc); call msf_manager_$close (out_fcbp); end; if mf_fcbp ^= null () then call msf_manager_$close (mf_fcbp); if prgdes then do; prgdes_bit_count = prgdes_seg_size * 9; /* 9 bits to a byte */ call terminate_file_ (prgdes_seg_ptr, prgdes_bit_count, TERM_FILE_TRUNC_BC_TERM, e); /* e doesn't matter*/ end; return; end closer; %page; copy_obj: proc; /**** Copy to the output library. */ calc_out_length: ; if (msw - outl - OBJECT_HEADER_LENGTH - obj_len) < 1 then do; call next_out_comp; goto calc_out_length; end; out_length = msw - outl; /* Words remaining in current output component. */ /*** Output object header. */ out_ptr = addr (out (outl + 1)); /* Pointer to next output word. */ out_ptr -> object_header.marker = MARKER; out_ptr -> object_header.obj_name = obj_name; out_ptr -> object_header.obj_len_wds = obj_len; out_ptr = addr (out_ptr -> object_header.obj_word1); out_length = out_length - OBJECT_HEADER_LENGTH; f, outl = outl + OBJECT_HEADER_LENGTH; out_ptr = addr (out (outl + 1)); /* Pointer to next output word. */ in_ptr = dcwbp; /* Pointer to next input word. */ remain_words = rl; total_moved = 0; in_length = obj_len; /* Words to move. */ do while (in_length > 0); words_moved = min (remain_words, in_length, out_length); /* Number of words to move. */ chars_moved = words_moved * 4; /* Number of characters to move. */ out_ptr -> move_seg = in_ptr -> move_seg; outl = outl + words_moved; in_length = in_length - words_moved; if in_length > 0 then do; /* More to move. */ total_moved = total_moved + words_moved; out_length = out_length - words_moved; if out_length > 0 then out_ptr = addr (out (msw - out_length + 1)); else do; call next_out_comp; out_ptr = outp; out_length = msw; end; remain_words = remain_words - words_moved; if remain_words > 0 then in_ptr = addrel (in_ptr, words_moved); else /* Position to next input library component. */ if word (catl + fw + total_moved, in_ptr, remain_words, cc2) then do; call com_err_ (error_table_$improper_data_format, ME, "Move of object ""^a"" exceeded input library ""^a"" component ^i. Quitting", name_chars, input_lib_path, nc); goto close_files; end; end; end; if (reloc_abs) | (reloc_wds > 0) then call com_err_ (error_table_$improper_data_format, ME, "Warning, relocation specified (^1b ^i words) object ""^a"", library ""^a""", reloc_abs, reloc_wds, obj_name, input_lib_path); if total_dcw_count ^= data_words then /* Lengths differ. */ call com_err_ (error_table_$improper_data_format, ME, "Object ""^a"" total dcw count = ^i, data words = ^i (lib ^a).", obj_name, total_dcw_count, data_wds, input_lib_path); if ^brief then call ioa_ ("Added module ""^a"" from ^a.", name_chars, input_lib_path); /**** now add entry to program descriptors */ if prgdes then do; /*** Obtain pointer to entry location word (5). */ call get_dcw_block_word (5, eo_word_loc); dcw_block_wds = 6 + ndcw; initial_load_address = initial_load_address - 1024; /* Minus 2000 octal, related to GCOS usage. */ if Debug then if initial_load_address < 66 then /* => 102 octal. */ call com_err_ (error_table_$improper_data_format, ME, "Object ""^a"" biased entry = ^i (lib ^a).", obj_name, initial_load_address, input_lib_path); call update_prgdes (obj_name , 1 /** Library number. */ , fixed (outc, 24) /** Output component. */ , f + dcw_block_wds /** Offset to object. */ , data_words + initial_load_address /** Program size (words). */ , fixed (data_words, 24) /** Object length (words). */ , fixed (entry_loc) /** Entry point. */ , initial_load_address /** Initial load address. */ ); end; return; dcl total_moved fixed bin (24); /* total words moved in this object */ dcl dcw_block_wds fixed bin (24); dcl f fixed bin (24); dcl in_length fixed bin (24); /* words left in input seg */ dcl out_length fixed bin (24); /* words left in output seg */ dcl words_moved fixed bin (24); /* number of words moved from in to out segs */ dcl chars_moved fixed bin (24); /* 4 times the words moved */ dcl min builtin; dcl move_seg char (chars_moved) based aligned; /* the Move Segment */ dcl out (msw) bit (36) aligned based (outp); dcl in_ptr ptr; dcl out_ptr ptr; dcl remain_words fixed bin (24); /* the number of words left in input to move */ end copy_obj; %page; get_dcw_block_word: proc (n, p); /**** Set (p) to n-th word of dcw block. */ dcl n fixed bin (24) parm; /* dcw block word number */ dcl p ptr parm; /* dcw ptr */ offset = n - 1; if rl > offset then do; p = addrel (dcwbp, offset); return; end; if word (catl + fw + offset, p, r, c) then do; call com_err_ (error_table_$improper_data_format, ME, "Input terminates with incomplete dcw block. Quitting."); goto close_files; end; return; dcl r fixed bin (24); dcl c fixed bin (24); dcl offset fixed bin (24); end get_dcw_block_word; %page; get_input_lib: proc returns (bit (1)); /**** Return TRUE if next input library could NOT be obtained. */ fw = 1; /* First word. */ obj_len = 0; /* Length of current object. */ rl = 0; /* Remaining length of component segment. */ if lib_fcbp ^= null () then /* Close last library. */ call msf_manager_$close (lib_fcbp); e = open_file (lib_name, lib_fcbp); if e ^= 0 then do; call com_err_ (e, ME, "Library ""^a"" not available. Library skipped.", path); return (TRUE); end; input_lib_path = path; /*** Obtain list of pointers to components and their word lengths. */ do nc = 0 to hbound (comp, 1); cp (nc) = null (); wl (nc) = 0; call msf_manager_$get_ptr (lib_fcbp, nc, USE_EXISTING_COMPONENTS, cp (nc), bc, e); if e ^= 0 then do; if (e = error_table_$noentry) & (nc > 0) then return (FALSE); call com_err_ (e, ME, "Component ^i. ^a. Library skipped.", nc, input_lib_path); return (TRUE); end; if mod (bc, 36) ^= 0 then do; call com_err_ (error_table_$bad_file, ME, "Component ^i of ^a bit count (^i) not multiple of 36. Library skipped.", nc, input_lib_path, bc); return (TRUE); end; wl (nc) = divide (bc, 36, 24, 0); end; call com_err_ (error_table_$bad_file, ME, "Exceeded ^i components in ^a. Library skipped.", hbound (comp, 1) + 1, input_lib_path); return (TRUE); dcl lib_name char (lib_name_len (libc)) based (lib_name_loc (libc)); end get_input_lib; %page; lookup: proc (lookup_name) returns (bit (1)); /**** Return TRUE if lookup_name is specified in module names list. */ dcl lookup_name char (6) var parm; k = gfms_hash_ ((lookup_name), hbound (start, 1) + 1); ln = 0; n = start (k); do while (n > 0); /* Search linked list. */ if lookup_name = mod_name (n) then do; /* Found. */ if ln = 0 then start (k) = link (n); /* Start with next entry. */ else link (ln) = link (n); /* Link around entry. */ link (n) = -1; /* Mark entry found. */ nm = nm - 1; /* Reduce name count. */ return (TRUE); end; ln = n; /* Record last entry. */ n = link (n); /* Proceed to next entry. */ end; return (FALSE); /* Not found. */ dcl k fixed bin (24); dcl n fixed bin (24); dcl ln fixed bin (24); end lookup; %page; next_mod_name: proc (p, l); /**** Store next module name (upper cased) in hash list. */ dcl l fixed bin (24) parm; dcl p ptr parm; if l > 6 then call com_err_ (error_table_$bigarg, ME, "Module name ""^a"" truncated to 6 characters.", name); nm = nm + 1; if nm > hbound (hash_list, 1) then do; if (nm - 1) = hbound (hash_list, 1) then call com_err_ (error_table_$too_many_names, ME, "Only space for ^i module names. Names starting with ""^a"" lost.", hbound (hash_list, 1), name); end; else do; mod_name (nm) = translate (name , "ABCDEFGHIJKLMNOPQRSTUVWXYZ" , "abcdefghijklmnopqrstuvwxyz" ); /*** Store name in hash list. */ k = gfms_hash_ ((mod_name (nm)), hbound (start, 1) + 1); link (nm) = start (k); start (k) = nm; end; return; dcl name char (l) based (p); dcl k fixed bin (24); end next_mod_name; %page; next_out_comp: proc; /**** Obtain next output msf component. */ outc = outc + 1; call msf_manager_$get_ptr (out_fcbp, outc, PROVIDE_NEW_COMPONENTS, outp, outl, e); if e ^= 0 then do; call com_err_ (e, ME, "Can not obtain output ""^a"". Quitting.", output_lib_path); goto close_files; end; if mod (outl, 36) ^= 0 then do; call com_err_ (e, ME, "Component ^i of msf ""^a"" bit count (^i) not modulo 36. Quitting.", outc, output_lib_path, outl); goto close_files; end; outl = divide (outl, 36, 24, 0); return; end next_out_comp; %page; open_file: proc (arg, fcbp) returns (fixed bin (35)); /**** Set file control block pointer (fcbp) to the msf file named by (arg). Return msf_manager error code. */ dcl arg char (*) parm; dcl fcbp ptr parm; l = length (arg); k = search (reverse (arg), ">"); if k > 0 then do; /* User supplied directory. */ dir = substr (arg, 1, l - k); msf = substr (arg, l - k + 2); end; else do; if wdl = 0 then do; wd = get_wdir_ (); wdl = search (wd, " ") - 1; if wdl < 0 then wdl = length (wd); end; dir = substr (wd, 1, wdl); msf = arg; end; path = dir || ">" || msf; /*** Open the input library file. */ fcbp = null (); call msf_manager_$open ((dir), (msf), fcbp, e); return (e); dcl dir char (168) var; dcl e fixed bin (35); /* error code */ dcl k fixed bin (24); /* position of > before enttry name */ dcl l fixed bin (24); /* arg length of path */ dcl msf char (32) var; end open_file; %page; print_catalog: proc; catp = null (); if catl = 0 then call ioa_ ("^/Library ^a appears to be native gcos and has no catalog.", input_lib_path); else do; catp = cp (0); call ioa_ ("Catalog for ^a:", input_lib_path); do i = 1 to catalog.no_ent; call gfms_bcd_ascii_ (addr (catalog.elements (i).name), 6, addr (name_chars)); call ioa_ ("^4i.^-^a^-^o", i, name_chars, catalog.elements (i).address); end; end; return; dcl i fixed bin (24); dcl catp ptr; dcl 1 catalog aligned based (catp), 2 fill fixed bin (24), 2 no_ent fixed bin (24), 2 elements (no_ent), 3 name bit (36), 3 address fixed bin (24); end print_catalog; %page; update_prgdes: proc (call_name, lib_num, comp_num, offset, prog_size, load_size, entry_pt, load_addr); /**** Update prgdes_path with program descriptor info for call_name The seg named by prgdes_path (which is a copy of gtss_prgdes_alm_.incl.alm) MUST be in the following format: 1---------------------------------------------------------------------------- segdef prgdes prgdes: null " Program descriptor 1. CARD: PRGDES 0,0,0,0,0,0,0, card,(CARDCL,1),,.BCMCL label: PRGDES STR1,STR2,{,STRi} " Program descriptor . CMDL: PRGDES cmdl,EXPCL,.TSCLD,.BEXEC,LODX MUST BE LAST DESCR. " Program descriptor end. end ---------------------------------------------------------------------------- Notes: label: is optional. STR1 etc. are optional. The are for the module . Although, is third arg of the second line, it is also the only occurance on that line. That is, the string "" is unique in any one prog. desc. The are either all zero (as in the first one) or are these values 1. library number, always 1 2. component number of the output library 3. offset of this object in this component 4. the program size 5. the load size 6. the address of the entry point 7. the initial load address This routine replaces all the program descriptors in prgdes_path which contain the given call name. The eight parameters to this procedure are the call name and the seven numbers required for the program descriptor. */ dcl call_name char (6) var parm; dcl lib_num fixed bin (24) parm; dcl comp_num fixed bin (24) parm; dcl offset fixed bin (24) parm; dcl prog_size fixed bin (24) parm; dcl load_size fixed bin (24) parm; dcl entry_pt fixed bin (24) parm; dcl load_addr fixed bin (24) parm; /* Initialize */ found_name = FALSE; current_prgdes = start_prgdes; prgdes_inc = 0; /*** For each match of the call name, back up and replace the program descriptors */ do while (current_prgdes < end_prgdes); /*** find next reference to call name */ current_prgdes_size = end_prgdes - current_prgdes; rel_next_name = index (substr (prgdes_seg, current_prgdes, current_prgdes_size), "," || call_name); if rel_next_name = 0 then goto prgdes_done; /* call name not found */ next_name = rel_next_name + current_prgdes; /* now absolute */ if verify (substr (prgdes_seg, next_name + length (call_name), 1), VALID_FOL_CHAR) ^= 0 then goto get_next_prgdes; /*** locate the old prgdes */ old_prgdes_last_char = next_name - index (reverse (substr (prgdes_seg, current_prgdes, rel_next_name)), NL) - 1; prgdes_first_char = old_prgdes_last_char - index (reverse (substr (prgdes_seg, current_prgdes, old_prgdes_last_char - current_prgdes)) , reverse_PRGDES) + 1; old_prgdes_size = old_prgdes_last_char - prgdes_first_char + 1; if (old_prgdes_size < 1) then do; call com_err_ (error_table_$improper_data_format, ME, "Cannot find program descriptors for ""^a"" in ^a. Check format.", call_name, prgdes_path); goto close_files; end; /*** build the new prgdes */ if substr (prgdes_seg, prgdes_first_char, 1) = "0" /* lib=0 */ then update_type = "Added"; else update_type = "Replaced"; if ^found_name then call ioa_$rsnnl ("^7(^i,^) "" ^a by gtbl on ^a", new_prgdes, new_prgdes_size, libn, comp_num, offset, prog_size, load_size, entry_pt, load_addr, update_type, run_date); found_name = TRUE; /*** WHEW! Now comes the easy part: updating the seg with the new prgdes */ prgdes_inc = new_prgdes_size - old_prgdes_size; if prgdes_inc > 0 then do; /* hole is too small */ prgdes_move_len = prgdes_seg_size - old_prgdes_last_char; prgdes_seg_size = prgdes_seg_size + prgdes_inc; call mrl_ (addcharno (prgdes_seg_ptr, old_prgdes_last_char), prgdes_move_len, addcharno (prgdes_seg_ptr, old_prgdes_last_char + prgdes_inc), prgdes_move_len); end; /*** now move it in */ substr (prgdes_seg, prgdes_first_char, new_prgdes_size) = new_prgdes; if prgdes_inc < 0 /* hole was too big! blank out rest */ then substr (prgdes_seg, prgdes_first_char + new_prgdes_size, -prgdes_inc) = " "; if ^brief then do; /*** figure out which prgdes this is */ this_prgdes = old_prgdes_last_char - index (reverse (substr (prgdes_seg, current_prgdes, old_prgdes_last_char - current_prgdes)), reverse_prog_desc) + 1; this_prgdes_num = substr (prgdes_seg, this_prgdes, index (substr (prgdes_seg, this_prgdes, 4), ".") - 1); call ioa_ ("^a program descriptor ^a for ""^a"".", update_type, this_prgdes_num, call_name); end; if Debug then call ioa_ ("^a^-^a", call_name, new_prgdes); get_next_prgdes: ; /*** move up to next prgdes and continue */ if prgdes_inc < 0 then prgdes_inc = 0; end_prgdes = end_prgdes + prgdes_inc; current_prgdes = next_name + prgdes_inc + index (substr (prgdes_seg, next_name + prgdes_inc), NL) + 1; prgdes_inc = 0; end; prgdes_done: if ^found_name then if ^brief then call ioa_$ioa_stream ("error_output", "Call name ""^a"" not found in ^a. Module WAS added to ^a", call_name, prgdes_path, output_lib_path); return; dcl current_prgdes fixed bin (24); dcl current_prgdes_size fixed bin (24); dcl found_name bit (1); dcl new_prgdes char (100) varying; dcl new_prgdes_size fixed bin (24); dcl next_name fixed bin (24); dcl old_prgdes_last_char fixed bin (24); dcl old_prgdes_size fixed bin (24); dcl prgdes_first_char fixed bin (24); dcl prgdes_inc fixed bin (24); dcl prgdes_move_len fixed bin (24); dcl rel_next_name fixed bin (24); dcl this_prgdes fixed bin (24); dcl this_prgdes_num char (3) var; dcl update_type char (8) varying; end update_prgdes; %page; word: proc (w, p, l, c) returns (bit (1)); /**** Set pointer (p) to word (w) of input msf and set the length (l) to number of words available in component segment. Set (c) to the number of the msf component in which the word was found. Return FALSE; Return TRUE if word (w) not available. */ dcl c fixed bin (24) parm; dcl l fixed bin (24) parm; dcl p ptr parm; dcl w fixed bin (24) parm; c = -1; if w < 1 then return (TRUE); k = 0; do i = 0 to nc; k = k + wl (i); if w <= k then do; /* Component located. */ l = k - w + 1; p = addrel (cp (i), wl (i) - l); c = i; return (FALSE); end; end; return (TRUE); dcl i fixed bin (24); dcl k fixed bin (24); end word; %page; /* Constants */ dcl ME char (28) static int options (constant) init ("gcos_tss_build_library (1.1)"); dcl TRUE bit (1) static int options (constant) init ("1"b); dcl FALSE bit (1) static int options (constant) init ("0"b); dcl MARKER bit (36) static int options (constant) init ("101100011111000000001111111111111000"b); dcl USE_EXISTING_COMPONENTS bit (1) static int options (constant) init ("0"b); dcl PROVIDE_NEW_COMPONENTS bit (1) static int options (constant) init ("1"b); dcl NL char (1) static int options (constant) init (" "); dcl FAST_LIB_HEADER_LENGTH fixed bin (24) static int options (constant) init (4); dcl OBJECT_HEADER_LENGTH fixed bin (24) static int options (constant) init (5); dcl VALID_FOL_CHAR char (4) static int options (constant) init (", "); /* comma, space, tab, new line */ %page; /**** builtins, conditions, entries, externals (non-variables) */ dcl (addcharno, addr, addrel, divide, fixed, hbound, index, length, max, mod, null, reverse, search, substr, translate, verify) builtin; dcl cleanup condition; dcl clock_ entry () returns (fixed bin (71)); dcl com_err_ entry options (variable); dcl cu_$arg_count entry (fixed bin (24), fixed bin (35)); dcl cu_$arg_ptr entry (fixed bin (24), ptr, fixed bin (24), fixed bin (35)); dcl date_time_ entry (fixed bin (71), char (*)); dcl expand_pathname_ entry (char (*), char (*), char (*), fixed bin (35)); dcl get_wdir_ entry returns (char (168)); dcl gfms_bcd_ascii_ entry (ptr, fixed bin (24), ptr); dcl gfms_hash_ entry (char (*), fixed bin (24)) returns (fixed bin (35)); dcl initiate_file_ entry (char (*), char (*), bit (*), ptr, fixed bin (24), fixed bin (35)); dcl ioa_ entry options (variable); dcl ioa_$ioa_stream entry options (variable); dcl ioa_$rsnnl entry () options (variable); dcl mrl_ entry options (variable); dcl msf_manager_$adjust entry (ptr, fixed bin, fixed bin (24), bit (3), fixed bin (35)); dcl msf_manager_$close entry (ptr); dcl msf_manager_$get_ptr entry (ptr, fixed bin, bit (1), ptr, fixed bin (24), fixed bin (35)); dcl msf_manager_$open entry (char (*), char (*), ptr, fixed bin (35)); dcl terminate_file_ entry (ptr, fixed bin (24), bit (*), fixed bin (35)); dcl (error_table_$bad_arg, error_table_$bad_file, error_table_$badopt, error_table_$bigarg, error_table_$improper_data_format, error_table_$inconsistent, error_table_$noarg, error_table_$noentry, error_table_$too_many_names) fixed bin (35) ext static; dcl sys_info$max_seg_size fixed bin (35) ext static; %page; /**** Variables for gtbl: IDENTIFIER ATTRIBUTES */ dcl al fixed bin (24); dcl all_mods bit (1); dcl ap ptr; dcl arg char (al) based (ap); dcl arg_num fixed bin (24); dcl bc fixed bin (24); dcl brief bit (1); dcl catl fixed bin (24); dcl catl_parm fixed bin (24); dcl cc fixed bin (24); dcl cc2 fixed bin (24); dcl dcwbc fixed bin (24); dcl e fixed bin (35); dcl end_prgdes fixed bin (24); dcl f bit (1); dcl fw fixed bin (24); dcl get_mod_name bit (1); dcl have_output_lib bit (1); dcl i fixed bin (24); dcl initial_load_address fixed bin (24); dcl init_nm fixed bin (24); dcl input_lib_path char (168) var; dcl j fixed bin (24); dcl k fixed bin (24); dcl libc fixed bin (24); /* current input library number */ dcl lib_fcbp ptr; dcl max_dcw_count fixed bin (24); dcl mf char (mfl) based (mfp); /* module file */ dcl mfa (mfl) char (1) based (mfp); dcl mfl fixed bin (24); dcl mfp ptr; dcl mf_fcbp ptr; dcl msw fixed bin (24); /* max seg words */ dcl nargs fixed bin (24); dcl name_loc ptr; dcl nc fixed bin; dcl ndcw fixed bin (24); dcl need_1_mod_name bit (1); dcl no_cat bit (1); dcl obj_len fixed bin (24); dcl obj_name char (6) var based (addr (nl)); dcl obj_num fixed bin (24); dcl prgdes bit (1); dcl prgdes_bit_count fixed bin (24); dcl prgdes_dir char (168); dcl prgdes_entry char (32); dcl prgdes_fcbp ptr; dcl prgdes_path char (168); dcl prgdes_seg char (prgdes_seg_size) based (prgdes_seg_ptr); dcl prgdes_seg_ptr ptr; dcl prgdes_seg_size fixed bin (24); /* number of chars in prgdes seg */ dcl process_mf bit (1); dcl process_ol bit (1); dcl open_prgdes bit (1); dcl outc fixed bin; /* output lib component num */ dcl outl fixed bin (24); /* output lib word length */ dcl outp ptr; /* output lib pointer */ dcl output_lib_path char (168) var; dcl out_fcbp ptr; dcl path char (168) var; dcl pr_cat bit (1); dcl reverse_PRGDES char (8); /* PRGDES spelled backwards */ dcl reverse_prog_desc char (19); /* Program descriptor backwards */ dcl rl fixed bin (24); dcl run_date char (16); /* don't want time zone and day */ dcl start_prgdes fixed bin (24); dcl total_dcw_count fixed bin (24); dcl wd char (168); /* working dir */ dcl wdl fixed bin (24); /* working dir length */ dcl just_a_word bit (36) based; /* format: off */ dcl 1 object_name_structure, 2 nl fixed bin(24), /* Number characters in Name. */ 2 name_chars char(6); dcl 1 msf aligned , 2 nc fixed bin(24) /* Number of components. */ , 2 comp (0:99) /* Components: */ , 3 cp ptr /* segment. */ , 3 wl fixed bin(24) /* number words. */ ; dcl 1 copy_names , 2 nm fixed bin(24) /* Number of module names. */ , 2 start (0:1020)fixed bin(24)/* Hash start list. >0 => hash_list entry. */ , 2 hash_list (2000) , 3 link fixed bin(24) /* >0 => previous hash_list entry. */ , 3 mod_name char(6)var /* Module name. */ ; dcl dcwbp ptr; dcl 1 dcw_block aligned based(dcwbp) , 2 data_check fixed bin(24) /* Checksum for data words. */ , 2 rel_check fixed bin(24) /* checksum for reloc words */ , 2 rel_abs bit(36) /* 6th bit = "1"b => relocatable. */ , 2 name bit(36) /* name of program (BCD). */ , 2 word5 , 3 entry bit(18)unal /* entry address. */ , 3 origin bit(18)unal /* origin. */ , 2 word6 , 3 reloc_words fixed bin(17)unal /* Number of relocation words. */ , 3 data_words fixed bin(17)unal /* Number of data words. */ , 2 dcws (ndcw)bit(36) ; dcl eo_word_loc ptr; dcl 1 eo_word aligned based(eo_word_loc) , 2 entry_loc bit(18)unal , 2 origin_loc bit(18)unal ; dcl reloc_word_loc ptr; dcl 1 reloc_word aligned based(reloc_word_loc) , 2 fill1 bit( 6)unal , 2 reloc_abs bit( 1)unal /* "1"b => relocatable. */ , 2 fill2 bit(29)unal ; dcl rd_word_loc ptr; dcl 1 rd_word aligned based(rd_word_loc) , 2 reloc_wds fixed bin(17)unal , 2 data_wds fixed bin(17)unal ; dcl dcw_loc ptr; dcl 1 dcw aligned based(dcw_loc) , 2 data_address bit(18)unal , 2 zero bit( 3)unal , 2 action bit( 3)unal , 2 count bit(12)unal ; dcl 1 lib_stack , 2 libn fixed bin(24) /* total number of input libraries */ , 2 input_lib (10) , 3 lib_name_loc ptr , 3 lib_name_len fixed bin(24) ; dcl 1 fast_lib_header aligned based , 2 id char(8) , 2 num_objects pic "(8)9" ; dcl 1 object_header aligned based , 2 marker bit(36) , 2 obj_name char(8)var , 2 obj_len_wds fixed bin(24) , 2 obj_word1 bit(36) ; %page; %include gcos_xio_dcl_; %page; %include terminate_file; %page; %include access_mode_values; end gcos_tss_build_library;  gcos_xio_.pl1 09/09/83 1357.7rew 09/09/83 1006.7 25659 /* *********************************************************** * * * Copyright, (C) Honeywell Information Systems Inc., 1983 * * * *********************************************************** */ gcos_xio_: proc; /* Open or close an IO stream with iox__ Created: Ron Barstad 83-03-04 based on XIO */ %page; /* P R O C E D U R E */ dcl ( cl, sn, mv, pn ) char(*) parm; dcl cp ptr parm; call com_err_ (error_table_$badcall, "gcos_xio_", "Valid gcos_xio_ entries are open and close."); return; open: entry (cl, sn, mv, cp, pn) returns (bit (1)); /** Execute iox routines to "open" the file: 1. For caller "cl". 2. for stream "sn". 3. Mode "mv" = { "1" | "input", "2" | "output" }. 4. Caller supplied pointer "cp" for i/o control block. 5. To segment "pn". Return "1"b if failure. **/ if (mv = "1") | (mv = "input") then mode = 1; else if (mv = "2") | (mv = "output") then mode = 2; else do; call com_err_ (error_table_$bad_subr_arg, cl, "Mode, ""^a"", not 1 or input nor 2 or output.", mv); return ("1"b); end; call iox_$attach_ioname (sn, tp, "vfile_ "||pn, ec); if ec>0 then do; call iox_$close (tp, ec); call iox_$detach_iocb (tp, ec); if ec = 0 then call iox_$attach_ioname (sn, tp, "vfile_ "||pn, ec); end; if ec>0 then do; call com_err_ (ec, cl, "(attach) stream ""^a"", segment ""^a""", sn, pn); cp = null (); return ("1"b); end; call iox_$open (tp, mode, "0"b, ec); if ec>0 then do; call iox_$close (tp, ec); call iox_$open (tp, mode, "0"b, ec); end; if ec>0 then do; call com_err_ (ec, cl, "(open) mode ""^a"", stream ""^a"", segment ""^a""", mv, sn, pn); call iox_$detach_iocb (tp, ec); cp = null (); return ("1"b); end; cp = tp; return ("0"b); close: entry (cl, cp) returns (bit (1)); /** Execute iox routines to "close" the file: 1. For caller "cl". 2. With i/o control block pointer "cp". Return "1"b if failure. **/ call iox_$close (cp, ec); if ec>0 then call com_err_ (ec, cl, "(close)."); call iox_$detach_iocb (cp, ec); if ec>0 then call com_err_ (ec, cl, "(detach)."); if ec>0 then return ("1"b); return ("0"b); %page; /* D A T A */ dcl tp ptr; dcl mode fixed bin; dcl ec fixed bin(35); dcl com_err_ entry options(variable); dcl error_table_$bad_subr_arg fixed bin(35) ext static; dcl error_table_$badcall fixed bin(35) ext static; dcl iox_$attach_ioname entry( char(*), ptr, char(*), fixed bin(35)); dcl iox_$close entry(ptr,fixed bin(35)); dcl iox_$detach_iocb entry(ptr,fixed bin(35)); dcl iox_$open entry(ptr, fixed bin, bit(1) aligned, fixed bin(35)); dcl null builtin; end gcos_xio_; bull_copyright_notice.txt 08/30/05 1008.4r 08/30/05 1007.3 00020025 ----------------------------------------------------------- Historical Background This edition of the Multics software materials and documentation is provided and donated to Massachusetts Institute of Technology by Group Bull including Bull HN Information Systems Inc. as a contribution to computer science knowledge. This donation is made also to give evidence of the common contributions of Massachusetts Institute of Technology, Bell Laboratories, General Electric, Honeywell Information Systems Inc., Honeywell Bull Inc., Groupe Bull and Bull HN Information Systems Inc. to the development of this operating system. Multics development was initiated by Massachusetts Institute of Technology Project MAC (1963-1970), renamed the MIT Laboratory for Computer Science and Artificial Intelligence in the mid 1970s, under the leadership of Professor Fernando Jose Corbato.Users consider that Multics provided the best software architecture for managing computer hardware properly and for executing programs. Many subsequent operating systems incorporated Multics principles. Multics was distributed in 1975 to 2000 by Group Bull in Europe , and in the U.S. by Bull HN Information Systems Inc., as successor in interest by change in name only to Honeywell Bull Inc. and Honeywell Information Systems Inc. . ----------------------------------------------------------- Permission to use, copy, modify, and distribute these programs and their documentation for any purpose and without fee is hereby granted,provided that the below copyright notice and historical background appear in all copies and that both the copyright notice and historical background and this permission notice appear in supporting documentation, and that the names of MIT, HIS, Bull or Bull HN not be used in advertising or publicity pertaining to distribution of the programs without specific prior written permission. Copyright 1972 by Massachusetts Institute of Technology and Honeywell Information Systems Inc. Copyright 2006 by Bull HN Information Systems Inc. Copyright 2006 by Bull SAS All Rights Reserved