25
26 /*
27 * files.c
28 *
29 * Various file related routines:
30 * Figure out if file exists
31 * Wildcard resolution for directory reader
32 * Directory reader
33 */
34
35
36 /*
37 * Included files
38 */
39 #include <dirent.h> /* opendir() */
40 #include <errno.h> /* errno */
41 #include <mk/defs.h>
42 #include <mksh/macro.h> /* getvar() */
43 #include <mksh/misc.h> /* get_prop(), append_prop() */
44 #include <sys/stat.h> /* lstat() */
45
46 /*
47 * Defined macros
48 */
49
50 /*
51 * typedefs & structs
52 */
53
54 /*
55 * Static variables
56 */
57
58 /*
59 * File table of contents
60 */
61 extern timestruc_t& exists(register Name target);
62 extern void set_target_stat(register Name target, struct stat buf);
63 static timestruc_t& vpath_exists(register Name target);
64 static Name enter_file_name(wchar_t *name_string, wchar_t *library);
85 exists(register Name target)
86 {
87 struct stat buf;
88 register int result;
89
90 /* We cache stat information. */
91 if (target->stat.time != file_no_time) {
92 return target->stat.time;
93 }
94
95 /*
96 * If the target is a member, we have to extract the time
97 * from the archive.
98 */
99 if (target->is_member &&
100 (get_prop(target->prop, member_prop) != NULL)) {
101 return read_archive(target);
102 }
103
104 if (debug_level > 1) {
105 (void) printf(NOCATGETS("%*sstat(%s)\n"),
106 recursion_level,
107 "",
108 target->string_mb);
109 }
110
111 result = lstat_vroot(target->string_mb, &buf, NULL, VROOT_DEFAULT);
112 if ((result != -1) && ((buf.st_mode & S_IFMT) == S_IFLNK)) {
113 /*
114 * If the file is a symbolic link, we remember that
115 * and then we get the status for the refd file.
116 */
117 target->stat.is_sym_link = true;
118 result = stat_vroot(target->string_mb, &buf, NULL, VROOT_DEFAULT);
119 } else {
120 target->stat.is_sym_link = false;
121 }
122
123 if (result < 0) {
124 target->stat.time = file_doesnt_exist;
125 target->stat.stat_errno = errno;
343 ((dp->d_name[0] == (int) period_char) &&
344 ((dp->d_name[1] == 0) ||
345 ((dp->d_name[1] == (int) period_char) &&
346 (dp->d_name[2] == 0))))) {
347 continue;
348 }
349 /*
350 * Build the full name of the file using whatever
351 * path supplied to the function.
352 */
353 MBSTOWCS(tmp_wcs_buffer, dp->d_name);
354 (void) wscpy(file_name_p, tmp_wcs_buffer);
355 file = enter_file_name(file_name, library);
356 if ((pattern != NULL) && amatch(tmp_wcs_buffer, pattern)) {
357 /*
358 * If we are expanding a wildcard pattern, we
359 * enter the file as a dependency for the target.
360 */
361 if (debug_level > 0){
362 WCSTOMBS(mbs_buffer, pattern);
363 (void) printf(catgets(catd, 1, 231, "'%s: %s' due to %s expansion\n"),
364 line->body.line.target->string_mb,
365 file->string_mb,
366 mbs_buffer);
367 }
368 enter_dependency(line, file, false);
369 result++;
370 } else {
371 /*
372 * If the file has an SCCS/s. file,
373 * we will detect that later on.
374 */
375 file->stat.has_sccs = NO_SCCS;
376 /*
377 * If this is an s. file, we also enter it as if it
378 * existed in the plain directory.
379 */
380 if ((dp->d_name[0] == 's') &&
381 (dp->d_name[1] == (int) period_char)) {
382
383 MBSTOWCS(tmp_wcs_buffer, dp->d_name + 2);
384 plain_file_name_p = plain_file_name;
385 (void) wscpy(plain_file_name_p, tmp_wcs_buffer);
386 plain_file = GETNAME(plain_file_name, FIND_LENGTH);
387 plain_file->stat.is_file = true;
388 plain_file->stat.has_sccs = HAS_SCCS;
389 /*
390 * Enter the s. file as a dependency for the
391 * plain file.
392 */
393 maybe_append_prop(plain_file, sccs_prop)->
394 body.sccs.file = file;
395 MBSTOWCS(tmp_wcs_buffer, dp->d_name + 2);
396 if ((pattern != NULL) &&
397 amatch(tmp_wcs_buffer, pattern)) {
398 if (debug_level > 0) {
399 WCSTOMBS(mbs_buffer, pattern);
400 (void) printf(catgets(catd, 1, 232, "'%s: %s' due to %s expansion\n"),
401 line->body.line.target->
402 string_mb,
403 plain_file->string_mb,
404 mbs_buffer);
405 }
406 enter_dependency(line, plain_file, false);
407 result++;
408 }
409 }
410 }
411 }
412 (void) closedir(dir_fd);
413 if ((vpath != NULL) && (*vpath != (int) nul_char)) {
414 while ((*vpath != (int) nul_char) &&
415 (iswspace(*vpath) || (*vpath == (int) colon_char))) {
416 vpath++;
417 }
418 p = vpath;
419 while ((*vpath != (int) colon_char) &&
420 (*vpath != (int) nul_char)) {
435 * files in the plain directory. They are also entered in their own right.
436 * Prepare the string where we build the true name of the SCCS files.
437 */
438 (void) wsncpy(plain_file_name,
439 file_name,
440 file_name_p - file_name);
441 plain_file_name[file_name_p - file_name] = 0;
442 plain_file_name_p = plain_file_name + wslen(plain_file_name);
443
444 if(!svr4) {
445
446 if (sccs_dir_path != NULL) {
447 wchar_t tmp_wchar;
448 wchar_t path[MAXPATHLEN];
449 char mb_path[MAXPATHLEN];
450
451 if (file_name_p - file_name > 0) {
452 tmp_wchar = *file_name_p;
453 *file_name_p = 0;
454 WCSTOMBS(mbs_buffer, file_name);
455 (void) sprintf(mb_path, NOCATGETS("%s/%s/SCCS"),
456 sccs_dir_path,
457 mbs_buffer);
458 *file_name_p = tmp_wchar;
459 } else {
460 (void) sprintf(mb_path, NOCATGETS("%s/SCCS"), sccs_dir_path);
461 }
462 MBSTOWCS(path, mb_path);
463 (void) wscpy(file_name, path);
464 } else {
465 MBSTOWCS(wcs_buffer, NOCATGETS("SCCS"));
466 (void) wscpy(file_name_p, wcs_buffer);
467 }
468 } else {
469 MBSTOWCS(wcs_buffer, NOCATGETS("."));
470 (void) wscpy(file_name_p, wcs_buffer);
471 }
472 /* Internalize the constructed SCCS dir name. */
473 (void) exists(dir = GETNAME(file_name, FIND_LENGTH));
474 /* Just give up if the directory file doesnt exist. */
475 if (!dir->stat.is_file) {
476 return result;
477 }
478 /* Open the directory. */
479 dir_fd = opendir(dir->string_mb);
480 if (dir_fd == NULL) {
481 return result;
482 }
483 MBSTOWCS(wcs_buffer, "/");
484 (void) wscat(file_name, wcs_buffer);
485 file_name_p = file_name + wslen(file_name);
486
487 while ((dp = readdir(dir_fd)) != NULL) {
488 if ((dp->d_fileno == 0) ||
489 ((dp->d_name[0] == (int) period_char) &&
515 Property sprop = get_prop(plain_file->prop,sccs_prop);
516 if(sprop != NULL) {
517 if (sprop->body.sccs.file) {
518 goto try_pattern;
519 }
520 }
521 }
522
523 /*
524 * Enter the s. file as a dependency for the
525 * plain file.
526 */
527 maybe_append_prop(plain_file, sccs_prop)->
528 body.sccs.file = file;
529 try_pattern:
530 MBSTOWCS(tmp_wcs_buffer, dp->d_name + 2);
531 if ((pattern != NULL) &&
532 amatch(tmp_wcs_buffer, pattern)) {
533 if (debug_level > 0) {
534 WCSTOMBS(mbs_buffer, pattern);
535 (void) printf(catgets(catd, 1, 233, "'%s: %s' due to %s expansion\n"),
536 line->body.line.target->
537 string_mb,
538 plain_file->string_mb,
539 mbs_buffer);
540 }
541 enter_dependency(line, plain_file, false);
542 result++;
543 }
544 }
545 }
546 (void) closedir(dir_fd);
547
548 return result;
549 }
550
551 /*
552 * enter_file_name(name_string, library)
553 *
554 * Helper function for read_dir().
555 *
|
25
26 /*
27 * files.c
28 *
29 * Various file related routines:
30 * Figure out if file exists
31 * Wildcard resolution for directory reader
32 * Directory reader
33 */
34
35
36 /*
37 * Included files
38 */
39 #include <dirent.h> /* opendir() */
40 #include <errno.h> /* errno */
41 #include <mk/defs.h>
42 #include <mksh/macro.h> /* getvar() */
43 #include <mksh/misc.h> /* get_prop(), append_prop() */
44 #include <sys/stat.h> /* lstat() */
45 #include <libintl.h>
46
47 /*
48 * Defined macros
49 */
50
51 /*
52 * typedefs & structs
53 */
54
55 /*
56 * Static variables
57 */
58
59 /*
60 * File table of contents
61 */
62 extern timestruc_t& exists(register Name target);
63 extern void set_target_stat(register Name target, struct stat buf);
64 static timestruc_t& vpath_exists(register Name target);
65 static Name enter_file_name(wchar_t *name_string, wchar_t *library);
86 exists(register Name target)
87 {
88 struct stat buf;
89 register int result;
90
91 /* We cache stat information. */
92 if (target->stat.time != file_no_time) {
93 return target->stat.time;
94 }
95
96 /*
97 * If the target is a member, we have to extract the time
98 * from the archive.
99 */
100 if (target->is_member &&
101 (get_prop(target->prop, member_prop) != NULL)) {
102 return read_archive(target);
103 }
104
105 if (debug_level > 1) {
106 (void) printf("%*sstat(%s)\n",
107 recursion_level,
108 "",
109 target->string_mb);
110 }
111
112 result = lstat_vroot(target->string_mb, &buf, NULL, VROOT_DEFAULT);
113 if ((result != -1) && ((buf.st_mode & S_IFMT) == S_IFLNK)) {
114 /*
115 * If the file is a symbolic link, we remember that
116 * and then we get the status for the refd file.
117 */
118 target->stat.is_sym_link = true;
119 result = stat_vroot(target->string_mb, &buf, NULL, VROOT_DEFAULT);
120 } else {
121 target->stat.is_sym_link = false;
122 }
123
124 if (result < 0) {
125 target->stat.time = file_doesnt_exist;
126 target->stat.stat_errno = errno;
344 ((dp->d_name[0] == (int) period_char) &&
345 ((dp->d_name[1] == 0) ||
346 ((dp->d_name[1] == (int) period_char) &&
347 (dp->d_name[2] == 0))))) {
348 continue;
349 }
350 /*
351 * Build the full name of the file using whatever
352 * path supplied to the function.
353 */
354 MBSTOWCS(tmp_wcs_buffer, dp->d_name);
355 (void) wscpy(file_name_p, tmp_wcs_buffer);
356 file = enter_file_name(file_name, library);
357 if ((pattern != NULL) && amatch(tmp_wcs_buffer, pattern)) {
358 /*
359 * If we are expanding a wildcard pattern, we
360 * enter the file as a dependency for the target.
361 */
362 if (debug_level > 0){
363 WCSTOMBS(mbs_buffer, pattern);
364 (void) printf(gettext("'%s: %s' due to %s expansion\n"),
365 line->body.line.target->string_mb,
366 file->string_mb,
367 mbs_buffer);
368 }
369 enter_dependency(line, file, false);
370 result++;
371 } else {
372 /*
373 * If the file has an SCCS/s. file,
374 * we will detect that later on.
375 */
376 file->stat.has_sccs = NO_SCCS;
377 /*
378 * If this is an s. file, we also enter it as if it
379 * existed in the plain directory.
380 */
381 if ((dp->d_name[0] == 's') &&
382 (dp->d_name[1] == (int) period_char)) {
383
384 MBSTOWCS(tmp_wcs_buffer, dp->d_name + 2);
385 plain_file_name_p = plain_file_name;
386 (void) wscpy(plain_file_name_p, tmp_wcs_buffer);
387 plain_file = GETNAME(plain_file_name, FIND_LENGTH);
388 plain_file->stat.is_file = true;
389 plain_file->stat.has_sccs = HAS_SCCS;
390 /*
391 * Enter the s. file as a dependency for the
392 * plain file.
393 */
394 maybe_append_prop(plain_file, sccs_prop)->
395 body.sccs.file = file;
396 MBSTOWCS(tmp_wcs_buffer, dp->d_name + 2);
397 if ((pattern != NULL) &&
398 amatch(tmp_wcs_buffer, pattern)) {
399 if (debug_level > 0) {
400 WCSTOMBS(mbs_buffer, pattern);
401 (void) printf(gettext("'%s: %s' due to %s expansion\n"),
402 line->body.line.target->
403 string_mb,
404 plain_file->string_mb,
405 mbs_buffer);
406 }
407 enter_dependency(line, plain_file, false);
408 result++;
409 }
410 }
411 }
412 }
413 (void) closedir(dir_fd);
414 if ((vpath != NULL) && (*vpath != (int) nul_char)) {
415 while ((*vpath != (int) nul_char) &&
416 (iswspace(*vpath) || (*vpath == (int) colon_char))) {
417 vpath++;
418 }
419 p = vpath;
420 while ((*vpath != (int) colon_char) &&
421 (*vpath != (int) nul_char)) {
436 * files in the plain directory. They are also entered in their own right.
437 * Prepare the string where we build the true name of the SCCS files.
438 */
439 (void) wsncpy(plain_file_name,
440 file_name,
441 file_name_p - file_name);
442 plain_file_name[file_name_p - file_name] = 0;
443 plain_file_name_p = plain_file_name + wslen(plain_file_name);
444
445 if(!svr4) {
446
447 if (sccs_dir_path != NULL) {
448 wchar_t tmp_wchar;
449 wchar_t path[MAXPATHLEN];
450 char mb_path[MAXPATHLEN];
451
452 if (file_name_p - file_name > 0) {
453 tmp_wchar = *file_name_p;
454 *file_name_p = 0;
455 WCSTOMBS(mbs_buffer, file_name);
456 (void) sprintf(mb_path, "%s/%s/SCCS",
457 sccs_dir_path,
458 mbs_buffer);
459 *file_name_p = tmp_wchar;
460 } else {
461 (void) sprintf(mb_path, "%s/SCCS", sccs_dir_path);
462 }
463 MBSTOWCS(path, mb_path);
464 (void) wscpy(file_name, path);
465 } else {
466 MBSTOWCS(wcs_buffer, "SCCS");
467 (void) wscpy(file_name_p, wcs_buffer);
468 }
469 } else {
470 MBSTOWCS(wcs_buffer, ".");
471 (void) wscpy(file_name_p, wcs_buffer);
472 }
473 /* Internalize the constructed SCCS dir name. */
474 (void) exists(dir = GETNAME(file_name, FIND_LENGTH));
475 /* Just give up if the directory file doesnt exist. */
476 if (!dir->stat.is_file) {
477 return result;
478 }
479 /* Open the directory. */
480 dir_fd = opendir(dir->string_mb);
481 if (dir_fd == NULL) {
482 return result;
483 }
484 MBSTOWCS(wcs_buffer, "/");
485 (void) wscat(file_name, wcs_buffer);
486 file_name_p = file_name + wslen(file_name);
487
488 while ((dp = readdir(dir_fd)) != NULL) {
489 if ((dp->d_fileno == 0) ||
490 ((dp->d_name[0] == (int) period_char) &&
516 Property sprop = get_prop(plain_file->prop,sccs_prop);
517 if(sprop != NULL) {
518 if (sprop->body.sccs.file) {
519 goto try_pattern;
520 }
521 }
522 }
523
524 /*
525 * Enter the s. file as a dependency for the
526 * plain file.
527 */
528 maybe_append_prop(plain_file, sccs_prop)->
529 body.sccs.file = file;
530 try_pattern:
531 MBSTOWCS(tmp_wcs_buffer, dp->d_name + 2);
532 if ((pattern != NULL) &&
533 amatch(tmp_wcs_buffer, pattern)) {
534 if (debug_level > 0) {
535 WCSTOMBS(mbs_buffer, pattern);
536 (void) printf(gettext("'%s: %s' due to %s expansion\n"),
537 line->body.line.target->
538 string_mb,
539 plain_file->string_mb,
540 mbs_buffer);
541 }
542 enter_dependency(line, plain_file, false);
543 result++;
544 }
545 }
546 }
547 (void) closedir(dir_fd);
548
549 return result;
550 }
551
552 /*
553 * enter_file_name(name_string, library)
554 *
555 * Helper function for read_dir().
556 *
|