COMPILATION LISTING OF SEGMENT mseg_message_ Compiled by: Multics PL/I Compiler, Release 29, of July 28, 1986 Compiled at: Honeywell Bull, Phx. Az., Sys-M Compiled on: 08/06/87 1019.6 mst Thu Options: optimize map 1 /****^ *********************************************************** 2* * * 3* * Copyright, (C) Honeywell Bull Inc., 1987 * 4* * * 5* * Copyright, (C) Honeywell Information Systems Inc., 1985 * 6* * * 7* *********************************************************** */ 8 9 10 /****^ HISTORY COMMENTS: 11* 1) change(85-04-01,Palter), approve(), audit(), install(): 12* Pre-hcom comments. 13* Created: April 1985 by G. Palter based upon mseg_, mseg_add_, and 14* mseg_util_ 15* 2) change(86-09-30,Lippard), approve(86-11-24,MCR7578), 16* audit(87-07-13,Dickson), install(87-08-06,MR12.1-1067): 17* Modified to always give new message IDs. 18* END HISTORY COMMENTS */ 19 20 21 /* Message segment primitive operations (mseg_) which manipulate the individual messages within the segment */ 22 23 /* format: style3,linecom */ 24 25 mseg_message_: 26 procedure (); 27 28 return; /* not an entrypoint */ 29 30 31 /* Parameters */ 32 33 dcl P_mseg_operation_ptr /* -> description of this operation (I) */ 34 pointer parameter; 35 dcl P_code fixed binary (35) parameter; 36 37 dcl P_operation_name character (*) parameter; /* *_for_mseg: the actual operation performing this act (I) */ 38 39 dcl P_ms_count fixed binary parameter; /* count_messages: set to # of accessible messages (O) */ 40 41 dcl P_users_area_ptr pointer parameter; /* read_message*: -> area in which to allocate message (I) */ 42 43 44 /* Local copies of parameters */ 45 46 dcl users_area area based (users_area_ptr); 47 dcl users_area_ptr pointer; 48 49 dcl code fixed binary (35); 50 51 52 /* Remaining declarations */ 53 54 dcl 1 local_md aligned like message_descriptor; 55 56 dcl 1 mseg_message_bits aligned based (mseg_message_info.ms_ptr), 57 2 data bit (mseg_message_info.ms_len) unaligned; 58 59 dcl 1 local_aef aligned like audit_event_flags; 60 61 dcl local_message_block (32) bit (36) aligned; 62 63 dcl operation_specific_return 64 entry (fixed binary (35)) variable; 65 dcl operation_specific_abort 66 entry () variable; 67 dcl operation_name character (64); 68 dcl operation_started_locally 69 bit (1) aligned; 70 71 dcl mseg_dir_name character (168); 72 dcl mseg_entryname character (32); 73 74 dcl (first_mb_ptr, prev_mb_ptr, next_mb_ptr) 75 pointer; 76 dcl (prev_md_ptr, next_md_ptr) 77 pointer; 78 dcl next_message_in_hash_chain 79 pointer; 80 81 dcl rqo_detected bit (1) aligned; 82 dcl do_owner_check bit (1) aligned; 83 84 dcl now fixed binary (71); 85 dcl (n_bits_remaining, n_bits_copied, n_bits_to_copy) 86 fixed binary (24); 87 dcl message_offset fixed binary (18) unaligned unsigned; 88 dcl (n_blocks_needed, block_no, block_id, last_block_allocated) 89 fixed binary (18); 90 dcl hash_idx fixed binary (9); 91 92 dcl ( 93 error_table_$bad_segment, 94 error_table_$bad_subr_arg, 95 error_table_$bigarg, 96 error_table_$noalloc, 97 error_table_$notalloc, 98 error_table_$no_message, 99 error_table_$null_info_ptr, 100 error_table_$rqover, 101 error_table_$smallarg, 102 error_table_$unimplemented_version 103 ) fixed binary (35) external; 104 105 dcl access_operations_$mseg_add_message 106 bit (36) aligned external; 107 dcl sys_info$ring1_privilege 108 bit (36) aligned external; 109 110 dcl access_audit_r1_$get_audit_flags 111 entry () returns (bit (36) aligned); 112 dcl access_audit_r1_$log_obj_ptr 113 entry () options (variable); 114 dcl get_process_id_ entry () returns (bit (36)); 115 dcl mseg_check_access_$message 116 entry (pointer, fixed binary (35)); 117 dcl mseg_utils_$abort_operation 118 entry (pointer); 119 dcl mseg_utils_$begin_operation 120 entry (bit (36) aligned, pointer, character (*), character (*), character (*), pointer, 121 bit (1) aligned, fixed binary (35)); 122 dcl mseg_utils_$finish_operation 123 entry (pointer); 124 dcl mseg_utils_$salvage_for_cause 125 entry (pointer, fixed binary (35)) options (variable); 126 dcl read_allowed_ entry (bit (72) aligned, bit (72) aligned) returns (bit (1) aligned); 127 128 dcl (addr, after, before, clock, currentsize, divide, fixed, index, length, min, mod, null, rtrim, setwordno, string, 129 substr, unspec, wordno) 130 builtin; 131 132 dcl (area, cleanup) condition; 133 134 /* Add a message */ 135 136 mseg_message_$add_message: 137 entry (P_mseg_operation_ptr, P_code); 138 139 call setup_operation (); /* for cleanup handler */ 140 on cleanup call operation_was_aborted (); 141 142 call begin_operation (mseg_operations_$add_message); 143 if rqo_detected 144 then call return_from_operation (error_table_$rqover); 145 else if code ^= 0 146 then call return_from_operation (code); 147 148 149 ADD_MESSAGE: 150 mseg_message_info_ptr = addr (mseg_operation.message_info); 151 if (mseg_message_info.ms_ptr = null ()) & (mseg_message_info.ms_len ^= 0) 152 then call return_from_operation (error_table_$null_info_ptr); 153 else if mseg_message_info.ms_len < 0 154 then call return_from_operation (error_table_$smallarg); 155 else if mseg_message_info.ms_len > (36 * mseg_data_$max_message_size) 156 then call return_from_operation (error_table_$bigarg); 157 158 159 /*** Set that portion of the message descriptor which we already know */ 160 161 unspec (local_md) = ""b; 162 163 if mseg_operation.add_message_info_all_valid 164 then do; /*** Admin Add -- Caller has supplied the message and all required data about its sender */ 165 local_md = mseg_message_info, by name; 166 if rtrim (operation_name) = "mseg_$add_message" 167 then local_md.ms_id = ""b; 168 end; 169 170 else do; /*** Ordinary Add -- Caller has supplied only ms_ptr, ms_len, and ms_access_class */ 171 local_md.ms_id = ""b; /* generate one presently */ 172 local_md.ms_len = mseg_message_info.ms_len; 173 local_md.ms_access_class = mseg_message_info.ms_access_class; 174 local_md.sender_id = mseg_operation.group_id; 175 local_md.sender_process_id = get_process_id_ (); 176 local_md.sender_level = mseg_operation.validation_level; 177 local_md.sender_authorization = mseg_operation.authorization; 178 local_md.sender_max_authorization = mseg_operation.max_authorization; 179 if mseg_operation.call_admin_gate 180 then local_md.sender_audit = access_audit_r1_$get_audit_flags (); 181 else local_md.sender_audit = ""b; 182 end; 183 184 if local_md.ms_id = ""b /* we must generate a message ID */ 185 then do; 186 now = clock (); /* ... IDs for now are simply clock readings */ 187 local_md.ms_id = unspec (now); 188 end; 189 190 191 /*** Compute the number of blocks needed to hold the message */ 192 193 mb_ptr = addr (local_message_block); /* to allow PL/I to compute block sizes for us */ 194 md_ptr = addr (local_md); 195 message_block_header.data_lth = 0; 196 197 n_blocks_needed = 1 /* ... the first block which includes the descriptor */ 198 + 199 divide ((local_md.ms_len - length (first_message_block.pad) + length (other_message_block.pad) - 1), 200 length (other_message_block.pad), 18, 0); 201 202 if n_blocks_needed > mseg_segment.n_blocks_unused 203 then do; /* not enough room in the segment */ 204 call check_block_map_consistency (); /* ... be sure the segment's not damanged */ 205 if mseg_operation.call_admin_gate & ^mseg_operation.suppress_access_checks 206 then do; /* ... audit the covert channel */ 207 string (local_aef) = ""b; 208 local_aef.cc_10_100 = "1"b; 209 call access_audit_r1_$log_obj_ptr (operation_name, mseg_operation.validation_level, 210 string (local_aef), access_operations_$mseg_add_message, mseg_ptr, 211 error_table_$notalloc, null (), 0, "Message segment is full."); 212 end; 213 call return_from_operation (error_table_$notalloc); 214 end; 215 216 mseg_segment.modification_in_progress = "1"b; /* a fault now will cause the segment to be salvaged */ 217 218 219 /*** Pre-allocate the blocks for the message and thread them together */ 220 221 last_block_allocated = 0; 222 223 do block_no = 1 to n_blocks_needed; 224 225 begin; 226 dcl rest_of_block_map bit (mseg_segment.n_blocks_allocated - last_block_allocated) unaligned 227 defined (mseg_segment.block_map.map) position (last_block_allocated + 1); 228 block_id = index (rest_of_block_map, "0"b); 229 if block_id = 0 /* ... not as many free blocks as the header claimed */ 230 then call salvage_and_return (mseg_format_errors_$inconsistent_block_map); 231 block_id, last_block_allocated = block_id + last_block_allocated; 232 end; 233 234 substr (mseg_segment.block_map.map, block_id, 1) = "1"b; 235 mb_ptr = setwordno (mseg_ptr, mseg_segment.block_size * (block_id - 1)); 236 237 if block_no = 1 238 then do; /* first block of the message */ 239 first_mb_ptr = mb_ptr; 240 message_block_header.descriptor_present = "1"b; 241 md_ptr = addr (first_message_block.descriptor); 242 end; 243 else prev_mb_ptr -> message_block_header.next_block = wordno (mb_ptr); 244 245 prev_mb_ptr = mb_ptr; 246 end; 247 248 message_block_header.next_block = 0; /* indicate end of chain for the last block */ 249 250 251 /*** Fill in the real message descriptor in the first block */ 252 253 message_descriptor = local_md; /* copy info we've already gathered */ 254 255 message_descriptor.sentinel = MESSAGE_DESCRIPTOR_SENTINEL; 256 257 message_descriptor.message_chain.next_message = 0;/* this will be the last message in the segment */ 258 message_descriptor.message_chain.prev_message = mseg_segment.message_chain.last_message; 259 260 hash_idx = fixed (substr (local_md.ms_id, 64, 9), 9, 0); 261 message_descriptor.prev_message_in_hash_chain = mseg_segment.hash_table.last_message (hash_idx); 262 263 264 /*** Copy the user's message into the segment */ 265 266 n_bits_remaining = mseg_message_info.ms_len; /* haven't copied anything yet */ 267 n_bits_copied = 0; 268 269 mb_ptr = first_mb_ptr; 270 271 do block_no = 1 to n_blocks_needed; 272 273 message_block_header.data_lth = 0; /* allows PL/I to compute # of bits available in the block */ 274 if block_no = 1 275 then n_bits_to_copy = min (n_bits_remaining, length (first_message_block.pad)); 276 else n_bits_to_copy = min (n_bits_remaining, length (other_message_block.pad)); 277 278 message_block_header.data_lth = n_bits_to_copy; 279 if n_bits_to_copy > 0 /* there's something to put in this block */ 280 then begin; 281 dcl source_bits bit (n_bits_to_copy) unaligned defined (mseg_message_bits.data) 282 position (n_bits_copied + 1); 283 if block_no = 1 284 then first_message_block.data = source_bits; 285 else other_message_block.data = source_bits; 286 n_bits_remaining = n_bits_remaining - n_bits_to_copy; 287 n_bits_copied = n_bits_copied + n_bits_to_copy; 288 end; 289 290 mb_ptr = setwordno (mseg_ptr, message_block_header.next_block); 291 end; 292 293 294 /*** Thread the message into the appropriate chains */ 295 296 if mseg_segment.n_messages = 0 /* it's the first message */ 297 then mseg_segment.message_chain.first_message = wordno (first_mb_ptr); 298 else do; /* it's not the first message */ 299 call set_message_ptrs (mseg_segment.message_chain.last_message, prev_mb_ptr, prev_md_ptr); 300 prev_md_ptr -> message_descriptor.message_chain.next_message = wordno (first_mb_ptr); 301 end; 302 303 mseg_segment.message_chain.last_message = wordno (first_mb_ptr); 304 mseg_segment.hash_table.last_message (hash_idx) = wordno (first_mb_ptr); 305 306 mseg_segment.n_blocks_unused = mseg_segment.n_blocks_unused - n_blocks_needed; 307 308 mseg_segment.n_messages = mseg_segment.n_messages + 1; 309 310 mseg_segment.modification_in_progress = "0"b; /* all done */ 311 312 if mseg_message_info.ms_id = ""b 313 then mseg_message_info.ms_id = local_md.ms_id; /* return the message ID to our caller */ 314 315 call return_from_operation (0); 316 317 /* Add a message on behalf of another message primitive operation -- This entrypoint is identical to add_message, above, 318* except that it does not invoke mseg_utils_$begin_operation. */ 319 320 mseg_message_$add_message_for_mseg: 321 entry (P_mseg_operation_ptr, P_operation_name, P_code); 322 323 call setup_operation (); /* for cleanup handler */ 324 operation_started_locally = "0"b; 325 326 on cleanup call operation_was_aborted (); 327 328 mseg_operation_ptr = P_mseg_operation_ptr; 329 operation_name = P_operation_name; 330 331 mseg_ptr = mseg_operation.mseg_ptr; 332 333 go to ADD_MESSAGE; 334 335 /* Count the accessible messages */ 336 337 mseg_message_$count_messages: 338 entry (P_mseg_operation_ptr, P_ms_count, P_code); 339 340 call setup_operation (); /* for cleanup handler */ 341 on cleanup call operation_was_aborted (); 342 343 call begin_operation (mseg_operations_$count_messages); 344 if rqo_detected 345 then do; /* couldn't even lock the segment: it must be empty */ 346 P_ms_count = 0; 347 call return_from_operation (0); 348 end; 349 else if code ^= 0 350 then call return_from_operation (code); 351 352 if mseg_segment.n_messages = 0 353 then P_ms_count = 0; /* the segment is empty */ 354 355 else if mseg_operation.suppress_access_checks 356 then P_ms_count = mseg_segment.n_messages; /* the caller doesn't want us to worry about access */ 357 358 else if ring1_privilege () 359 | read_allowed_ (mseg_operation.caller.authorization, mseg_operation.access_info.access_class) 360 then P_ms_count = mseg_segment.n_messages; /* the user has access to see everything in the segment */ 361 362 else do; /* we have to count the messages */ 363 do_owner_check = "0"b; /* ... we must have "s" so we don't need to check owner */ 364 P_ms_count = 0; 365 do message_offset = mseg_segment.message_chain.first_message 366 repeat (message_descriptor.message_chain.next_message) while (message_offset ^= 0); 367 call set_message_ptrs (message_offset, mb_ptr, md_ptr); 368 if is_accessible_message () 369 then P_ms_count = P_ms_count + 1; 370 end; 371 end; 372 373 call return_from_operation (0); 374 375 /* Delete a message */ 376 377 mseg_message_$delete_message: 378 entry (P_mseg_operation_ptr, P_code); 379 380 call setup_operation (); /* for cleanup handler */ 381 on cleanup call operation_was_aborted (); 382 383 call begin_operation (mseg_operations_$delete_message); 384 if rqo_detected 385 then call return_from_operation (error_table_$no_message); 386 else if code ^= 0 387 then call return_from_operation (code); 388 389 if mseg_segment.n_messages = 0 /* can't delete if there's nothing there */ 390 then call return_from_operation (error_table_$no_message); 391 392 mseg_message_info_ptr = addr (mseg_operation.message_info); 393 394 call find_message (mseg_message_info.ms_id); 395 if mb_ptr = null () /* the given ID doesn't identify a real message */ 396 then call return_from_operation (error_table_$no_message); 397 398 mseg_operation.md_ptr_valid = "1"b; 399 mseg_operation.md_ptr = md_ptr; 400 call mseg_check_access_$message (mseg_operation_ptr, code); 401 if code ^= 0 /* the message can't be deleted */ 402 then call return_from_operation (code); 403 404 local_md = message_descriptor; /* will need these later to unthread the message */ 405 message_offset = wordno (mb_ptr); 406 407 mseg_segment.modification_in_progress = "1"b; /* a fault now will cause the segment to be salvaged */ 408 409 call process_message (mb_ptr, "0"b, "0"b, "1"b); /* does most of the dirty work */ 410 411 call unchain_message (); /* remove it from the various chains */ 412 413 mseg_segment.modification_in_progress = "0"b; /* all done */ 414 415 call return_from_operation (0); 416 417 /* Read (and optionally delete) a message */ 418 419 mseg_message_$read_message: 420 entry (P_mseg_operation_ptr, P_users_area_ptr, P_code); 421 422 call setup_operation (); /* for cleanup handler */ 423 on cleanup call operation_was_aborted (); 424 425 if P_users_area_ptr ^= null () /* the user must supply an area */ 426 then users_area_ptr = P_users_area_ptr; 427 else call return_from_operation (error_table_$bad_subr_arg); 428 429 call begin_operation (mseg_operations_$read_message); 430 if rqo_detected 431 then call return_from_operation (error_table_$no_message); 432 else if code ^= 0 433 then call return_from_operation (code); 434 435 READ_MESSAGE: 436 if mseg_segment.n_messages = 0 /* can't read something if there's nothing there */ 437 then call return_from_operation (error_table_$no_message); 438 439 mseg_message_info_ptr = addr (mseg_operation.message_info); 440 if mseg_message_info.version ^= MSEG_MESSAGE_INFO_V1 441 then call return_from_operation (error_table_$unimplemented_version); 442 443 do_owner_check = mseg_operation.only_own_access | mseg_message_info.own; 444 445 446 /*** Find the desired message and check the user's access to same */ 447 448 if mseg_message_info.message_code = MSEG_READ_SPECIFIED 449 then call find_message (mseg_message_info.ms_id); 450 451 else if mseg_message_info.message_code = MSEG_READ_FIRST 452 then do; 453 call set_message_ptrs (mseg_segment.message_chain.first_message, mb_ptr, md_ptr); 454 call find_next_accessible_message ((72)"0"b); 455 end; 456 457 else if mseg_message_info.message_code = MSEG_READ_LAST 458 then do; 459 call set_message_ptrs (mseg_segment.message_chain.last_message, mb_ptr, md_ptr); 460 call find_previous_accessible_message ((72)"1"b); 461 end; 462 463 else if mseg_message_info.message_code = MSEG_READ_BEFORE_SPECIFIED 464 then do; 465 call find_message (mseg_message_info.ms_id); 466 if mb_ptr = null () 467 then do; /* given ID doesn't exist: search the entire backward chain */ 468 call set_message_ptrs (mseg_segment.message_chain.last_message, mb_ptr, md_ptr); 469 call find_previous_accessible_message (mseg_message_info.ms_id); 470 end; 471 else if message_descriptor.message_chain.prev_message ^= 0 472 then do; /* it exists: search from its previous message */ 473 call set_message_ptrs (message_descriptor.message_chain.prev_message, mb_ptr, md_ptr); 474 call find_previous_accessible_message (mseg_message_info.ms_id); 475 end; 476 else call return_from_operation (error_table_$no_message); 477 end; 478 479 else if mseg_message_info.message_code = MSEG_READ_AFTER_SPECIFIED 480 then do; 481 call find_message (mseg_message_info.ms_id); 482 if mb_ptr = null () 483 then do; /* given ID doesn't exist: search the entire forward chain */ 484 call set_message_ptrs (mseg_segment.message_chain.first_message, mb_ptr, md_ptr); 485 call find_next_accessible_message (mseg_message_info.ms_id); 486 end; 487 else if message_descriptor.message_chain.next_message ^= 0 488 then do; /* it exists: search from its next message */ 489 call set_message_ptrs (message_descriptor.message_chain.next_message, mb_ptr, md_ptr); 490 call find_next_accessible_message (mseg_message_info.ms_id); 491 end; 492 else call return_from_operation (error_table_$no_message); 493 end; 494 495 else call return_from_operation (error_table_$bad_subr_arg); 496 497 if mb_ptr = null () /* didn't find a message to read */ 498 then call return_from_operation (error_table_$no_message); 499 500 mseg_operation.md_ptr_valid = "1"b; 501 mseg_operation.md_ptr = md_ptr; 502 call mseg_check_access_$message (mseg_operation_ptr, code); 503 if code ^= 0 /* insufficient access to read the message */ 504 then call return_from_operation (code); 505 506 507 /*** Allocate space in the user's storage for the message and copy it from the segment */ 508 509 mseg_message_info.ms_ptr = null (); /* for cleanup handler */ 510 operation_specific_abort = abort_read_operation; 511 operation_specific_return = return_from_read_operation; 512 513 mseg_message_info.ms_len = message_descriptor.ms_len; 514 515 on area 516 begin; 517 code = error_table_$noalloc; 518 go to RETURN_FROM_READ_OPERATION; /* avoids making return_from_operation non-quick */ 519 end; 520 521 allocate mseg_message_bits in (users_area) set (mseg_message_info.ms_ptr); 522 523 524 /*** We can now copy the relevant data directly from the message descriptor 525* into our caller's mseg_message_info structure. However, we must not reveal the sender's audit flags unless 526* the caller could obtain them itself (via access_audit_r1_$get_audit_flags) or the process has ring-1 527* privilege. Otherwise, if we always returned the sender's audit flags, a user could determine his audit 528* flags by adding and then reading a message from any message segment. (A user isn't allowed to know his 529* audit flags to prevent him from only trying certain "incorrect" acts when he knows he won't be audited.) */ 530 531 mseg_message_info = message_descriptor, by name; 532 533 if operation_started_locally /* never censor if read was initiated directly by mseg_ */ 534 then if ^(ring1_privilege () | (mseg_operation.caller.validation_level = mseg_data_$admin_ring)) 535 then mseg_message_info.sender_audit = ""b; 536 537 538 /*** Copy the message from the segment and, if requested, delete it */ 539 540 local_md = message_descriptor; 541 542 if mseg_message_info.delete 543 then do; /* stash data that will be needed later to finish deletion */ 544 message_offset = wordno (mb_ptr); 545 mseg_segment.modification_in_progress = "1"b; 546 end; 547 548 call process_message (mb_ptr, "1"b, "0"b, (mseg_message_info.delete)); 549 /* does most of the dirty work */ 550 551 if mseg_message_info.delete 552 then do; 553 call unchain_message (); 554 mseg_segment.modification_in_progress = "0"b; 555 end; 556 557 code = 0; /* success */ 558 559 560 RETURN_FROM_READ_OPERATION: 561 call return_from_operation (code); 562 563 564 565 /* Special processing required upon completion of a read operation */ 566 567 return_from_read_operation: 568 procedure (p_code); 569 570 dcl p_code fixed binary (35) parameter; 571 572 if p_code ^= 0 /* the read failed ... */ 573 then if mseg_message_info.ms_ptr ^= null () /* ... so we must eliminate whatever we did manage to read */ 574 then do; 575 free mseg_message_bits in (users_area); 576 mseg_message_info.ms_ptr = null (); 577 end; 578 579 return; 580 581 end return_from_read_operation; 582 583 584 585 /* Special processing required upon abnormal termination of a read operation */ 586 587 abort_read_operation: 588 procedure (); 589 590 if mseg_message_info.ms_ptr ^= null () 591 then do; 592 free mseg_message_bits in (users_area); 593 mseg_message_info.ms_ptr = null (); 594 end; 595 596 return; 597 598 end abort_read_operation; 599 600 /* Read (and optionally delete) a message on behalf of another message primitive operation -- This entrypoint is identical 601* to read_message, above, except that it does not invoke mseg_utils_$begin_operation. */ 602 603 mseg_message_$read_message_for_mseg: 604 entry (P_mseg_operation_ptr, P_operation_name, P_users_area_ptr, P_code); 605 606 call setup_operation (); /* for cleanup handler */ 607 operation_started_locally = "0"b; 608 609 on cleanup call operation_was_aborted (); 610 611 mseg_operation_ptr = P_mseg_operation_ptr; 612 operation_name = P_operation_name; 613 users_area_ptr = P_users_area_ptr; /* guaranteed non-null by our caller */ 614 615 mseg_ptr = mseg_operation.mseg_ptr; 616 617 go to READ_MESSAGE; 618 619 /* Update a message -- The data stored in the message are replaced by the data supplied by the caller. If the caller 620* provides less data than are presently in the message, this operation will only replace the first part of the data and 621* leave the remaining data intact. Thus, this operation can be used to update the application header in a message 622* without actually having to first read the message from the segment. */ 623 624 mseg_message_$update_message: 625 entry (P_mseg_operation_ptr, P_code); 626 627 call setup_operation (); /* for cleanup handler */ 628 on cleanup call operation_was_aborted (); 629 630 call begin_operation (mseg_operations_$update_message); 631 if rqo_detected 632 then call return_from_operation (error_table_$no_message); 633 else if code ^= 0 634 then call return_from_operation (code); 635 636 if mseg_segment.n_messages = 0 /* can't update if there's nothing there */ 637 then call return_from_operation (error_table_$no_message); 638 639 mseg_message_info_ptr = addr (mseg_operation.message_info); 640 641 call find_message (mseg_message_info.ms_id); 642 if mb_ptr = null () /* the given ID doesn't identify a real message */ 643 then call return_from_operation (error_table_$no_message); 644 645 mseg_operation.md_ptr_valid = "1"b; 646 mseg_operation.md_ptr = md_ptr; 647 call mseg_check_access_$message (mseg_operation_ptr, code); 648 if code ^= 0 /* the message can't be updated */ 649 then call return_from_operation (code); 650 651 if mseg_message_info.ms_len > message_descriptor.ms_len 652 then call return_from_operation (error_table_$bigarg); 653 654 local_md = message_descriptor; 655 656 call process_message (mb_ptr, "0"b, "1"b, "0"b); /* does the real dirty work */ 657 658 call return_from_operation (0); 659 660 /* Common initialization for all operations */ 661 662 setup_operation: 663 procedure (); 664 665 code = 0; 666 667 operation_specific_abort = nulle; /* nothing special when we abort or return (yet) */ 668 operation_specific_return = nulle; 669 670 mseg_operation_ptr = null (); 671 672 operation_started_locally = "1"b; /* abort/return must invoke mseg_utils_ */ 673 674 return; 675 676 end setup_operation; 677 678 679 680 /* Begin the operation -- This procedure isn't part of setup_operation so that we can be certain to have a cleanup handler 681* available at all times that the message segment may be in use. */ 682 683 begin_operation: 684 procedure (p_mseg_operation_id); 685 686 dcl p_mseg_operation_id bit (36) aligned parameter; 687 688 mseg_operation_ptr = P_mseg_operation_ptr; 689 690 call mseg_utils_$begin_operation (p_mseg_operation_id, mseg_operation_ptr, operation_name, mseg_dir_name, 691 mseg_entryname, mseg_ptr, rqo_detected, code); 692 693 return; 694 695 end begin_operation; 696 697 698 699 /* The "null" entry which indicates that there's no special abort/return processing for an operation */ 700 701 nulle: 702 procedure (); 703 704 return; 705 706 end nulle; 707 708 /* Return after completion of an operation */ 709 710 return_from_operation: 711 procedure (p_code); 712 713 dcl p_code fixed binary (35) parameter; 714 715 if operation_specific_return ^= nulle /* let the operation do anything special */ 716 then call operation_specific_return (p_code); 717 718 if operation_started_locally & (mseg_operation_ptr ^= null ()) 719 then call mseg_utils_$finish_operation (mseg_operation_ptr); 720 /* may be invoked before we've called begin_operation */ 721 722 P_code = p_code; /* set our caller's status code */ 723 go to RETURN_FROM_OPERATION; 724 725 end return_from_operation; 726 727 RETURN_FROM_OPERATION: 728 return; 729 730 731 732 /* Abort an operation */ 733 734 operation_was_aborted: 735 procedure (); 736 737 if operation_specific_abort ^= nulle /* let the operation do anything special */ 738 then call operation_specific_abort (); 739 740 if operation_started_locally 741 then call mseg_utils_$abort_operation (mseg_operation_ptr); 742 743 return; 744 745 end operation_was_aborted; 746 747 748 749 /* Salvage the message segment due to internal inconsistencies and return error_table_$bad_segment to our caller */ 750 751 salvage_and_return: 752 procedure (p_format_error); 753 754 dcl p_format_error fixed binary (35) parameter; 755 756 call mseg_utils_$salvage_for_cause (mseg_operation_ptr, p_format_error); 757 758 call return_from_operation (error_table_$bad_segment); 759 760 end salvage_and_return; 761 762 /* Set the supplied message block and descriptor pointers from the given offset */ 763 764 set_message_ptrs: 765 procedure (p_message_offset, p_mb_ptr, p_md_ptr); 766 767 dcl p_message_offset fixed binary (18) unaligned unsigned parameter; 768 dcl (p_mb_ptr, p_md_ptr) 769 pointer parameter; 770 dcl block_id fixed binary (18); 771 772 if (p_message_offset 773 <= (wordno (addr (mseg_segment.block_map)) + divide (mseg_segment.n_blocks_allocated + 35, 36, 18, 0))) 774 | (p_message_offset > (mseg_segment.block_size * (mseg_segment.n_blocks_allocated - 1))) 775 then call salvage_and_return (mseg_format_errors_$invalid_message_block_offset); 776 777 if mod (p_message_offset, mseg_segment.block_size) ^= 0 778 then call salvage_and_return (mseg_format_errors_$invalid_message_block_offset); 779 780 block_id = divide (p_message_offset, mseg_segment.block_size, 18, 0) + 1; 781 if substr (mseg_segment.block_map.map, block_id, 1) = "0"b 782 then call salvage_and_return (mseg_format_errors_$unused_block_in_message); 783 784 p_mb_ptr = setwordno (mseg_ptr, p_message_offset); 785 786 if p_mb_ptr -> message_block_header.descriptor_present 787 then do; 788 begin; 789 dcl saved_mb_ptr bit (72) aligned; 790 /*** The following code fragment is a replacement for the statement 791* p_md_ptr = addr (p_mb_ptr -> first_message_block_descriptor); 792* That statement will not work as PL/I must reference through mb_ptr in order to compute the 793* size of first_message_block.data_space.pad. Additionally, we can't use normal assignment 794* statements to save/restore the value of mb_ptr as it is sometimes legimately unitialized 795* when this procedure is invoked. */ 796 unspec (saved_mb_ptr) = unspec (mb_ptr); 797 mb_ptr = p_mb_ptr; 798 p_md_ptr = addr (first_message_block.descriptor); 799 unspec (mb_ptr) = unspec (saved_mb_ptr); 800 end; 801 if p_md_ptr -> message_descriptor.sentinel ^= MESSAGE_DESCRIPTOR_SENTINEL 802 then call salvage_and_return (mseg_format_errors_$bad_descriptor_sentinel); 803 end; 804 805 else call salvage_and_return (mseg_format_errors_$no_descriptor_in_first_block); 806 807 return; /* executed iff the message looks OK so far */ 808 809 end set_message_ptrs; 810 811 /* Determine if the user has ring1 privilege */ 812 813 ring1_privilege: 814 procedure () returns (bit (1) aligned); 815 816 return ((mseg_operation.caller.privileges & sys_info$ring1_privilege) ^= ""b); 817 818 end ring1_privilege; 819 820 821 822 /* Determine if the current message (mb_ptr, md_ptr) is accessible to (i.e., readable by) the user */ 823 824 is_accessible_message: 825 procedure () returns (bit (1) aligned); 826 827 if do_owner_check /* we have to checks that it's our message */ 828 then if owner_doesnt_match () 829 then return ("0"b); /* ... and it isn't */ 830 831 if mseg_operation.suppress_access_checks 832 then return ("1"b); /* our caller doesn't want us to worry about AIM, etc. */ 833 834 return (ring1_privilege () 835 | read_allowed_ (mseg_operation.caller.authorization, message_descriptor.ms_access_class)); 836 837 838 839 /* Determine if the user doesn't own this message */ 840 841 owner_doesnt_match: 842 procedure () returns (bit (1) aligned); 843 844 declare name character (32) varying; 845 declare message_name character (32) varying; 846 847 name = before (mseg_operation.caller.group_id, "."); 848 message_name = before (message_descriptor.sender_id, "."); 849 850 if (name ^= "anonymous") & (message_name ^= "anonymous") 851 then /*** The user isn't anonymous and the message wasn't written by an anonymous user. We can simply test the 852* Person_ids to see if the user owns this message. */ 853 return (name ^= message_name); 854 855 else if (name = "anonymous") & (message_name = "anonymous") 856 then do; /*** The user is an anonymous user and the message was written by an anonymous user. We must test the 857* Project_ids to see if the user owns this message. */ 858 name = before (after (mseg_operation.caller.group_id, "."), "."); 859 message_name = before (after (message_descriptor.sender_id, "."), "."); 860 return (name ^= message_name); 861 end; 862 863 else /*** Either the user is an anonymous user and the message wsn't written by one or vice-versa. By 864* definition, the user can not possibly own this message. */ 865 return ("1"b); 866 867 end owner_doesnt_match; 868 869 end is_accessible_message; 870 871 /* Search the message hash table with the given message ID */ 872 873 find_message: 874 procedure (p_ms_id); 875 876 dcl p_ms_id bit (72) aligned parameter; 877 dcl message_offset fixed binary (18) unaligned unsigned; 878 dcl n_messages_checked fixed binary (18); 879 880 hash_idx = fixed (substr (p_ms_id, 64, 9), 9, 0); 881 882 next_message_in_hash_chain = null (); /* hash chain isn't doubly linked (sigh) */ 883 n_messages_checked = 0; 884 885 do message_offset = mseg_segment.hash_table.last_message (hash_idx) 886 repeat (message_descriptor.prev_message_in_hash_chain) while (message_offset ^= 0); 887 888 call set_message_ptrs (message_offset, mb_ptr, md_ptr); 889 890 if message_descriptor.ms_id = p_ms_id /* found it! */ 891 then return; 892 else next_message_in_hash_chain = md_ptr; 893 894 n_messages_checked = n_messages_checked + 1; 895 if n_messages_checked > mseg_segment.n_messages 896 then call salvage_and_return (mseg_format_errors_$circular_hash_chain); 897 end; 898 899 900 /*** Control arrives here iff the given ID isn't in the hash table */ 901 902 mb_ptr, md_ptr = null (); 903 904 return; 905 906 end find_message; 907 908 /* Find the first accessible message in the specified direction along the chronological message chain whose message ID is 909* greater than (if forward) or less than (if backward) the specified value. If the current message (mb_ptr, md_ptr) 910* satisfies the criteria, it is selected. */ 911 912 find_accessible_message: 913 procedure (p_ms_id_key); 914 return; /* not used */ 915 916 dcl p_ms_id_key bit (72) aligned parameter; 917 918 dcl (hash_mb_ptr, hash_md_ptr) 919 pointer; 920 dcl (scan_forward, scan_backward) 921 bit (1) aligned; 922 dcl message_offset fixed binary (18) unaligned unsigned; 923 dcl n_messages_checked fixed binary (18); 924 925 926 find_next_accessible_message: /* ... using the forward chain and ID > KEY */ 927 entry (p_ms_id_key); 928 929 scan_forward = "1"b; 930 scan_backward = "0"b; 931 go to FIND_THE_MESSAGE; 932 933 934 find_previous_accessible_message: /* ... using the backward chain and ID < KEY */ 935 entry (p_ms_id_key); 936 937 scan_backward = "1"b; 938 scan_forward = "0"b; 939 go to FIND_THE_MESSAGE; 940 941 942 FIND_THE_MESSAGE: 943 n_messages_checked = 0; 944 945 do while (mb_ptr ^= null ()); 946 947 if is_accessible_message () /* the user can see this message */ 948 then if scan_forward 949 then if message_descriptor.ms_id > p_ms_id_key 950 then go to FOUND_THE_MESSAGE; 951 else ; 952 else if scan_backward 953 then if message_descriptor.ms_id < p_ms_id_key 954 then go to FOUND_THE_MESSAGE; 955 else ; 956 957 n_messages_checked = n_messages_checked + 1; 958 if n_messages_checked > mseg_segment.n_messages 959 then call salvage_and_return (mseg_format_errors_$circular_message_chain); 960 961 if scan_forward 962 then message_offset = message_descriptor.message_chain.next_message; 963 else message_offset = message_descriptor.message_chain.prev_message; 964 965 if message_offset ^= 0 /* there are more candidates */ 966 then call set_message_ptrs (message_offset, mb_ptr, md_ptr); 967 else mb_ptr = null (); 968 end; 969 970 971 /*** Control arrives here iff an appropriate message is not found */ 972 973 md_ptr = null (); /* be sure both message pointers are null */ 974 return; 975 976 977 /*** Control arrives here when an appropriate message has been found. If we are going to delete the message, we 978* must find its successor in its hash chain so we can later relink said chain. This is necessary as the hash 979* chains are not doubly linked. (In version 6 message segments, we will doubly link the hash chain). */ 980 981 FOUND_THE_MESSAGE: 982 if mseg_message_info.delete 983 then do; 984 hash_idx = fixed (substr (message_descriptor.ms_id, 64, 9), 9, 0); 985 next_message_in_hash_chain = null (); 986 n_messages_checked = 0; 987 988 do message_offset = mseg_segment.hash_table.last_message (hash_idx) 989 repeat (hash_md_ptr -> message_descriptor.prev_message_in_hash_chain) 990 while (message_offset ^= 0); 991 call set_message_ptrs (message_offset, hash_mb_ptr, hash_md_ptr); 992 if hash_md_ptr -> message_descriptor.ms_id = message_descriptor.ms_id 993 then return; /* found it: next_message_in_hash_chain is now properly set */ 994 else next_message_in_hash_chain = hash_md_ptr; 995 n_messages_checked = n_messages_checked + 1; 996 if n_messages_checked > mseg_segment.n_messages 997 then call salvage_and_return (mseg_format_errors_$circular_hash_chain); 998 end; 999 1000 /*** Control arrives here iff the message doesn't appear in its hash chain which means that the 1001* message segment is inconsistent. */ 1002 call salvage_and_return (mseg_format_errors_$inconsistent_hash_chain); 1003 end; 1004 1005 return; 1006 1007 end find_accessible_message; 1008 1009 /* Process an already extant message for reading, updating, or deletion -- The major portion of the processing for each of 1010* these operations consists of walking the chain of blocks which comprise the message and validating that it is a 1011* properly formed message. Only a small fraction of the work involves the actual reading, updating, or deleting. */ 1012 1013 process_message: 1014 procedure (p_first_mb_ptr, p_read, p_update, p_delete); 1015 1016 dcl p_first_mb_ptr pointer parameter; 1017 dcl (p_read, p_update, p_delete) 1018 bit (1) aligned parameter; 1019 1020 dcl next_mb_ptr pointer; 1021 dcl first_block bit (1) aligned; 1022 dcl (actual_ms_len, n_bits_remaining, n_bits_copied, n_bits_to_copy) 1023 fixed binary (24); 1024 dcl (n_actual_blocks, block_id) 1025 fixed binary (18); 1026 1027 actual_ms_len = 0; /* check actual length and # of blocks for inconsistencies */ 1028 n_actual_blocks = 0; 1029 1030 n_bits_copied = 0; 1031 if p_update 1032 then n_bits_remaining = mseg_message_info.ms_len; 1033 1034 first_block = "1"b; /* we are called with the first block in the message */ 1035 1036 do mb_ptr = p_first_mb_ptr repeat (next_mb_ptr) while (mb_ptr ^= null ()); 1037 1038 block_id = divide (wordno (mb_ptr), mseg_segment.block_size, 18, 0) + 1; 1039 if substr (mseg_segment.block_map.map, block_id, 1) = "0"b 1040 then call salvage_and_return (mseg_format_errors_$unused_block_in_message); 1041 1042 actual_ms_len = actual_ms_len + message_block_header.data_lth; 1043 if actual_ms_len > local_md.ms_len /* check that the message length is OK */ 1044 then call salvage_and_return (mseg_format_errors_$inconsistent_message_length); 1045 1046 n_actual_blocks = n_actual_blocks + 1; /* check that the block chain is OK */ 1047 if n_actual_blocks > mseg_segment.n_blocks_allocated 1048 then call salvage_and_return (mseg_format_errors_$circular_message_blocks); 1049 1050 if message_block_header.next_block = 0 /* find the next block now as deleting will zero the header */ 1051 then next_mb_ptr = null (); 1052 else next_mb_ptr = setwordno (mseg_ptr, message_block_header.next_block); 1053 1054 if ^first_block /* only the first block should have a descriptor */ 1055 then if message_block_header.descriptor_present 1056 then call salvage_and_return (mseg_format_errors_$descriptor_in_other_block); 1057 1058 if p_read 1059 then do; /*** Copy the message from the segment to the storage previously allocated in the user's area */ 1060 n_bits_to_copy = message_block_header.data_lth; 1061 if n_bits_to_copy > 0 1062 then begin; /* if there's something to get from this block */ 1063 dcl target_bits bit (n_bits_to_copy) unaligned defined (mseg_message_bits.data) 1064 position (n_bits_copied + 1); 1065 if first_block 1066 then target_bits = first_message_block.data; 1067 else target_bits = other_message_block.data; 1068 n_bits_copied = n_bits_copied + n_bits_to_copy; 1069 end; 1070 end; 1071 1072 else if p_update 1073 then do; /*** Copy the updated portion of the message from the user's storage */ 1074 n_bits_to_copy = min (n_bits_remaining, message_block_header.data_lth); 1075 if n_bits_to_copy > 0 /* there's something to put into this block */ 1076 then begin; 1077 dcl source_bits bit (n_bits_to_copy) unaligned defined (mseg_message_bits.data) 1078 position (n_bits_copied + 1); 1079 dcl target_bits bit (n_bits_to_copy) unaligned defined (other_message_block.data) position (1); 1080 target_bits = source_bits; 1081 n_bits_remaining = n_bits_remaining - n_bits_to_copy; 1082 n_bits_copied = n_bits_copied + n_bits_to_copy; 1083 end; 1084 end; 1085 1086 if p_delete 1087 then do; /*** Delete this block */ 1088 substr (mseg_segment.block_map.map, block_id, 1) = "0"b; 1089 if first_block 1090 then unspec (first_message_block) = ""b; 1091 else unspec (other_message_block) = ""b; 1092 mseg_segment.n_blocks_unused = mseg_segment.n_blocks_unused + 1; 1093 end; 1094 1095 first_block = "0"b; 1096 end; 1097 1098 if actual_ms_len < local_md.ms_len /* the descriptor says it should be longer */ 1099 then call salvage_and_return (mseg_format_errors_$inconsistent_message_length); 1100 1101 return; 1102 1103 end process_message; 1104 1105 /* Remove the now-deleted message that was located at message_offset and whose descriptor is in local_md from the various 1106* message chains in the segment */ 1107 1108 unchain_message: 1109 procedure (); 1110 1111 if local_md.message_chain.prev_message = 0 1112 then do; /* it was the first message in the segment */ 1113 if mseg_segment.message_chain.first_message ^= message_offset 1114 then call salvage_and_return (mseg_format_errors_$inconsistent_forward_chain); 1115 mseg_segment.message_chain.first_message = local_md.message_chain.next_message; 1116 end; 1117 else do; /* it wasn't first */ 1118 call set_message_ptrs (local_md.message_chain.prev_message, prev_mb_ptr, prev_md_ptr); 1119 if prev_md_ptr -> message_descriptor.message_chain.next_message ^= message_offset 1120 then call salvage_and_return (mseg_format_errors_$inconsistent_forward_chain); 1121 prev_md_ptr -> message_descriptor.message_chain.next_message = local_md.message_chain.next_message; 1122 end; 1123 1124 if local_md.message_chain.next_message = 0 1125 then do; /* it was the last message in the segment */ 1126 if mseg_segment.message_chain.last_message ^= message_offset 1127 then call salvage_and_return (mseg_format_errors_$inconsistent_backward_chain); 1128 mseg_segment.message_chain.last_message = local_md.message_chain.prev_message; 1129 end; 1130 else do; /* it wasn't last */ 1131 call set_message_ptrs (local_md.message_chain.next_message, next_mb_ptr, next_md_ptr); 1132 if next_md_ptr -> message_descriptor.message_chain.prev_message ^= message_offset 1133 then call salvage_and_return (mseg_format_errors_$inconsistent_backward_chain); 1134 next_md_ptr -> message_descriptor.message_chain.prev_message = local_md.message_chain.prev_message; 1135 end; 1136 1137 if next_message_in_hash_chain = null () 1138 then do; /* it was the last message in its hash chain */ 1139 if mseg_segment.hash_table.last_message (hash_idx) ^= message_offset 1140 then call salvage_and_return (mseg_format_errors_$inconsistent_hash_chain); 1141 mseg_segment.hash_table.last_message (hash_idx) = local_md.prev_message_in_hash_chain; 1142 end; 1143 else do; /* it wasn't last */ 1144 if next_message_in_hash_chain -> message_descriptor.prev_message_in_hash_chain ^= message_offset 1145 then call salvage_and_return (mseg_format_errors_$inconsistent_hash_chain); 1146 next_message_in_hash_chain -> message_descriptor.prev_message_in_hash_chain = 1147 local_md.prev_message_in_hash_chain; 1148 end; 1149 1150 mseg_segment.n_messages = mseg_segment.n_messages - 1; 1151 1152 return; 1153 1154 end unchain_message; 1155 1156 /* Check that the block map and unused block count are consistent */ 1157 1158 check_block_map_consistency: 1159 procedure (); 1160 1161 dcl (actual_n_blocks_unused, last_block_checked, next_unused_block, next_used_block) 1162 fixed binary (18); 1163 1164 actual_n_blocks_unused = 0; 1165 last_block_checked = 0; 1166 1167 do while (last_block_checked < mseg_segment.n_blocks_allocated); 1168 1169 begin; /* find the next unused block (if any) */ 1170 dcl rest_of_block_map bit (mseg_segment.n_blocks_allocated - last_block_checked) unaligned 1171 defined (mseg_segment.block_map.map) position (last_block_checked + 1); 1172 next_unused_block = index (rest_of_block_map, "0"b); 1173 end; 1174 1175 if next_unused_block = 0 /* all the remaining blocks are in use */ 1176 then last_block_checked = mseg_segment.n_blocks_allocated; 1177 1178 else do; /* at least one more unused block */ 1179 last_block_checked = last_block_checked + next_unused_block - 1; 1180 begin; /* find the first used block after this unused block */ 1181 dcl rest_of_block_map bit (mseg_segment.n_blocks_allocated - last_block_checked) unaligned 1182 defined (mseg_segment.block_map.map) position (last_block_checked + 1); 1183 next_used_block = index (rest_of_block_map, "1"b); 1184 if next_used_block = 0 /* ... the rest of the blocks are unused */ 1185 then next_used_block = length (rest_of_block_map) + 1; 1186 end; 1187 actual_n_blocks_unused = actual_n_blocks_unused + next_used_block - 1; 1188 last_block_checked = last_block_checked + next_used_block - 1; 1189 end; 1190 end; 1191 1192 if actual_n_blocks_unused ^= mseg_segment.n_blocks_unused 1193 then call salvage_and_return (mseg_format_errors_$inconsistent_block_map); 1194 1195 return; 1196 1197 end check_block_map_consistency; 1198 1199 /* format: off */ 1200 /* Begin include file mseg_data_.incl.pl1 BIM 1985-04-15 */ 1 2 /* format: style4 */ 1 3 1 4 declare mseg_data_$lock_id bit (72) aligned external; 1 5 declare mseg_data_$block_size fixed bin (35) ext static; 1 6 declare mseg_data_$max_message_size fixed bin (35) ext static; 1 7 declare mseg_data_$template_operation bit (36) aligned external static; /* like mseg_operation */ 1 8 declare mseg_data_$admin_ring fixed binary (3) external; 1 9 declare mseg_data_$execution_ring fixed bin (3) ext static; 1 10 declare mseg_data_$process_max_authorization bit (72) aligned ext static; 1 11 declare mseg_data_$group_id char (32) unaligned external static; 1 12 1 13 /* End include file mseg_data_.incl.pl1 */ 1200 1201 /* BEGIN INCLUDE FILE ... mseg_segment.incl.pl1 */ 2 2 /* Created: April 1985 by G. Palter from msg_hdr.incl.pl1 */ 2 3 2 4 /* format: style3,linecom */ 2 5 2 6 /* NOTE: This include file references the mseg_wakeup_state structure which is defined separately in 2 7* mseg_wakeup_state.incl.pl1. Programs which use this include file must also include mseg_wakeup_state.incl.pl1 to 2 8* prevent compilation errors. */ 2 9 2 10 2 11 /* Definition of the structure of a message segment -- 2 12* 2 13* A message segment is composed of three sections -- the header, the block map, and the blocks space. 2 14* 2 15* In addition to the message ID hash table and the head&tail of the chronological message chain, the message header also 2 16* contains the state of wakeup acceptance for this segment. In order to maintain compatibility with early version 5 2 17* message segments, the wakeup state is maintained in a 64 word area of the header which had been known as the "header 2 18* message". See mseg_wakeup_state.incl.pl1 for additional information. 2 19* 2 20* The entire message segment, including the header and block map, is treated as an array of fixed size blocks. The block 2 21* map contains a bit for each block in the message which indicates whether that block is in use. (The blocks which 2 22* overlay the header and block map are always marked as being in use). The size of the block map is based on the 2 23* maxlength of the message segment in order to provide more free space in very small message segments. 2 24* 2 25* When a message is added to a message segment, its content is split into blocks which are allocated in the blocks space. 2 26* The blocks space starts with the first block after the block map and occupies the remainder of the segment. */ 2 27 2 28 declare 1 mseg_segment aligned based (mseg_ptr), 2 29 2 header aligned, 2 30 3 lock bit (36) aligned, 2 31 3 sentinel bit (36) aligned, /* proves that this segment is a message segment */ 2 32 3 reserved bit (72) aligned, /* ... for compatibility with early version 5 segments */ 2 33 3 date_time_last_salvaged 2 34 fixed binary (71), 2 35 3 pad (2) bit (36) aligned, 2 36 3 message_chain, /* the chronological chain of messages in the segment ... */ 2 37 4 first_message /* ... the first (oldest) message */ 2 38 fixed binary (18) unaligned unsigned, 2 39 4 pad1 bit (18) unaligned, 2 40 4 last_message /* ... the last (youngest) message */ 2 41 fixed binary (18) unaligned unsigned, 2 42 4 pad2 bit (18) unaligned, 2 43 3 n_blocks_allocated /* total # of blocks available in this message segment ... */ 2 44 fixed binary (18), /* ... including space occupied by the header and block map */ 2 45 3 n_blocks_unused 2 46 fixed binary (18), 2 47 3 n_messages fixed binary (18), 2 48 3 block_size fixed binary, /* ... in words */ 2 49 3 flags, 2 50 4 modification_in_progress 2 51 bit (1) unaligned, 2 52 4 salvaged bit (1) unaligned, /* ON => the message segment had been salvaged earlier */ 2 53 4 wakeup_state_set 2 54 bit (1) unaligned, 2 55 4 salvage_in_progress 2 56 bit (1) unaligned, 2 57 4 pad bit (32) unaligned, 2 58 3 version fixed binary, 2 59 3 wakeup_state aligned, 2 60 4 state aligned like mseg_wakeup_state, 2 61 4 pad (64 - 10) bit (36) aligned, /* ... for compatibility with early version 5 segments */ 2 62 3 hash_table aligned, /* ... based on the low order 9 bits of the message ID */ 2 63 4 last_message 2 64 (0:511) fixed binary (18) unaligned unsigned, 2 65 2 block_map aligned, /* ON => the block is in use */ 2 66 3 map bit (0 refer (mseg_segment.n_blocks_allocated)) unaligned; 2 67 2 68 declare mseg_ptr pointer; 2 69 2 70 declare MSEG_SEGMENT_VERSION_5 /* presently supported version */ 2 71 fixed binary static options (constant) initial (5); 2 72 2 73 declare MSEG_SEGMENT_SENTINEL 2 74 bit (36) aligned static options (constant) initial ("252525252525"b3); 2 75 2 76 2 77 /* Redefinitions required to access the wakeup_state of the segment in early version 5 message segments */ 2 78 2 79 declare header_msg_access_class 2 80 bit (72) aligned defined (mseg_segment.reserved); 2 81 2 82 declare header_msg_present bit (1) unaligned defined (mseg_segment.wakeup_state_set); 2 83 2 84 declare header_msg (64) bit (36) aligned based (addr (mseg_segment.wakeup_state)); 2 85 2 86 /* END INCLUDE FILE ... mseg_segment.incl.pl1 */ 1201 1202 /* BEGIN INCLUDE FILE ... mseg_wakeup_state.incl.pl1 */ 3 2 /* Created: April 1985 by G. Palter */ 3 3 3 4 /* format: style3,linecom */ 3 5 3 6 /* Description of the wakeup state of a message segment -- 3 7* 3 8* The wakeup state defines which process, if any, is willing to receive normal or urgent IPC wakeups when a message which 3 9* requests such a wakeup is added to a message segment. The process is allowed to separately accept or defer normal and 3 10* urgent wakeups. Note that deferring a wakeup is not the same as not accepting wakeups. A process is not allowed to 3 11* stop accepting wakeups once it has accepted them as to do so would introduce a relatively high badnwidth covert 3 12* channel. (In the present implementation, urgent wakeups are really no different from normal wakeups. Eventually, 3 13* urgent wakeups should be implemented using an IPS signal along with the IPC wakeup). 3 14* 3 15* mseg_$get_wakeup_state_seg requires that the caller supply the proper value for mseg_wakeup_state.version in the 3 16* mseg_operation. If there is no wakeup state recorded in the message segment, mseg_$get_wakeup_state_seg will return 3 17* the status code error_table_$messages_off. 3 18* 3 19* mseg_$set_wakeup_state_seg ignores the values of the access_class, process_id, and lock_id elements supplied by the 3 20* caller in the mseg_operation. mseg_$set_wakeup_state_seg will, instead, furnish the values of the process making the 3 21* call for these elements and will return these values to its caller. In other words, mseg_$set_wakeup_state_seg can not 3 22* be used by one process to accept/defer wakeups on behalf of another process. */ 3 23 3 24 declare 1 mseg_wakeup_state aligned based (mseg_wakeup_state_ptr), 3 25 2 version character (8) unaligned, 3 26 2 flags aligned, 3 27 3 accepting_normal_wakeups /* ON => process has accepted normal wakeups */ 3 28 bit (1) unaligned, /* OFF => process has deferred normal wakeups */ 3 29 3 accepting_urgent_wakeups /* ON => process has accepted urgent wakeups */ 3 30 bit (1) unaligned, /* OFF => process has deferred urgent wakeups */ 3 31 3 pad bit (34) unaligned, 3 32 2 pad bit (36) aligned, 3 33 2 event_channel fixed binary (71), /* IPC event channel on which to send normal/urgent wakeups */ 3 34 2 access_class bit (72) aligned, /* AIM access class of the process accepting wakeups */ 3 35 2 process_id bit (36) aligned, /* ID of the process accepting wakeups */ 3 36 2 lock_id bit (36) aligned; /* lock ID used to test if said process is still alive */ 3 37 3 38 declare mseg_wakeup_state_ptr 3 39 pointer; 3 40 3 41 declare MSEG_WAKEUP_STATE_VERSION_1 3 42 character (8) static options (constant) initial ("msegwkp1"); 3 43 3 44 /* END INCLUDE FILE ... mseg_wakeup_state.incl.pl1 */ 1202 1203 /* BEGIN INCLUDE FILE ... mseg_message.incl.pl1 */ 4 2 /* Created: April 1985 by G. Palter from ms_block_hdr.incl.pl1 and ms_block_trailer.incl.pl1 */ 4 3 4 4 /* format: style3,linecom */ 4 5 4 6 /* NOTE: This include file references components of the mseg_segment structure which is defined separately in 4 7* mseg_segment.incl.pl1. Programs which use this include file must also include mseg_segment.incl.pl1 to prevent 4 8* compilation errors. */ 4 9 4 10 4 11 /* Definition of the structure of a message stored in a message segment -- 4 12* 4 13* When a message is added to a message segment, it is split into one or more fixed sized blocks. These blocks are then 4 14* allocated in the blocks space of the message segment. (See mseg_message.incl.pl1 and mseg_message_.pl1 for more 4 15* information). Each block includes a header which records where the next block of the message, if any, resides and how 4 16* many bits of data is actually recorded in the block. 4 17* 4 18* In addition, the first block allocated for a message always includes a message descriptor. This descriptor includes 4 19* various pieces of information about the message such as its total length, access class, author, etc. */ 4 20 4 21 4 22 /* Definition of the header found in all message blocks */ 4 23 4 24 declare 1 message_block_header 4 25 aligned based (mb_ptr), 4 26 2 next_block fixed binary (18) unaligned unsigned, 4 27 2 descriptor_present /* ON => a descriptor is in the last 22 words of the block */ 4 28 bit (1) unaligned, 4 29 2 data_lth /* ... in bits */ 4 30 fixed binary (17) unaligned unsigned; 4 31 4 32 declare mb_ptr pointer; 4 33 4 34 4 35 /* Definition of the descriptor for a message recorded in the first block of the message */ 4 36 4 37 declare 1 message_descriptor 4 38 aligned based (md_ptr), 4 39 2 sentinel bit (36) aligned, /* proves that this is a message descriptor */ 4 40 2 message_chain, /* the chronological chain of messages in the segment */ 4 41 3 next_message fixed binary (18) unaligned unsigned, 4 42 3 prev_message fixed binary (18) unaligned unsigned, 4 43 2 sender_level fixed binary (3) unaligned unsigned, 4 44 2 pad1 bit (5) unaligned, 4 45 2 prev_message_in_hash_chain 4 46 fixed binary (18) unaligned unsigned, 4 47 2 pad2 bit (10) unaligned, 4 48 2 ms_id bit (72) aligned, 4 49 2 ms_len fixed binary (24) unaligned unsigned, 4 50 2 pad3 bit (12) unaligned, 4 51 2 sender_id char (32) aligned, 4 52 2 sender_authorization 4 53 bit (72) aligned, 4 54 2 ms_access_class bit (72) aligned, 4 55 2 sender_max_authorization 4 56 bit (72) aligned, 4 57 2 sender_process_id 4 58 bit (36) aligned, 4 59 2 sender_audit bit (36) aligned; 4 60 4 61 declare md_ptr pointer; 4 62 4 63 declare MESSAGE_DESCRIPTOR_SENTINEL 4 64 bit (36) aligned static options (constant) initial ("777777777777"b3); 4 65 4 66 4 67 /* Definition of the first block allocated for a message in a message segment */ 4 68 4 69 declare 1 first_message_block 4 70 aligned based (mb_ptr), 4 71 2 header aligned like message_block_header, 4 72 2 data_space, 4 73 3 data bit (0 refer (first_message_block.data_lth)) unaligned, 4 74 3 pad bit (36 4 75 * (mseg_segment.block_size - currentsize (message_block_header) 4 76 - currentsize (message_descriptor)) - first_message_block.data_lth) unaligned, 4 77 2 descriptor aligned like message_descriptor; 4 78 4 79 4 80 /* Definition of all but the first block allocated for a message in a message segment */ 4 81 4 82 declare 1 other_message_block 4 83 aligned based (mb_ptr), 4 84 2 header aligned like message_block_header, 4 85 2 data_space, 4 86 3 data bit (0 refer (other_message_block.data_lth)) unaligned, 4 87 3 pad bit (36 * (mseg_segment.block_size - currentsize (message_block_header)) 4 88 - other_message_block.data_lth) unaligned; 4 89 4 90 /* END INCLUDE FILE ... mseg_message.incl.pl1 */ 1203 1204 /* BEGIN INCLUDE FILE ... mseg_operation.incl.pl1 */ 5 2 5 3 /* format: style3,idind30,linecom */ 5 4 5 5 /**** Created 1985-04-16, BIM: from Pandolf's mseg_access_operation */ 5 6 5 7 /**** NOTES: 5 8* The caller of mseg_ must set mseg_operation.access_operation to record 5 9* the type of access checking it has performed and which mseg_ should 5 10* perform when needed (i.e., for those entrypoints which operate on 5 11* messages like mseg_$read_message). 5 12* 5 13* mseg_operation.operation is reserved explicitly for use by mseg_ and 5 14* its underlying modules. 5 15* 5 16* You must also include entry_access_info, mseg_message_info, and 5 17* mbx_wakeup_state along with this include file. */ 5 18 5 19 dcl mseg_operation_ptr pointer; 5 20 dcl MSEG_OPERATION_VERSION_1 fixed bin internal static options (constant) init (1); 5 21 dcl MSEG_TYPE_MBX fixed bin init (1) internal static options (constant); 5 22 dcl MSEG_TYPE_MS fixed bin init (2) internal static options (constant); 5 23 5 24 dcl 1 mseg_operation based (mseg_operation_ptr) aligned, 5 25 2 version fixed binary, /* current version is MSEG_OPERATION_VERSION_1 */ 5 26 2 type fixed binary, /* MBX or MS */ 5 27 2 access_operation fixed binary, /* type of access checks required for the operation */ 5 28 2 operation bit (36) aligned, /* for use by mseg_ and underlying modules */ 5 29 2 caller aligned, /* always collected in gate target */ 5 30 3 validation_level fixed bin (3), 5 31 3 privileges bit (18) aligned, /* factored for speed */ 5 32 3 pad_align_double fixed bin (71), /* just to force alignment */ 5 33 3 authorization bit (72) aligned, /* must be 2word aligned */ 5 34 3 max_authorization bit (72) aligned, 5 35 3 group_id char (32) unaligned, 5 36 2 flags aligned, 5 37 3 mseg_pathname_valid bit (1) unaligned, 5 38 3 mseg_ptr_valid bit (1) unaligned, 5 39 3 mseg_index_valid bit (1) unaligned, 5 40 3 access_info_valid bit (1) unaligned, 5 41 3 md_ptr_valid bit (1) unaligned, 5 42 3 message_info_valid bit (1) unaligned, /* note -- for some operations not all fields are used */ 5 43 3 wakeup_state_valid bit (1) unaligned, 5 44 3 suppress_access_checks bit (1) unaligned, /* set by privileged interfaces, suppresses ALL access checking */ 5 45 3 call_admin_gate bit (1) unaligned, /* we is in ring 1, boss */ 5 46 3 only_own_access bit (1) unaligned, /* the user had o rather than r/d */ 5 47 3 add_message_info_all_valid 5 48 bit (1) unaligned, /* Believe ALL the fields in message info on an add */ 5 49 3 pad bit (24) unaligned, 5 50 2 dir_name char (168) unaligned, 5 51 2 entryname char (32) unaligned, 5 52 2 mseg_ptr pointer, 5 53 2 md_ptr pointer, /* message descriptor */ 5 54 2 mseg_index fixed bin, 5 55 2 access_info aligned like entry_access_info, 5 56 2 message_info aligned like mseg_message_info, 5 57 2 wakeup_state aligned like mseg_wakeup_state; 5 58 5 59 /* END INCLUDE FILE ... mseg_operation.incl.pl1 */ 1204 1205 /* BEGIN INCLUDE FILE . . . mseg_message_info.incl.pl1 BIM 1984-10-10 */ 6 2 /* format: style3,idind30 */ 6 3 6 4 /* structure returned when message is read from a message segment */ 6 5 6 6 6 7 dcl mseg_message_info_ptr pointer; 6 8 6 9 dcl 1 mseg_message_info based (mseg_message_info_ptr) aligned, 6 10 2 version char (8) aligned, 6 11 2 message_code fixed bin, 6 12 2 control_flags unaligned, 6 13 3 own bit (1), 6 14 3 delete bit (1), 6 15 3 pad bit (34), 6 16 2 ms_ptr ptr, /* pointer to message */ 6 17 2 ms_len fixed bin (24), /* length of message in bits */ 6 18 2 ms_id bit (72), /* unique ID of message */ 6 19 /* input in some cases */ 6 20 2 ms_access_class bit (72), /* message access class */ 6 21 2 sender_id char (32) unaligned,/* process-group ID of sender */ 6 22 2 sender_process_id bit (36) aligned, /* if nonzero, process that sent */ 6 23 2 sender_level fixed bin, /* validation level of sender */ 6 24 2 sender_authorization bit (72), /* access authorization of message sender */ 6 25 2 sender_max_authorization bit (72), /* max authorization of sending process */ 6 26 2 sender_audit bit (36) aligned; /* audit flags */ 6 27 6 28 declare MSEG_MESSAGE_INFO_V1 char (8) aligned init ("msegmi01") int static options (constant); 6 29 6 30 declare ( 6 31 MSEG_READ_FIRST init (1), 6 32 MSEG_READ_LAST init (2), 6 33 MSEG_READ_SPECIFIED init (3), 6 34 MSEG_READ_BEFORE_SPECIFIED init (4), 6 35 MSEG_READ_AFTER_SPECIFIED init (5)) 6 36 fixed bin int static options (constant); 6 37 6 38 declare (MSEG_READ_OWN init ("1"b), 6 39 MSEG_READ_DELETE init ("01"b) 6 40 ) bit (36) aligned internal static options (constant); 6 41 6 42 /* END INCLUDE FILE . . . mseg_message_info.incl.pl1 */ 1205 1206 /* BEGIN INCLUDE FILE ... entry_access_info.incl.pl1 */ 7 2 7 3 /* 7 4* Written 03/22/85 by M. Pandolf 7 5* Modified 1985-04-19, BIM: added parent access class. 7 6**/ 7 7 7 8 dcl entry_access_info_ptr pointer; 7 9 dcl ENTRY_ACCESS_INFO_VERSION_1 char (8) internal static options (constant) 7 10 init ("eainf001"); 7 11 7 12 dcl 1 entry_access_info aligned based (entry_access_info_ptr), 7 13 2 version char (8), /* = ENTRY_ACCESS_INFO_VERSION_1 */ 7 14 2 type fixed bin, /* see status_structures.incl.pl1 */ 7 15 2 dir_name char (168) unaligned, /* parent of this entry */ 7 16 2 entryname char (32) unaligned, /* primary name of this entry */ 7 17 2 uid bit (36) aligned, 7 18 2 ring_brackets (3) fixed bin (3), /* for dirs, the dir ring brackets are here */ 7 19 2 extended_ring_brackets (3) fixed bin (3), /* not-yet-implemented x-rb's */ 7 20 2 effective_access_modes bit (36) aligned, /* for dirs, dir mode is here */ 7 21 2 extended_access_modes bit (36) aligned, /* always null for dirs */ 7 22 2 access_class bit (72) aligned, /* for multiclass, max access class */ 7 23 2 parent_access_class bit (72) aligned, /* for multiclass, this is effectively the min access class */ 7 24 2 multiclass bit (1) aligned; 7 25 7 26 /* END INCLUDE FILE ... entry_access_info.incl.pl1 */ 1206 1207 /* BEGIN INCLUDE FILE ... mseg_operations_.incl.pl1 */ 8 2 /* Created: April 1985 by G. Palter */ 8 3 8 4 /* format: style3,linecom */ 8 5 8 6 /* The defined message segment primitive operations (mseg_) */ 8 7 8 8 declare ( 8 9 mseg_operations_$add_acl_entries_seg, 8 10 mseg_operations_$add_message, 8 11 mseg_operations_$chname_seg, 8 12 mseg_operations_$close_seg, 8 13 mseg_operations_$compact_seg, 8 14 mseg_operations_$copy_seg_source, 8 15 mseg_operations_$copy_seg_target, 8 16 mseg_operations_$count_messages, 8 17 mseg_operations_$create_seg, 8 18 mseg_operations_$delete_acl_entries_seg, 8 19 mseg_operations_$delete_message, 8 20 mseg_operations_$delete_seg, 8 21 mseg_operations_$get_salvaged_flag_seg, 8 22 mseg_operations_$get_wakeup_state_seg, 8 23 mseg_operations_$initiate_seg, 8 24 mseg_operations_$list_acl_seg, 8 25 mseg_operations_$list_acl_entries_seg, 8 26 mseg_operations_$open_seg, 8 27 mseg_operations_$read_message, 8 28 mseg_operations_$replace_acl_seg, 8 29 mseg_operations_$reset_salvaged_flag_seg, 8 30 mseg_operations_$reset_wakeup_state_seg, 8 31 mseg_operations_$set_max_length_seg, 8 32 mseg_operations_$set_safety_switch_seg, 8 33 mseg_operations_$set_wakeup_state_seg, 8 34 mseg_operations_$update_message 8 35 ) bit (36) aligned external; 8 36 8 37 /* END INCLUDE FILE ... mseg_operations_.incl.pl1 */ 1207 1208 /* BEGIN INCLUDE FILE ... mseg_format_errors_.incl.pl1 */ 9 2 /* Created: April 1985 by G. Palter */ 9 3 9 4 /* format: style3,linecom */ 9 5 9 6 /* Standard system status codes corresponding to the possible errors which the message segment primitives can detect in 9 7* the format of a message segment -- These errors are implemented as status codes to permit the use of 9 8* admin_gate_$syserr_error_code to actually record the errors in the syserr log. */ 9 9 9 10 declare ( 9 11 mseg_format_errors_$bad_descriptor_sentinel, 9 12 mseg_format_errors_$bad_mseg_sentinel, 9 13 mseg_format_errors_$bad_mseg_version, 9 14 mseg_format_errors_$circular_hash_chain, 9 15 mseg_format_errors_$circular_message_blocks, 9 16 mseg_format_errors_$circular_message_chain, 9 17 mseg_format_errors_$descriptor_in_other_block, 9 18 mseg_format_errors_$inconsistent_backward_chain, 9 19 mseg_format_errors_$inconsistent_block_map, 9 20 mseg_format_errors_$inconsistent_forward_chain, 9 21 mseg_format_errors_$inconsistent_hash_chain, 9 22 mseg_format_errors_$inconsistent_message_count, 9 23 mseg_format_errors_$inconsistent_message_length, 9 24 mseg_format_errors_$invalid_message_block_offset, 9 25 mseg_format_errors_$modification_in_progress, 9 26 mseg_format_errors_$negative_message_count, 9 27 mseg_format_errors_$no_descriptor_in_first_block, 9 28 mseg_format_errors_$salvage_in_progress, 9 29 mseg_format_errors_$unused_block_in_message 9 30 ) fixed binary (35) external; 9 31 9 32 /* END INCLUDE FILE ... mseg_format_errors_.incl.pl1 */ 1208 1209 /* begin include file - access_audit_eventflags.incl.pl1 */ 10 2 /* NOTE: This include file has an ALM counterpart made with cif. 10 3*Keep it up to date. */ 10 4 10 5 dcl 1 audit_event_flags based aligned, 10 6 2 special_op bit (1) unal, /* special sys operation */ 10 7 2 grant bit (1) unal, /* operation was successful */ 10 8 2 admin_op bit (1) unal, /* administrative operation */ 10 9 2 priv_op bit (1) unal, /* privileged operation */ 10 10 2 cc_1_10 bit (1) unal, /* small covert channel */ 10 11 2 cc_10_100 bit (1) unal, /* moderate covert channel */ 10 12 2 receiver bit (1) unal, /* on receiving end of channel */ 10 13 2 pad bit (29) unal; 10 14 10 15 /* end include file - access_audit_eventflags.incl.pl1 */ 1209 1210 1211 1212 /* BEGIN MESSAGE DOCUMENTATION 1213* 1214* 1215* Message: 1216* Audit (mseg_$add_message): DENIED addition of a message to a message segment 1217* ADDED_INFO 1218* 1219* S: $access_audit 1220* 1221* T: $run 1222* 1223* M: A message was not added to a mailbox or message segment because 1224* there is not enough room for the message in the segment. Repeated 1225* occurences of this event over a short period of time could indicate 1226* an attempt to exploit a moderate bandwidth covert channel. 1227* ADDED_INFO will identify the user and segment in question. 1228* 1229* A: $notify_ssa 1230* 1231* 1232* END MESSAGE DOCUMENTATION */ 1233 1234 /* format: on */ 1235 1236 end mseg_message_; SOURCE FILES USED IN THIS COMPILATION. LINE NUMBER DATE MODIFIED NAME PATHNAME 0 08/06/87 1019.6 mseg_message_.pl1 >spec>install>1067>mseg_message_.pl1 1200 1 05/17/85 0619.0 mseg_data_.incl.pl1 >ldd>include>mseg_data_.incl.pl1 1201 2 05/17/85 0615.7 mseg_segment.incl.pl1 >ldd>include>mseg_segment.incl.pl1 1202 3 05/17/85 0615.7 mseg_wakeup_state.incl.pl1 >ldd>include>mseg_wakeup_state.incl.pl1 1203 4 05/17/85 0615.6 mseg_message.incl.pl1 >ldd>include>mseg_message.incl.pl1 1204 5 05/17/85 0615.6 mseg_operation.incl.pl1 >ldd>include>mseg_operation.incl.pl1 1205 6 01/10/85 2002.8 mseg_message_info.incl.pl1 >ldd>include>mseg_message_info.incl.pl1 1206 7 05/17/85 0615.5 entry_access_info.incl.pl1 >ldd>include>entry_access_info.incl.pl1 1207 8 05/17/85 0615.7 mseg_operations_.incl.pl1 >ldd>include>mseg_operations_.incl.pl1 1208 9 05/17/85 0615.6 mseg_format_errors_.incl.pl1 >ldd>include>mseg_format_errors_.incl.pl1 1209 10 01/30/85 1523.9 access_audit_eventflags.incl.pl1 >ldd>include>access_audit_eventflags.incl.pl1 NAMES DECLARED IN THIS COMPILATION. IDENTIFIER OFFSET LOC STORAGE CLASS DATA TYPE ATTRIBUTES AND REFERENCES (* indicates a set context) NAMES DECLARED BY DECLARE STATEMENT. MESSAGE_DESCRIPTOR_SENTINEL 000022 constant bit(36) initial dcl 4-63 ref 255 801 MSEG_MESSAGE_INFO_V1 000000 constant char(8) initial dcl 6-28 ref 440 MSEG_READ_AFTER_SPECIFIED constant fixed bin(17,0) initial dcl 6-30 ref 479 MSEG_READ_BEFORE_SPECIFIED constant fixed bin(17,0) initial dcl 6-30 ref 463 MSEG_READ_FIRST constant fixed bin(17,0) initial dcl 6-30 ref 451 MSEG_READ_LAST constant fixed bin(17,0) initial dcl 6-30 ref 457 MSEG_READ_SPECIFIED constant fixed bin(17,0) initial dcl 6-30 ref 448 P_code parameter fixed bin(35,0) dcl 35 set ref 136 320 337 377 419 603 624 722* P_ms_count parameter fixed bin(17,0) dcl 39 set ref 337 346* 352* 355* 358* 364* 368* 368 P_mseg_operation_ptr parameter pointer dcl 33 ref 136 320 328 337 377 419 603 611 624 688 P_operation_name parameter char unaligned dcl 37 ref 320 329 603 612 P_users_area_ptr parameter pointer dcl 41 ref 419 425 425 603 613 access_audit_r1_$get_audit_flags 000040 constant entry external dcl 110 ref 179 access_audit_r1_$log_obj_ptr 000042 constant entry external dcl 112 ref 209 access_class 213 based bit(72) level 3 dcl 5-24 set ref 358* access_info 115 based structure level 2 dcl 5-24 access_operations_$mseg_add_message 000034 external static bit(36) dcl 105 set ref 209* actual_ms_len 000543 automatic fixed bin(24,0) dcl 1022 set ref 1027* 1042* 1042 1043 1098 actual_n_blocks_unused 000570 automatic fixed bin(18,0) dcl 1161 set ref 1164* 1187* 1187 1192 add_message_info_all_valid 24(10) based bit(1) level 3 packed unaligned dcl 5-24 ref 163 addr builtin function dcl 128 ref 149 193 194 241 392 439 639 772 798 after builtin function dcl 128 ref 858 859 area 000340 stack reference condition dcl 132 ref 515 audit_event_flags based structure level 1 dcl 10-5 authorization 10 based bit(72) level 3 dcl 5-24 set ref 177 358* 834* before builtin function dcl 128 ref 847 848 858 859 block_id 000434 automatic fixed bin(18,0) dcl 770 in procedure "set_message_ptrs" set ref 780* 781 block_id 000334 automatic fixed bin(18,0) dcl 88 in procedure "mseg_message_" set ref 228* 229 231 231* 234 235 block_id 000550 automatic fixed bin(18,0) dcl 1024 in procedure "process_message" set ref 1038* 1039 1088 block_map 520 based structure level 2 dcl 2-28 set ref 772 block_no 000333 automatic fixed bin(18,0) dcl 88 set ref 223* 237* 271* 274* 283 block_size 15 based fixed bin(17,0) level 3 dcl 2-28 ref 197 197 197 235 241 274 276 772 777 780 798 1038 1089 1091 call_admin_gate 24(08) based bit(1) level 3 packed unaligned dcl 5-24 ref 179 205 caller 4 based structure level 2 dcl 5-24 cc_10_100 0(05) 000131 automatic bit(1) level 2 packed unaligned dcl 59 set ref 208* cleanup 000346 stack reference condition dcl 132 ref 140 326 341 381 423 609 628 clock builtin function dcl 128 ref 186 code 000102 automatic fixed bin(35,0) dcl 49 set ref 145 145* 349 349* 386 386* 400* 401 401* 432 432* 502* 503 503* 517* 557* 560* 633 633* 647* 648 648* 665* 690* control_flags 3 based structure level 2 packed unaligned dcl 6-9 currentsize builtin function dcl 128 ref 197 197 197 197 241 241 274 274 276 798 798 1089 1089 1091 data 1 based bit level 3 in structure "first_message_block" packed unaligned dcl 4-69 in procedure "mseg_message_" set ref 283* 1065 data 1 based bit level 3 in structure "other_message_block" packed unaligned dcl 4-82 in procedure "mseg_message_" set ref 285* 1067 1080* 1080 data based bit level 2 in structure "mseg_message_bits" packed unaligned dcl 56 in procedure "mseg_message_" set ref 283 283 285 285 1065* 1065 1067* 1067 1080 1080 data_lth 0(19) based fixed bin(17,0) level 2 in structure "message_block_header" packed unsigned unaligned dcl 4-24 in procedure "mseg_message_" set ref 195* 273* 278* 1042 1060 1074 data_lth 0(19) based fixed bin(17,0) level 3 in structure "other_message_block" packed unsigned unaligned dcl 4-82 in procedure "mseg_message_" set ref 197 197 197 197 276 276 285 1067 1080 1091 1091 data_lth 0(19) based fixed bin(17,0) level 3 in structure "first_message_block" packed unsigned unaligned dcl 4-69 in procedure "mseg_message_" set ref 197 197 241 241 274 274 283 798 798 1065 1089 1089 data_space 1 based structure level 2 in structure "other_message_block" dcl 4-82 in procedure "mseg_message_" data_space 1 based structure level 2 in structure "first_message_block" dcl 4-69 in procedure "mseg_message_" delete 3(01) based bit(1) level 3 packed unaligned dcl 6-9 set ref 542 548 551 981 descriptor based structure level 2 dcl 4-69 set ref 241 798 descriptor_present 0(18) based bit(1) level 2 packed unaligned dcl 4-24 set ref 240* 786 1054 divide builtin function dcl 128 ref 197 772 780 1038 do_owner_check 000323 automatic bit(1) dcl 82 set ref 363* 443* 827 entry_access_info based structure level 1 dcl 7-12 error_table_$bad_segment 000010 external static fixed bin(35,0) dcl 92 set ref 758* error_table_$bad_subr_arg 000012 external static fixed bin(35,0) dcl 92 set ref 427* 495* error_table_$bigarg 000014 external static fixed bin(35,0) dcl 92 set ref 155* 651* error_table_$no_message 000022 external static fixed bin(35,0) dcl 92 set ref 384* 389* 395* 430* 435* 476* 492* 497* 631* 636* 642* error_table_$noalloc 000016 external static fixed bin(35,0) dcl 92 ref 517 error_table_$notalloc 000020 external static fixed bin(35,0) dcl 92 set ref 209* 213* error_table_$null_info_ptr 000024 external static fixed bin(35,0) dcl 92 set ref 151* error_table_$rqover 000026 external static fixed bin(35,0) dcl 92 set ref 143* error_table_$smallarg 000030 external static fixed bin(35,0) dcl 92 set ref 153* error_table_$unimplemented_version 000032 external static fixed bin(35,0) dcl 92 set ref 440* first_block 000542 automatic bit(1) dcl 1021 set ref 1034* 1054 1065 1089 1095* first_mb_ptr 000306 automatic pointer dcl 74 set ref 239* 269 296 300 303 304 first_message 10 based fixed bin(18,0) level 4 packed unsigned unaligned dcl 2-28 set ref 296* 365 453* 484* 1113 1115* first_message_block based structure level 1 dcl 4-69 set ref 1089* fixed builtin function dcl 128 ref 260 880 984 flags 16 based structure level 3 in structure "mseg_segment" dcl 2-28 in procedure "mseg_message_" flags 24 based structure level 2 in structure "mseg_operation" dcl 5-24 in procedure "mseg_message_" get_process_id_ 000044 constant entry external dcl 114 ref 175 group_id 14 based char(32) level 3 packed unaligned dcl 5-24 ref 174 847 858 hash_idx 000336 automatic fixed bin(9,0) dcl 90 set ref 260* 261 304 880* 885 984* 988 1139 1141 hash_mb_ptr 000522 automatic pointer dcl 918 set ref 991* hash_md_ptr 000524 automatic pointer dcl 918 set ref 991* 992 994 998 hash_table 120 based structure level 3 dcl 2-28 header based structure level 2 in structure "other_message_block" dcl 4-82 in procedure "mseg_message_" header based structure level 2 in structure "mseg_segment" dcl 2-28 in procedure "mseg_message_" header based structure level 2 in structure "first_message_block" dcl 4-69 in procedure "mseg_message_" index builtin function dcl 128 ref 228 1172 1183 last_block_allocated 000335 automatic fixed bin(18,0) dcl 88 set ref 221* 226 228 231 231* last_block_checked 000571 automatic fixed bin(18,0) dcl 1161 set ref 1165* 1167 1170 1172 1175* 1179* 1179 1181 1183 1184 1188* 1188 last_message 11 based fixed bin(18,0) level 4 in structure "mseg_segment" packed unsigned unaligned dcl 2-28 in procedure "mseg_message_" set ref 258 299* 303* 459* 468* 1126 1128* last_message 120 based fixed bin(18,0) array level 4 in structure "mseg_segment" packed unsigned unaligned dcl 2-28 in procedure "mseg_message_" set ref 261 304* 885 988 1139 1141* length builtin function dcl 128 ref 197 197 197 274 276 1184 local_aef 000131 automatic structure level 1 dcl 59 set ref 207* 209 209 local_md 000103 automatic structure level 1 dcl 54 set ref 161* 165* 194 253 404* 540* 654* local_message_block 000132 automatic bit(36) array dcl 61 set ref 193 map 520 based bit level 3 packed unaligned dcl 2-28 set ref 228 228 234* 781 1039 1088* 1172 1172 1183 1183 1184 1184 max_authorization 12 based bit(72) level 3 dcl 5-24 ref 178 mb_ptr 000356 automatic pointer dcl 4-32 set ref 193* 195 197 197 197 197 197 197 197 197 197 235* 239 240 241 241 241 243 245 248 269* 273 274 274 274 276 276 276 278 283 285 290* 290 367* 395 405 409* 453* 459* 466 468* 473* 482 484* 489* 497 544 548* 642 656* 796 797* 798 798 798 799* 888* 902* 945 965* 967* 1036* 1036* 1038 1042 1050 1052 1054 1060 1065 1067 1074 1080 1089 1089 1089 1091 1091 1091* md_ptr 000360 automatic pointer dcl 4-61 in procedure "mseg_message_" set ref 194* 197 241* 241 253 255 257 258 261 274 367* 370 399 404 453* 459* 468* 471 473 473* 484* 487 489 489* 501 513 531 540 646 651 654 798 834 848 859 888* 890 892 897 902* 947 952 961 963 965* 973* 984 992 1089 md_ptr 112 based pointer level 2 in structure "mseg_operation" dcl 5-24 in procedure "mseg_message_" set ref 399* 501* 646* md_ptr_valid 24(04) based bit(1) level 3 packed unaligned dcl 5-24 set ref 398* 500* 645* message_block_header based structure level 1 dcl 4-24 set ref 197 197 197 241 274 276 798 1089 1091 message_chain 1 000103 automatic structure level 2 in structure "local_md" dcl 54 in procedure "mseg_message_" message_chain 1 based structure level 2 in structure "message_descriptor" dcl 4-37 in procedure "mseg_message_" message_chain 10 based structure level 3 in structure "mseg_segment" dcl 2-28 in procedure "mseg_message_" message_code 2 based fixed bin(17,0) level 2 dcl 6-9 set ref 448 451 457 463 479 message_descriptor based structure level 1 dcl 4-37 set ref 197 241 253* 274 404 531 540 654 798 1089 message_info 220 based structure level 2 dcl 5-24 set ref 149 392 439 639 message_name 000473 automatic varying char(32) dcl 845 set ref 848* 850 850 855 859* 860 message_offset 000512 automatic fixed bin(18,0) unsigned unaligned dcl 877 in procedure "find_message" set ref 885* 885* 888* message_offset 000530 automatic fixed bin(18,0) unsigned unaligned dcl 922 in procedure "find_accessible_message" set ref 961* 963* 965 965* 988* 988* 991* message_offset 000331 automatic fixed bin(18,0) unsigned unaligned dcl 87 in procedure "mseg_message_" set ref 365* 365* 367* 405* 544* 1113 1119 1126 1132 1139 1144 min builtin function dcl 128 ref 274 276 1074 mod builtin function dcl 128 ref 777 modification_in_progress 16 based bit(1) level 4 packed unaligned dcl 2-28 set ref 216* 310* 407* 413* 545* 554* ms_access_class 11 based bit(72) level 2 in structure "mseg_message_info" dcl 6-9 in procedure "mseg_message_" set ref 173 ms_access_class 20 000103 automatic bit(72) level 2 in structure "local_md" dcl 54 in procedure "mseg_message_" set ref 173* ms_access_class 20 based bit(72) level 2 in structure "message_descriptor" dcl 4-37 in procedure "mseg_message_" set ref 834* ms_id 3 000103 automatic bit(72) level 2 in structure "local_md" dcl 54 in procedure "mseg_message_" set ref 166* 171* 184 187* 260 312 ms_id 7 based bit(72) level 2 in structure "mseg_message_info" dcl 6-9 in procedure "mseg_message_" set ref 312 312* 394* 448* 465* 469* 474* 481* 485* 490* 641* ms_id 3 based bit(72) level 2 in structure "message_descriptor" dcl 4-37 in procedure "mseg_message_" set ref 890 947 952 984 992 992 ms_len 6 based fixed bin(24,0) level 2 in structure "mseg_message_info" dcl 6-9 in procedure "mseg_message_" set ref 151 153 155 172 266 283 285 513* 521 575 592 651 1031 1065 1067 1080 ms_len 5 000103 automatic fixed bin(24,0) level 2 in structure "local_md" packed unsigned unaligned dcl 54 in procedure "mseg_message_" set ref 172* 197 1043 1098 ms_len 5 based fixed bin(24,0) level 2 in structure "message_descriptor" packed unsigned unaligned dcl 4-37 in procedure "mseg_message_" set ref 513 651 ms_ptr 4 based pointer level 2 dcl 6-9 set ref 151 283 285 509* 521* 572 575 576* 590 592 593* 1065 1067 1080 mseg_check_access_$message 000046 constant entry external dcl 115 ref 400 502 647 mseg_data_$admin_ring 000064 external static fixed bin(3,0) dcl 1-8 ref 533 mseg_data_$max_message_size 000062 external static fixed bin(35,0) dcl 1-6 ref 155 mseg_dir_name 000223 automatic char(168) unaligned dcl 71 set ref 690* mseg_entryname 000275 automatic char(32) unaligned dcl 72 set ref 690* mseg_format_errors_$bad_descriptor_sentinel 000100 external static fixed bin(35,0) dcl 9-10 set ref 801* mseg_format_errors_$circular_hash_chain 000102 external static fixed bin(35,0) dcl 9-10 set ref 895* 996* mseg_format_errors_$circular_message_blocks 000104 external static fixed bin(35,0) dcl 9-10 set ref 1047* mseg_format_errors_$circular_message_chain 000106 external static fixed bin(35,0) dcl 9-10 set ref 958* mseg_format_errors_$descriptor_in_other_block 000110 external static fixed bin(35,0) dcl 9-10 set ref 1054* mseg_format_errors_$inconsistent_backward_chain 000112 external static fixed bin(35,0) dcl 9-10 set ref 1126* 1132* mseg_format_errors_$inconsistent_block_map 000114 external static fixed bin(35,0) dcl 9-10 set ref 229* 1192* mseg_format_errors_$inconsistent_forward_chain 000116 external static fixed bin(35,0) dcl 9-10 set ref 1113* 1119* mseg_format_errors_$inconsistent_hash_chain 000120 external static fixed bin(35,0) dcl 9-10 set ref 1002* 1139* 1144* mseg_format_errors_$inconsistent_message_length 000122 external static fixed bin(35,0) dcl 9-10 set ref 1043* 1098* mseg_format_errors_$invalid_message_block_offset 000124 external static fixed bin(35,0) dcl 9-10 set ref 772* 777* mseg_format_errors_$no_descriptor_in_first_block 000126 external static fixed bin(35,0) dcl 9-10 set ref 805* mseg_format_errors_$unused_block_in_message 000130 external static fixed bin(35,0) dcl 9-10 set ref 781* 1039* mseg_message_bits based structure level 1 dcl 56 set ref 521 575 592 mseg_message_info based structure level 1 dcl 6-9 set ref 165 531* mseg_message_info_ptr 000364 automatic pointer dcl 6-7 set ref 149* 151 151 153 155 165 172 173 266 283 283 285 285 312 312 392* 394 439* 440 443 448 448 451 457 463 465 469 474 479 481 485 490 509 513 521 521 531 533 542 548 551 572 575 575 576 590 592 592 593 639* 641 651 981 1031 1065 1065 1067 1067 1080 1080 mseg_operation based structure level 1 dcl 5-24 mseg_operation_ptr 000362 automatic pointer dcl 5-19 set ref 149 163 174 176 177 178 179 205 205 209 328* 331 355 358 358 392 398 399 400* 439 443 500 501 502* 533 611* 615 639 645 646 647* 670* 688* 690* 718 718* 740* 756* 816 831 834 847 858 mseg_operations_$add_message 000066 external static bit(36) dcl 8-8 set ref 142* mseg_operations_$count_messages 000070 external static bit(36) dcl 8-8 set ref 343* mseg_operations_$delete_message 000072 external static bit(36) dcl 8-8 set ref 383* mseg_operations_$read_message 000074 external static bit(36) dcl 8-8 set ref 429* mseg_operations_$update_message 000076 external static bit(36) dcl 8-8 set ref 630* mseg_ptr 000354 automatic pointer dcl 2-68 in procedure "mseg_message_" set ref 197 197 197 202 209* 216 226 228 234 235 235 241 258 261 274 276 290 296 296 299 303 304 306 306 308 308 310 331* 352 355 358 365 389 407 413 435 453 459 468 484 545 554 615* 636 690* 772 772 772 772 777 780 781 784 798 885 895 958 988 996 1038 1039 1047 1052 1088 1089 1091 1092 1092 1113 1115 1126 1128 1139 1141 1150 1150 1167 1170 1172 1175 1181 1183 1184 1192 mseg_ptr 110 based pointer level 2 in structure "mseg_operation" dcl 5-24 in procedure "mseg_message_" ref 331 615 mseg_segment based structure level 1 dcl 2-28 mseg_utils_$abort_operation 000050 constant entry external dcl 117 ref 740 mseg_utils_$begin_operation 000052 constant entry external dcl 119 ref 690 mseg_utils_$finish_operation 000054 constant entry external dcl 122 ref 718 mseg_utils_$salvage_for_cause 000056 constant entry external dcl 124 ref 756 mseg_wakeup_state based structure level 1 dcl 3-24 n_actual_blocks 000547 automatic fixed bin(18,0) dcl 1024 set ref 1028* 1046* 1046 1047 n_bits_copied 000545 automatic fixed bin(24,0) dcl 1022 in procedure "process_message" set ref 1030* 1065 1067 1068* 1068 1080 1082* 1082 n_bits_copied 000327 automatic fixed bin(24,0) dcl 85 in procedure "mseg_message_" set ref 267* 283 285 287* 287 n_bits_remaining 000326 automatic fixed bin(24,0) dcl 85 in procedure "mseg_message_" set ref 266* 274 276 286* 286 n_bits_remaining 000544 automatic fixed bin(24,0) dcl 1022 in procedure "process_message" set ref 1031* 1074 1081* 1081 n_bits_to_copy 000546 automatic fixed bin(24,0) dcl 1022 in procedure "process_message" set ref 1060* 1061 1063 1068 1074* 1075 1077 1079 1081 1082 n_bits_to_copy 000330 automatic fixed bin(24,0) dcl 85 in procedure "mseg_message_" set ref 274* 276* 278 279 281 286 287 n_blocks_allocated 12 based fixed bin(18,0) level 3 dcl 2-28 ref 226 228 234 772 772 781 1039 1047 1088 1167 1170 1172 1175 1181 1183 1184 n_blocks_needed 000332 automatic fixed bin(18,0) dcl 88 set ref 197* 202 223 271 306 n_blocks_unused 13 based fixed bin(18,0) level 3 dcl 2-28 set ref 202 306* 306 1092* 1092 1192 n_messages 14 based fixed bin(18,0) level 3 dcl 2-28 set ref 296 308* 308 352 355 358 389 435 636 895 958 996 1150* 1150 n_messages_checked 000513 automatic fixed bin(18,0) dcl 878 in procedure "find_message" set ref 883* 894* 894 895 n_messages_checked 000531 automatic fixed bin(18,0) dcl 923 in procedure "find_accessible_message" set ref 942* 957* 957 958 986* 995* 995 996 name 000462 automatic varying char(32) dcl 844 set ref 847* 850 850 855 858* 860 next_block based fixed bin(18,0) level 2 packed unsigned unaligned dcl 4-24 set ref 243* 248* 290 1050 1052 next_mb_ptr 000312 automatic pointer dcl 74 in procedure "mseg_message_" set ref 1131* next_mb_ptr 000540 automatic pointer dcl 1020 in procedure "process_message" set ref 1050* 1052* 1096 next_md_ptr 000316 automatic pointer dcl 76 set ref 1131* 1132 1134 next_message 1 000103 automatic fixed bin(18,0) level 3 in structure "local_md" packed unsigned unaligned dcl 54 in procedure "mseg_message_" set ref 1115 1121 1124 1131* next_message 1 based fixed bin(18,0) level 3 in structure "message_descriptor" packed unsigned unaligned dcl 4-37 in procedure "mseg_message_" set ref 257* 300* 370 487 489* 961 1119 1121* next_message_in_hash_chain 000320 automatic pointer dcl 78 set ref 882* 892* 985* 994* 1137 1144 1146 next_unused_block 000572 automatic fixed bin(18,0) dcl 1161 set ref 1172* 1175 1179 next_used_block 000573 automatic fixed bin(18,0) dcl 1161 set ref 1183* 1184 1184* 1187 1188 now 000324 automatic fixed bin(71,0) dcl 84 set ref 186* 187 null builtin function dcl 128 ref 151 209 209 395 425 466 482 497 509 572 576 590 593 642 670 718 882 902 945 967 973 985 1036 1050 1137 only_own_access 24(09) based bit(1) level 3 packed unaligned dcl 5-24 ref 443 operation_name 000202 automatic char(64) unaligned dcl 67 set ref 166 209* 329* 612* 690* operation_specific_abort 000176 automatic entry variable dcl 65 set ref 510* 667* 737 737 operation_specific_return 000172 automatic entry variable dcl 63 set ref 511* 668* 715 715 operation_started_locally 000222 automatic bit(1) dcl 68 set ref 324* 533 607* 672* 718 740 other_message_block based structure level 1 dcl 4-82 set ref 1091* own 3 based bit(1) level 3 packed unaligned dcl 6-9 set ref 443 p_code parameter fixed bin(35,0) dcl 713 in procedure "return_from_operation" set ref 710 715* 722 p_code parameter fixed bin(35,0) dcl 570 in procedure "return_from_read_operation" ref 567 572 p_delete parameter bit(1) dcl 1017 ref 1013 1086 p_first_mb_ptr parameter pointer dcl 1016 ref 1013 1036 p_format_error parameter fixed bin(35,0) dcl 754 set ref 751 756* p_mb_ptr parameter pointer dcl 768 set ref 764 784* 786 797 p_md_ptr parameter pointer dcl 768 set ref 764 798* 801 p_message_offset parameter fixed bin(18,0) unsigned unaligned dcl 767 ref 764 772 772 777 780 784 p_ms_id parameter bit(72) dcl 876 ref 873 880 890 p_ms_id_key parameter bit(72) dcl 916 ref 912 926 934 947 952 p_mseg_operation_id parameter bit(36) dcl 686 set ref 683 690* p_read parameter bit(1) dcl 1017 ref 1013 1058 p_update parameter bit(1) dcl 1017 ref 1013 1031 1072 pad based bit level 3 in structure "first_message_block" packed unaligned dcl 4-69 in procedure "mseg_message_" set ref 197 274 pad based bit level 3 in structure "other_message_block" packed unaligned dcl 4-82 in procedure "mseg_message_" set ref 197 197 276 prev_mb_ptr 000310 automatic pointer dcl 74 set ref 243 245* 299* 1118* prev_md_ptr 000314 automatic pointer dcl 76 set ref 299* 300 1118* 1119 1121 prev_message 1(18) based fixed bin(18,0) level 3 in structure "message_descriptor" packed unsigned unaligned dcl 4-37 in procedure "mseg_message_" set ref 258* 471 473* 963 1132 1134* prev_message 1(18) 000103 automatic fixed bin(18,0) level 3 in structure "local_md" packed unsigned unaligned dcl 54 in procedure "mseg_message_" set ref 1111 1118* 1128 1134 prev_message_in_hash_chain 2(08) based fixed bin(18,0) level 2 in structure "message_descriptor" packed unsigned unaligned dcl 4-37 in procedure "mseg_message_" set ref 261* 897 998 1144 1146* prev_message_in_hash_chain 2(08) 000103 automatic fixed bin(18,0) level 2 in structure "local_md" packed unsigned unaligned dcl 54 in procedure "mseg_message_" set ref 1141 1146 privileges 5 based bit(18) level 3 dcl 5-24 ref 816 read_allowed_ 000060 constant entry external dcl 126 ref 358 834 rest_of_block_map defined bit unaligned dcl 1181 in begin block on line 1180 ref 1183 1184 rest_of_block_map defined bit unaligned dcl 1170 in begin block on line 1169 ref 1172 rest_of_block_map defined bit unaligned dcl 226 in begin block on line 225 ref 228 rqo_detected 000322 automatic bit(1) dcl 81 set ref 143 344 384 430 631 690* rtrim builtin function dcl 128 ref 166 saved_mb_ptr 000436 automatic bit(72) dcl 789 set ref 796* 799 scan_backward 000527 automatic bit(1) dcl 920 set ref 930* 937* 952 scan_forward 000526 automatic bit(1) dcl 920 set ref 929* 938* 947 961 sender_audit 31 based bit(36) level 2 in structure "mseg_message_info" dcl 6-9 in procedure "mseg_message_" set ref 533* sender_audit 25 000103 automatic bit(36) level 2 in structure "local_md" dcl 54 in procedure "mseg_message_" set ref 179* 181* sender_authorization 16 000103 automatic bit(72) level 2 dcl 54 set ref 177* sender_id 6 based char(32) level 2 in structure "message_descriptor" dcl 4-37 in procedure "mseg_message_" set ref 848 859 sender_id 6 000103 automatic char(32) level 2 in structure "local_md" dcl 54 in procedure "mseg_message_" set ref 174* sender_level 2 000103 automatic fixed bin(3,0) level 2 packed unsigned unaligned dcl 54 set ref 176* sender_max_authorization 22 000103 automatic bit(72) level 2 dcl 54 set ref 178* sender_process_id 24 000103 automatic bit(36) level 2 dcl 54 set ref 175* sentinel based bit(36) level 2 dcl 4-37 set ref 255* 801 setwordno builtin function dcl 128 ref 235 290 784 1052 source_bits defined bit unaligned dcl 1077 in begin block on line 1075 ref 1080 source_bits defined bit unaligned dcl 281 in begin block on line 279 ref 283 285 string builtin function dcl 128 set ref 207* 209 209 substr builtin function dcl 128 set ref 234* 260 781 880 984 1039 1088* suppress_access_checks 24(07) based bit(1) level 3 packed unaligned dcl 5-24 ref 205 355 831 sys_info$ring1_privilege 000036 external static bit(36) dcl 107 ref 816 target_bits defined bit unaligned dcl 1063 in begin block on line 1061 set ref 1065* 1067* target_bits defined bit unaligned dcl 1079 in begin block on line 1075 set ref 1080* unspec builtin function dcl 128 set ref 161* 187 796* 796 799* 799 1089* 1091* users_area based area(1024) dcl 46 ref 521 575 592 users_area_ptr 000100 automatic pointer dcl 47 set ref 425* 521 575 592 613* validation_level 4 based fixed bin(3,0) level 3 dcl 5-24 set ref 176 209* 533 version based char(8) level 2 dcl 6-9 set ref 440 wordno builtin function dcl 128 ref 243 296 300 303 304 405 544 772 1038 NAMES DECLARED BY DECLARE STATEMENT AND NEVER REFERENCED. ENTRY_ACCESS_INFO_VERSION_1 internal static char(8) initial unaligned dcl 7-9 MSEG_OPERATION_VERSION_1 internal static fixed bin(17,0) initial dcl 5-20 MSEG_READ_DELETE internal static bit(36) initial dcl 6-38 MSEG_READ_OWN internal static bit(36) initial dcl 6-38 MSEG_SEGMENT_SENTINEL internal static bit(36) initial dcl 2-73 MSEG_SEGMENT_VERSION_5 internal static fixed bin(17,0) initial dcl 2-70 MSEG_TYPE_MBX internal static fixed bin(17,0) initial dcl 5-21 MSEG_TYPE_MS internal static fixed bin(17,0) initial dcl 5-22 MSEG_WAKEUP_STATE_VERSION_1 internal static char(8) initial unaligned dcl 3-41 entry_access_info_ptr automatic pointer dcl 7-8 header_msg based bit(36) array dcl 2-84 header_msg_access_class defined bit(72) dcl 2-79 header_msg_present defined bit(1) unaligned dcl 2-82 mseg_data_$block_size external static fixed bin(35,0) dcl 1-5 mseg_data_$execution_ring external static fixed bin(3,0) dcl 1-9 mseg_data_$group_id external static char(32) unaligned dcl 1-11 mseg_data_$lock_id external static bit(72) dcl 1-4 mseg_data_$process_max_authorization external static bit(72) dcl 1-10 mseg_data_$template_operation external static bit(36) dcl 1-7 mseg_format_errors_$bad_mseg_sentinel external static fixed bin(35,0) dcl 9-10 mseg_format_errors_$bad_mseg_version external static fixed bin(35,0) dcl 9-10 mseg_format_errors_$inconsistent_message_count external static fixed bin(35,0) dcl 9-10 mseg_format_errors_$modification_in_progress external static fixed bin(35,0) dcl 9-10 mseg_format_errors_$negative_message_count external static fixed bin(35,0) dcl 9-10 mseg_format_errors_$salvage_in_progress external static fixed bin(35,0) dcl 9-10 mseg_operations_$add_acl_entries_seg external static bit(36) dcl 8-8 mseg_operations_$chname_seg external static bit(36) dcl 8-8 mseg_operations_$close_seg external static bit(36) dcl 8-8 mseg_operations_$compact_seg external static bit(36) dcl 8-8 mseg_operations_$copy_seg_source external static bit(36) dcl 8-8 mseg_operations_$copy_seg_target external static bit(36) dcl 8-8 mseg_operations_$create_seg external static bit(36) dcl 8-8 mseg_operations_$delete_acl_entries_seg external static bit(36) dcl 8-8 mseg_operations_$delete_seg external static bit(36) dcl 8-8 mseg_operations_$get_salvaged_flag_seg external static bit(36) dcl 8-8 mseg_operations_$get_wakeup_state_seg external static bit(36) dcl 8-8 mseg_operations_$initiate_seg external static bit(36) dcl 8-8 mseg_operations_$list_acl_entries_seg external static bit(36) dcl 8-8 mseg_operations_$list_acl_seg external static bit(36) dcl 8-8 mseg_operations_$open_seg external static bit(36) dcl 8-8 mseg_operations_$replace_acl_seg external static bit(36) dcl 8-8 mseg_operations_$reset_salvaged_flag_seg external static bit(36) dcl 8-8 mseg_operations_$reset_wakeup_state_seg external static bit(36) dcl 8-8 mseg_operations_$set_max_length_seg external static bit(36) dcl 8-8 mseg_operations_$set_safety_switch_seg external static bit(36) dcl 8-8 mseg_operations_$set_wakeup_state_seg external static bit(36) dcl 8-8 mseg_wakeup_state_ptr automatic pointer dcl 3-38 NAMES DECLARED BY EXPLICIT CONTEXT. ADD_MESSAGE 000144 constant label dcl 149 ref 333 FIND_THE_MESSAGE 004056 constant label dcl 942 ref 931 939 FOUND_THE_MESSAGE 004164 constant label dcl 981 ref 947 952 READ_MESSAGE 001723 constant label dcl 435 ref 617 RETURN_FROM_OPERATION 002765 constant label dcl 727 ref 723 RETURN_FROM_READ_OPERATION 002473 constant label dcl 560 ref 518 abort_read_operation 003020 constant entry internal dcl 587 ref 510 begin_operation 003061 constant entry internal dcl 683 ref 142 343 383 429 630 check_block_map_consistency 005036 constant entry internal dcl 1158 ref 204 find_accessible_message 004037 constant entry internal dcl 912 find_message 003752 constant entry internal dcl 873 ref 394 448 465 481 641 find_next_accessible_message 004042 constant entry internal dcl 926 ref 454 485 490 find_previous_accessible_message 004050 constant entry internal dcl 934 ref 460 469 474 is_accessible_message 003516 constant entry internal dcl 824 ref 368 947 mseg_message_ 000051 constant entry external dcl 25 mseg_message_$add_message 000063 constant entry external dcl 136 mseg_message_$add_message_for_mseg 001155 constant entry external dcl 320 mseg_message_$count_messages 001237 constant entry external dcl 337 mseg_message_$delete_message 001422 constant entry external dcl 377 mseg_message_$read_message 001621 constant entry external dcl 419 mseg_message_$read_message_for_mseg 002503 constant entry external dcl 603 mseg_message_$update_message 002570 constant entry external dcl 624 nulle 003135 constant entry internal dcl 701 ref 667 668 715 737 operation_was_aborted 003211 constant entry internal dcl 734 ref 140 326 341 381 423 609 628 owner_doesnt_match 003571 constant entry internal dcl 841 ref 827 process_message 004254 constant entry internal dcl 1013 ref 409 548 656 return_from_operation 003143 constant entry internal dcl 710 ref 143 145 151 153 155 213 315 347 349 373 384 386 389 395 401 415 427 430 432 435 440 476 492 495 497 503 560 631 633 636 642 648 651 658 758 return_from_read_operation 002767 constant entry internal dcl 567 ref 511 ring1_privilege 003505 constant entry internal dcl 813 ref 358 533 834 salvage_and_return 003252 constant entry internal dcl 751 ref 229 772 777 781 801 805 895 958 996 1002 1039 1043 1047 1054 1098 1113 1119 1126 1132 1139 1144 1192 set_message_ptrs 003276 constant entry internal dcl 764 ref 299 367 453 459 468 473 484 489 888 965 991 1118 1131 setup_operation 003045 constant entry internal dcl 662 ref 139 323 340 380 422 606 627 unchain_message 004617 constant entry internal dcl 1108 ref 411 553 THERE WERE NO NAMES DECLARED BY CONTEXT OR IMPLICATION. STORAGE REQUIREMENTS FOR THIS PROGRAM. Object Text Link Symbol Defs Static Start 0 0 6400 6532 5320 6410 Length 7274 5320 132 526 1060 0 BLOCK NAME STACK SIZE TYPE WHY NONQUICK/WHO SHARES STACK FRAME mseg_message_ 552 external procedure is an external procedure. on unit on line 140 64 on unit begin block on line 225 begin block shares stack frame of external procedure mseg_message_. begin block on line 279 begin block shares stack frame of external procedure mseg_message_. on unit on line 326 64 on unit on unit on line 341 64 on unit on unit on line 381 64 on unit on unit on line 423 64 on unit on unit on line 515 64 on unit return_from_read_operation 64 internal procedure is assigned to an entry variable. abort_read_operation 64 internal procedure is assigned to an entry variable. on unit on line 609 64 on unit on unit on line 628 64 on unit setup_operation internal procedure shares stack frame of external procedure mseg_message_. begin_operation internal procedure shares stack frame of external procedure mseg_message_. nulle 64 internal procedure is assigned to an entry variable. return_from_operation internal procedure shares stack frame of external procedure mseg_message_. operation_was_aborted 68 internal procedure is called by several nonquick procedures. salvage_and_return internal procedure shares stack frame of external procedure mseg_message_. set_message_ptrs internal procedure shares stack frame of external procedure mseg_message_. begin block on line 788 begin block shares stack frame of external procedure mseg_message_. ring1_privilege internal procedure shares stack frame of external procedure mseg_message_. is_accessible_message internal procedure shares stack frame of external procedure mseg_message_. owner_doesnt_match internal procedure shares stack frame of external procedure mseg_message_. find_message internal procedure shares stack frame of external procedure mseg_message_. find_accessible_message internal procedure shares stack frame of external procedure mseg_message_. process_message internal procedure shares stack frame of external procedure mseg_message_. begin block on line 1061 begin block shares stack frame of external procedure mseg_message_. begin block on line 1075 begin block shares stack frame of external procedure mseg_message_. unchain_message internal procedure shares stack frame of external procedure mseg_message_. check_block_map_consistency internal procedure shares stack frame of external procedure mseg_message_. begin block on line 1169 begin block shares stack frame of external procedure mseg_message_. begin block on line 1180 begin block shares stack frame of external procedure mseg_message_. STORAGE FOR AUTOMATIC VARIABLES. STACK FRAME LOC IDENTIFIER BLOCK NAME mseg_message_ 000100 users_area_ptr mseg_message_ 000102 code mseg_message_ 000103 local_md mseg_message_ 000131 local_aef mseg_message_ 000132 local_message_block mseg_message_ 000172 operation_specific_return mseg_message_ 000176 operation_specific_abort mseg_message_ 000202 operation_name mseg_message_ 000222 operation_started_locally mseg_message_ 000223 mseg_dir_name mseg_message_ 000275 mseg_entryname mseg_message_ 000306 first_mb_ptr mseg_message_ 000310 prev_mb_ptr mseg_message_ 000312 next_mb_ptr mseg_message_ 000314 prev_md_ptr mseg_message_ 000316 next_md_ptr mseg_message_ 000320 next_message_in_hash_chain mseg_message_ 000322 rqo_detected mseg_message_ 000323 do_owner_check mseg_message_ 000324 now mseg_message_ 000326 n_bits_remaining mseg_message_ 000327 n_bits_copied mseg_message_ 000330 n_bits_to_copy mseg_message_ 000331 message_offset mseg_message_ 000332 n_blocks_needed mseg_message_ 000333 block_no mseg_message_ 000334 block_id mseg_message_ 000335 last_block_allocated mseg_message_ 000336 hash_idx mseg_message_ 000354 mseg_ptr mseg_message_ 000356 mb_ptr mseg_message_ 000360 md_ptr mseg_message_ 000362 mseg_operation_ptr mseg_message_ 000364 mseg_message_info_ptr mseg_message_ 000434 block_id set_message_ptrs 000436 saved_mb_ptr begin block on line 788 000462 name owner_doesnt_match 000473 message_name owner_doesnt_match 000512 message_offset find_message 000513 n_messages_checked find_message 000522 hash_mb_ptr find_accessible_message 000524 hash_md_ptr find_accessible_message 000526 scan_forward find_accessible_message 000527 scan_backward find_accessible_message 000530 message_offset find_accessible_message 000531 n_messages_checked find_accessible_message 000540 next_mb_ptr process_message 000542 first_block process_message 000543 actual_ms_len process_message 000544 n_bits_remaining process_message 000545 n_bits_copied process_message 000546 n_bits_to_copy process_message 000547 n_actual_blocks process_message 000550 block_id process_message 000570 actual_n_blocks_unused check_block_map_consistency 000571 last_block_checked check_block_map_consistency 000572 next_unused_block check_block_map_consistency 000573 next_used_block check_block_map_consistency THE FOLLOWING EXTERNAL OPERATORS ARE USED BY THIS PROGRAM. r_e_as r_ne_as call_ent_var call_ext_out_desc call_ext_out call_int_other return_mac make_label_var tra_ext_1 mdfx1 enable_op ext_entry ext_entry_desc int_entry index_bs_1_eis divide_fx3 op_alloc_ op_freen_ clock_mac THE FOLLOWING EXTERNAL ENTRIES ARE CALLED BY THIS PROGRAM. access_audit_r1_$get_audit_flags access_audit_r1_$log_obj_ptr get_process_id_ mseg_check_access_$message mseg_utils_$abort_operation mseg_utils_$begin_operation mseg_utils_$finish_operation mseg_utils_$salvage_for_cause read_allowed_ THE FOLLOWING EXTERNAL VARIABLES ARE USED BY THIS PROGRAM. access_operations_$mseg_add_message error_table_$bad_segment error_table_$bad_subr_arg error_table_$bigarg error_table_$no_message error_table_$noalloc error_table_$notalloc error_table_$null_info_ptr error_table_$rqover error_table_$smallarg error_table_$unimplemented_version mseg_data_$admin_ring mseg_data_$max_message_size mseg_format_errors_$bad_descriptor_sentinel mseg_format_errors_$circular_hash_chain mseg_format_errors_$circular_message_blocks mseg_format_errors_$circular_message_chain mseg_format_errors_$descriptor_in_other_block mseg_format_errors_$inconsistent_backward_chain mseg_format_errors_$inconsistent_block_map mseg_format_errors_$inconsistent_forward_chain mseg_format_errors_$inconsistent_hash_chain mseg_format_errors_$inconsistent_message_length mseg_format_errors_$invalid_message_block_offset mseg_format_errors_$no_descriptor_in_first_block mseg_format_errors_$unused_block_in_message mseg_operations_$add_message mseg_operations_$count_messages mseg_operations_$delete_message mseg_operations_$read_message mseg_operations_$update_message sys_info$ring1_privilege LINE LOC LINE LOC LINE LOC LINE LOC LINE LOC LINE LOC LINE LOC 25 000050 28 000056 136 000057 139 000073 140 000074 142 000116 143 000125 145 000140 149 000144 151 000147 153 000165 155 000177 161 000215 163 000220 165 000224 166 000263 168 000302 171 000303 172 000305 173 000311 174 000315 175 000320 176 000331 177 000337 178 000343 179 000347 181 000362 184 000363 186 000365 187 000367 193 000371 194 000373 195 000375 197 000401 202 000445 204 000447 205 000450 207 000457 208 000460 209 000462 213 000544 216 000553 221 000556 223 000557 226 000567 228 000573 229 000604 231 000614 234 000620 235 000624 237 000631 239 000634 240 000635 241 000637 242 000660 243 000661 245 000666 246 000667 248 000671 253 000674 255 000700 257 000702 258 000704 260 000710 261 000713 266 000717 267 000722 269 000723 271 000725 273 000735 274 000741 276 000770 278 001004 279 001007 281 001011 283 001013 285 001033 286 001047 287 001051 290 001053 291 001060 296 001062 299 001072 300 001104 303 001111 304 001117 306 001130 308 001132 310 001133 312 001135 315 001145 320 001150 323 001173 324 001174 326 001175 328 001217 329 001223 331 001230 333 001232 337 001233 340 001247 341 001250 343 001272 344 001301 346 001304 347 001306 348 001311 349 001312 352 001316 355 001324 358 001333 363 001364 364 001365 365 001367 367 001377 368 001401 370 001410 373 001414 377 001417 380 001432 381 001433 383 001455 384 001464 386 001477 389 001503 392 001515 394 001520 395 001526 398 001541 399 001544 400 001546 401 001557 404 001563 405 001567 407 001573 409 001576 411 001605 413 001606 415 001611 419 001614 422 001633 423 001634 425 001656 427 001666 429 001675 430 001704 432 001717 435 001723 439 001735 440 001740 443 001753 448 001765 451 001777 453 002001 454 002014 455 002020 457 002021 459 002023 460 002036 461 002042 463 002043 465 002045 466 002053 468 002057 469 002072 470 002101 471 002102 473 002106 474 002122 475 002131 476 002132 477 002141 479 002142 481 002144 482 002152 484 002156 485 002171 486 002200 487 002201 489 002205 490 002217 491 002226 492 002227 493 002236 495 002237 497 002246 500 002261 501 002264 502 002266 503 002277 509 002303 510 002306 511 002311 513 002314 515 002320 517 002334 518 002337 521 002342 531 002353 533 002411 540 002431 542 002435 544 002441 545 002445 548 002450 551 002462 553 002466 554 002467 557 002472 560 002473 603 002475 606 002523 607 002524 609 002525 611 002547 612 002553 613 002560 615 002563 617 002565 624 002566 627 002600 628 002601 630 002623 631 002632 633 002645 636 002651 639 002663 641 002666 642 002674 645 002707 646 002712 647 002714 648 002725 651 002731 654 002746 656 002752 658 002762 727 002765 567 002766 572 002774 575 003005 576 003012 579 003016 587 003017 590 003025 592 003033 593 003040 596 003044 662 003045 665 003046 667 003047 668 003052 670 003054 672 003056 674 003060 683 003061 688 003063 690 003067 693 003133 701 003134 704 003142 710 003143 715 003145 718 003167 722 003204 723 003207 734 003210 737 003216 740 003237 743 003251 751 003252 756 003254 758 003266 760 003275 764 003276 772 003300 777 003342 780 003364 781 003377 784 003412 786 003424 796 003427 797 003431 798 003435 799 003457 801 003461 803 003474 805 003475 807 003504 813 003505 816 003507 824 003516 827 003520 831 003532 834 003542 841 003571 847 003573 848 003610 850 003625 855 003647 858 003661 859 003710 860 003737 863 003747 873 003752 880 003754 882 003760 883 003762 885 003763 888 003775 890 003777 892 004011 894 004012 895 004013 897 004026 902 004033 904 004036 912 004037 914 004041 926 004042 929 004044 930 004046 931 004047 934 004050 937 004052 938 004054 939 004055 942 004056 945 004057 947 004064 951 004105 952 004106 957 004121 958 004122 961 004135 963 004144 965 004150 967 004156 968 004160 973 004161 974 004163 981 004164 984 004170 985 004173 986 004175 988 004176 991 004207 992 004211 994 004222 995 004223 996 004224 998 004237 1002 004244 1005 004253 1013 004254 1027 004256 1028 004257 1030 004260 1031 004261 1034 004267 1036 004271 1038 004300 1039 004306 1042 004321 1043 004324 1046 004337 1047 004340 1050 004353 1052 004362 1054 004365 1058 004401 1060 004405 1061 004410 1063 004411 1065 004413 1067 004431 1068 004444 1070 004446 1072 004447 1074 004452 1075 004460 1077 004462 1079 004464 1080 004465 1081 004502 1082 004504 1086 004506 1088 004512 1089 004517 1091 004551 1092 004576 1095 004577 1096 004600 1098 004603 1101 004616 1108 004617 1111 004620 1113 004623 1115 004642 1116 004645 1118 004646 1119 004650 1121 004667 1124 004672 1126 004675 1128 004714 1129 004720 1131 004721 1132 004723 1134 004742 1137 004745 1139 004751 1141 004776 1142 005004 1144 005005 1146 005025 1150 005032 1152 005035 1158 005036 1164 005037 1165 005040 1167 005041 1170 005046 1172 005052 1175 005063 1179 005067 1181 005072 1183 005076 1184 005107 1187 005113 1188 005116 1190 005122 1192 005123 1195 005135 ----------------------------------------------------------- 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