1 /* my.c:
2 *
3 ****************************************************************
4 * Copyright (C) 2003 Tom Lord
5 *
6 * See the file "COPYING" for further information about
7 * the copyright and warranty status of this work.
8 */
9
10
11 #include "hackerlab/os/stdlib.h"
12 #include "hackerlab/os/errno.h"
13 #include "hackerlab/os/errno-to-string.h"
14 #include "hackerlab/bugs/panic.h"
15 #include "hackerlab/char/str.h"
16 #include "hackerlab/fs/file-names.h"
17 #include "hackerlab/fs/cwd.h"
18 #include "hackerlab/vu/safe.h"
19 #include "tla/libfsutils/ensure-dir.h"
20 #include "tla/libfsutils/read-line.h"
21 #include "tla/libfsutils/file-contents.h"
22 #include "tla/libarch/namespace.h"
23 #include "tla/libarch/my.h"
24
25
26
27 t_uchar *
arch_my_arch_params(void)28 arch_my_arch_params (void)
29 {
30 t_uchar * home;
31 t_uchar * answer;
32
33 home = getenv ("HOME");
34
35 invariant (!!home);
36 answer = file_name_in_vicinity (0, home, ".arch-params");
37
38 return answer;
39 }
40
41
42 void
arch_ensure_my_arch_params(void)43 arch_ensure_my_arch_params (void)
44 {
45 int errn;
46 t_uchar * dir = 0;
47
48 dir = arch_my_arch_params ();
49
50 if (vu_mkdir (&errn, dir, 0700) && errn != EEXIST)
51 {
52 safe_printfmt (2, "arch: unable to create directory %s\n", dir);
53 exit (2);
54 }
55
56 lim_free (0, dir);
57 }
58
59
60
61 t_uchar *
arch_my_hook_script(void)62 arch_my_hook_script (void)
63 {
64 t_uchar * params_dir;
65 t_uchar * hook_script;
66
67 params_dir = arch_my_arch_params ();
68 hook_script = file_name_in_vicinity (0, params_dir, "hook");
69
70 {
71 int euid;
72 int egid;
73 struct stat stat;
74 int stat_ok;
75 int errn;
76
77 euid = geteuid ();
78 egid = getegid ();
79
80 stat_ok = vu_stat (&errn, hook_script, &stat);
81 if (stat_ok
82 || !(((euid == stat.st_uid) && (stat.st_mode & S_IXUSR))
83 || ((egid == stat.st_gid) && (stat.st_mode & S_IXGRP))
84 || (stat.st_mode & S_IXOTH)))
85 {
86 lim_free (0, hook_script);
87 hook_script = 0;
88 }
89 }
90
91 lim_free (0, params_dir);
92 return hook_script;
93 }
94
95
96
97 static t_uchar * my_id = 0;
98
99 t_uchar *
arch_my_id_file(void)100 arch_my_id_file (void)
101 {
102 t_uchar * params_dir;
103 t_uchar * id_file;
104
105 params_dir = arch_my_arch_params ();
106 id_file = file_name_in_vicinity (0, params_dir, "=id");
107 lim_free (0, params_dir);
108
109 return id_file;
110 }
111
112
113 void
arch_set_my_id(const t_uchar * id)114 arch_set_my_id (const t_uchar * id)
115 {
116 t_uchar * id_file;
117 int out_fd;
118
119 if (my_id)
120 lim_free (0, my_id);
121
122 invariant (arch_valid_id (id));
123
124 id_file = arch_my_id_file ();
125
126 arch_ensure_my_arch_params ();
127
128 out_fd = safe_open (id_file, O_WRONLY | O_CREAT, 0666);
129 safe_ftruncate (out_fd, 0L);
130 safe_printfmt (out_fd, "%s\n", id);
131 safe_close (out_fd);
132 lim_free (0, id_file);
133
134 my_id = str_save (0, id);
135 }
136
137
138 t_uchar *
arch_my_id(void)139 arch_my_id (void)
140 {
141 int errn;
142 t_uchar * id_file;
143 int in_fd;
144 t_uchar * id_contents;
145 size_t len;
146 t_uchar * eoid;
147
148 if (my_id)
149 return str_save (0, my_id);
150
151 id_file = arch_my_id_file ();
152 in_fd = vu_open (&errn, id_file, O_RDONLY, 0);
153 if (in_fd < 0)
154 {
155 if (errn == ENOENT)
156 safe_printfmt (2, "arch: no arch user id set\n");
157 else
158 safe_printfmt (2, "arch: i/o error for file %s (%s)\n", id_file, errno_to_string (errn));
159 exit (2);
160 }
161 lim_free (0, id_file);
162
163 id_contents = 0;
164 len = 0;
165 safe_file_to_string (&id_contents, &len, in_fd);
166 safe_close (in_fd);
167
168 eoid = str_chr_index_n (id_contents, len, '\n');
169 if (!eoid)
170 eoid = id_contents + len;
171
172 my_id = str_save_n (0, id_contents, eoid - id_contents);
173
174 lim_free (0, id_contents);
175
176 return str_save (0, my_id);
177 }
178
179
180 t_uchar *
arch_my_id_uid(void)181 arch_my_id_uid (void)
182 {
183 t_uchar * id = 0;
184 t_uchar * lb;
185 t_uchar * rb;
186 t_uchar * answer = 0;
187
188 id = arch_my_id ();
189 if (!id)
190 return 0;
191
192 lb = str_chr_rindex (id, '<');
193 rb = str_chr_rindex (id, '>');
194
195 invariant (lb && rb && ((lb + 1) < rb));
196
197 answer = str_save_n (0, (lb + 1), rb - (lb + 1));
198
199 lim_free (0, id);
200
201 return answer;
202 }
203
204
205
206
207 static t_uchar * my_home_archive = 0;
208
209 t_uchar *
arch_my_default_archive(const t_uchar * default_archive)210 arch_my_default_archive (const t_uchar * default_archive)
211 {
212 t_uchar * params_dir = 0;
213 t_uchar * default_archive_file = 0;
214 int in_fd;
215 t_uchar * default_archive_file_contents = 0;
216 size_t archive_contents_len;
217 t_uchar * nl_pos;
218 t_uchar * answer = 0;
219 int errn;
220
221 /* This does away with the arch conventions of using $ARCHIVE
222 * and has no support for -R
223 */
224
225 if (default_archive)
226 {
227 if (!arch_valid_archive_name (default_archive))
228 {
229 safe_printfmt (2, "invalid archive name %s\n", default_archive);
230 exit (2);
231 }
232 return str_save (0, default_archive);
233 }
234
235 if (my_home_archive)
236 return str_save (0, my_home_archive);
237
238
239 params_dir = arch_my_arch_params ();
240 default_archive_file = file_name_in_vicinity (0, params_dir, "=default-archive");
241
242 in_fd = vu_open (&errn, default_archive_file, O_RDONLY, 0);
243
244 if (in_fd < 0)
245 {
246 if (errn != ENOENT)
247 {
248 safe_printfmt (2, "arch: error opening %s\n", default_archive_file);
249 exit (2);
250 }
251 answer = 0;
252 }
253 else
254 {
255 safe_file_to_string (&default_archive_file_contents, &archive_contents_len, in_fd);
256
257 safe_close (in_fd);
258
259 nl_pos = str_chr_index_n (default_archive_file_contents, archive_contents_len, '\n');
260 if (!nl_pos)
261 nl_pos = default_archive_file_contents + archive_contents_len;
262
263 answer = str_save_n (0, default_archive_file_contents, nl_pos - default_archive_file_contents);
264 }
265
266 lim_free (0, default_archive_file_contents);
267 lim_free (0, default_archive_file);
268 lim_free (0, params_dir);
269
270 if (answer)
271 {
272 lim_free (0, my_home_archive);
273 my_home_archive = str_save (0, answer);
274 }
275
276 return answer;
277 }
278
279
280 void
arch_set_my_default_archive(const t_uchar * archive)281 arch_set_my_default_archive (const t_uchar * archive)
282 {
283 t_uchar * arch_params_dir;
284 t_uchar * default_archive_file;
285 int out_fd;
286
287 invariant (arch_valid_archive_name (archive));
288
289 if (my_home_archive)
290 {
291 lim_free (0, my_home_archive);
292 my_home_archive = 0;
293 }
294
295 arch_ensure_my_arch_params ();
296 arch_params_dir = arch_my_arch_params ();
297 default_archive_file = file_name_in_vicinity (0, arch_params_dir, "=default-archive");
298
299 out_fd = safe_open (default_archive_file, O_WRONLY | O_CREAT, 0666);
300
301 safe_ftruncate (out_fd, (long)0);
302 safe_write_retry (out_fd, archive, str_length (archive));
303 safe_close (out_fd);
304
305 lim_free (0, arch_params_dir);
306 lim_free (0, default_archive_file);
307
308 my_home_archive = str_save (0, archive);
309 }
310
311
312 void
arch_delete_my_default_archive(void)313 arch_delete_my_default_archive (void)
314 {
315 t_uchar * params_dir;
316 t_uchar * default_archive_file;
317 int errn;
318
319 if (my_home_archive)
320 {
321 lim_free (0, my_home_archive);
322 my_home_archive = 0;
323 }
324
325 params_dir = arch_my_arch_params ();
326 default_archive_file = file_name_in_vicinity (0, params_dir, "=default-archive");
327
328 if (vu_unlink (&errn, default_archive_file) && (errn != ENOENT))
329 {
330 panic ("unable to delete ~/.arch-params/=default-archive");
331 }
332
333 lim_free (0, params_dir);
334 lim_free (0, default_archive_file);
335 }
336
337
338
339 t_uchar *
arch_my_archive_locations_dir(void)340 arch_my_archive_locations_dir (void)
341 {
342 t_uchar * arch_params_path = 0;
343 t_uchar * answer = 0;
344
345 arch_params_path = arch_my_arch_params ();
346 answer = file_name_in_vicinity (0, arch_params_path, "=locations");
347
348 lim_free (0, arch_params_path);
349 return answer;
350 }
351
352
353
354
355 static t_uchar *
arch_my_default_library_file(void)356 arch_my_default_library_file (void)
357 {
358 t_uchar * params_dir;
359 t_uchar * lib_file;
360
361 params_dir = arch_my_arch_params ();
362 lib_file = file_name_in_vicinity (0, params_dir, "=revision-library");
363
364 lim_free (0, params_dir);
365
366 return lib_file;
367 }
368
369 static t_uchar *
arch_my_default_library_add_file(void)370 arch_my_default_library_add_file (void)
371 {
372 t_uchar * params_dir;
373 t_uchar * lib_file;
374
375 params_dir = arch_my_arch_params ();
376 lib_file = file_name_in_vicinity (0, params_dir, "=revision-library-adds");
377
378 lim_free (0, params_dir);
379
380 return lib_file;
381 }
382
383
384 rel_table
arch_my_library_path(enum arch_library_path_type path_type)385 arch_my_library_path (enum arch_library_path_type path_type)
386 {
387 t_uchar * first_file = 0;
388 t_uchar * second_file = 0;
389 rel_table answer = rel_table_nil;
390
391 switch (path_type)
392 {
393 case arch_library_path_search_only:
394 {
395 first_file = arch_my_default_library_file ();
396 break;
397 }
398 case arch_library_path_add_only:
399 {
400 first_file = arch_my_default_library_add_file ();
401 break;
402 }
403 case arch_library_path_search_order:
404 {
405 first_file = arch_my_default_library_file ();
406 second_file = arch_my_default_library_add_file ();
407 break;
408 }
409 case arch_library_path_add_order:
410 {
411 second_file = arch_my_default_library_file ();
412 first_file = arch_my_default_library_add_file ();
413 break;
414 }
415 }
416
417 if (first_file && !safe_access (first_file, F_OK))
418 {
419 int fd;
420
421 fd = safe_open (first_file, O_RDONLY, 0);
422 answer = rel_read_table (fd, 1, "tla", first_file);
423 safe_close (fd);
424 }
425
426 if (second_file && !safe_access (second_file, F_OK))
427 {
428 int fd;
429 rel_table answer2 = rel_table_nil;
430
431 fd = safe_open (second_file, O_RDONLY, 0);
432 answer2 = rel_read_table (fd, 1, "tla", second_file);
433 safe_close (fd);
434 rel_append_x (&answer, answer2);
435 rel_free_table (answer2);
436 }
437
438 lim_free (0, first_file);
439 lim_free (0, second_file);
440
441 return answer;
442 }
443
444
445 void
arch_set_my_library_path(enum arch_library_path_type path_type,enum arch_library_edit_op op,const t_uchar * dir_spec)446 arch_set_my_library_path (enum arch_library_path_type path_type,
447 enum arch_library_edit_op op,
448 const t_uchar * dir_spec)
449 {
450 t_uchar * dir = 0;
451 t_uchar * lib_file = 0;
452 rel_table old_path = rel_table_nil;
453 rel_table new_path = rel_table_nil;
454 int out_fd;
455
456 if (file_name_is_absolute (dir_spec))
457 {
458 dir = str_save (0, dir_spec);
459 }
460 else if (dir_spec)
461 {
462 t_uchar * here = 0;
463 here = safe_current_working_directory ();
464 dir = file_name_in_vicinity (0, here, dir_spec);
465 lim_free (0, here);
466 }
467
468 switch (path_type)
469 {
470 case arch_library_path_search_order:
471 case arch_library_path_search_only:
472 {
473 lib_file = arch_my_default_library_file ();
474 old_path = arch_my_library_path (arch_library_path_search_only);
475 break;
476 }
477 case arch_library_path_add_order:
478 case arch_library_path_add_only:
479 {
480 lib_file = arch_my_default_library_add_file ();
481 old_path = arch_my_library_path (arch_library_path_add_only);
482 break;
483 }
484 }
485
486
487 /* install first if appropriate
488 */
489 if (dir_spec && (op == arch_library_first))
490 {
491 rel_add_records (&new_path, rel_singleton_record_taking (rel_make_field_str (dir)), rel_record_null);
492 }
493
494 /* copy the old path, removing dir_spec (if any)
495 */
496 if (dir_spec)
497 {
498 int x;
499
500 for (x = 0; x < rel_n_records (old_path); ++x)
501 {
502 if (str_cmp (rel_peek_str (old_path, x, 0), dir))
503 {
504 rel_add_records (&new_path, rel_singleton_record_taking (rel_get_field (old_path, x, 0)), rel_record_null);
505 }
506 }
507 }
508
509 /* install last if appropriate
510 */
511 if (dir_spec && (op == arch_library_last))
512 {
513 rel_add_records (&new_path, rel_singleton_record_taking (rel_make_field_str (dir)), rel_record_null);
514 }
515
516
517 /* install the new path
518 */
519 arch_ensure_my_arch_params ();
520
521 out_fd = safe_open (lib_file, O_WRONLY | O_CREAT, 0666);
522 safe_ftruncate (out_fd, 0L);
523 rel_print_table (out_fd, new_path);
524 safe_close (out_fd);
525
526
527 lim_free (0, dir);
528 lim_free (0, lib_file);
529 rel_free_table (old_path);
530 rel_free_table (new_path);
531 }
532
533
534
535
536 t_uchar *
arch_my_util_path_file(void)537 arch_my_util_path_file (void)
538 {
539 t_uchar * params_dir;
540 t_uchar * path_file;
541
542 params_dir = arch_my_arch_params ();
543 path_file = file_name_in_vicinity (0, params_dir, "path");
544 lim_free (0, params_dir);
545
546 return path_file;
547 }
548
549
550 t_uchar **
arch_my_util_path(void)551 arch_my_util_path (void)
552 {
553 t_uchar * path_file = 0;
554 t_uchar ** answer = 0;
555
556 path_file = arch_my_util_path_file ();
557 if (!safe_access (path_file, F_OK))
558 {
559 t_uchar * contents = 0;
560
561 contents = file_contents_trimming (path_file);
562 answer = path_parse (0, contents);
563
564 lim_free (0, contents);
565 }
566
567 lim_free (0, path_file);
568 return answer;
569 }
570
571
572
573
574 t_uchar *
arch_my_metadata_rules_file(void)575 arch_my_metadata_rules_file (void)
576 {
577 t_uchar * params_dir;
578 t_uchar * path_file;
579
580 params_dir = arch_my_arch_params ();
581 path_file = file_name_in_vicinity (0, params_dir, "metadata-rules");
582 lim_free (0, params_dir);
583
584 return path_file;
585 }
586
587
588 int
arch_my_allow_full_meta(void)589 arch_my_allow_full_meta (void)
590 {
591 t_uchar * rules_file = 0;
592 struct stat statb;
593 int errn = 0;
594 int answer;
595
596 rules_file = arch_my_metadata_rules_file ();
597
598 if (0 == vu_stat (&errn, rules_file, &statb))
599 {
600 if (statb.st_size != 0)
601 {
602 safe_printfmt (2, "illegal ~/.arch-params/metadata-rules file (non-empty)\n file: %s\n", rules_file);
603 panic ("abort");
604 }
605
606 answer = 1;
607 }
608 else
609 {
610 if (errn == ENOENT)
611 answer = 0;
612 else
613 panic ("strange i/o error");
614 }
615
616 lim_free (0, rules_file);
617 return answer;
618 }
619
620
621
622
623 /* tag: Tom Lord Mon May 12 15:01:17 2003 (my.c)
624 */
625