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