]> Dogcows Code - chaz/tar/blob - src/names.c
(uid_to_uname, gid_to_gname): Don't used cached name for nameless
[chaz/tar] / src / names.c
1 /* Various processing of names.
2 Copyright (C) 1988, 92, 94, 96, 97, 1998 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify it
5 under the terms of the GNU General Public License as published by the
6 Free Software Foundation; either version 2, or (at your option) any later
7 version.
8
9 This program is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
12 Public License for more details.
13
14 You should have received a copy of the GNU General Public License along
15 with this program; if not, write to the Free Software Foundation, Inc.,
16 59 Place - Suite 330, Boston, MA 02111-1307, USA. */
17
18 #include "system.h"
19
20 #include <pwd.h>
21 #include <grp.h>
22
23 #ifndef FNM_LEADING_DIR
24 # include <fnmatch.h>
25 #endif
26
27 #include "common.h"
28 \f
29 /* User and group names. */
30
31 extern struct group *getgrnam ();
32 extern struct passwd *getpwnam ();
33 #if !HAVE_GETPWUID
34 extern struct passwd *getpwuid ();
35 #endif
36 #if !HAVE_GETGRGID
37 extern struct group *getgrgid ();
38 #endif
39
40 /* Make sure you link with the proper libraries if you are running the
41 Yellow Peril (thanks for the good laugh, Ian J.!), or, euh... NIS.
42 This code should also be modified for non-UNIX systems to do something
43 reasonable. */
44
45 static char cached_uname[UNAME_FIELD_SIZE] = "";
46 static char cached_gname[GNAME_FIELD_SIZE] = "";
47
48 static uid_t cached_uid; /* valid only if cached_uname is not empty */
49 static gid_t cached_gid; /* valid only if cached_gname is not empty */
50
51 /*------------------------------------------.
52 | Given UID, find the corresponding UNAME. |
53 `------------------------------------------*/
54
55 void
56 uid_to_uname (uid_t uid, char uname[UNAME_FIELD_SIZE])
57 {
58 struct passwd *passwd;
59
60 if (!cached_uname[0] || uid != cached_uid)
61 {
62 passwd = getpwuid (uid);
63 if (passwd)
64 {
65 cached_uid = uid;
66 strncpy (cached_uname, passwd->pw_name, UNAME_FIELD_SIZE);
67 }
68 else
69 {
70 *uname = '\0';
71 return;
72 }
73 }
74 strncpy (uname, cached_uname, UNAME_FIELD_SIZE);
75 }
76
77 /*------------------------------------------.
78 | Given GID, find the corresponding GNAME. |
79 `------------------------------------------*/
80
81 void
82 gid_to_gname (gid_t gid, char gname[GNAME_FIELD_SIZE])
83 {
84 struct group *group;
85
86 if (!cached_gname[0] || gid != cached_gid)
87 {
88 setgrent (); /* FIXME: why?! */
89 group = getgrgid (gid);
90 if (group)
91 {
92 cached_gid = gid;
93 strncpy (cached_gname, group->gr_name, GNAME_FIELD_SIZE);
94 }
95 else
96 {
97 *gname = '\0';
98 return;
99 }
100 }
101 strncpy (gname, cached_gname, GNAME_FIELD_SIZE);
102 }
103
104 /*-------------------------------------------------------------------------.
105 | Given UNAME, set the corresponding UID and return 1, or else, return 0. |
106 `-------------------------------------------------------------------------*/
107
108 int
109 uname_to_uid (char uname[UNAME_FIELD_SIZE], uid_t *uidp)
110 {
111 struct passwd *passwd;
112
113 if (!cached_uname[0]
114 || uname[0] != cached_uname[0]
115 || strncmp (uname, cached_uname, UNAME_FIELD_SIZE) != 0)
116 {
117 passwd = getpwnam (uname);
118 if (passwd)
119 {
120 cached_uid = passwd->pw_uid;
121 strncpy (cached_uname, uname, UNAME_FIELD_SIZE);
122 }
123 else
124 return 0;
125 }
126 *uidp = cached_uid;
127 return 1;
128 }
129
130 /*-------------------------------------------------------------------------.
131 | Given GNAME, set the corresponding GID and return 1, or else, return 0. |
132 `-------------------------------------------------------------------------*/
133
134 int
135 gname_to_gid (char gname[GNAME_FIELD_SIZE], gid_t *gidp)
136 {
137 struct group *group;
138
139 if (!cached_gname[0]
140 || gname[0] != cached_gname[0]
141 || strncmp (gname, cached_gname, GNAME_FIELD_SIZE) != 0)
142 {
143 group = getgrnam (gname);
144 if (group)
145 {
146 cached_gid = group->gr_gid;
147 strncpy (cached_gname, gname, GNAME_FIELD_SIZE);
148 }
149 else
150 return 0;
151 }
152 *gidp = cached_gid;
153 return 1;
154 }
155 \f
156 /* Names from the command call. */
157
158 static const char **name_array; /* store an array of names */
159 static int allocated_names; /* how big is the array? */
160 static int names; /* how many entries does it have? */
161 static int name_index = 0; /* how many of the entries have we scanned? */
162
163 /*------------------------.
164 | Initialize structures. |
165 `------------------------*/
166
167 void
168 init_names (void)
169 {
170 allocated_names = 10;
171 name_array = (const char **)
172 xmalloc (sizeof (const char *) * allocated_names);
173 names = 0;
174 }
175
176 /*--------------------------------------------------------------.
177 | Add NAME at end of name_array, reallocating it as necessary. |
178 `--------------------------------------------------------------*/
179
180 void
181 name_add (const char *name)
182 {
183 if (names == allocated_names)
184 {
185 allocated_names *= 2;
186 name_array = (const char **)
187 xrealloc (name_array, sizeof (const char *) * allocated_names);
188 }
189 name_array[names++] = name;
190 }
191 \f
192 /* Names from external name file. */
193
194 static FILE *name_file; /* file to read names from */
195 static char *name_buffer; /* buffer to hold the current file name */
196 static size_t name_buffer_length; /* allocated length of name_buffer */
197
198 /*---.
199 | ? |
200 `---*/
201
202 /* FIXME: I should better check more closely. It seems at first glance that
203 is_pattern is only used when reading a file, and ignored for all
204 command line arguments. */
205
206 static inline int
207 is_pattern (const char *string)
208 {
209 return strchr (string, '*') || strchr (string, '[') || strchr (string, '?');
210 }
211
212 /*-----------------------------------------------------------------------.
213 | Set up to gather file names for tar. They can either come from a file |
214 | or were saved from decoding arguments. |
215 `-----------------------------------------------------------------------*/
216
217 void
218 name_init (int argc, char *const *argv)
219 {
220 name_buffer = xmalloc (NAME_FIELD_SIZE + 2);
221 name_buffer_length = NAME_FIELD_SIZE;
222
223 if (files_from_option)
224 {
225 if (!strcmp (files_from_option, "-"))
226 {
227 request_stdin ("-T");
228 name_file = stdin;
229 }
230 else if (name_file = fopen (files_from_option, "r"), !name_file)
231 FATAL_ERROR ((0, errno, _("Cannot open file %s"), files_from_option));
232 }
233 }
234
235 /*---.
236 | ? |
237 `---*/
238
239 void
240 name_term (void)
241 {
242 free (name_buffer);
243 free (name_array);
244 }
245
246 /*---------------------------------------------------------------------.
247 | Read the next filename from name_file and null-terminate it. Put it |
248 | into name_buffer, reallocating and adjusting name_buffer_length if |
249 | necessary. Return 0 at end of file, 1 otherwise. |
250 `---------------------------------------------------------------------*/
251
252 static int
253 read_name_from_file (void)
254 {
255 int character;
256 size_t counter = 0;
257
258 /* FIXME: getc may be called even if character was EOF the last time here. */
259
260 /* FIXME: This + 2 allocation might serve no purpose. */
261
262 while (character = getc (name_file),
263 character != EOF && character != filename_terminator)
264 {
265 if (counter == name_buffer_length)
266 {
267 name_buffer_length += NAME_FIELD_SIZE;
268 name_buffer = xrealloc (name_buffer, name_buffer_length + 2);
269 }
270 name_buffer[counter++] = character;
271 }
272
273 if (counter == 0 && character == EOF)
274 return 0;
275
276 if (counter == name_buffer_length)
277 {
278 name_buffer_length += NAME_FIELD_SIZE;
279 name_buffer = xrealloc (name_buffer, name_buffer_length + 2);
280 }
281 name_buffer[counter] = '\0';
282
283 return 1;
284 }
285
286 /*------------------------------------------------------------------------.
287 | Get the next name from ARGV or the file of names. Result is in static |
288 | storage and can't be relied upon across two calls. |
289 | |
290 | If CHANGE_DIRS is true, treat a filename of the form "-C" as meaning |
291 | that the next filename is the name of a directory to change to. If |
292 | `filename_terminator' is NUL, CHANGE_DIRS is effectively always false. |
293 `------------------------------------------------------------------------*/
294
295 char *
296 name_next (int change_dirs)
297 {
298 const char *source;
299 char *cursor;
300 int chdir_flag = 0;
301
302 if (filename_terminator == '\0')
303 change_dirs = 0;
304
305 while (1)
306 {
307 /* Get a name, either from file or from saved arguments. */
308
309 if (name_file)
310 {
311 if (!read_name_from_file ())
312 break;
313 }
314 else
315 {
316 if (name_index == names)
317 break;
318
319 source = name_array[name_index++];
320 if (strlen (source) > name_buffer_length)
321 {
322 free (name_buffer);
323 name_buffer_length = strlen (source);
324 name_buffer = xmalloc (name_buffer_length + 2);
325 }
326 strcpy (name_buffer, source);
327 }
328
329 /* Zap trailing slashes. */
330
331 cursor = name_buffer + strlen (name_buffer) - 1;
332 while (cursor > name_buffer && *cursor == '/')
333 *cursor-- = '\0';
334
335 if (chdir_flag)
336 {
337 if (chdir (name_buffer) < 0)
338 FATAL_ERROR ((0, errno, _("Cannot change to directory %s"),
339 name_buffer));
340 chdir_flag = 0;
341 }
342 else if (change_dirs && strcmp (name_buffer, "-C") == 0)
343 chdir_flag = 1;
344 else
345 #if 0
346 if (!exclude_option || !check_exclude (name_buffer))
347 #endif
348 {
349 unquote_string (name_buffer);
350 return name_buffer;
351 }
352 }
353
354 /* No more names in file. */
355
356 if (name_file && chdir_flag)
357 FATAL_ERROR ((0, 0, _("Missing file name after -C")));
358
359 return NULL;
360 }
361
362 /*------------------------------.
363 | Close the name file, if any. |
364 `------------------------------*/
365
366 void
367 name_close (void)
368 {
369 if (name_file != NULL && name_file != stdin)
370 if (fclose (name_file) == EOF)
371 ERROR ((0, errno, "%s", name_buffer));
372 }
373
374 /*-------------------------------------------------------------------------.
375 | Gather names in a list for scanning. Could hash them later if we really |
376 | care. |
377 | |
378 | If the names are already sorted to match the archive, we just read them |
379 | one by one. name_gather reads the first one, and it is called by |
380 | name_match as appropriate to read the next ones. At EOF, the last name |
381 | read is just left in the buffer. This option lets users of small |
382 | machines extract an arbitrary number of files by doing "tar t" and |
383 | editing down the list of files. |
384 `-------------------------------------------------------------------------*/
385
386 void
387 name_gather (void)
388 {
389 /* Buffer able to hold a single name. */
390 static struct name *buffer;
391 static size_t allocated_length = 0;
392
393 char *name;
394
395 if (same_order_option)
396 {
397 if (allocated_length == 0)
398 {
399 allocated_length = sizeof (struct name) + NAME_FIELD_SIZE;
400 buffer = (struct name *) xmalloc (allocated_length);
401 /* FIXME: This memset is overkill, and ugly... */
402 memset (buffer, 0, allocated_length);
403 }
404 name = name_next (0);
405 if (name)
406 {
407 if (strcmp (name, "-C") == 0)
408 {
409 char *copy = xstrdup (name_next (0));
410
411 name = name_next (0);
412 if (!name)
413 FATAL_ERROR ((0, 0, _("Missing file name after -C")));
414 buffer->change_dir = copy;
415 }
416 buffer->length = strlen (name);
417 if (sizeof (struct name) + buffer->length >= allocated_length)
418 {
419 allocated_length = sizeof (struct name) + buffer->length;
420 buffer = (struct name *) xrealloc (buffer, allocated_length);
421 }
422 strncpy (buffer->name, name, (size_t) buffer->length);
423 buffer->name[buffer->length] = 0;
424 buffer->next = NULL;
425 buffer->found = 0;
426
427 /* FIXME: Poorly named globals, indeed... */
428 namelist = buffer;
429 namelast = namelist;
430 }
431 return;
432 }
433
434 /* Non sorted names -- read them all in. */
435
436 while (name = name_next (0), name)
437 addname (name);
438 }
439
440 /*-----------------------------.
441 | Add a name to the namelist. |
442 `-----------------------------*/
443
444 void
445 addname (const char *string)
446 {
447 /* FIXME: This is ugly. How is memory managed? */
448 static char *chdir_name = NULL;
449
450 struct name *name;
451 size_t length;
452
453 if (strcmp (string, "-C") == 0)
454 {
455 chdir_name = xstrdup (name_next (0));
456 string = name_next (0);
457 if (!chdir_name)
458 FATAL_ERROR ((0, 0, _("Missing file name after -C")));
459
460 if (chdir_name[0] != '/')
461 {
462 char *path = xmalloc (PATH_MAX);
463
464 /* FIXME: Shouldn't we use xgetcwd? */
465 #if HAVE_GETCWD
466 if (!getcwd (path, PATH_MAX))
467 FATAL_ERROR ((0, 0, _("Could not get current directory")));
468 #else
469 char *getwd ();
470
471 if (!getwd (path))
472 FATAL_ERROR ((0, 0, _("Could not get current directory: %s"),
473 path));
474 #endif
475 chdir_name = new_name (path, chdir_name);
476 free (path);
477 }
478 }
479
480 length = string ? strlen (string) : 0;
481 name = (struct name *) xmalloc (sizeof (struct name) + length);
482 memset (name, 0, sizeof (struct name) + length);
483 name->next = NULL;
484
485 if (string)
486 {
487 name->fake = 0;
488 name->length = length;
489 /* FIXME: Possibly truncating a string, here? Tss, tss, tss! */
490 strncpy (name->name, string, length);
491 name->name[length] = '\0';
492 }
493 else
494 name->fake = 1;
495
496 name->found = 0;
497 name->regexp = 0; /* assume not a regular expression */
498 name->firstch = 1; /* assume first char is literal */
499 name->change_dir = chdir_name;
500 name->dir_contents = 0;
501
502 if (string && is_pattern (string))
503 {
504 name->regexp = 1;
505 if (string[0] == '*' || string[0] == '[' || string[0] == '?')
506 name->firstch = 0;
507 }
508
509 if (namelast)
510 namelast->next = name;
511 namelast = name;
512 if (!namelist)
513 namelist = name;
514 }
515
516 /*------------------------------------------------------------------------.
517 | Return true if and only if name PATH (from an archive) matches any name |
518 | from the namelist. |
519 `------------------------------------------------------------------------*/
520
521 int
522 name_match (const char *path)
523 {
524 size_t length = strlen (path);
525
526 while (1)
527 {
528 struct name *cursor = namelist;
529
530 if (!cursor)
531 return 1; /* empty namelist is easy */
532
533 if (cursor->fake)
534 {
535 if (cursor->change_dir && chdir (cursor->change_dir))
536 FATAL_ERROR ((0, errno, _("Cannot change to directory %s"),
537 cursor->change_dir));
538 namelist = 0;
539 return 1;
540 }
541
542 for (; cursor; cursor = cursor->next)
543 {
544 /* If first chars don't match, quick skip. */
545
546 if (cursor->firstch && cursor->name[0] != path[0])
547 continue;
548
549 /* Regular expressions (shell globbing, actually). */
550
551 if (cursor->regexp)
552 {
553 if (fnmatch (cursor->name, path, FNM_LEADING_DIR) == 0)
554 {
555 cursor->found = 1; /* remember it matched */
556 if (starting_file_option)
557 {
558 free (namelist);
559 namelist = NULL;
560 }
561 if (cursor->change_dir && chdir (cursor->change_dir))
562 FATAL_ERROR ((0, errno, _("Cannot change to directory %s"),
563 cursor->change_dir));
564
565 /* We got a match. */
566 return 1;
567 }
568 continue;
569 }
570
571 /* Plain Old Strings. */
572
573 if (cursor->length <= length
574 /* archive length >= specified */
575 && (path[cursor->length] == '\0'
576 || path[cursor->length] == '/')
577 /* full match on file/dirname */
578 && strncmp (path, cursor->name, cursor->length) == 0)
579 /* name compare */
580 {
581 cursor->found = 1; /* remember it matched */
582 if (starting_file_option)
583 {
584 free ((void *) namelist);
585 namelist = 0;
586 }
587 if (cursor->change_dir && chdir (cursor->change_dir))
588 FATAL_ERROR ((0, errno, _("Cannot change to directory %s"),
589 cursor->change_dir));
590
591 /* We got a match. */
592 return 1;
593 }
594 }
595
596 /* Filename from archive not found in namelist. If we have the whole
597 namelist here, just return 0. Otherwise, read the next name in and
598 compare it. If this was the last name, namelist->found will remain
599 on. If not, we loop to compare the newly read name. */
600
601 if (same_order_option && namelist->found)
602 {
603 name_gather (); /* read one more */
604 if (namelist->found)
605 return 0;
606 }
607 else
608 return 0;
609 }
610 }
611
612 /*------------------------------------------------------------------.
613 | Print the names of things in the namelist that were not matched. |
614 `------------------------------------------------------------------*/
615
616 void
617 names_notfound (void)
618 {
619 struct name *cursor;
620 struct name *next;
621
622 for (cursor = namelist; cursor; cursor = next)
623 {
624 next = cursor->next;
625 if (!cursor->found && !cursor->fake)
626 ERROR ((0, 0, _("%s: Not found in archive"), cursor->name));
627
628 /* We could free the list, but the process is about to die anyway, so
629 save some CPU time. Amigas and other similarly broken software
630 will need to waste the time, though. */
631
632 #ifdef amiga
633 if (!same_order_option)
634 free (cursor);
635 #endif
636 }
637 namelist = (struct name *) NULL;
638 namelast = (struct name *) NULL;
639
640 if (same_order_option)
641 {
642 char *name;
643
644 while (name = name_next (1), name)
645 ERROR ((0, 0, _("%s: Not found in archive"), name));
646 }
647 }
648
649 /*---.
650 | ? |
651 `---*/
652
653 void
654 name_expand (void)
655 {
656 }
657
658 /*-------------------------------------------------------------------------.
659 | This is like name_match, except that it returns a pointer to the name it |
660 | matched, and doesn't set FOUND in structure. The caller will have to do |
661 | that if it wants to. Oh, and if the namelist is empty, it returns NULL, |
662 | unlike name_match, which returns TRUE. |
663 `-------------------------------------------------------------------------*/
664
665 struct name *
666 name_scan (const char *path)
667 {
668 size_t length = strlen (path);
669
670 while (1)
671 {
672 struct name *cursor = namelist;
673
674 if (!cursor)
675 return NULL; /* empty namelist is easy */
676
677 for (; cursor; cursor = cursor->next)
678 {
679 /* If first chars don't match, quick skip. */
680
681 if (cursor->firstch && cursor->name[0] != path[0])
682 continue;
683
684 /* Regular expressions. */
685
686 if (cursor->regexp)
687 {
688 if (fnmatch (cursor->name, path, FNM_LEADING_DIR) == 0)
689 return cursor; /* we got a match */
690 continue;
691 }
692
693 /* Plain Old Strings. */
694
695 if (cursor->length <= length
696 /* archive length >= specified */
697 && (path[cursor->length] == '\0'
698 || path[cursor->length] == '/')
699 /* full match on file/dirname */
700 && strncmp (path, cursor->name, cursor->length) == 0)
701 /* name compare */
702 return cursor; /* we got a match */
703 }
704
705 /* Filename from archive not found in namelist. If we have the whole
706 namelist here, just return 0. Otherwise, read the next name in and
707 compare it. If this was the last name, namelist->found will remain
708 on. If not, we loop to compare the newly read name. */
709
710 if (same_order_option && namelist->found)
711 {
712 name_gather (); /* read one more */
713 if (namelist->found)
714 return NULL;
715 }
716 else
717 return NULL;
718 }
719 }
720
721 /*-----------------------------------------------------------------------.
722 | This returns a name from the namelist which doesn't have ->found set. |
723 | It sets ->found before returning, so successive calls will find and |
724 | return all the non-found names in the namelist |
725 `-----------------------------------------------------------------------*/
726
727 struct name *gnu_list_name = NULL;
728
729 char *
730 name_from_list (void)
731 {
732 if (!gnu_list_name)
733 gnu_list_name = namelist;
734 while (gnu_list_name && gnu_list_name->found)
735 gnu_list_name = gnu_list_name->next;
736 if (gnu_list_name)
737 {
738 gnu_list_name->found = 1;
739 if (gnu_list_name->change_dir)
740 if (chdir (gnu_list_name->change_dir) < 0)
741 FATAL_ERROR ((0, errno, _("Cannot change to directory %s"),
742 gnu_list_name->change_dir));
743 return gnu_list_name->name;
744 }
745 return NULL;
746 }
747
748 /*---.
749 | ? |
750 `---*/
751
752 void
753 blank_name_list (void)
754 {
755 struct name *name;
756
757 gnu_list_name = 0;
758 for (name = namelist; name; name = name->next)
759 name->found = 0;
760 }
761
762 /*---.
763 | ? |
764 `---*/
765
766 char *
767 new_name (const char *path, const char *name)
768 {
769 char *buffer = (char *) xmalloc (strlen (path) + strlen (name) + 2);
770
771 sprintf (buffer, "%s/%s", path, name);
772 return buffer;
773 }
774 \f
775 /* Excludes names. */
776
777 static char *exclude_pool = NULL;
778 static size_t exclude_pool_size = 0;
779 static size_t allocated_exclude_pool_size = 0;
780
781 static char **simple_exclude_array = NULL;
782 static int simple_excludes = 0;
783 static int allocated_simple_excludes = 0;
784
785 static char **pattern_exclude_array = NULL;
786 static int pattern_excludes = 0;
787 static int allocated_pattern_excludes = 0;
788
789 /*---.
790 | ? |
791 `---*/
792
793 void
794 add_exclude (char *name)
795 {
796 size_t name_size;
797
798 unquote_string (name); /* FIXME: unquote in all cases? If ever? */
799 name_size = strlen (name) + 1;
800
801 if (exclude_pool_size + name_size > allocated_exclude_pool_size)
802 {
803 char *previous_exclude_pool = exclude_pool;
804 char **cursor;
805
806 allocated_exclude_pool_size = exclude_pool_size + name_size + 1024;
807 exclude_pool = (char *)
808 xrealloc (exclude_pool, allocated_exclude_pool_size);
809
810 for (cursor = simple_exclude_array;
811 cursor < simple_exclude_array + simple_excludes;
812 cursor++)
813 *cursor = exclude_pool + (*cursor - previous_exclude_pool);
814 for (cursor = pattern_exclude_array;
815 cursor < pattern_exclude_array + pattern_excludes;
816 cursor++)
817 *cursor = exclude_pool + (*cursor - previous_exclude_pool);
818 }
819
820 if (is_pattern (name))
821 {
822 if (pattern_excludes == allocated_pattern_excludes)
823 {
824 allocated_pattern_excludes += 32;
825 pattern_exclude_array = (char **)
826 xrealloc (pattern_exclude_array,
827 allocated_pattern_excludes * sizeof (char *));
828 }
829 pattern_exclude_array[pattern_excludes++]
830 = exclude_pool + exclude_pool_size;
831 }
832 else
833 {
834 if (simple_excludes == allocated_simple_excludes)
835 {
836 allocated_simple_excludes += 32;
837 simple_exclude_array = (char **)
838 xrealloc (simple_exclude_array,
839 allocated_simple_excludes * sizeof (char *));
840 }
841 simple_exclude_array[simple_excludes++]
842 = exclude_pool + exclude_pool_size;
843 }
844
845 strcpy (exclude_pool + exclude_pool_size, name);
846 exclude_pool_size += name_size;
847 }
848
849 /*---.
850 | ? |
851 `---*/
852
853 void
854 add_exclude_file (const char *name)
855 {
856 FILE *file;
857 char buffer[1024];
858
859 if (strcmp (name, "-"))
860 file = fopen (name, "r");
861 else
862 {
863 request_stdin ("-X");
864 file = stdin;
865 }
866 if (!file)
867 FATAL_ERROR ((0, errno, _("Cannot open %s"), name));
868
869 while (fgets (buffer, 1024, file))
870 {
871 char *end_of_line = strrchr (buffer, '\n');
872
873 if (end_of_line)
874 *end_of_line = '\0';
875 add_exclude (buffer);
876 }
877 if (fclose (file) == EOF)
878 ERROR ((0, errno, "%s", name));
879 }
880
881 /*------------------------------------------------------------------.
882 | Returns true if the file NAME should not be added nor extracted. |
883 `------------------------------------------------------------------*/
884
885 int
886 check_exclude (const char *name)
887 {
888 int counter;
889
890 for (counter = 0; counter < pattern_excludes; counter++)
891 if (fnmatch (pattern_exclude_array[counter], name, FNM_LEADING_DIR) == 0)
892 return 1;
893
894 for (counter = 0; counter < simple_excludes; counter++)
895 {
896 /* Accept the output from strstr only if it is the last part of the
897 string. FIXME: Find a faster way to do this. */
898
899 char *string = strstr (name, simple_exclude_array[counter]);
900
901 if (string
902 && (string == name || string[-1] == '/')
903 && string[strlen (simple_exclude_array[counter])] == '\0')
904 return 1;
905 }
906 return 0;
907 }
This page took 0.080869 seconds and 5 git commands to generate.