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 /* Utility procedure for backup reloader. */
 14 backup_util: proc (dname, ename);
 15 
 16 /* Created by R H Campbell. */
 17 /* Modified 2 April 1970, R H Campbell. */
 18 /* Modified 21 October 1970, R. J. Feiertag to scrunch ring brackets. */
 19 /* modified on 12.11.72 by A. Downing to increase the size of (name_area) */
 20 /* modified by Kobziar on 11-20-73 to not print err for obsolete CACLs */
 21 /* last modified by Kobziar 10-21-74 to add access_mode arg to $build_tree call */
 22 /* last modified by R. Bratt 7-18-75 to remove pre 18-0 dinosaurs */
 23 /* MCR 4310 add missing options to map 01/28/80 S. Herbst */
 24 /* Modified: 17 November 1980 by G. Palter to allow backup_util$add_names to be called with other than the primary name */
 25 /* obsolete and useless $replace_acl entry removed 5/3/82 BIM */
 26 
 27 dcl (dname character (168),                                 /* directory path name */
 28      ename character (32)) aligned;                         /* entry name */
 29 
 30 
 31 dcl (i, j, k, l) fixed bin,                                 /* Temporary storage. */
 32      a_code fixed bin,                                      /* return status code */
 33      code fixed bin,                                        /* file system error code */
 34      access_class bit (72) aligned,                         /* access_class of path */
 35      esw fixed bin,                                         /* Entry switch */
 36      area_ptr ptr,                                          /* ptr to system_free_area */
 37      ix pointer;                                            /* Pointer to array element. */
 38 
 39 dcl (error_table_$moderr, error_table_$user_not_found, error_table_$nonamerr,
 40      error_table_$logical_volume_not_connected, error_table_$vtoce_connection_fail,
 41      error_table_$logical_volume_not_defined,
 42      error_table_$noentry, error_table_$bad_ring_brackets, error_table_$incorrect_access, error_table_$no_info,
 43      error_table_$fulldir, error_table_$segnamedup, error_table_$namedup, error_table_$safety_sw_on,
 44      error_table_$copy_sw_on) fixed bin ext;
 45 
 46 dcl  init static bit (1) initial ("1"b),                    /* Flag to cause static initialization. */
 47      group_id static character (32) aligned;                /* Our name.project.tag. */
 48 
 49 dcl 1 name (1) based (np) aligned,
 50     2 size bit (17),
 51     2 string character (32);
 52 
 53 dcl 1 stat_area,                                            /* structure returned by status_ for get_real_name */
 54     2 (pad1 bit (18),
 55      nrp bit (18),
 56      pad2 bit (108)) unaligned;
 57 
 58 dcl  names (1) char (32) based;                             /* primary entry name */
 59 
 60 dcl (oldp, newp) ptr,                                       /* pathnames for get_primary name */
 61     (oldn based (oldp), newn based (newp)) char (168),
 62      newl fixed bin;                                        /* length of revised pathname */
 63 
 64 dcl (dir, work) char (168), ent char (32);                  /* workspace */
 65 
 66 dcl  backup_map_$fs_error_line entry (fixed bin, char (*) aligned, char (168) aligned, char (32) aligned),
 67      backup_map_$name_line entry (pointer, fixed binary),
 68      backup_load_dir_list$build_tree entry (char (*) aligned, char (*) aligned, fixed bin,
 69      fixed bin (24), fixed bin (2), char (*) aligned, bit (72) aligned, fixed bin),
 70     (backup_util$delete_name, backup_util$give_access) entry (char (168) aligned, char (32) aligned, fixed bin);
 71 
 72 dcl  get_group_id_ entry returns (character (32)),
 73      get_system_free_area_ entry returns (ptr),
 74      hcs_$add_acl_entries entry (char (*) aligned, char (*) aligned, ptr, fixed bin, fixed bin),
 75      hcs_$add_dir_acl_entries entry (char (*) aligned, char (*) aligned, ptr, fixed bin, fixed bin),
 76      hcs_$status_minf entry (char (*) aligned, char (*) aligned, fixed bin (1), fixed bin (2), fixed bin (24), fixed bin),
 77      hcs_$chname_file entry (char (*) aligned, char (*) aligned, char (*) aligned, char (*) aligned, fixed binary),
 78     (hcs_$del_dir_tree, hcs_$delentry_file) entry (char (*) aligned, char (*) aligned, fixed binary),
 79      hcs_$status_ entry (char (*), char (*), fixed bin (1), ptr, ptr, fixed bin),
 80      hcs_$get_access_class entry (char (*) aligned, char (*) aligned, bit (72) aligned, fixed bin),
 81      hcs_$set_copysw entry (char (*) aligned, char (*) aligned, bit (1), fixed bin),
 82      hcs_$set_safety_sw entry (char (*) aligned, char (*) aligned, bit (1), fixed bin);
 83 
 84 
 85 dcl (addr, empty, fixed, index, length, min, pointer, substr, rtrim) builtin;
 86 
 87 %include bk_ss_;
 88 %include acl_structures;
 89  ^L
 90 add_names: entry (dname, ename, np, nnames, list_names);    /* Entry to add all names to entry. */
 91 
 92 dcl  np ptr,                                                /* Pointer to names. */
 93      nnames fixed bin,                                      /* Number of names. */
 94      list_names bit (1);                                    /* Flag to enable writing of names. */
 95           do i = 1 to nnames;
 96                ix = addr (np -> name (i));                  /* Get pointer to this array element. */
 97                if (ename ^= ix -> name(1).string) then do;  /* not added yet */
 98                     if bk_ss_$no_reload then go to print_name;   /* Not reloading so print the name only */
 99 add:                call hcs_$chname_file (dname, ename, "", ix -> name (1).string, code); /* Try to add the name. */
100                     if code = error_table_$namedup then do; /* Was name already in directory? */
101                          call backup_util$delete_name (dname, ix -> name (1).string, code);    /* Try to remove the name. */
102                          if code = 0 then go to add;        /* Removal successful? */
103                     end;                                    /* Any errors here will be reported by delete_name. */
104                     else if code = error_table_$segnamedup then; /* Leave name already on branch */
105                     else if code ^= 0 then                  /* If unsuccessful, don't write name line. */
106                          call backup_map_$fs_error_line (code, "chname_file in add_names", dname, ix -> name (1).string);
107                     else if bk_ss_$mapsw & list_names then  /* Write the name if map desired. */
108 print_name:              call backup_map_$name_line (addr (ix -> name (1).string), fixed (ix -> name (1).size, 17));
109                end;
110           end;
111           return;                                           /* Return to caller. */
112 
113 
114 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
115 delete_name: entry (dname, ename, a_code);                  /* Entry to remove offending name from directory. */
116           call hcs_$chname_file (dname, ename, ename, "", code); /* Try to remove the name from its entry. */
117           if code = error_table_$nonamerr then do;          /* Is it the last name on its entry? */
118 delete:        call hcs_$delentry_file (dname, ename, code); /* try simple delete first */
119                if code = error_table_$moderr | code = error_table_$incorrect_access then do; /* Do we have right access? */
120 get_access:         call backup_util$give_access (dname, ename, code); /* Try to change it. */
121                     if code = 0 then go to delete;          /* try again if changed successfully */
122                end;
123                else if code = error_table_$safety_sw_on then do; /* Turn off the safety switch, else if necessary. */
124                     call hcs_$set_safety_sw (dname, ename, "0"b, code);
125                     if code = 0 then go to delete;          /* Try again if successful. */
126                     call backup_map_$fs_error_line (code, "backup_util$delete_name", dname, ename);
127                end;
128                else if code = error_table_$copy_sw_on then do; /* Turn off copy switch */
129                     call hcs_$set_copysw (dname, ename, "0"b, code);
130                     if code = 0 then go to delete;
131                     call backup_map_$fs_error_line (code, "backup_util$delete_name", dname, ename);
132                end;
133                else if code = error_table_$user_not_found then go to get_access; /* Were we on the ACL at all? */
134                else if code = error_table_$fulldir then do; /* was it a non-empty directory? */
135                     call hcs_$del_dir_tree (dname, ename, code); /* yes, delete inferior entries */
136                     if code = 0 then go to delete;
137                     call backup_map_$fs_error_line (code, "backup_util$delete_name", dname, ename);
138                end;
139                else if code ^= 0 then                       /* If unsuccessful, give error comment. */
140                     call backup_map_$fs_error_line (code, "backup_util$delete_name", dname, ename);
141           end;
142           else if code ^= 0 then                            /* If unexpected error, give error comment. */
143                call backup_map_$fs_error_line (code, "backup_util$delete_name", dname, ename);
144           a_code = code;                                    /* return status */
145           return;                                           /* Return to caller. */
146 
147 
148 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
149 
150 
151 give_access: entry (dname, ename, a_code);                  /* Entry to give ourselves access to entry. */
152 
153 dcl  seg_aclp ptr int static,
154      dir_aclp ptr int static;
155 
156 dcl 1 seg_acl (1) aligned like segment_acl_entry int static;
157 dcl 1 dir_acl (1) aligned like directory_acl_entry int static;
158 
159 dcl  type fixed bin (2),
160      bitcnt fixed bin (24);
161 
162           if init then do;                                  /* Must we initialize? */
163                group_id = get_group_id_ ();                 /* Get our ID code. */
164                seg_acl.access_name (1),
165                     dir_acl.access_name (1) = group_id;
166                seg_acl.mode = "111"b;
167                seg_acl.extended_mode = ""b;
168                dir_acl.mode = "111"b;
169                seg_aclp = addr (seg_acl);
170                dir_aclp = addr (dir_acl);
171                init = ""b;                                  /* Clear flag. */
172           end;
173           call hcs_$status_minf (dname, ename, 1, type, bitcnt, code);
174           if code ^= 0 then
175                if code = error_table_$logical_volume_not_defined then code = 0;
176                else if code = error_table_$logical_volume_not_connected then code = 0;
177                else if code = error_table_$vtoce_connection_fail then code = 0;
178                else go to ret;
179           if type = 0 then go to ret;
180           if type = 1 then call hcs_$add_acl_entries (dname, ename, seg_aclp, 1, code); /* put us on ACL */
181           else call hcs_$add_dir_acl_entries (dname, ename, dir_aclp, 1, code);
182 
183           if code = error_table_$no_info | code = error_table_$incorrect_access then do;
184                call hcs_$get_access_class (dname, "", access_class, code);
185                if code ^= 0 then access_class = "0"b;       /* try with this value */
186                call backup_load_dir_list$build_tree (dname, "", 3, 0, 0, "", access_class, code);
187           end;                                              /* If we cannot get access, then recurse. */
188 ret:      a_code = code;                                    /* Return status */
189           return;                                           /* Return to caller. */
190 
191 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
192 
193 
194 
195 
196 get_real_name: entry (oldp, newp, newl, a_code);            /* entry to get a "more proper" version of a pathname */
197           l = 0;                                            /* l is current length of output pathname */
198           work = "";                                        /* new pathname built here, level by level */
199           i = index (oldn, " ");                            /* determine length of old pathname */
200           if i = 0 then i = 169;                            /* it may be the full 168 */
201           j = 1;                                            /* current position on input pathname */
202           do while (j < i - 1);                             /* scan entire input name */
203                k = index (substr (oldn, j), ">");           /* find next directory level */
204                if k = 0 then go to done;                    /* if there isn't one, scan is finished */
205                dir = substr (oldn, 1, j + k - 2);           /* save directories so far seen */
206                j = j + k;                                   /* move along input */
207                if j = 2 then dir = ">";                     /* status wants a trailing ">" only for the root */
208                k = index (substr (oldn, j), ">");           /* next level is entry name for this level */
209                if k = 0 then ent = substr (oldn, j, i - j); /* if there isn't another level, use remainder of input */
210                else ent = substr (oldn, j, k - 1);          /* otherwise characters up to next ">" */
211                area_ptr = get_system_free_area_ ();
212                call hcs_$status_ (dir, ent, 1, addr (stat_area), area_ptr, code); /* get the names of this entity */
213                if code ^= 0 then
214                     if code = error_table_$logical_volume_not_connected then code = 0;
215                     else if code = error_table_$logical_volume_not_defined then code = 0;
216                     else if code = error_table_$vtoce_connection_fail then code = 0;
217                     else do;                                /* if something was wrong */
218                          if code ^= error_table_$noentry then go to grn_ret; /* it had better be entry not found */
219                          work = substr (work, 1, l) || ">" || substr (oldn, j, i - j); /* it was, tack on unfound part of input */
220                          l = l + i - j + 1;                 /* compute total length of result */
221                          go to done;                        /* job is done */
222                     end;
223                work = substr (work, 1, l) || ">" || pointer (area_ptr, stat_area.nrp) -> names (1);
224                l = index (work, " ") - 1;                   /* new length with new primary name appended */
225           end;
226 done:     code = 0;                                         /* return zero if nothing was done */
227           newl = l;                                         /* set the length argument */
228           if oldn = work then go to grn_ret;                /* see if anything useful was accomplished */
229           if l = 0 then go to grn_ret;                      /* pathname didn't have any ">"s */
230           newn = work;                                      /* hand over the new pathname */
231           code = 1;                                         /* and say we did so */
232 grn_ret:  a_code = code;                                    /* Return status code */
233           return;
234 
235 
236 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
237 
238 
239 idline:   entry (rfile, rdate, linep, n);                   /* entry to format retriever's signature line */
240 
241 dcl (rfile, rdate) char (*),                                /* retrieval control file, retriever version */
242      linep ptr,
243      line char (300) based (linep),                         /* output line */
244      n fixed bin;                                           /* its length */
245           call append (rtrim (bk_ss_$myname));              /* insert our name in id line */
246           call append ((rdate));                            /* add version of loader */
247           if rfile ^= "" then call append (rtrim (rfile));  /* control file to be used */
248           call append ("map");                              /* Report map option setting */
249           if bk_ss_$quotasw then call append ("quota");     /* Report setting of quota restoration switch. */
250           else call append ("noquota");
251           if bk_ss_$onlysw then call append ("first");      /* Report satisfaction criterion */
252           else call append ("last");
253           if bk_ss_$trimsw then call append ("trim");       /* Report pruning option setting. */
254           else call append ("notrim");
255           if bk_ss_$debugsw then call append ("debug");     /* Report debug mode setting. */
256           if bk_ss_$dir_trim then call append ("dir_trim"); /* for reload system release */
257           if bk_ss_$err_onlinesw then call append ("error_on");
258           if bk_ss_$ignore_dates then call append ("ignore_dates");  /* for reload system release */
259           if bk_ss_$no_primary then call append ("noprimary");  /* do not use primary pathnames */
260           if bk_ss_$no_reload then call append ("noreload");  /* testing reloader */
261           if bk_ss_$no_setlvid then call append ("nosetlvid");  /* don't set logical voilume id */
262           if bk_ss_$qchecksw then call append ("qcheck");   /* check quotas */
263           else call append ("noqcheck");                    /* default */
264           return;
265 
266 
267 append:   procedure (string);                               /* Append string to identification line */
268 
269 dcl  string character (*) aligned;                          /* What to append. */
270                if n < length (line) then do;                /* Is there room in buffer? */
271                     n = n + 1;                              /* Count it. */
272                     substr (line, n, 1) = " ";              /* Prepend a blank. */
273                     i = min (length (line) - n, length (string)); /* Don't overflow. */
274                     substr (line, n + 1, i) = string;       /* Append this string. */
275                     n = n + i;                              /* Count length. */
276                end;
277           end append;
278 
279      end backup_util;