1
2
3
4
5
6
7
8
9
10
11
12
13
14 retv_util:
15 proc;
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 dcl a_access_name char (*);
39 dcl a_aclc fixed bin;
40 dcl a_aclp ptr;
41 dcl a_areap ptr;
42 dcl a_auth bit (72) aligned;
43 dcl a_code fixed bin (35);
44 dcl a_dirname char (*);
45 dcl a_dp ptr;
46 dcl a_dtd bit (36) aligned;
47 dcl a_dtm bit (36);
48 dcl a_ename char (*);
49 dcl a_ep ptr;
50 dcl a_level fixed bin;
51 dcl a_mode bit (36) aligned;
52 dcl a_new_bc fixed bin (24);
53 dcl a_newname char (*);
54 dcl a_nlc fixed bin;
55 dcl a_nlp ptr;
56 dcl a_np ptr;
57 dcl a_old_bc fixed bin (24);
58 dcl a_pmode bit (36) aligned;
59 dcl a_pvid bit (36) aligned;
60 dcl a_type fixed bin;
61 dcl a_uid bit (36) aligned;
62 dcl a_volid (3) bit (36) aligned;
63
64
65
66 dcl DIRECTORY fixed bin int static init (2) options (constant);
67 dcl LINK fixed bin int static init (3) options (constant);
68 dcl SEGMENT fixed bin int static init (1) options (constant);
69 dcl check_entry fixed bin static init (1) options (constant);
70 dcl delete_entry fixed bin static init (5) options (constant);
71 dcl get_entry fixed bin static init (3) options (constant);
72 dcl set_bc_entry fixed bin static init (4) options (constant);
73 dcl status_entry fixed bin static init (2) options (constant);
74
75 dcl access_name char (32);
76 dcl acl_start_ptr ptr;
77 dcl aclc fixed bin;
78 dcl aclp ptr;
79 dcl add_sw bit (1);
80 dcl auth bit (72);
81 dcl bmode bit (36) aligned;
82 dcl code fixed bin (35);
83 dcl dirl bit (1) aligned;
84 dcl dirname char (168);
85 dcl dtd bit (36) aligned;
86 dcl dtm bit (36);
87 dcl ename char (32);
88 dcl entry_sw fixed bin;
89 dcl exmode bit (36) aligned;
90 dcl i fixed bin;
91 dcl idx fixed bin;
92 dcl ignore fixed bin (35);
93 dcl level fixed bin;
94 dcl 1 local_entry like entry;
95 dcl 1 local_vtoce like vtoce aligned;
96 dcl mode bit (36) aligned;
97 dcl new_bc fixed bin (24);
98 dcl newname char (32);
99 dcl nlc fixed bin;
100 dcl nlp ptr;
101 dcl old_bc fixed bin (24);
102 dcl par_dirl bit (1) aligned;
103 dcl par_ep ptr;
104 dcl pmode bit (36) aligned;
105 dcl prior_dir_acl_count fixed bin;
106 dcl pvid bit (36) aligned;
107 dcl pvtx fixed bin;
108 dcl rp bit (18) aligned;
109 dcl saved_change_pclock fixed bin (35);
110 dcl type fixed bin;
111 dcl uid bit (36) aligned;
112 dcl volid (3) bit (36) aligned;
113
114
115
116 dcl 1 acl_list (aclc) aligned like input_acl based;
117 dcl 1 based_entry like entry based (a_ep);
118 dcl 1 input_acl based aligned,
119 2 person char (32),
120 2 project char (32),
121 2 tag char (1),
122 2 mode bit (36),
123 2 exmode bit (36);
124 dcl name_list (nlc) char (32) based aligned;
125 dcl user_area area based (a_areap);
126
127
128
129 dcl error_table_$vtoce_connection_fail
130 ext fixed bin (35);
131
132
133
134 dcl access_mode$user_effmode
135 entry (ptr, char (32), bit (72), fixed bin, bit (36) aligned, bit (36) aligned,
136 fixed bin (35));
137 dcl acl_$add_entry entry (fixed bin, bit (36) aligned, ptr, ptr, bit (1), fixed bin (35));
138 dcl acl_$del_acl entry (ptr, fixed bin (35));
139 dcl chname$retv entry (ptr, char (*), char (*), fixed bin (35));
140 dcl delentry$salv_delete_branch
141 entry (ptr, fixed bin (35));
142 dcl get_pvtx entry (bit (36), fixed bin (35)) returns (fixed bin);
143 dcl getuid entry returns (bit (36));
144 dcl hash$search entry (ptr, ptr, ptr, fixed bin (35));
145 dcl lock$dir_lock_read entry (ptr, fixed bin (35));
146 dcl lock$dir_unlock entry (ptr);
147 dcl sum$dirmod entry (pointer);
148 dcl sum$getbranch entry (ptr, fixed bin, ptr, fixed bin (35));
149 dcl vtoc_man$get_vtoce entry (bit (36), fixed bin, fixed bin, bit (3), ptr, fixed bin (35));
150
151
152
153 dcl bad_dir_ condition;
154 dcl seg_fault_error condition;
155
156 dcl addr builtin;
157 dcl fixed builtin;
158 dcl null builtin;
159 dcl ptr builtin;
160 dcl unspec builtin;
161 %page;
162 delete:
163 entry (a_dirname, a_ename, a_code);
164 entry_sw = delete_entry;
165 goto common;
166
167 set_bc:
168 entry (a_dirname, a_ename, a_new_bc, a_old_bc, a_code);
169 entry_sw = set_bc_entry;
170 new_bc = a_new_bc;
171 goto common;
172
173 get:
174 entry (a_dirname, a_ename, a_ep, a_code);
175 entry_sw = get_entry;
176 goto common;
177
178 check:
179 entry (a_dirname, a_ename, a_type, a_dtm, a_code);
180
181
182
183 entry_sw = check_entry;
184 dtm = "0"b;
185 goto common;
186
187 status:
188 entry (a_dirname, a_ename, a_auth, a_access_name, a_level, a_type, a_mode, a_pmode, a_uid, a_pvid, a_volid, a_dtd,
189 a_code);
190
191
192
193 entry_sw = status_entry;
194 access_name = a_access_name;
195 level = a_level;
196 auth = a_auth;
197
198
199 uid = "0"b;
200 pvid = "0"b;
201 volid (*) = "0"b;
202 dtd = "0"b;
203 bmode = "0"b;
204 pmode = "0"b;
205
206 common:
207 dirname = a_dirname;
208 ename = a_ename;
209
210
211 code = 0;
212 type = 0;
213 dp = null;
214 dirl = "0"b;
215 par_dirl = "0"b;
216
217
218
219 on seg_fault_error
220 begin;
221 code = error_table_$vtoce_connection_fail;
222 goto status_ret;
223 end;
224
225
226
227
228 if entry_sw = delete_entry
229 then call dc_find$obj_delete_priv (dirname, ename, DC_FIND_NO_CHASE, ep, code);
230 else if entry_sw = set_bc_entry
231 then call dc_find$obj_status_write_priv (dirname, ename, DC_FIND_NO_CHASE, FS_OBJ_BC_MOD, ep, code);
232 else call dc_find$obj_status_read_priv (dirname, ename, DC_FIND_NO_CHASE, ep, code);
233 if code ^= 0
234 then goto status_ret;
235 dp = ptr (ep, 0);
236 dirl = "1"b;
237 if entry_sw = delete_entry
238 then do;
239 call delentry$salv_delete_branch (ep, code);
240 goto status_ret;
241 end;
242 if entry_sw = get_entry
243 then do;
244 unspec (local_entry) = unspec (entry);
245 goto status_ret;
246 end;
247 if entry_sw = set_bc_entry
248 then do;
249 old_bc = entry.bc;
250 entry.bc = new_bc;
251 goto status_ret;
252 end;
253
254
255 if ^entry.bs
256 then type = LINK;
257 else if entry.dirsw
258 then type = DIRECTORY;
259 else type = SEGMENT;
260 if entry_sw = status_entry
261 then do;
262 uid = entry.uid;
263 if type ^= LINK
264 then do;
265 pvid = entry.pvid;
266 call access_mode$user_effmode (ep, access_name, auth, level, mode, exmode, code);
267 if code ^= 0
268 then goto status_ret;
269 if entry.dirsw
270 then bmode = exmode;
271 else bmode = mode;
272 end;
273 call sum$getbranch (dp, 0, par_ep, code);
274 if code ^= 0
275 then goto status_ret;
276 par_dirl = "1"b;
277
278 call access_mode$user_effmode (par_ep, access_name, auth, level, mode, exmode, code);
279 if code ^= 0
280 then goto status_ret;
281 pmode = exmode;
282 end;
283
284 if entry.bs
285 then do;
286 unspec (local_vtoce) = "0"b;
287 vtocep = addr (local_vtoce);
288 pvtx = get_pvtx (entry.pvid, code);
289 if code ^= 0
290 then goto status_ret;
291 call vtoc_man$get_vtoce (entry.pvid, pvtx, fixed (entry.vtocx, 17), "101"b, vtocep, code);
292 if code ^= 0
293 then goto status_ret;
294 if vtoce.uid ^= entry.uid | vtoce.damaged
295 then do;
296 code = error_table_$vtoce_connection_fail;
297 goto status_ret;
298 end;
299 if entry_sw = status_entry
300 then do;
301 volid (*) = vtoce.volid (*);
302 dtd = vtoce.dtd;
303 end;
304 else dtm = vtoce.dtm;
305 end;
306
307
308 status_ret:
309 if dp ^= null
310 then call dc_find$finished (dp, dirl);
311 if par_dirl
312 then call lock$dir_unlock (ptr (par_ep, 0));
313 if entry_sw = status_entry
314 then do;
315 a_mode = bmode;
316 a_pmode = pmode;
317 a_uid = uid;
318 a_pvid = pvid;
319 a_volid (*) = volid (*);
320 a_dtd = dtd;
321 a_type = type;
322 end;
323 else if entry_sw = set_bc_entry
324 then do;
325 a_old_bc = old_bc;
326 end;
327 else if entry_sw = check_entry
328 then do;
329 a_dtm = dtm;
330 a_type = type;
331 end;
332 else if entry_sw = get_entry
333 then do;
334 local_entry.uid = getuid ();
335 unspec (based_entry) = unspec (local_entry);
336 end;
337 a_code = code;
338 return;
339 %page;
340 name_list:
341 entry (a_dirname, a_areap, a_nlp, a_nlc, a_code);
342
343
344 dirname = a_dirname;
345 code = 0;
346 dirl = "0"b;
347 idx = 0;
348 dp = null;
349
350
351
352 RETRY: call dc_find$dir_read_priv (dirname, dp, code);
353 if code ^= 0
354 then goto name_list_ret;
355 dirl = "1"b;
356
357 nlc = dir.seg_count + dir.dir_count + dir.lcount;
358 saved_change_pclock = dir.change_pclock;
359
360 call lock$dir_unlock (dp);
361 dirl = "0"b;
362
363
364
365 allocate name_list in (user_area) set (nlp);
366
367
368
369 call lock$dir_lock_read (dp, code);
370 if code ^= 0
371 then goto name_list_ret;
372 dirl = "1"b;
373
374 if dir.change_pclock ^= saved_change_pclock
375 then do;
376 call lock$dir_unlock (dp);
377 dirl = "0"b;
378 free nlp -> name_list;
379 go to RETRY;
380 end;
381
382
383
384
385
386 i = 0;
387 do rp = dir.entryfrp repeat (entry.efrp) while (rp ^= "0"b);
388 i = i + 1;
389 if i > nlc
390 then signal bad_dir_;
391 ep = ptr (dp, rp);
392 if entry.bs
393 then if entry.owner ^= dir.uid | entry.type ^= SEG_TYPE & entry.type ^= DIR_TYPE
394 then signal bad_dir_;
395 else ;
396 else if link.owner ^= dir.uid | link.type ^= LINK_TYPE
397 then signal bad_dir_;
398 idx = idx + 1;
399 nlp -> name_list (idx) = ptr (ep, entry.name_frp) -> names.name;
400 end;
401 call lock$dir_unlock (dp);
402 dirl = "0"b;
403
404
405
406 a_nlc = nlc;
407 a_nlp = nlp;
408
409 name_list_ret:
410 if dp ^= null
411 then call dc_find$finished (dp, dirl);
412 a_code = code;
413 return;
414
415
416
417
418 hash_search:
419 entry (a_dp, a_np, a_ep, a_code);
420
421 call hash$search (a_dp, a_np, a_ep, a_code);
422 return;
423
424 addname:
425 entry (a_dirname, a_ename, a_newname, a_code);
426
427
428 dirl = "0"b;
429 dirname = a_dirname;
430 ename = a_ename;
431 newname = a_newname;
432 dp = null;
433
434
435
436 call dc_find$obj_status_write_priv (dirname, ename, DC_FIND_NO_CHASE, FS_OBJ_RENAME, ep, code);
437 if code ^= 0
438 then goto addname_ret;
439 dirl = "1"b;
440 dp = ptr (ep, 0);
441 call chname$retv (ep, "", newname, code);
442
443 addname_ret:
444 if dp ^= null
445 then call dc_find$finished (dp, dirl);
446 a_code = code;
447 return;
448
449
450
451
452 add_acl:
453 entry (a_dirname, a_ename, a_aclp, a_aclc, a_code);
454 dirname = a_dirname;
455 ename = a_ename;
456 aclc = a_aclc;
457 aclp = a_aclp;
458 dirl = "0"b;
459 dp = null;
460
461
462
463
464
465
466
467 call dc_find$obj_access_write_priv (dirname, ename, DC_FIND_NO_CHASE, FS_OBJ_ACL_MOD, ep, code);
468 if code ^= 0
469 then goto add_acl_ret;
470 dirl = "1"b;
471 dp = ptr (ep, 0);
472
473
474
475
476 prior_dir_acl_count = dir.acle_total;
477 acl_start_ptr = addr (entry.acl_frp);
478 do i = 1 to aclc while (code = 0);
479 call acl_$add_entry (fixed (entry.acle_count), entry.uid, acl_start_ptr, addr (aclp -> acl_list (i)),
480 add_sw, code);
481 if code ^= 0
482 then do;
483 call acl_$del_acl (acl_start_ptr, ignore);
484 dir.acle_total = prior_dir_acl_count;
485 end;
486 else if add_sw
487 then do;
488 dir.acle_total = dir.acle_total + 1;
489 entry.acle_count = entry.acle_count + 1;
490 end;
491 end;
492 call sum$dirmod (dp);
493 add_acl_ret:
494 if dp ^= null
495 then call dc_find$finished (dp, dirl);
496 a_code = code;
497 return;
498 %page;
499 %include dc_find_dcls;
500 %page;
501 %include dir_entry;
502 %page;
503 %include dir_header;
504 %page;
505 %include dir_name;
506 %page;
507 %include dir_link;
508 %page;
509 %include fs_obj_access_codes;
510 %page;
511 %include fs_types;
512 %page;
513 %include vtoce;
514 end retv_util;