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