]> Dogcows Code - chaz/tar/blob - src/misc.c
Port to Forte Developer 7 C 5.4 and C99.
[chaz/tar] / src / misc.c
1 /* Miscellaneous functions, not really specific to GNU tar.
2
3 Copyright (C) 1988, 1992, 1994, 1995, 1996, 1997, 1999, 2000, 2001,
4 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
5
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any later
9 version.
10
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
14 Public License for more details.
15
16 You should have received a copy of the GNU General Public License along
17 with this program; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
19
20 #include <system.h>
21 #include <sys/time.h>
22 #include <sys/resource.h>
23 #include <rmt.h>
24 #include "common.h"
25 #include <quotearg.h>
26 #include <save-cwd.h>
27 #include <xgetcwd.h>
28 #include <unlinkdir.h>
29 #include <utimens.h>
30
31 #if HAVE_STROPTS_H
32 # include <stropts.h>
33 #endif
34 #if HAVE_SYS_FILIO_H
35 # include <sys/filio.h>
36 #endif
37
38 \f
39 /* Handling strings. */
40
41 /* Assign STRING to a copy of VALUE if not zero, or to zero. If
42 STRING was nonzero, it is freed first. */
43 void
44 assign_string (char **string, const char *value)
45 {
46 if (*string)
47 free (*string);
48 *string = value ? xstrdup (value) : 0;
49 }
50
51 /* Allocate a copy of the string quoted as in C, and returns that. If
52 the string does not have to be quoted, it returns a null pointer.
53 The allocated copy should normally be freed with free() after the
54 caller is done with it.
55
56 This is used in one context only: generating the directory file in
57 incremental dumps. The quoted string is not intended for human
58 consumption; it is intended only for unquote_string. The quoting
59 is locale-independent, so that users needn't worry about locale
60 when reading directory files. This means that we can't use
61 quotearg, as quotearg is locale-dependent and is meant for human
62 consumption. */
63 char *
64 quote_copy_string (const char *string)
65 {
66 const char *source = string;
67 char *destination = 0;
68 char *buffer = 0;
69 int copying = 0;
70
71 while (*source)
72 {
73 int character = *source++;
74
75 switch (character)
76 {
77 case '\n': case '\\':
78 if (!copying)
79 {
80 size_t length = (source - string) - 1;
81
82 copying = 1;
83 buffer = xmalloc (length + 2 + 2 * strlen (source) + 1);
84 memcpy (buffer, string, length);
85 destination = buffer + length;
86 }
87 *destination++ = '\\';
88 *destination++ = character == '\\' ? '\\' : 'n';
89 break;
90
91 default:
92 if (copying)
93 *destination++ = character;
94 break;
95 }
96 }
97 if (copying)
98 {
99 *destination = '\0';
100 return buffer;
101 }
102 return 0;
103 }
104
105 /* Takes a quoted C string (like those produced by quote_copy_string)
106 and turns it back into the un-quoted original. This is done in
107 place. Returns 0 only if the string was not properly quoted, but
108 completes the unquoting anyway.
109
110 This is used for reading the saved directory file in incremental
111 dumps. It is used for decoding old `N' records (demangling names).
112 But also, it is used for decoding file arguments, would they come
113 from the shell or a -T file, and for decoding the --exclude
114 argument. */
115 int
116 unquote_string (char *string)
117 {
118 int result = 1;
119 char *source = string;
120 char *destination = string;
121
122 /* Escape sequences other than \\ and \n are no longer generated by
123 quote_copy_string, but accept them for backwards compatibility,
124 and also because unquote_string is used for purposes other than
125 parsing the output of quote_copy_string. */
126
127 while (*source)
128 if (*source == '\\')
129 switch (*++source)
130 {
131 case '\\':
132 *destination++ = '\\';
133 source++;
134 break;
135
136 case 'a':
137 *destination++ = '\a';
138 source++;
139 break;
140
141 case 'b':
142 *destination++ = '\b';
143 source++;
144 break;
145
146 case 'f':
147 *destination++ = '\f';
148 source++;
149 break;
150
151 case 'n':
152 *destination++ = '\n';
153 source++;
154 break;
155
156 case 'r':
157 *destination++ = '\r';
158 source++;
159 break;
160
161 case 't':
162 *destination++ = '\t';
163 source++;
164 break;
165
166 case 'v':
167 *destination++ = '\v';
168 source++;
169 break;
170
171 case '?':
172 *destination++ = 0177;
173 source++;
174 break;
175
176 case '0':
177 case '1':
178 case '2':
179 case '3':
180 case '4':
181 case '5':
182 case '6':
183 case '7':
184 {
185 int value = *source++ - '0';
186
187 if (*source < '0' || *source > '7')
188 {
189 *destination++ = value;
190 break;
191 }
192 value = value * 8 + *source++ - '0';
193 if (*source < '0' || *source > '7')
194 {
195 *destination++ = value;
196 break;
197 }
198 value = value * 8 + *source++ - '0';
199 *destination++ = value;
200 break;
201 }
202
203 default:
204 result = 0;
205 *destination++ = '\\';
206 if (*source)
207 *destination++ = *source++;
208 break;
209 }
210 else if (source != destination)
211 *destination++ = *source++;
212 else
213 source++, destination++;
214
215 if (source != destination)
216 *destination = '\0';
217 return result;
218 }
219 \f
220 /* Handling numbers. */
221
222 /* Output fraction and trailing digits appropriate for a nanoseconds
223 count equal to NS, but don't output unnecessary '.' or trailing
224 zeros. */
225
226 void
227 code_ns_fraction (int ns, char *p)
228 {
229 if (ns == 0)
230 *p = '\0';
231 else
232 {
233 int i = 9;
234 *p++ = '.';
235
236 while (ns % 10 == 0)
237 {
238 ns /= 10;
239 i--;
240 }
241
242 p[i] = '\0';
243
244 for (;;)
245 {
246 p[--i] = '0' + ns % 10;
247 if (i == 0)
248 break;
249 ns /= 10;
250 }
251 }
252 }
253
254 char const *
255 code_timespec (struct timespec t, char sbuf[TIMESPEC_STRSIZE_BOUND])
256 {
257 time_t s = t.tv_sec;
258 int ns = t.tv_nsec;
259 char *np;
260 bool negative = s < 0;
261
262 if (negative && ns != 0)
263 {
264 s++;
265 ns = BILLION - ns;
266 }
267
268 np = umaxtostr (negative ? - (uintmax_t) s : (uintmax_t) s, sbuf + 1);
269 if (negative)
270 *--np = '-';
271 code_ns_fraction (ns, sbuf + UINTMAX_STRSIZE_BOUND);
272 return np;
273 }
274 \f
275 /* File handling. */
276
277 /* Saved names in case backup needs to be undone. */
278 static char *before_backup_name;
279 static char *after_backup_name;
280
281 /* Return 1 if FILE_NAME is obviously "." or "/". */
282 static bool
283 must_be_dot_or_slash (char const *file_name)
284 {
285 file_name += FILE_SYSTEM_PREFIX_LEN (file_name);
286
287 if (ISSLASH (file_name[0]))
288 {
289 for (;;)
290 if (ISSLASH (file_name[1]))
291 file_name++;
292 else if (file_name[1] == '.'
293 && ISSLASH (file_name[2 + (file_name[2] == '.')]))
294 file_name += 2 + (file_name[2] == '.');
295 else
296 return ! file_name[1];
297 }
298 else
299 {
300 while (file_name[0] == '.' && ISSLASH (file_name[1]))
301 {
302 file_name += 2;
303 while (ISSLASH (*file_name))
304 file_name++;
305 }
306
307 return ! file_name[0] || (file_name[0] == '.' && ! file_name[1]);
308 }
309 }
310
311 /* Some implementations of rmdir let you remove '.' or '/'.
312 Report an error with errno set to zero for obvious cases of this;
313 otherwise call rmdir. */
314 static int
315 safer_rmdir (const char *file_name)
316 {
317 if (must_be_dot_or_slash (file_name))
318 {
319 errno = 0;
320 return -1;
321 }
322
323 return rmdir (file_name);
324 }
325
326 /* Remove FILE_NAME, returning 1 on success. If FILE_NAME is a directory,
327 then if OPTION is RECURSIVE_REMOVE_OPTION is set remove FILE_NAME
328 recursively; otherwise, remove it only if it is empty. If FILE_NAME is
329 a directory that cannot be removed (e.g., because it is nonempty)
330 and if OPTION is WANT_DIRECTORY_REMOVE_OPTION, then return -1.
331 Return 0 on error, with errno set; if FILE_NAME is obviously the working
332 directory return zero with errno set to zero. */
333 int
334 remove_any_file (const char *file_name, enum remove_option option)
335 {
336 /* Try unlink first if we cannot unlink directories, as this saves
337 us a system call in the common case where we're removing a
338 non-directory. */
339 bool try_unlink_first = cannot_unlink_dir ();
340
341 if (try_unlink_first)
342 {
343 if (unlink (file_name) == 0)
344 return 1;
345
346 /* POSIX 1003.1-2001 requires EPERM when attempting to unlink a
347 directory without appropriate privileges, but many Linux
348 kernels return the more-sensible EISDIR. */
349 if (errno != EPERM && errno != EISDIR)
350 return 0;
351 }
352
353 if (safer_rmdir (file_name) == 0)
354 return 1;
355
356 switch (errno)
357 {
358 case ENOTDIR:
359 return !try_unlink_first && unlink (file_name) == 0;
360
361 case 0:
362 case EEXIST:
363 #if defined ENOTEMPTY && ENOTEMPTY != EEXIST
364 case ENOTEMPTY:
365 #endif
366 switch (option)
367 {
368 case ORDINARY_REMOVE_OPTION:
369 break;
370
371 case WANT_DIRECTORY_REMOVE_OPTION:
372 return -1;
373
374 case RECURSIVE_REMOVE_OPTION:
375 {
376 char *directory = savedir (file_name);
377 char const *entry;
378 size_t entrylen;
379
380 if (! directory)
381 return 0;
382
383 for (entry = directory;
384 (entrylen = strlen (entry)) != 0;
385 entry += entrylen + 1)
386 {
387 char *file_name_buffer = new_name (file_name, entry);
388 int r = remove_any_file (file_name_buffer,
389 RECURSIVE_REMOVE_OPTION);
390 int e = errno;
391 free (file_name_buffer);
392
393 if (! r)
394 {
395 free (directory);
396 errno = e;
397 return 0;
398 }
399 }
400
401 free (directory);
402 return safer_rmdir (file_name) == 0;
403 }
404 }
405 break;
406 }
407
408 return 0;
409 }
410
411 /* Check if FILE_NAME already exists and make a backup of it right now.
412 Return success (nonzero) only if the backup is either unneeded, or
413 successful. For now, directories are considered to never need
414 backup. If THIS_IS_THE_ARCHIVE is nonzero, this is the archive and
415 so, we do not have to backup block or character devices, nor remote
416 entities. */
417 bool
418 maybe_backup_file (const char *file_name, bool this_is_the_archive)
419 {
420 struct stat file_stat;
421
422 /* Check if we really need to backup the file. */
423
424 if (this_is_the_archive && _remdev (file_name))
425 return true;
426
427 if (stat (file_name, &file_stat))
428 {
429 if (errno == ENOENT)
430 return true;
431
432 stat_error (file_name);
433 return false;
434 }
435
436 if (S_ISDIR (file_stat.st_mode))
437 return true;
438
439 if (this_is_the_archive
440 && (S_ISBLK (file_stat.st_mode) || S_ISCHR (file_stat.st_mode)))
441 return true;
442
443 assign_string (&before_backup_name, file_name);
444
445 /* A run situation may exist between Emacs or other GNU programs trying to
446 make a backup for the same file simultaneously. If theoretically
447 possible, real problems are unlikely. Doing any better would require a
448 convention, GNU-wide, for all programs doing backups. */
449
450 assign_string (&after_backup_name, 0);
451 after_backup_name = find_backup_file_name (file_name, backup_type);
452 if (! after_backup_name)
453 xalloc_die ();
454
455 if (rename (before_backup_name, after_backup_name) == 0)
456 {
457 if (verbose_option)
458 fprintf (stdlis, _("Renaming %s to %s\n"),
459 quote_n (0, before_backup_name),
460 quote_n (1, after_backup_name));
461 return true;
462 }
463 else
464 {
465 /* The backup operation failed. */
466 int e = errno;
467 ERROR ((0, e, _("%s: Cannot rename to %s"),
468 quotearg_colon (before_backup_name),
469 quote_n (1, after_backup_name)));
470 assign_string (&after_backup_name, 0);
471 return false;
472 }
473 }
474
475 /* Try to restore the recently backed up file to its original name.
476 This is usually only needed after a failed extraction. */
477 void
478 undo_last_backup (void)
479 {
480 if (after_backup_name)
481 {
482 if (rename (after_backup_name, before_backup_name) != 0)
483 {
484 int e = errno;
485 ERROR ((0, e, _("%s: Cannot rename to %s"),
486 quotearg_colon (after_backup_name),
487 quote_n (1, before_backup_name)));
488 }
489 if (verbose_option)
490 fprintf (stdlis, _("Renaming %s back to %s\n"),
491 quote_n (0, after_backup_name),
492 quote_n (1, before_backup_name));
493 assign_string (&after_backup_name, 0);
494 }
495 }
496
497 /* Depending on DEREF, apply either stat or lstat to (NAME, BUF). */
498 int
499 deref_stat (bool deref, char const *name, struct stat *buf)
500 {
501 return deref ? stat (name, buf) : lstat (name, buf);
502 }
503
504 /* Set FD's (i.e., FILE's) access time to TIMESPEC[0]. If that's not
505 possible to do by itself, set its access and data modification
506 times to TIMESPEC[0] and TIMESPEC[1], respectively. */
507 int
508 set_file_atime (int fd, char const *file, struct timespec const timespec[2])
509 {
510 #ifdef _FIOSATIME
511 if (0 <= fd)
512 {
513 struct timeval timeval;
514 timeval.tv_sec = timespec[0].tv_sec;
515 timeval.tv_usec = timespec[0].tv_nsec / 1000;
516 if (ioctl (fd, _FIOSATIME, &timeval) == 0)
517 return 0;
518 }
519 #endif
520
521 return futimens (fd, file, timespec);
522 }
523
524 /* A description of a working directory. */
525 struct wd
526 {
527 char const *name;
528 int saved;
529 struct saved_cwd saved_cwd;
530 };
531
532 /* A vector of chdir targets. wd[0] is the initial working directory. */
533 static struct wd *wd;
534
535 /* The number of working directories in the vector. */
536 static size_t wds;
537
538 /* The allocated size of the vector. */
539 static size_t wd_alloc;
540
541 /* DIR is the operand of a -C option; add it to vector of chdir targets,
542 and return the index of its location. */
543 int
544 chdir_arg (char const *dir)
545 {
546 if (wds == wd_alloc)
547 {
548 if (wd_alloc == 0)
549 {
550 wd_alloc = 2;
551 wd = xmalloc (sizeof *wd * wd_alloc);
552 }
553 else
554 wd = x2nrealloc (wd, &wd_alloc, sizeof *wd);
555
556 if (! wds)
557 {
558 wd[wds].name = ".";
559 wd[wds].saved = 0;
560 wds++;
561 }
562 }
563
564 /* Optimize the common special case of the working directory,
565 or the working directory as a prefix. */
566 if (dir[0])
567 {
568 while (dir[0] == '.' && ISSLASH (dir[1]))
569 for (dir += 2; ISSLASH (*dir); dir++)
570 continue;
571 if (! dir[dir[0] == '.'])
572 return wds - 1;
573 }
574
575 wd[wds].name = dir;
576 wd[wds].saved = 0;
577 return wds++;
578 }
579
580 /* Return maximum number of open files */
581 int
582 get_max_open_files ()
583 {
584 #if defined _SC_OPEN_MAX
585 return sysconf (_SC_OPEN_MAX);
586 #elif defined RLIMIT_NOFILE
587 struct rlimit rlim;
588
589 if (getrlimit(RLIMIT_NOFILE, &rlim) == 0)
590 return rlim.rlim_max;
591 return -1;
592 #elif defined HAVE_GETDTABLESIZE
593 return getdtablesize ();
594 #else
595 return -1;
596 #endif
597 }
598
599 /* Close all descriptors, except the first three */
600 void
601 closeopen ()
602 {
603 int i;
604
605 for (i = get_max_open_files () - 1; i > 2; i--)
606 close (i);
607 }
608
609 /* Change to directory I. If I is 0, change to the initial working
610 directory; otherwise, I must be a value returned by chdir_arg. */
611 void
612 chdir_do (int i)
613 {
614 static int previous;
615 static int saved_count;
616
617 if (previous != i)
618 {
619 struct wd *prev = &wd[previous];
620 struct wd *curr = &wd[i];
621
622 if (! prev->saved)
623 {
624 prev->saved = 1;
625 saved_count++;
626 /* Make sure we still have at least one descriptor available */
627 if (saved_count >= get_max_open_files () - 4)
628 {
629 /* Force restore_cwd to use chdir_long */
630 prev->saved_cwd.desc = -1;
631 prev->saved_cwd.name = xgetcwd ();
632 }
633 else if (save_cwd (&prev->saved_cwd) != 0)
634 FATAL_ERROR ((0, 0, _("Cannot save working directory")));
635 }
636
637 if (curr->saved)
638 {
639 if (restore_cwd (&curr->saved_cwd))
640 FATAL_ERROR ((0, 0, _("Cannot change working directory")));
641 }
642 else
643 {
644 if (i && ! ISSLASH (curr->name[0]))
645 chdir_do (i - 1);
646 if (chdir (curr->name) != 0)
647 chdir_fatal (curr->name);
648 }
649
650 previous = i;
651 }
652 }
653 \f
654 void
655 close_diag (char const *name)
656 {
657 if (ignore_failed_read_option)
658 close_warn (name);
659 else
660 close_error (name);
661 }
662
663 void
664 open_diag (char const *name)
665 {
666 if (ignore_failed_read_option)
667 open_warn (name);
668 else
669 open_error (name);
670 }
671
672 void
673 read_diag_details (char const *name, off_t offset, size_t size)
674 {
675 if (ignore_failed_read_option)
676 read_warn_details (name, offset, size);
677 else
678 read_error_details (name, offset, size);
679 }
680
681 void
682 readlink_diag (char const *name)
683 {
684 if (ignore_failed_read_option)
685 readlink_warn (name);
686 else
687 readlink_error (name);
688 }
689
690 void
691 savedir_diag (char const *name)
692 {
693 if (ignore_failed_read_option)
694 savedir_warn (name);
695 else
696 savedir_error (name);
697 }
698
699 void
700 seek_diag_details (char const *name, off_t offset)
701 {
702 if (ignore_failed_read_option)
703 seek_warn_details (name, offset);
704 else
705 seek_error_details (name, offset);
706 }
707
708 void
709 stat_diag (char const *name)
710 {
711 if (ignore_failed_read_option)
712 stat_warn (name);
713 else
714 stat_error (name);
715 }
716
717 void
718 write_fatal_details (char const *name, ssize_t status, size_t size)
719 {
720 write_error_details (name, status, size);
721 fatal_exit ();
722 }
723
724 /* Fork, aborting if unsuccessful. */
725 pid_t
726 xfork (void)
727 {
728 pid_t p = fork ();
729 if (p == (pid_t) -1)
730 call_arg_fatal ("fork", _("child process"));
731 return p;
732 }
733
734 /* Create a pipe, aborting if unsuccessful. */
735 void
736 xpipe (int fd[2])
737 {
738 if (pipe (fd) < 0)
739 call_arg_fatal ("pipe", _("interprocess channel"));
740 }
741
742 /* Return PTR, aligned upward to the next multiple of ALIGNMENT.
743 ALIGNMENT must be nonzero. The caller must arrange for ((char *)
744 PTR) through ((char *) PTR + ALIGNMENT - 1) to be addressable
745 locations. */
746
747 static inline void *
748 ptr_align (void *ptr, size_t alignment)
749 {
750 char *p0 = ptr;
751 char *p1 = p0 + alignment - 1;
752 return p1 - (size_t) p1 % alignment;
753 }
754
755 /* Return the address of a page-aligned buffer of at least SIZE bytes.
756 The caller should free *PTR when done with the buffer. */
757
758 void *
759 page_aligned_alloc (void **ptr, size_t size)
760 {
761 size_t alignment = getpagesize ();
762 size_t size1 = size + alignment;
763 if (size1 < size)
764 xalloc_die ();
765 *ptr = xmalloc (size1);
766 return ptr_align (*ptr, alignment);
767 }
This page took 0.068174 seconds and 5 git commands to generate.