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 
 13 /* format: style1,ind5,^inddcls,ifthenstmt,dclind2,declareind2,ifthendo,ifthen*/
 14 
 15 retv_copy: proc (a_dirname, a_ename, a_auth, a_userid, a_level, a_vtocep, a_objectp, a_attributes, a_code);
 16 
 17 /* This routine provides a controlled method of copying data from a temp orary buffer
 18    in an outer ring either into an existant or non-existant object, regardless of whether that object is
 19    a segment or a directory */
 20 
 21 /*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * */
 22 /*                                                                                        */
 23 /* Status:                                                                                */
 24 /* 0) Created by Dave Vinograd in the distant past.                                       */
 25 /* 1) Modified: 8/18/82 by GA Texada to fix phx13506                                      */
 26 /* 2) Modified: 8/08/83 by E. N. Kittlitz for setfaults$if_active pvid, vtocx args        */
 27 /* 3) Modified: 7/6/84 by Keith Loepere to use the new dc_find.                           */
 28 /* 4) Modified: 10/15/84 by Keith Loepere to explicitly activate dir on makeknown_,       */
 29 /*                  also for auditing info.                                               */
 30 /* 5) Modified: 12/13/84 by Keith Loepere to reload dir quota also.                       */
 31 /*                                                                                        */
 32 /*  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  *  * */
 33 
 34 /* Parameters */
 35 
 36 dcl a_attributes         bit (36);
 37 dcl a_auth               bit (72) aligned;
 38 dcl a_code               fixed bin (35);
 39 dcl a_dirname            char (*) aligned;
 40 dcl a_ename              char (*) aligned;
 41 dcl a_level              fixed bin;
 42 dcl a_objectp            ptr;
 43 dcl a_userid             char (*) aligned;
 44 dcl a_vtocep             ptr;
 45 
 46 /* Variables */
 47 
 48 dcl attributes           bit (36);
 49 dcl code                 fixed bin (35);
 50 dcl del_code             fixed bin (35);
 51 dcl del_ename            char (32);
 52 dcl del_pname            char (168);
 53 dcl dir_pvid             bit (36) aligned;
 54 dcl dir_uid              bit (36) aligned;
 55 dcl dir_vtocx            fixed bin;
 56 dcl dirl                 bit (1) aligned;
 57 dcl dirname              char (168);
 58 dcl dirsw                bit (1);
 59 dcl ec                   fixed bin (35);
 60 dcl ename                char (32);
 61 dcl found                bit (1);
 62 dcl hold                 bit (1);
 63 dcl i                    fixed bin;
 64 dcl ignore               fixed bin (35);
 65 dcl inf_received         (0:1) fixed bin (18);
 66 dcl 1 input_vtoce        like vtoce aligned;
 67 dcl 1 local_audit_user_info like audit_user_info aligned;
 68 dcl 1 local_dir_header   like dir aligned;
 69 dcl 1 local_makeknown_info like makeknown_info aligned;
 70 dcl 1 local_quota_cell   like quota_cell aligned;
 71 dcl 1 local_vtoce        like vtoce aligned;
 72 dcl mismatch             bit (1);
 73 dcl ncd                  fixed bin;
 74 dcl new_ep               ptr;
 75 dcl new_vtoce            bit (1);
 76 dcl nid                  fixed bin;
 77 dcl objectp              ptr;
 78 dcl old_ep               ptr;
 79 dcl old_uid              bit (36) aligned;
 80 dcl par_ep               ptr;
 81 dcl par_pvid             bit (36) aligned;
 82 dcl par_quota            (0:1) fixed bin (18);
 83 dcl par_received         (0:1) fixed bin (18);
 84 dcl par_uid              bit (36) aligned;
 85 dcl par_vtocx            fixed bin;
 86 dcl pardirl              bit (1) aligned;
 87 dcl pvid                 bit (36) aligned;
 88 dcl pvtx                 fixed bin;
 89 dcl quota_type           fixed bin;
 90 dcl segno                fixed bin;
 91 dcl segptr               ptr;
 92 dcl skip_list            (1500) bit (36) aligned;
 93 dcl skip_list_cnt        fixed bin init (0);
 94 dcl skip_list_idx        fixed bin;
 95 dcl target_dirl          bit (1);
 96 dcl target_dp            ptr;
 97 dcl 1 temp_quota_cell    like quota_cell aligned;
 98 dcl uid                  bit (36) aligned;
 99 dcl vtocx                fixed bin;
100 
101 /* Based */
102 
103 dcl dates_set            defined attributes position (1) bit (1);
104 dcl dump_info_set        defined attributes position (3) bit (1);
105 dcl dump_switches_set    defined attributes position (2) bit (1);
106 dcl page                 (512) bit (72) aligned based;
107 dcl pc_switches_set      defined attributes position (4) bit (1);
108 dcl quota_set            defined attributes position (5) bit (1);
109 
110 /* External */
111 
112 dcl error_table_$action_not_performed ext fixed bin (35);
113 dcl error_table_$argerr  ext fixed bin (35);
114 dcl error_table_$fulldir ext fixed bin (35);
115 dcl error_table_$invalidsegno ext fixed bin (35);
116 dcl error_table_$segknown ext fixed bin (35);
117 dcl error_table_$vtoce_connection_fail ext fixed bin (35);
118 dcl sys_info$max_seg_size ext fixed bin;
119 
120 /* Entries */
121 
122 dcl create_vtoce         entry (ptr, bit (36) aligned, fixed bin, fixed bin (35));
123 dcl del_dir_tree$retv    entry (char (*), char (*), fixed bin (35));
124 dcl delentry$retv        entry (char (*), char (*), fixed bin (35));
125 dcl get_kstep            entry (fixed bin, ptr, fixed bin (35));
126 dcl get_pvtx             entry (bit (36) aligned, fixed bin (35)) returns (fixed bin);
127 dcl get_pvtx$release_pvtx entry (bit (36) aligned, fixed bin);
128 dcl grab_aste            entry (ptr, fixed bin, fixed bin (35), ptr);
129 dcl lock$dir_lock_read   entry (ptr, fixed bin (35));
130 dcl lock$dir_unlock      entry (ptr);
131 dcl makeknown_           entry (ptr, fixed bin, fixed bin, fixed bin (35));
132 dcl makeunknown_         entry (fixed bin, bit (36) aligned, bit (1) aligned, fixed bin (35));
133 dcl mountedp             entry (bit (36) aligned) returns (fixed bin (35));
134 dcl setfaults$disconnect entry (fixed bin);
135 dcl setfaults$if_active  entry (bit (36) aligned, bit (36) aligned, fixed bin, bit (1));
136 dcl sum$getbranch        entry (ptr, bit (36), ptr, fixed bin (35));
137 dcl syserr$error_code    entry options (variable);
138 dcl truncate_vtoce$hold  entry (ptr, fixed bin, fixed bin (35));
139 dcl vtoc_attributes$get_quota entry (bit (36) aligned, bit (36) aligned, fixed bin, ptr, fixed bin, fixed bin (35));
140 dcl vtoc_attributes$set_dates entry (bit (36) aligned, bit (36) aligned, fixed bin, bit (36), bit (36), fixed bin (35));
141 dcl vtoc_attributes$set_dump_info entry (bit (36) aligned, bit (36) aligned, fixed bin, bit (36), (3) bit (36),
142                          fixed bin (35));
143 dcl vtoc_attributes$set_dump_switches entry (bit (36) aligned, bit (36) aligned, fixed bin, fixed bin, fixed bin,
144                          fixed bin (35));
145 dcl vtoc_attributes$set_max_lth entry (bit (36) aligned, bit (36) aligned, fixed bin, fixed bin (9), bit (1),
146                          fixed bin (35));
147 dcl vtoc_attributes$set_pc_switches entry (bit (36) aligned, bit (36) aligned, fixed bin, bit (36), bit (36),
148                          fixed bin (35));
149 dcl vtoc_attributes$set_quota entry (bit (36) aligned, bit (36) aligned, fixed bin, ptr, fixed bin, fixed bin (35));
150 dcl vtoc_man$get_vtoce   entry (bit (36) aligned, fixed bin, fixed bin, bit (3), ptr, fixed bin (35));
151 
152 /* Misc */
153 
154 dcl bad_dir_             condition;
155 dcl cleanup              condition;
156 
157 dcl (addr, baseptr, fixed, null, ptr, rel, rtrim, substr, unspec) builtin;
158 %page;
159           audit_user_info_ptr = addr (local_audit_user_info);
160           unspec (audit_user_info) = "0"b;
161 
162 /* copy input args */
163           dirname = a_dirname;
164           ename = a_ename;
165           objectp = a_objectp;
166           audit_user_info.version = audit_user_info_version_1;
167           audit_user_info.user_id = a_userid;
168           audit_user_info.ring = a_level;
169           audit_user_info.process_id = "0"b;                /* may not be logged on */
170           audit_user_info.authorization_range(2),           /* use auth as max_auth until we can get real max_auth */
171                audit_user_info.authorization = a_auth;
172           audit_user_info.audit_flags = (36)"1"b;           /* audit anything until we can get the real audit flags */
173           input_vtoce = a_vtocep -> vtoce;
174                                                             /* initialize control variables */
175           target_dirl, dirl, pardirl, hold, new_vtoce = "0"b;
176           attributes = "0"b;
177           code = 0;
178           segno = -1;
179           astep, dp, kstep = null;
180                                                             /* be prepared for vtoce connection failures */
181           on cleanup begin;
182                     code = error_table_$action_not_performed;
183                     if kstep ^= null then call revert_kst_access;
184                     goto fin;
185                end;
186 
187 /* If the object to be copied is a directory then lock it, even though it may not exist. */
188 
189           if input_vtoce.dirsw then do;
190                     unspec (local_dir_header) = "0"b;
191                     target_dp = addr (local_dir_header);
192                     local_dir_header.uid = input_vtoce.uid;
193                     call lock$dir_lock_read (target_dp, code);
194                     if code ^= 0 then goto fin;
195                     target_dirl = "1"b;
196                end;
197 
198 /* set aste.ehs on outer ring buffer so we will not segfault while dir is locked */
199 
200           call grab_aste (objectp, sys_info$max_seg_size, code, astep);
201           if code ^= 0 then goto fin;
202                                                             /* locate entry */
203           call dc_find$obj_volume_retrieve (dirname, ename, audit_user_info_ptr, ep, code);
204           if code ^= 0 then goto fin;
205           dp = ptr (ep, 0);
206           dirl = "1"b;
207                                                             /* check if object and entry match */
208           if entry.uid ^= input_vtoce.uid then do;
209                     code = error_table_$vtoce_connection_fail;
210                     goto fin;
211                end;
212                                                             /* links don't have objects */
213           if ^entry.bs then do;
214                     code = error_table_$action_not_performed;
215                     goto fin;
216                end;
217           if ^entry.dirsw then do;                          /* ensure that the logical volume is mounted      */
218                     code = mountedp (dir.sons_lvid);        /* before we truncate the target vtoce.           */
219                     if code ^= 0 then goto fin;             /* Thank you Steve Harris                         */
220                end;
221 
222           if entry.dirsw then do;                           /* Get some quota info and save it. */
223                     call sum$getbranch (dp, "0"b, par_ep, code);
224                     if code ^= 0 then goto fin;
225                     pardirl = "1"b;
226 
227                     par_uid = par_ep -> entry.uid;
228                     par_vtocx = par_ep -> entry.vtocx;
229                     par_pvid = par_ep -> entry.pvid;
230                     qcp = addr (local_quota_cell);
231                     do quota_type = 0 to 1;
232                          call vtoc_attributes$get_quota (par_uid, par_pvid, par_vtocx, qcp, quota_type, code);
233                          if code ^= 0 then goto fin;
234                          par_received (quota_type) = quota_cell.received;
235                          par_quota (quota_type) = quota_cell.quota;
236                     end;
237                                                             /* all done with parent so unlock */
238                     call lock$dir_unlock (ptr (par_ep, 0));
239                     pardirl = "0"b;
240                end;
241 
242 /* Check to see if entry has vtoce. If not create a new one and set a flag */
243 
244           pvid = entry.pvid;
245           uid = entry.uid;
246           pvtx = get_pvtx (pvid, code);
247           if code ^= 0 then goto fin;
248           vtocx = entry.vtocx;
249           vtocep = addr (local_vtoce);
250           call vtoc_man$get_vtoce (pvid, pvtx, vtocx, "100"b, vtocep, code);
251           if code ^= 0 then goto fin;
252           if entry.uid ^= vtoce.uid then do;                /* no vtoce */
253                     call create_vtoce (ep, pvid, vtocx, code);
254                     if code ^= 0 then goto fin;
255                     entry.vtocx = vtocx;
256                     entry.pvid = pvid;
257                     pvtx = get_pvtx (pvid, code);
258                     if code ^= 0 then goto fin;
259                     new_vtoce = "1"b;
260                end;
261                                                             /* Make the entry known */
262           makeknown_infop = addr (local_makeknown_info);
263           makeknown_info.uid = uid;
264           makeknown_info.entryp = ep;
265           makeknown_info.activate, makeknown_info.dirsw = entry.dirsw;
266           makeknown_info.rsw = "0"b;
267           makeknown_info.allow_write = "1"b;
268           makeknown_info.priv_init = "1"b;
269           makeknown_info.audit = "0"b;
270           call makeknown_ (makeknown_infop, segno, (0), code);
271           if code ^= 0 then do;
272                     if code = error_table_$segknown then code = 0;
273                     else goto fin;
274                end;
275                                                             /* Fudge access in KST entry */
276           call force_kst_access;
277           if code ^= 0 then goto fin;
278           segptr = baseptr (segno);
279 
280 /* If the old object exists and it's a dir then there may entries in it that are in the newer copy.
281    If so then they should be preserved, not lost. Simiarly if the old directory has entries that the new
282    copy does not then they should be deleted.  */
283 
284           mismatch = "1"b;
285           if ^new_vtoce & entry.dirsw then
286                do while (mismatch);
287                     call reset_new_dir;
288                     if code ^= 0 then goto fin;
289                end;
290                                                             /* Truncate the object but hold the pvol its on */
291           call truncate_vtoce$hold (ep, 0, code);
292           if code ^= 0 then goto fin;
293           hold = "1"b;
294                                                             /* Set the max length prior to the copy */
295           call vtoc_attributes$set_max_lth (uid, pvid, vtocx, fixed (input_vtoce.msl, 9), "1"b, code);
296           if code ^= 0 then goto fin;
297                                                             /* Copy each non null page from the buffer */
298           do i = 0 to fixed (input_vtoce.csl, 9) - 1;
299                if substr (input_vtoce.fm (i), 1, 1) = "0"b then
300                     ptr (segptr, i * 1024) -> page = ptr (objectp, i * 1024) -> page;
301           end;
302                                                             /* Reset dir header */
303           if entry.dirsw then do;
304                     segptr -> dir.pvid = pvid;
305                     segptr -> dir.vtocx = vtocx;
306                end;
307                                                             /* cleanup */
308           call revert_kst_access;
309           call makeunknown_ (segno, "0"b, ("0"b), ignore);
310                                                             /* reset dates from input vtoce */
311           call vtoc_attributes$set_dates (uid, pvid, vtocx, input_vtoce.dtu, input_vtoce.dtm, ec);
312           dates_set = (ec ^= 0);
313                                                             /* reset dump control switches from input vtoce */
314           if input_vtoce.nid = "1"b then nid = 1; else nid = -1;
315           if input_vtoce.ncd = "1"b then ncd = 1; else ncd = -1;
316           call vtoc_attributes$set_dump_switches (uid, pvid, vtocx, nid, ncd, ec);
317           dump_switches_set = (ec ^= 0);
318                                                             /* and dump info */
319           call vtoc_attributes$set_dump_info (uid, pvid, vtocx, input_vtoce.dtd, input_vtoce.volid, ec);
320           dump_info_set = (ec ^= 0);
321                                                             /* and pc control switches */
322           call vtoc_attributes$set_pc_switches (uid, pvid, vtocx, input_vtoce.dnzp || input_vtoce.gtpd, "11"b, ec);
323           pc_switches_set = (ec ^= 0);
324 
325 /* Now we check if the directory being copied will
326    create  new quota. If its a new vtoce we first reset the quota info from the input vtoce, otherwise just take
327    the quota and recieved. Next we check to see that the total recieved at this level is less then or equal to
328    the ammount the parent ditributed. If this fails we set the quota to 1. We must set it to 1 (and
329    manufacture some quota) or delete the directory for if we set it to 0 we would destroy the quota tree.
330 */
331 
332           if entry.dirsw then do;
333                     qcp = addr (local_quota_cell);
334                     call compute_inf_received;
335                     if ec ^= 0 then goto q_done;
336                     do quota_type = 0 to 1;
337                          call vtoc_attributes$get_quota (uid, pvid, vtocx, qcp, quota_type, ec);
338                          if ec ^= 0 then goto q_done;
339                          if new_vtoce then do;
340                                    quota_cell.quota = input_vtoce.quota (quota_type);
341                                    quota_cell.used = input_vtoce.used (quota_type);
342                                    quota_cell.received = input_vtoce.received (quota_type);
343                                    quota_cell.tup = input_vtoce.trp_time (quota_type);
344                                    quota_cell.trp = input_vtoce.trp (quota_type);
345                                    quota_cell.pad = 0;
346                               end;
347                          else do;
348                                    quota_cell.quota = input_vtoce.quota (quota_type);
349                                    quota_cell.received = input_vtoce.received (quota_type);
350                               end;
351                          if inf_received (quota_type) + par_quota (quota_type) + input_vtoce.received (quota_type) <= par_received (quota_type) then
352                               call vtoc_attributes$set_quota (uid, pvid, vtocx, qcp, quota_type, ec);
353                          else do;
354                                    quota_set = "1"b;
355                                    quota_cell.quota = 1;
356                                    call vtoc_attributes$set_quota (uid, pvid, vtocx, qcp, quota_type, ec);
357                                    goto q_next;
358                               end;
359 q_done:                  quota_set = quota_set | (ec ^= 0);
360 q_next:             end;
361                end;
362 
363 fin:
364                                                             /* cleanup, unlock, deference, and return args */
365           if hold then call get_pvtx$release_pvtx (pvid, pvtx);
366           if target_dirl then call lock$dir_unlock (target_dp);
367           if dp ^= null then call dc_find$finished (dp, dirl);
368           if pardirl then call lock$dir_unlock (ptr (par_ep, 0));
369           if astep ^= null then aste.ehs = "0"b;
370           a_attributes = attributes;
371 ret:      a_code = code;
372           return;
373 %page;
374 force_kst_access: proc;
375 
376 /* This proc locates the KST entry for segno, and forces the access so we can use it. It also set faults all other users.
377    users. Since we already have the directory locked, the access can not be change nor can any
378    user recoonect to the segment */
379 
380           call get_kstep (segno, kstep, code);
381           if code ^= 0 then return;
382           kste.dtbm = entry.dtem;
383           kste.access = "101"b;
384           call setfaults$if_active (uid, pvid, vtocx, "0"b);
385           return;
386 
387      end force_kst_access;
388 
389 revert_kst_access: proc;
390 
391 /* This proc resets the KST entry and disconnects it from us */
392 
393           kste.dtbm = (36)"1"b;
394           call setfaults$disconnect (segno);
395           return;
396 
397      end revert_kst_access;
398 
399 compute_inf_received: proc;
400 
401 /* This proc sums the recieved quota for all directory entries inferior to some directory */
402 
403 dcl nentries             fixed bin;
404 dcl ok                   fixed bin (35);
405 dcl seen                 fixed bin;
406 
407           inf_received (*) = 0;
408           nentries = dir.lcount + dir.seg_count + dir.dir_count;
409           seen = 0;
410           do ep = ptr (dp, dir.entryfrp) repeat (ptr (dp, entry.efrp)) while (rel (ep) ^= "0"b);
411                seen = seen + 1;
412                if seen > nentries then signal bad_dir_;
413                if entry.bs then
414                     if entry.owner ^= dir.uid then signal bad_dir_;
415                     else ;
416                else if link.owner ^= dir.uid
417                          | link.type ^= LINK_TYPE then signal bad_dir_;
418                if entry.dirsw then do;
419                          if entry.type ^= DIR_TYPE then signal bad_dir_;
420                          dir_vtocx = entry.vtocx;
421                          dir_pvid = entry.pvid;
422                          dir_uid = entry.uid;
423                          qcp = addr (temp_quota_cell);
424                          do quota_type = 0 to 1;
425                               call vtoc_attributes$get_quota (dir_uid, dir_pvid, dir_vtocx, qcp, quota_type, ok);
426                               if ok = 0 then inf_received (quota_type) = inf_received (quota_type) + quota_cell.received;
427                          end;
428                     end;
429           end;
430           return;
431 
432      end compute_inf_received;
433 
434 reset_new_dir: proc;
435 
436 /* This proc compares the old and new copies of a directory. For each uid match  it resets
437    the vtoce pointer. For each entry in the old not in the new it deletes it. This deletion operation is made without
438    access control checks. If deletion won't work the fact is logged with the reason. Of course when the copy
439    is made the subtrees will be automaticaly deleted, in the sense that they won't be found */
440 
441 dcl nentries1            fixed bin;
442 dcl nentries2            fixed bin;
443 dcl seen1                fixed bin;
444 dcl seen2                fixed bin;
445 
446           mismatch = "0"b;
447 reset_loop: seen2 = 0;
448           nentries2 = segptr -> dir.lcount + segptr -> dir.dir_count + segptr -> dir.seg_count;
449           do old_ep = ptr (segptr, segptr -> dir.entryfrp) repeat (ptr (segptr, old_ep -> entry.efrp))
450                while (rel (old_ep) ^= "0"b);
451                seen2 = seen2 + 1;
452                if seen2 > nentries2 then signal bad_dir_;
453                seen1 = 0;
454                nentries1 = objectp -> dir.lcount + objectp -> dir.dir_count + objectp -> dir.seg_count;
455                do new_ep = ptr (objectp, objectp -> dir.entryfrp) repeat (ptr (objectp, new_ep -> entry.efrp))
456                     while (rel (new_ep) ^= "0"b & new_ep -> entry.uid ^= old_ep -> entry.uid);
457                     seen1 = seen1 + 1;
458                     if seen1 > nentries1 then do;
459                               code = error_table_$argerr;
460                               return;
461                          end;
462                end;
463                if rel (new_ep) ^= "0"b then do;             /* entry in old and in new */
464                          new_ep -> entry.pvid = old_ep -> entry.pvid;
465                          new_ep -> entry.vtocx = old_ep -> entry.vtocx;
466                     end;
467                else if ^on_skip_list () then do;            /* entry in old but not in new - delete it */
468                          mismatch = "1"b;
469                          del_ename = ptr (old_ep, old_ep -> entry.name_frp) -> names.name;
470                          if dirname = ">" then del_pname = ">" || ename;
471                          else del_pname = rtrim (dirname) || ">" || ename;
472                          old_uid = old_ep -> entry.uid;
473                          dirsw = old_ep -> entry.dirsw;
474                          call lock$dir_unlock (segptr);     /* for delentry/del_dir_tree to work */
475                          target_dirl = "0"b;
476                          call dc_find$finished (dp, "1"b);
477                          dp = null;
478                          dirl = "0"b;
479                          if dirsw then do;
480 subtree:                           call del_dir_tree$retv (del_pname, del_ename, del_code);
481                                    if del_code ^= 0 then goto delerr;
482                               end;
483                          call delentry$retv (del_pname, del_ename, del_code);
484                          if del_code = error_table_$fulldir then goto subtree;
485                          if del_code ^= 0 then do;
486 delerr:                            call syserr$error_code (4, del_code, "retv_copy: deleting ^a>^a without recovering resources",
487                                         del_pname, del_ename);
488                                    call add_to_skip_list;
489                               end;
490                          call lock$dir_lock_read (segptr, code);
491                          if code ^= 0 then return;
492                          target_dirl = "1"b;
493                          call dc_find$obj_volume_retrieve (dirname, ename, audit_user_info_ptr, ep, code);
494                          if code ^= 0 then return;
495                          dirl = "1"b;
496                          if ep -> entry.uid ^= uid then do; /* where did our dir go? */
497                               code = error_table_$invalidsegno;
498                               return;
499                          end;
500                          dp = ptr (ep, 0);
501                          goto reset_loop;
502                     end;
503           end;
504           return;
505 
506      end reset_new_dir;
507 
508 on_skip_list: proc returns (bit (1));
509           found = "0"b;
510           do skip_list_idx = 1 to skip_list_cnt while (skip_list (skip_list_idx) ^= old_uid);
511           end;
512           if skip_list_idx <= skip_list_cnt then found = "1"b;
513           return (found);
514 
515      end on_skip_list;
516 
517 add_to_skip_list: proc;
518           skip_list_cnt = skip_list_cnt + 1;
519           skip_list (skip_list_cnt) = old_uid;
520           return;
521 
522      end add_to_skip_list;
523 %page; %include access_audit_user_info;
524 %page; %include aste;
525 %page; %include dc_find_dcls;
526 %page; %include dir_entry;
527 %page; %include dir_header;
528 %page; %include dir_link;
529 %page; %include dir_name;
530 %page; %include fs_types;
531 %page; %include kst;
532 %page; %include makeknown_info;
533 %page; %include quota_cell;
534 %page; %include sdw;
535 %page; %include vtoce;
536 %page;
537 
538 /* BEGIN MESSAGE DOCUMENTATION
539 
540    Message:
541    retv_copy: deleting PATH without recovering resources ERROR_MESSAGE
542 
543    S: $log
544 
545    T: Volume retrieval
546 
547    M: While retrieving a segment,
548    the retriever attempted to delete an old copy
549    of a segment before using a newer one.
550    The deletion attempt failed.
551    Space may be wasted on the volume
552    until a sweep_pv -gc is done.
553 
554    A: Note for volume administrator.
555 
556    END MESSAGE DOCUMENTATION */
557 
558      end retv_copy;