1 /****^  ***********************************************************
  2         *                                                         *
  3         * Copyright, (C) Honeywell Bull Inc., 1987                *
  4         *                                                         *
  5         * Copyright, (C) Honeywell Information Systems Inc., 1982 *
  6         *                                                         *
  7         * Copyright (c) 1972 by Massachusetts Institute of        *
  8         * Technology and Honeywell Information Systems, Inc.      *
  9         *                                                         *
 10         *********************************************************** */
 11 
 12 /* format: style4,indattr,ifthenstmt,ifthen,idind35,^indcomtxt */
 13 
 14 delentry: proc;
 15 
 16 /* modified by Kobziar on 11-15-73 not to require "w" on seg in order to delete */
 17 /* last modified April 1975 by R. Bratt for new RNT/KST system             */
 18 /* last modified Feb. 1976 by R. Bratt for pam flush     */
 19 /* last modified April 20, 1976 by R. Bratt to check mountedness of volume */
 20 /* modified 760324 by L. Scheffler to fix call to dir_control_error to call with dp, not ep */
 21 /* last modified April 24, 1976 by R. Bratt to swallow known_in_other_rings code from makeunknown */
 22 /* last modified June 1, 1976 by R. Bratt to call find_$finished when done   */
 23 /* Modified by D.Vinograd 6/76 to add entry retv, used by volume retriever, which deletes without access checking */
 24 /* Modified 4/77 by M. Weaver to replace makeknown by makeknown_ */
 25 /* Modified April 1979 by D. Spector to remove logging of privileged deletions */
 26 /* Modified June 1981 by J. Bongiovanni to call pathname_am$clear when deleting
 27       per-process directory */
 28 /* Modified June 30 1981 by M. Pierret to remove access checking for priviledged entry.*/
 29 /* Modified 2/82 BIM for new name of side-door dir unlocker. */
 30 /* Modified 9/83 E. N. Kittlitz to handle makeknown_ returning connection_fail */
 31 /* Modified 6/84 Keith Loepere to use the new dc_find. */
 32 /* Modified 10/84 Keith Loepere for auditing of deletions. */
 33 /* Modified 84-11-27 to change access_audit_ arg lists */
 34 /* Modified 85-04-01 Keith Loepere for new access_audit_check_ep_. */
 35 /* Modified 85-05-08 EJ Sharpe: renamed priv_duid to duid_mdir_priv, added duid_mdir entry */
 36 /* Modified 85-05-15 EJ Sharpe: fix so hpdl can delete master dirs */
 37 
 38 /*
 39    The delentry routine implements the user callable primitives for deleting
 40    an entry in a directory.
 41 
 42    Entry: delentry$dfile
 43 
 44    This entry deletes the entry designamed by the directory pathname, dirname,
 45    and the entry name, ename.
 46 
 47    Usage: call delentry$dfile (dirname, ename, code);
 48 
 49    1) dirname (character (168))                   parent directory pathname (Input)
 50 
 51    2) ename (character(32)                        entryname to be deleted (Input)
 52 
 53    3) code (fixed bin)                            return error code (Output)
 54 
 55 
 56    Entry: delentry$dseg
 57 
 58    This entry deletes the entry designated by the pointer sp.
 59 
 60    Usage: call delentry$dseg (sp, code);
 61 
 62    1) sp (pointer)                                pointer to segment to be deleted (Input)
 63 
 64    2) code (fixed bin)                            error code (Output)
 65 
 66    Note:  If the entry is a segment, then the contents of the segment are deleted
 67 
 68    before the entry is deleted.  If it is a directory entry then  an error code is returned and
 69    del_dir_tree must be called.
 70    */
 71 
 72 /* Parameters */
 73 
 74 dcl  a_code                             fixed bin (35) parameter;
 75 dcl  a_dirname                          char (*) parameter;
 76 dcl  a_ename                            char (*) parameter;
 77 dcl  a_ep                               ptr parameter;
 78 dcl  a_sp                               ptr parameter;
 79 dcl  a_trp                              fixed bin (71) parameter; /* to return time-record product */
 80 dcl  a_uidpath                          (0:15) bit (36) aligned parameter;
 81 
 82 /* Variables */
 83 
 84 dcl  acl_count                          fixed bin;
 85 dcl  aclep                              ptr;
 86 dcl  areap                              ptr;
 87 dcl  asize                              fixed bin;
 88 dcl  audit_eventflags                   bit (36) aligned;
 89 dcl  code                               fixed bin (35);
 90 dcl  damaged                            bit (1) init ("0"b);/* TRUE if dir uid is 0 */
 91 dcl  dirl                               bit (1) init ("0"b);
 92 dcl  dirname                            char (168);
 93 dcl  e_sw                               fixed bin;
 94 dcl  ename                              char (32);
 95 dcl  ignore                             fixed bin (35);
 96 dcl  1 mk_info                          aligned like makeknown_info;
 97 dcl  mkunk_uid                          bit (36) aligned init ("0"b);
 98 dcl  ncnt                               fixed bin;
 99 dcl  nnames                             fixed bin (18);
100 dcl  nrp                                bit (18) aligned;
101 dcl  onp                                ptr;
102 dcl  priv_entry                         bit (1) init ("0"b);
103 dcl  pvid                               bit (36) aligned;
104 dcl  1 qcell                            like quota_cell aligned automatic;
105 dcl  ring                               fixed bin;
106 dcl  seg_uid                            bit (36) aligned;
107 dcl  segl                               bit (1) init ("0"b);
108 dcl  segno                              fixed bin;
109 dcl  segptr                             ptr init (null);
110 dcl  sp                                 ptr;
111 dcl  trp                                fixed bin (71);
112 dcl  type                               fixed bin;
113 dcl  uidpath                            (0:15) bit (36) aligned;
114 dcl  vtocx                              fixed bin;
115 
116 /* Constants */
117 
118 dcl  directory                          init (2) fixed bin static;
119 dcl  link_br                            init (0) fixed bin static;
120 dcl  file                               init (0) fixed bin static;
121 dcl  read_lock                          bit (36) aligned init ("0"b);
122 dcl  retv                               init (3) fixed bin static;
123 dcl  seg                                init (1) fixed bin static;
124 dcl  segment                            init (1) fixed bin static;
125 dcl  uid_mdir                           init (2) fixed bin static;
126 
127 /* External */
128 
129 dcl  active_hardcore_data$ensize        fixed bin external;
130 dcl  active_hardcore_data$esize         fixed bin external;
131 dcl  error_table_$copy_sw_on            fixed bin (35) external;
132 dcl  error_table_$dirseg                fixed bin (35) external;
133 dcl  error_table_$fulldir               fixed bin (35) external;
134 dcl  error_table_$infcnt_non_zero       fixed bin (35) external;
135 dcl  error_table_$invalidsegno          fixed bin (35) external;
136 dcl  error_table_$known_in_other_rings  fixed bin (35) external;
137 dcl  error_table_$lower_ring            fixed bin (35) external;
138 dcl  error_table_$master_dir            fixed bin (35) external;
139 dcl  error_table_$safety_sw_on          fixed bin (35) external;
140 dcl  error_table_$seg_unknown           fixed bin (35) external;
141 dcl  error_table_$segknown              fixed bin (35) external;
142 dcl  error_table_$vtoce_connection_fail fixed bin (35) external; ;
143 dcl  pds$access_authorization           bit (72) aligned external;
144 dcl  pds$process_group_id               char (24) ext;
145 dcl  pds$processid                      bit (36) aligned ext;
146 
147 /* Entries */
148 
149 dcl  acc_name_$delete                   entry (ptr);
150 dcl  access_audit_check_ep_$self        entry (bit (36) aligned, bit (36) aligned, ptr) returns (bit (1));
151 dcl  access_audit_$log_entry_ptr        entry (char (*), fixed bin, bit (36) aligned, bit (36) aligned, ptr, fixed bin (35), ptr, fixed bin (18), char (*));
152 dcl  acl_$del_acl                       entry (fixed bin, bit (36) aligned, ptr);
153 dcl  aim_check_$equal                   entry (bit (72) aligned, bit (72) aligned) returns (bit (1) aligned);
154 dcl  delete_vtoce                       entry (ptr, fixed bin (35));
155 dcl  fs_alloc$free                      entry (ptr, fixed bin, ptr);
156 dcl  hash$out                           entry (ptr, ptr, ptr, fixed bin (35));
157 dcl  level$get                          entry returns (fixed bin);
158 dcl  lock$dir_lock_write                entry (ptr, fixed bin (35));
159 dcl  lock$dir_unlock                    entry (ptr);
160 dcl  lock$dir_unlock_given_uid          entry (bit (36) aligned);
161 dcl  makeknown_                         entry (ptr, fixed bin, fixed bin, fixed bin (35));
162 dcl  makeunknown_                       entry (fixed bin, bit (36) aligned, bit (1) aligned, fixed bin (35));
163 dcl  mountedp                           entry (bit (36) aligned) returns (fixed bin (35));
164 dcl  pathname_am$clear                  entry (fixed bin (17));
165 dcl  pathname_am$flush                  entry (bit (36) aligned);
166 dcl  sum$dirmod                         entry (ptr);
167 dcl  syserr                             entry options (variable);
168 dcl  syserr$error_code                  entry options (variable);
169 dcl  terminate_$id                      entry (bit (36) aligned, fixed bin, fixed bin (35));
170 dcl  vtoc_attributes$get_quota          entry (bit (36) aligned, bit (36) aligned, fixed bin, ptr, fixed bin, fixed bin (35));
171 
172 /* Misc */
173 
174 dcl  (addr, fixed, ptr, rel, null, baseptr, unspec) builtin;
175 
176 dcl  bad_dir_                           condition;
177 dcl  seg_fault_error                    condition;
178 %page;
179 salv_delete_branch: entry (a_ep, a_code);                   /* Make branch go awayy */
180 
181           ep = a_ep;
182           dp = ptr (ep, 0);
183           dirl = "0"b;                                      /* Don't unlock dir */
184           code = 0;
185           damaged = "1"b;                                   /* Couldnt get inferior dir */
186           segptr = null;                                    /* didn't touch inferior */
187           segl = "0"b;                                      /* or lock it */
188           if ^entry.bs then type = link_br;
189           else if entry.dirsw then type = directory;
190           else type = segment;
191           go to remove;                                     /* Remove the branch */
192 
193 retv: entry (a_dirname, a_ename, a_code);
194 
195           e_sw = retv;
196           goto set_code;
197 
198 
199 priv_dfile: entry (a_dirname, a_ename, a_code);
200           priv_entry = "1"b;
201 
202 dfile: entry (a_dirname, a_ename, a_code);
203           e_sw = file;                                      /* indicate through which entry point entered */
204 
205 set_code: code = 0;                                         /* clear return status code */
206           dirname = a_dirname;                              /* copy arguments */
207           ename = a_ename;
208 
209           if e_sw ^= retv & ^priv_entry then call dc_find$obj_delete (dirname, ename, DC_FIND_NO_CHASE, ep, code);
210           else call dc_find$obj_delete_priv (dirname, ename, DC_FIND_NO_CHASE, ep, code); /* get ptr to entry + lock dir for writing */
211           if code ^= 0 then go to ret;
212           go to common;
213 
214 
215 dseg: entry (a_sp, a_code);
216 
217           code = 0;                                         /* clear return status code */
218           e_sw = seg;                                       /* indicate through entry point we entered */
219           sp = a_sp;                                        /* copy arg */
220           call dc_find$obj_delete_ptr (sp, ep, code);       /* get ptr to entry + lock for write */
221           if code ^= 0 then go to ret;
222           go to common;
223 
224 duid_mdir_priv: entry (a_uidpath, a_trp, a_code);           /* entry to delete given uidpathname */
225 
226           e_sw = uid_mdir;                                  /* name type entry */
227           uidpath = a_uidpath;                              /* copy path */
228           call dc_find$obj_delete_priv_uid (uidpath, dirname, ename, ep, code); /* find the thing */
229           if code ^= 0 then go to ret;
230           priv_entry = "1"b;
231           trp = 0;
232           goto common;
233 
234 duid_mdir: entry (a_uidpath, a_trp, a_code);                /* entry to delete given uidpathname */
235 
236           e_sw = uid_mdir;                                  /* name type entry */
237           uidpath = a_uidpath;                              /* copy path */
238           call dc_find$obj_delete_uid (uidpath, dirname, ename, ep, code); /* find the thing */
239           if code ^= 0 then go to ret;
240           trp = 0;
241 
242 common:
243           dp = ptr (ep, 0);
244           dirl = "1"b;
245           if ^ep -> entry.bs then do;                       /* link case */
246                type = link_br;                              /* set type of entry */
247                go to remove;
248           end;
249           else if ^ep -> entry.dirsw then type = segment;   /* non-directory branch */
250           else type = directory;                            /* directory branch */
251 
252           if e_sw ^= retv & ^priv_entry then do;
253                ring = level$get ();                         /* get validation level */
254                if (type = segment & ring > fixed (ep -> entry.ring_brackets (1), 3)) |
255                     (type ^= segment & ring > fixed (ep -> entry.ex_ring_brackets (1), 3)) then do;
256                     code = error_table_$lower_ring;         /* ringbrackets must be consistent with validation level */
257                     go to finale;
258                end;
259 
260                if entry.copysw then do;                     /* branch cannot be deleted if copy on */
261                     code = error_table_$copy_sw_on;
262                     go to finale;
263                end;
264                if entry.safety_sw then do;                  /* branch may not be deleted if safety switch on */
265                     code = error_table_$safety_sw_on;
266                     go to finale;
267                end;
268           end;
269                                                             /* If ename is a directory branch, be sure there are */
270           if type = directory then do;                      /* no entries in that directory before deleting it */
271                if e_sw = seg then do;                       /* Forbid use of ptr entry */
272                     code = error_table_$dirseg;
273                     go to finale;
274                end;
275                seg_uid = entry.uid;                         /* Make sure nobody deletes it */
276                segptr = null;
277                on seg_fault_error begin;
278                     damaged = "1"b;
279                     goto dir_glop;
280                end;
281                unspec (mk_info) = "0"b;
282                mk_info.uid = seg_uid;
283                mk_info.entryp = ep;
284                mk_info.dirsw = "1"b;
285                mk_info.allow_write = "1"b;
286                mk_info.activate = "1"b;
287                call makeknown_ (addr (mk_info), segno, (0), code);
288                if code = 0 | code = error_table_$segknown then
289                     segptr = baseptr (segno);
290                else if code = error_table_$vtoce_connection_fail then damaged = "1"b;
291                else goto finale;
292                call dc_find$finished (dp, "1"b);            /* unlock and unreference (initiated dir will hold parent) - allows seg_fault to work */
293                dirl = "0"b;
294                if damaged then goto dir_glop;               /* skip segfault on next statement */
295 
296                if segptr -> dir.uid = "0"b then do;         /* If the directory's UID is 0 we cant lock it */
297                     call syserr (4, "delentry: deleting damaged dir ^a>^a for ^a",
298                          dirname, ename, pds$process_group_id);
299                     damaged = "1"b;                         /* .. but then, nobody else can either */
300                end;
301                else do;
302                     call lock$dir_lock_write (segptr, code);/* Lock the dir to be deleted */
303                     if code ^= 0 then go to finale;
304                     segl = "1"b;
305                end;
306 dir_glop:      revert seg_fault_error;
307                if e_sw = seg then call dc_find$obj_delete_ptr (sp, ep, code); /* refind dir */
308                else if e_sw = retv | priv_entry then call dc_find$obj_delete_priv (dirname, ename, DC_FIND_NO_CHASE, ep, code);
309                else call dc_find$obj_delete (dirname, ename, DC_FIND_NO_CHASE, ep, code);
310                if code ^= 0 then do;
311                     if segptr ^= null then do;
312                          call lock$dir_unlock (segptr);     /* Gack. How does this happen */
313                          call makeunknown_ (segno, "0"b, ("0"b), ignore); /* .. ayway cleanup */
314                     end;
315                     go to ret;
316                end;
317                dp = ptr (ep, 0);                            /* Regenerate dp just in case */
318                dirl = "1"b;
319                if seg_uid ^= entry.uid then do;             /* Check that our access check above .. */
320                     code = error_table_$invalidsegno;       /* .. hasn't been interfered with */
321                     go to finale;                           /* nasty */
322                end;
323                if ^damaged then do;                         /* Various validity checks. skip for bad dir */
324                     if segptr -> dir.master_dir then
325                          if e_sw ^= uid_mdir & ^priv_entry then do;
326                               code = error_table_$master_dir; /* Do not delete master directory */
327                               go to finale;
328                          end;
329                     if segptr -> dir.seg_count ^= 0         /* check if directory has any branches */
330                          | segptr -> dir.dir_count ^= 0
331                          | segptr -> dir.lcount ^= 0 then do;
332 
333                          code = error_table_$fulldir;
334                          if /* tree */ ^aim_check_$equal (pds$access_authorization, segptr -> dir.access_class) then /* audit possible covert channel */
335                               if ^addr (pds$access_authorization) -> aim_template.privileges.dir then do;
336                                    audit_eventflags = "0"b;
337                                    addr (audit_eventflags) -> audit_event_flags.cc_10_100 = "1"b;
338                                    if access_audit_check_ep_$self (audit_eventflags, access_operations_$fs_obj_delete, ep) then
339                                         call access_audit_$log_entry_ptr
340                                              ("delentry", level$get (), audit_eventflags, access_operations_$fs_obj_delete, ep, code, null, 0, "");
341                               end;
342                          go to finale;
343                     end;
344                     if e_sw = uid_mdir then do;             /* caller wants a time record product */
345                          pvid = entry.pvid;
346                          vtocx = entry.vtocx;
347                          qcp = addr (qcell);
348                          call vtoc_attributes$get_quota (seg_uid, pvid, vtocx, qcp, 0, code);
349                          if code = 0 then trp = quota_cell.trp; /* save it if i got it */
350                     end;
351                end;
352           end;
353 
354 
355 
356 /* Everything AOK. Remove segment and branch and go to finale. */
357 
358           if type ^= link_br then do;
359                if priv_entry | type = directory then code = 0; /* only check if unpriv or segment */
360                else code = mountedp (dir.sons_lvid);
361                if code = 0 then do;
362                     call delete_vtoce (ep, code);
363                     if code ^= 0 then call syserr$error_code (LOG, code, "delentry: failed to delete_vtoce for ^w ^o.", ep -> entry.pvid, ep -> entry.vtocx);
364                end;
365                if code ^= 0 then                            /* error from delete_vtoce prob volume not up */
366                     if ^priv_entry | code = error_table_$infcnt_non_zero then /* unprivileged attempt or dir contains known inferior segments */
367                          go to finale;                      /* leave branch intact and return error code */
368                                                             /*                  else call syserr$error_code (4, code,
369                                                                "delentry: priv_dfile error deleting vtoce for ^a>^a for ^a",
370                                                                dirname, ename, pds$process_group_id);
371                                                                -- Priv deletions used to be logged */
372           end;
373 
374 remove:
375           dir.modify = pds$processid;                       /* mark dir unstable */
376           nrp = entry.name_brp;                             /* get rp to last name */
377           areap = ptr (dp, dir.arearp);                     /* get ptr to area */
378           nnames = fixed (entry.nnames, 18);                /* pick up count of names */
379           ncnt = 0;
380 
381 name_loop:
382           ncnt = ncnt + 1;                                  /* keep track of number of names deleted */
383           if ncnt > nnames then signal bad_dir_;            /* too many times through the loop */
384           np = ptr (dp, nrp);                               /* get ptr to name entry to be removed */
385           if np -> names.type ^= NAME_TYPE
386                | np -> names.owner ^= entry.uid
387                | np -> names.entry_rp ^= rel (ep) then signal bad_dir_;
388           call hash$out (dp, addr (np -> names.name), onp, code); /* remove name from hash table */
389           if code ^= 0 then call syserr$error_code (4, code, "delentry: error from hash$out on ""^a"" for ^a",
390                     np -> names.name, pds$process_group_id);
391 
392           if np ^= onp then signal bad_dir_;                /* check that hash table entry and name entry are consistent */
393 
394           nrp = np -> names.bp;                             /* get rp to previous name on list */
395           if nrp then do;                                   /* if not primary name stored in the entry */
396                entry.name_brp = nrp;                        /* thread name list to entry */
397                call fs_alloc$free (areap, active_hardcore_data$ensize, np); /* free name entry */
398                go to name_loop;                             /* continue removing names */
399           end;
400           entry.name_frp, entry.name_brp = "0"b;            /* clear name threads */
401           entry.nnames = 0;                                 /* zero name count */
402 
403           if type ^= link_br then do;                       /* in the branch case free the storage of the acl */
404                aclep = addr (entry.acl_frp);                /* get pointer to start of acl */
405                acl_count = fixed (entry.acle_count, 18);    /* get count of acls assoc with this entry */
406                call acl_$del_acl (acl_count, entry.uid, aclep); /* remove entire acl */
407 
408                dir.acle_total =                             /* decrease count of acl entries in dir header */
409                     dir.acle_total - acl_count;
410 
411                entry.acl_frp, entry.acl_brp = "0"b;         /* zero out acl threads */
412                entry.acle_count = 0;                        /* zero out acl count in entry */
413 
414                asize = active_hardcore_data$esize;          /* size of area to be freed is entry size */
415                                                             /* delete bc author and update pers and proj name lists */
416                call acc_name_$delete (addr (entry.bc_author));
417 
418                mkunk_uid = entry.uid;                       /* get it unknown later */
419                segptr = null;
420           end;
421           else do;                                          /* in link case set pathname size to zero */
422                ep -> link.pathname_size = 0;
423                asize = ep -> link.size;                     /* pick up number of words in link entry (for freeing) */
424           end;
425 
426           call acc_name_$delete (addr (entry.author));      /* delete author and update pers and proj name lists */
427 
428           if entry.ebrp then ptr (ep, entry.ebrp) -> entry.efrp = entry.efrp; /* unthread the entry */
429           if entry.efrp then ptr (ep, entry.efrp) -> entry.ebrp = entry.ebrp;
430           if rel (ep) = dir.entrybrp then dir.entrybrp = entry.ebrp;
431           if rel (ep) = dir.entryfrp then dir.entryfrp = entry.efrp;
432           entry.ebrp, entry.efrp = "0"b;
433           if type = link_br then dir.lcount = dir.lcount - 1; /* fix seg, dir, or link_br count in dir */
434           else if type = segment then dir.seg_count = dir.seg_count - 1;
435           else dir.dir_count = dir.dir_count - 1;
436           entry.uid = "0"b;                                 /* clear uid */
437           entry.pvid = "0"b;
438           call fs_alloc$free (areap, asize, ep);            /* free the entry */
439           if type = directory & ^damaged then do;
440                if ^entry.per_process_sw then call pathname_am$flush (mkunk_uid);
441                else call pathname_am$clear (segno);
442                call lock$dir_unlock_given_uid (seg_uid);
443                segl = "0"b;
444           end;
445           if dirl then dir.modify = "0"b;                   /* If we locked dir, mark as ok now. */
446           call sum$dirmod (dp);
447 
448 
449 finale:
450           if segl then call lock$dir_unlock_given_uid (seg_uid); /* may not be all there */
451           if dirl then do;
452                dir.modify = "0"b;
453                if e_sw ^= seg then call dc_find$finished (dp, "1"b);
454                else call lock$dir_unlock (dp);
455                                                             /* dont touch lot unless we locked dir */
456                if segptr ^= null then call makeunknown_ (segno, "0"b, ("0"b), ignore); /* implies dir */
457                else if mkunk_uid ^= "0"b then do;
458                     call terminate_$id (mkunk_uid, 0, code);
459                     if code ^= 0 then if code = error_table_$seg_unknown
460                               | code = error_table_$invalidsegno
461                               | code = error_table_$known_in_other_rings then code = 0;
462                          else call syserr$error_code (4, code, "delentry: error from terminate_ for ^a", pds$process_group_id);
463                end;
464           end;
465           if e_sw = uid_mdir then a_trp = trp;
466 ret:
467           a_code = code;
468           return;
469 
470 /* format: off */
471 
472 %page; %include access_audit_eventflags;
473 %page; %include aim_template;
474 %page; %include dc_find_dcls;
475 %page; %include dir_entry;
476 %page; %include dir_header;
477 %page; %include dir_link;
478 %page; %include dir_name;
479 %page; %include fs_obj_access_codes;
480 %page; %include fs_types;
481 %page; %include makeknown_info;
482 %page; %include quota_cell;
483 %page; %include syserr_constants;
484 %page;
485 /* format: on */
486 
487 /* BEGIN MESSAGE DOCUMENTATION
488 
489    Message:
490    delentry: deleting damaged dir PATH for USERID
491 
492    S:     $log
493 
494    T:     $run
495 
496    M:     An attempt to delete a directory
497    found that the directory header had a zero UID.
498    The directory was deleted anyway.
499 
500    A:     $ignore
501 
502    Message:
503    delentry: priv_dfile error deleting vtoce for PATH for USERID. ERROR_CODE
504 
505    S:     $log
506 
507    T:     $run
508 
509    M:     A privileged call to delete a segment
510    discovered a branch with not VTOC entry.
511    This situation is called a "connection failure."
512    The branch was deleted anyway.
513 
514    A:     $ignore
515 
516    Message:
517    delentry: error from hash$out on "NAME" for USERID. ERROR_CODE
518 
519    S:     $log
520 
521    T:     $run
522 
523    M:     An attempt to delete the entry name NAME from the directory
524    hash table failed.
525    $err
526 
527    A:     $ignore
528 
529    Message:
530    delentry: error from terminate_ for USERID. ERROR_CODE
531 
532    S:     $log
533 
534    T:     $run
535 
536    M:     An error code was returned while trying to
537    make a directory unknown
538    while deleting it.
539    $err
540 
541    A:     $ignore
542 
543    END MESSAGE DOCUMENTATION */
544 
545      end delentry;