1 /* GNU dump extensions to tar.
3 Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001,
4 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
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
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.
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. */
26 /* Incremental dump specialities. */
28 /* Which child files to save under a directory. */
36 #define DIRF_INIT 0x0001 /* directory structure is initialized
37 (procdir called at least once) */
38 #define DIRF_NFS 0x0002 /* directory is mounted on nfs */
39 #define DIRF_FOUND 0x0004 /* directory is found on fs */
40 #define DIRF_NEW 0x0008 /* directory is new (not found
41 in the previous dump) */
42 #define DIRF_RENAMED 0x0010 /* directory is renamed */
44 #define DIR_IS_INITED(d) ((d)->flags & DIRF_INIT)
45 #define DIR_IS_NFS(d) ((d)->flags & DIRF_NFS)
46 #define DIR_IS_FOUND(d) ((d)->flags & DIRF_FOUND)
47 #define DIR_IS_NEW(d) ((d)->flags & DIRF_NEW)
48 #define DIR_IS_RENAMED(d) ((d)->flags & DIRF_RENAMED)
50 #define DIR_SET_FLAG(d,f) (d)->flags |= (f)
51 #define DIR_CLEAR_FLAG(d,f) (d)->flags &= ~(f)
53 /* Directory attributes. */
56 struct timespec mtime
; /* Modification time */
57 dev_t device_number
; /* device number for directory */
58 ino_t inode_number
; /* inode number for directory */
59 char *contents
; /* Directory contents */
60 char *icontents
; /* Initial contents if the directory was
62 enum children children
; /* What to save under this directory */
63 unsigned flags
; /* See DIRF_ macros above */
64 struct directory
*orig
; /* If the directory was renamed, points to
65 the original directory structure */
66 char name
[1]; /* file name of directory */
69 static Hash_table
*directory_table
;
70 static Hash_table
*directory_meta_table
;
72 #if HAVE_ST_FSTYPE_STRING
73 static char const nfs_string
[] = "nfs";
74 # define NFS_FILE_STAT(st) (strcmp ((st).st_fstype, nfs_string) == 0)
76 # define ST_DEV_MSB(st) (~ (dev_t) 0 << (sizeof (st).st_dev * CHAR_BIT - 1))
77 # define NFS_FILE_STAT(st) (((st).st_dev & ST_DEV_MSB (st)) != 0)
80 /* Calculate the hash of a directory. */
82 hash_directory_name (void const *entry
, size_t n_buckets
)
84 struct directory
const *directory
= entry
;
85 return hash_string (directory
->name
, n_buckets
);
88 /* Compare two directories for equality of their names. */
90 compare_directory_names (void const *entry1
, void const *entry2
)
92 struct directory
const *directory1
= entry1
;
93 struct directory
const *directory2
= entry2
;
94 return strcmp (directory1
->name
, directory2
->name
) == 0;
98 hash_directory_meta (void const *entry
, size_t n_buckets
)
100 struct directory
const *directory
= entry
;
101 /* FIXME: Work out a better algorytm */
102 return (directory
->device_number
+ directory
->inode_number
) % n_buckets
;
105 /* Compare two directories for equality of their device and inode numbers. */
107 compare_directory_meta (void const *entry1
, void const *entry2
)
109 struct directory
const *directory1
= entry1
;
110 struct directory
const *directory2
= entry2
;
111 return directory1
->device_number
== directory2
->device_number
112 && directory1
->inode_number
== directory2
->inode_number
;
115 /* Make a directory entry for given NAME */
116 static struct directory
*
117 make_directory (const char *name
)
119 size_t namelen
= strlen (name
);
120 size_t size
= offsetof (struct directory
, name
) + namelen
+ 1;
121 struct directory
*directory
= xmalloc (size
);
122 directory
->contents
= directory
->icontents
= NULL
;
123 directory
->orig
= NULL
;
124 directory
->flags
= false;
125 strcpy (directory
->name
, name
);
126 if (ISSLASH (directory
->name
[namelen
-1]))
127 directory
->name
[namelen
-1] = 0;
131 /* Create and link a new directory entry for directory NAME, having a
132 device number DEV and an inode number INO, with NFS indicating
133 whether it is an NFS device and FOUND indicating whether we have
134 found that the directory exists. */
135 static struct directory
*
136 note_directory (char const *name
, struct timespec mtime
,
137 dev_t dev
, ino_t ino
, bool nfs
, bool found
, char *contents
)
139 struct directory
*directory
= make_directory (name
);
141 directory
->mtime
= mtime
;
142 directory
->device_number
= dev
;
143 directory
->inode_number
= ino
;
144 directory
->children
= CHANGED_CHILDREN
;
146 DIR_SET_FLAG (directory
, DIRF_NFS
);
148 DIR_SET_FLAG (directory
, DIRF_FOUND
);
151 size_t size
= dumpdir_size (contents
);
152 directory
->contents
= xmalloc (size
);
153 memcpy (directory
->contents
, contents
, size
);
156 directory
->contents
= NULL
;
158 if (! ((directory_table
159 || (directory_table
= hash_initialize (0, 0,
161 compare_directory_names
, 0)))
162 && hash_insert (directory_table
, directory
)))
165 if (! ((directory_meta_table
166 || (directory_meta_table
= hash_initialize (0, 0,
168 compare_directory_meta
,
170 && hash_insert (directory_meta_table
, directory
)))
176 /* Return a directory entry for a given file NAME, or zero if none found. */
177 static struct directory
*
178 find_directory (const char *name
)
180 if (! directory_table
)
184 struct directory
*dir
= make_directory (name
);
185 struct directory
*ret
= hash_lookup (directory_table
, dir
);
191 /* Return a directory entry for a given combination of device and inode
192 numbers, or zero if none found. */
193 static struct directory
*
194 find_directory_meta (dev_t dev
, ino_t ino
)
196 if (! directory_meta_table
)
200 struct directory
*dir
= make_directory ("");
201 struct directory
*ret
;
202 dir
->device_number
= dev
;
203 dir
->inode_number
= ino
;
204 ret
= hash_lookup (directory_meta_table
, dir
);
211 update_parent_directory (const char *name
)
213 struct directory
*directory
;
217 directory
= find_directory (p
);
221 if (deref_stat (dereference_option
, p
, &st
) != 0)
224 directory
->mtime
= get_stat_mtime (&st
);
229 static struct directory
*
230 procdir (char *name_buffer
, struct stat
*stat_data
,
232 enum children children
,
235 struct directory
*directory
;
236 bool nfs
= NFS_FILE_STAT (*stat_data
);
238 if ((directory
= find_directory (name_buffer
)) != NULL
)
240 if (DIR_IS_INITED (directory
))
243 /* With NFS, the same file can have two different devices
244 if an NFS directory is mounted in multiple locations,
245 which is relatively common when automounting.
246 To avoid spurious incremental redumping of
247 directories, consider all NFS devices as equal,
248 relying on the i-node to establish differences. */
250 if (! (((DIR_IS_NFS (directory
) & nfs
)
251 || directory
->device_number
== stat_data
->st_dev
)
252 && directory
->inode_number
== stat_data
->st_ino
))
254 /* FIXME: find_directory_meta ignores nfs */
255 struct directory
*d
= find_directory_meta (stat_data
->st_dev
,
260 WARN ((0, 0, _("%s: Directory has been renamed from %s"),
261 quotearg_colon (name_buffer
),
262 quote_n (1, d
->name
)));
264 DIR_SET_FLAG (directory
, DIRF_RENAMED
);
265 directory
->children
= CHANGED_CHILDREN
;
270 WARN ((0, 0, _("%s: Directory has been renamed"),
271 quotearg_colon (name_buffer
)));
272 directory
->children
= ALL_CHILDREN
;
273 directory
->device_number
= stat_data
->st_dev
;
274 directory
->inode_number
= stat_data
->st_ino
;
277 DIR_SET_FLAG (directory
, DIRF_NFS
);
280 directory
->children
= CHANGED_CHILDREN
;
282 DIR_SET_FLAG (directory
, DIRF_FOUND
);
286 struct directory
*d
= find_directory_meta (stat_data
->st_dev
,
289 directory
= note_directory (name_buffer
,
290 get_stat_mtime(stat_data
),
300 WARN ((0, 0, _("%s: Directory has been renamed from %s"),
301 quotearg_colon (name_buffer
),
302 quote_n (1, d
->name
)));
304 DIR_SET_FLAG (directory
, DIRF_RENAMED
);
305 directory
->children
= CHANGED_CHILDREN
;
309 DIR_SET_FLAG (directory
, DIRF_NEW
);
311 WARN ((0, 0, _("%s: Directory is new"),
312 quotearg_colon (name_buffer
)));
313 directory
->children
=
314 (listed_incremental_option
315 || (OLDER_STAT_TIME (*stat_data
, m
)
316 || (after_date_option
317 && OLDER_STAT_TIME (*stat_data
, c
))))
323 /* If the directory is on another device and --one-file-system was given,
325 if (one_file_system_option
&& device
!= stat_data
->st_dev
326 /* ... except if it was explicitely given in the command line */
327 && !is_individual_file (name_buffer
))
328 directory
->children
= NO_CHILDREN
;
329 else if (children
== ALL_CHILDREN
)
330 directory
->children
= ALL_CHILDREN
;
332 DIR_SET_FLAG (directory
, DIRF_INIT
);
337 /* Locate NAME in the dumpdir array DUMP.
338 Return pointer to the slot in the array, or NULL if not found */
340 dumpdir_locate (const char *dump
, const char *name
)
345 /* Ignore 'R' (rename) and 'X' (tempname) entries, since they break
346 alphabetical ordering.
347 They normally do not occur in dumpdirs from the snapshot files,
348 but this function is also used by purge_directory, which operates
349 on a dumpdir from the archive, hence the need for this test. */
350 if (!strchr ("RX", *dump
))
352 int rc
= strcmp (dump
+ 1, name
);
358 dump
+= strlen (dump
) + 1;
363 /* Return size in bytes of the dumpdir array P */
365 dumpdir_size (const char *p
)
371 size_t size
= strlen (p
) + 1;
379 compare_dirnames (const void *first
, const void *second
)
381 char const *const *name1
= first
;
382 char const *const *name2
= second
;
383 return strcmp (*name1
, *name2
);
386 /* Compare dumpdir array from DIRECTORY with directory listing DIR and
387 build a new dumpdir template.
389 DIR must be returned by a previous call to savedir().
391 File names in DIRECTORY->contents must be sorted
394 DIRECTORY->contents is replaced with the created template. Each entry is
395 prefixed with ' ' if it was present in DUMP and with 'Y' otherwise. */
398 makedumpdir (struct directory
*directory
, const char *dir
)
401 dirsize
, /* Number of elements in DIR */
402 len
; /* Length of DIR, including terminating nul */
405 char *new_dump
, *new_dump_ptr
;
408 if (directory
->children
== ALL_CHILDREN
)
410 else if (DIR_IS_RENAMED (directory
))
411 dump
= directory
->orig
->icontents
?
412 directory
->orig
->icontents
: directory
->orig
->contents
;
414 dump
= directory
->contents
;
416 /* Count the size of DIR and the number of elements it contains */
419 for (p
= dir
; *p
; p
+= strlen (p
) + 1, dirsize
++)
420 len
+= strlen (p
) + 2;
423 /* Create a sorted directory listing */
424 array
= xcalloc (dirsize
, sizeof array
[0]);
425 for (i
= 0, p
= dir
; *p
; p
+= strlen (p
) + 1, i
++)
428 qsort (array
, dirsize
, sizeof (array
[0]), compare_dirnames
);
430 /* Prepare space for new dumpdir */
431 new_dump
= xmalloc (len
);
432 new_dump_ptr
= new_dump
;
434 /* Fill in the dumpdir template */
435 for (i
= 0; i
< dirsize
; i
++)
437 const char *loc
= dumpdir_locate (dump
, array
[i
]);
440 *new_dump_ptr
++ = ' ';
441 dump
= loc
+ strlen (loc
) + 1;
444 *new_dump_ptr
++ = 'Y'; /* New entry */
446 /* Copy the file name */
447 for (p
= array
[i
]; (*new_dump_ptr
++ = *p
++); )
451 directory
->icontents
= directory
->contents
;
452 directory
->contents
= new_dump
;
456 /* Recursively scan the given directory. */
458 scan_directory (char *dir_name
, dev_t device
)
460 char *dirp
= savedir (dir_name
); /* for scanning directory */
461 char *name_buffer
; /* directory, `/', and directory member */
462 size_t name_buffer_size
; /* allocated size of name_buffer, minus 2 */
463 size_t name_length
; /* used length in name_buffer */
464 struct stat stat_data
;
465 struct directory
*directory
;
468 savedir_error (dir_name
);
470 name_buffer_size
= strlen (dir_name
) + NAME_FIELD_SIZE
;
471 name_buffer
= xmalloc (name_buffer_size
+ 2);
472 strcpy (name_buffer
, dir_name
);
473 if (! ISSLASH (dir_name
[strlen (dir_name
) - 1]))
474 strcat (name_buffer
, "/");
475 name_length
= strlen (name_buffer
);
477 if (deref_stat (dereference_option
, name_buffer
, &stat_data
))
479 stat_diag (name_buffer
);
481 children = CHANGED_CHILDREN;
488 directory
= procdir (name_buffer
, &stat_data
, device
, NO_CHILDREN
, false);
490 if (dirp
&& directory
->children
!= NO_CHILDREN
)
492 char *entry
; /* directory entry being scanned */
493 size_t entrylen
; /* length of directory entry */
495 makedumpdir (directory
, dirp
);
497 for (entry
= directory
->contents
;
498 (entrylen
= strlen (entry
)) != 0;
499 entry
+= entrylen
+ 1)
501 if (name_buffer_size
<= entrylen
- 1 + name_length
)
504 name_buffer_size
+= NAME_FIELD_SIZE
;
505 while (name_buffer_size
<= entrylen
- 1 + name_length
);
506 name_buffer
= xrealloc (name_buffer
, name_buffer_size
+ 2);
508 strcpy (name_buffer
+ name_length
, entry
+ 1);
510 if (excluded_name (name_buffer
))
514 if (deref_stat (dereference_option
, name_buffer
, &stat_data
))
516 stat_diag (name_buffer
);
521 if (S_ISDIR (stat_data
.st_mode
))
523 procdir (name_buffer
, &stat_data
, device
,
529 else if (one_file_system_option
&& device
!= stat_data
.st_dev
)
532 else if (*entry
== 'Y')
533 /* New entry, skip further checks */;
535 /* FIXME: if (S_ISHIDDEN (stat_data.st_mode))?? */
537 else if (OLDER_STAT_TIME (stat_data
, m
)
538 && (!after_date_option
539 || OLDER_STAT_TIME (stat_data
, c
)))
551 return directory
->contents
;
555 get_directory_contents (char *dir_name
, dev_t device
)
557 return scan_directory (dir_name
, device
);
562 obstack_code_rename (struct obstack
*stk
, char *from
, char *to
)
564 obstack_1grow (stk
, 'R');
565 obstack_grow (stk
, from
, strlen (from
) + 1);
566 obstack_1grow (stk
, 'T');
567 obstack_grow (stk
, to
, strlen (to
) + 1);
571 rename_handler (void *data
, void *proc_data
)
573 struct directory
*dir
= data
;
574 struct obstack
*stk
= proc_data
;
576 if (DIR_IS_RENAMED (dir
))
578 struct directory
*prev
, *p
;
580 /* Detect eventual cycles and clear DIRF_RENAMED flag, so these entries
581 are ignored when hit by this function next time.
582 If the chain forms a cycle, prev points to the entry DIR is renamed
583 from. In this case it still retains DIRF_RENAMED flag, which will be
584 cleared in the `else' branch below */
585 for (prev
= dir
; prev
&& prev
->orig
!= dir
; prev
= prev
->orig
)
586 DIR_CLEAR_FLAG (prev
, DIRF_RENAMED
);
590 for (p
= dir
; p
&& p
->orig
; p
= p
->orig
)
591 obstack_code_rename (stk
, p
->orig
->name
, p
->name
);
597 DIR_CLEAR_FLAG (prev
, DIRF_RENAMED
);
599 /* Break the cycle by using a temporary name for one of its
601 First, create a temp name stub entry. */
602 temp_name
= dir_name (dir
->name
);
603 obstack_1grow (stk
, 'X');
604 obstack_grow (stk
, temp_name
, strlen (temp_name
) + 1);
606 obstack_code_rename (stk
, dir
->name
, "");
608 for (p
= dir
; p
!= prev
; p
= p
->orig
)
609 obstack_code_rename (stk
, p
->orig
->name
, p
->name
);
611 obstack_code_rename (stk
, "", prev
->name
);
618 append_incremental_renames (const char *dump
)
623 if (directory_table
== NULL
)
629 size
= dumpdir_size (dump
) - 1;
630 obstack_grow (&stk
, dump
, size
);
635 hash_do_for_each (directory_table
, rename_handler
, &stk
);
636 if (obstack_object_size (&stk
) != size
)
638 obstack_1grow (&stk
, 0);
639 dump
= obstack_finish (&stk
);
642 obstack_free (&stk
, NULL
);
648 static FILE *listed_incremental_stream
;
650 /* Version of incremental format snapshots (directory files) used by this
651 tar. Currently it is supposed to be a single decimal number. 0 means
652 incremental snapshots as per tar version before 1.15.2.
654 The current tar version supports incremental versions from
655 0 up to TAR_INCREMENTAL_VERSION, inclusive.
656 It is able to create only snapshots of TAR_INCREMENTAL_VERSION */
658 #define TAR_INCREMENTAL_VERSION 2
660 /* Read incremental snapshot formats 0 and 1 */
662 read_incr_db_01 (int version
, const char *initbuf
)
675 if (getline (&buf
, &bufsize
, listed_incremental_stream
) <= 0)
677 read_error (listed_incremental_option
);
685 buf
= strdup (initbuf
);
686 bufsize
= strlen (buf
) + 1;
689 sec
= TYPE_MINIMUM (time_t);
692 u
= strtoumax (buf
, &ebuf
, 10);
693 if (!errno
&& TYPE_MAXIMUM (time_t) < u
)
695 if (errno
|| buf
== ebuf
)
696 ERROR ((0, errno
, "%s:%ld: %s",
697 quotearg_colon (listed_incremental_option
),
699 _("Invalid time stamp")));
704 if (version
== 1 && *ebuf
)
706 char const *buf_ns
= ebuf
+ 1;
708 u
= strtoumax (buf_ns
, &ebuf
, 10);
709 if (!errno
&& BILLION
<= u
)
711 if (errno
|| buf_ns
== ebuf
)
713 ERROR ((0, errno
, "%s:%ld: %s",
714 quotearg_colon (listed_incremental_option
),
716 _("Invalid time stamp")));
717 sec
= TYPE_MINIMUM (time_t);
724 /* pre-1 incremental format does not contain nanoseconds */
728 newer_mtime_option
.tv_sec
= sec
;
729 newer_mtime_option
.tv_nsec
= nsec
;
732 while (0 < (n
= getline (&buf
, &bufsize
, listed_incremental_stream
)))
736 bool nfs
= buf
[0] == '+';
737 char *strp
= buf
+ nfs
;
738 struct timespec mtime
;
742 if (buf
[n
- 1] == '\n')
748 u
= strtoumax (strp
, &ebuf
, 10);
749 if (!errno
&& TYPE_MAXIMUM (time_t) < u
)
751 if (errno
|| strp
== ebuf
|| *ebuf
!= ' ')
753 ERROR ((0, errno
, "%s:%ld: %s",
754 quotearg_colon (listed_incremental_option
), lineno
,
755 _("Invalid modification time (seconds)")));
763 u
= strtoumax (strp
, &ebuf
, 10);
764 if (!errno
&& BILLION
<= u
)
766 if (errno
|| strp
== ebuf
|| *ebuf
!= ' ')
768 ERROR ((0, errno
, "%s:%ld: %s",
769 quotearg_colon (listed_incremental_option
), lineno
,
770 _("Invalid modification time (nanoseconds)")));
776 mtime
.tv_nsec
= nsec
;
780 memset (&mtime
, 0, sizeof mtime
);
783 u
= strtoumax (strp
, &ebuf
, 10);
784 if (!errno
&& TYPE_MAXIMUM (dev_t
) < u
)
786 if (errno
|| strp
== ebuf
|| *ebuf
!= ' ')
788 ERROR ((0, errno
, "%s:%ld: %s",
789 quotearg_colon (listed_incremental_option
), lineno
,
790 _("Invalid device number")));
798 u
= strtoumax (strp
, &ebuf
, 10);
799 if (!errno
&& TYPE_MAXIMUM (ino_t
) < u
)
801 if (errno
|| strp
== ebuf
|| *ebuf
!= ' ')
803 ERROR ((0, errno
, "%s:%ld: %s",
804 quotearg_colon (listed_incremental_option
), lineno
,
805 _("Invalid inode number")));
813 unquote_string (strp
);
814 note_directory (strp
, mtime
, dev
, ino
, nfs
, false, NULL
);
819 /* Read a nul-terminated string from FP and store it in STK.
820 Store the number of bytes read (including nul terminator) in PCOUNT.
822 Return the last character read or EOF on end of file. */
824 read_obstack (FILE *fp
, struct obstack
*stk
, size_t *pcount
)
829 for (i
= 0, c
= getc (fp
); c
!= EOF
&& c
!= 0; c
= getc (fp
), i
++)
830 obstack_1grow (stk
, c
);
831 obstack_1grow (stk
, 0);
837 /* Read from file FP a nul-terminated string and convert it to
838 intmax_t. Return the resulting value in PVAL. Assume '-' has
841 Throw a fatal error if the string cannot be converted or if the
842 converted value is less than MIN_VAL. */
845 read_negative_num (FILE *fp
, intmax_t min_val
, intmax_t *pval
)
849 char buf
[INT_BUFSIZE_BOUND (intmax_t)];
853 for (i
= 1; ISDIGIT (c
= getc (fp
)); i
++)
855 if (i
== sizeof buf
- 1)
856 FATAL_ERROR ((0, 0, _("Field too long while reading snapshot file")));
863 FATAL_ERROR ((0, errno
, _("Read error in snapshot file")));
865 FATAL_ERROR ((0, 0, _("Unexpected EOF in snapshot file")));
870 *pval
= strtoimax (buf
, &ep
, 10);
871 if (c
|| errno
|| *pval
< min_val
)
872 FATAL_ERROR ((0, errno
, _("Unexpected field value in snapshot file")));
875 /* Read from file FP a nul-terminated string and convert it to
876 uintmax_t. Return the resulting value in PVAL. Assume C has
879 Throw a fatal error if the string cannot be converted or if the
880 converted value exceeds MAX_VAL.
882 Return the last character read or EOF on end of file. */
885 read_unsigned_num (int c
, FILE *fp
, uintmax_t max_val
, uintmax_t *pval
)
888 char buf
[UINTMAX_STRSIZE_BOUND
], *ep
;
890 for (i
= 0; ISDIGIT (c
); i
++)
892 if (i
== sizeof buf
- 1)
893 FATAL_ERROR ((0, 0, _("Field too long while reading snapshot file")));
901 FATAL_ERROR ((0, errno
, _("Read error in snapshot file")));
905 FATAL_ERROR ((0, 0, _("Unexpected EOF in snapshot file")));
910 *pval
= strtoumax (buf
, &ep
, 10);
911 if (c
|| errno
|| max_val
< *pval
)
912 FATAL_ERROR ((0, errno
, _("Unexpected field value in snapshot file")));
916 /* Read from file FP a nul-terminated string and convert it to
917 uintmax_t. Return the resulting value in PVAL.
919 Throw a fatal error if the string cannot be converted or if the
920 converted value exceeds MAX_VAL.
922 Return the last character read or EOF on end of file. */
925 read_num (FILE *fp
, uintmax_t max_val
, uintmax_t *pval
)
927 return read_unsigned_num (getc (fp
), fp
, max_val
, pval
);
930 /* Read from FP two NUL-terminated strings representing a struct
931 timespec. Return the resulting value in PVAL.
933 Throw a fatal error if the string cannot be converted. */
936 read_timespec (FILE *fp
, struct timespec
*pval
)
944 read_negative_num (fp
, TYPE_MINIMUM (time_t), &i
);
950 c
= read_unsigned_num (c
, fp
, TYPE_MAXIMUM (time_t), &u
);
954 if (c
|| read_num (fp
, BILLION
- 1, &u
))
955 FATAL_ERROR ((0, 0, "%s: %s",
956 quotearg_colon (listed_incremental_option
),
957 _("Unexpected EOF in snapshot file")));
961 /* Read incremental snapshot format 2 */
970 read_timespec (listed_incremental_stream
, &newer_mtime_option
);
974 struct timespec mtime
;
982 if (read_num (listed_incremental_stream
, 1, &u
))
983 return; /* Normal return */
987 read_timespec (listed_incremental_stream
, &mtime
);
989 if (read_num (listed_incremental_stream
, TYPE_MAXIMUM (dev_t
), &u
))
993 if (read_num (listed_incremental_stream
, TYPE_MAXIMUM (ino_t
), &u
))
997 if (read_obstack (listed_incremental_stream
, &stk
, &s
))
1000 name
= obstack_finish (&stk
);
1002 while (read_obstack (listed_incremental_stream
, &stk
, &s
) == 0 && s
> 1)
1004 if (getc (listed_incremental_stream
) != 0)
1005 FATAL_ERROR ((0, 0, "%s: %s",
1006 quotearg_colon (listed_incremental_option
),
1007 _("Missing record terminator")));
1009 content
= obstack_finish (&stk
);
1010 note_directory (name
, mtime
, dev
, ino
, nfs
, false, content
);
1011 obstack_free (&stk
, content
);
1013 FATAL_ERROR ((0, 0, "%s: %s",
1014 quotearg_colon (listed_incremental_option
),
1015 _("Unexpected EOF in snapshot file")));
1018 /* Read incremental snapshot file (directory file).
1019 If the file has older incremental version, make sure that it is processed
1020 correctly and that tar will use the most conservative backup method among
1021 possible alternatives (i.e. prefer ALL_CHILDREN over CHANGED_CHILDREN,
1022 etc.) This ensures that the snapshots are updated to the recent version
1023 without any loss of data. */
1025 read_directory_file (void)
1031 /* Open the file for both read and write. That way, we can write
1032 it later without having to reopen it, and don't have to worry if
1033 we chdir in the meantime. */
1034 fd
= open (listed_incremental_option
, O_RDWR
| O_CREAT
, MODE_RW
);
1037 open_error (listed_incremental_option
);
1041 listed_incremental_stream
= fdopen (fd
, "r+");
1042 if (! listed_incremental_stream
)
1044 open_error (listed_incremental_option
);
1049 if (0 < getline (&buf
, &bufsize
, listed_incremental_stream
))
1052 uintmax_t incremental_version
;
1054 if (strncmp (buf
, PACKAGE_NAME
, sizeof PACKAGE_NAME
- 1) == 0)
1056 ebuf
= buf
+ sizeof PACKAGE_NAME
- 1;
1058 ERROR((1, 0, _("Bad incremental file format")));
1059 for (; *ebuf
!= '-'; ebuf
++)
1061 ERROR((1, 0, _("Bad incremental file format")));
1063 incremental_version
= strtoumax (ebuf
+ 1, NULL
, 10);
1066 incremental_version
= 0;
1068 switch (incremental_version
)
1072 read_incr_db_01 (incremental_version
, buf
);
1075 case TAR_INCREMENTAL_VERSION
:
1080 ERROR ((1, 0, _("Unsupported incremental format version: %"PRIuMAX
),
1081 incremental_version
));
1086 if (ferror (listed_incremental_stream
))
1087 read_error (listed_incremental_option
);
1092 /* Output incremental data for the directory ENTRY to the file DATA.
1093 Return nonzero if successful, preserving errno on write failure. */
1095 write_directory_file_entry (void *entry
, void *data
)
1097 struct directory
const *directory
= entry
;
1100 if (DIR_IS_FOUND (directory
))
1102 char buf
[UINTMAX_STRSIZE_BOUND
];
1105 s
= DIR_IS_NFS (directory
) ? "1" : "0";
1106 fwrite (s
, 2, 1, fp
);
1107 s
= (TYPE_SIGNED (time_t)
1108 ? imaxtostr (directory
->mtime
.tv_sec
, buf
)
1109 : umaxtostr (directory
->mtime
.tv_sec
, buf
));
1110 fwrite (s
, strlen (s
) + 1, 1, fp
);
1111 s
= umaxtostr (directory
->mtime
.tv_nsec
, buf
);
1112 fwrite (s
, strlen (s
) + 1, 1, fp
);
1113 s
= umaxtostr (directory
->device_number
, buf
);
1114 fwrite (s
, strlen (s
) + 1, 1, fp
);
1115 s
= umaxtostr (directory
->inode_number
, buf
);
1116 fwrite (s
, strlen (s
) + 1, 1, fp
);
1118 fwrite (directory
->name
, strlen (directory
->name
) + 1, 1, fp
);
1119 if (directory
->contents
)
1122 for (p
= directory
->contents
; *p
; p
+= strlen (p
) + 1)
1124 if (strchr ("YND", *p
))
1125 fwrite (p
, strlen (p
) + 1, 1, fp
);
1128 fwrite ("\0\0", 2, 1, fp
);
1131 return ! ferror (fp
);
1135 write_directory_file (void)
1137 FILE *fp
= listed_incremental_stream
;
1138 char buf
[UINTMAX_STRSIZE_BOUND
];
1144 if (fseek (fp
, 0L, SEEK_SET
) != 0)
1145 seek_error (listed_incremental_option
);
1146 if (sys_truncate (fileno (fp
)) != 0)
1147 truncate_error (listed_incremental_option
);
1149 fprintf (fp
, "%s-%s-%d\n", PACKAGE_NAME
, PACKAGE_VERSION
,
1150 TAR_INCREMENTAL_VERSION
);
1152 s
= (TYPE_SIGNED (time_t)
1153 ? imaxtostr (start_time
.tv_sec
, buf
)
1154 : umaxtostr (start_time
.tv_sec
, buf
));
1155 fwrite (s
, strlen (s
) + 1, 1, fp
);
1156 s
= umaxtostr (start_time
.tv_nsec
, buf
);
1157 fwrite (s
, strlen (s
) + 1, 1, fp
);
1159 if (! ferror (fp
) && directory_table
)
1160 hash_do_for_each (directory_table
, write_directory_file_entry
, fp
);
1163 write_error (listed_incremental_option
);
1164 if (fclose (fp
) != 0)
1165 close_error (listed_incremental_option
);
1169 /* Restoration of incremental dumps. */
1172 get_gnu_dumpdir (struct tar_stat_info
*stat_info
)
1176 union block
*data_block
;
1180 size
= stat_info
->stat
.st_size
;
1182 archive_dir
= xmalloc (size
);
1185 set_next_block_after (current_header
);
1186 mv_begin (stat_info
);
1188 for (; size
> 0; size
-= copied
)
1190 mv_size_left (size
);
1191 data_block
= find_next_block ();
1193 ERROR ((1, 0, _("Unexpected EOF in archive")));
1194 copied
= available_space_after (data_block
);
1197 memcpy (to
, data_block
->buffer
, copied
);
1199 set_next_block_after ((union block
*)
1200 (data_block
->buffer
+ copied
- 1));
1205 stat_info
->dumpdir
= archive_dir
;
1206 stat_info
->skipped
= true; /* For skip_member() and friends
1207 to work correctly */
1210 /* Return T if STAT_INFO represents a dumpdir archive member.
1211 Note: can invalidate current_header. It happens if flush_archive()
1212 gets called within get_gnu_dumpdir() */
1214 is_dumpdir (struct tar_stat_info
*stat_info
)
1216 if (stat_info
->is_dumpdir
&& !stat_info
->dumpdir
)
1217 get_gnu_dumpdir (stat_info
);
1218 return stat_info
->is_dumpdir
;
1222 dumpdir_ok (char *dumpdir
)
1225 int has_tempdir
= 0;
1228 for (p
= dumpdir
; *p
; p
+= strlen (p
) + 1)
1230 if (expect
&& *p
!= expect
)
1233 _("Malformed dumpdir: expected '%c' but found %#3o"),
1243 _("Malformed dumpdir: 'X' duplicated")));
1256 _("Malformed dumpdir: empty name in 'R'")));
1269 _("Malformed dumpdir: 'T' not preceeded by 'R'")));
1272 if (p
[1] == 0 && !has_tempdir
)
1275 _("Malformed dumpdir: empty name in 'T'")));
1287 /* FIXME: bail out? */
1295 _("Malformed dumpdir: expected '%c' but found end of data"),
1301 WARN ((0, 0, _("Malformed dumpdir: 'X' never used")));
1306 /* Examine the directories under directory_name and delete any
1307 files that were not there at the time of the back-up. */
1309 try_purge_directory (char const *directory_name
)
1312 char *cur
, *arc
, *p
;
1313 char *temp_stub
= NULL
;
1315 if (!is_dumpdir (¤t_stat_info
))
1318 current_dir
= savedir (directory_name
);
1321 /* The directory doesn't exist now. It'll be created. In any
1322 case, we don't have to delete any files out of it. */
1325 /* Verify if dump directory is sane */
1326 if (!dumpdir_ok (current_stat_info
.dumpdir
))
1329 /* Process renames */
1330 for (arc
= current_stat_info
.dumpdir
; *arc
; arc
+= strlen (arc
) + 1)
1334 #define TEMP_DIR_TEMPLATE "tar.XXXXXX"
1335 size_t len
= strlen (arc
+ 1);
1336 temp_stub
= xrealloc (temp_stub
, len
+ 1 + sizeof TEMP_DIR_TEMPLATE
);
1337 memcpy (temp_stub
, arc
+ 1, len
);
1338 temp_stub
[len
] = '/';
1339 memcpy (temp_stub
+ len
+ 1, TEMP_DIR_TEMPLATE
,
1340 sizeof TEMP_DIR_TEMPLATE
);
1341 if (!mkdtemp (temp_stub
))
1344 _("Cannot create temporary directory using template %s"),
1345 quote (temp_stub
)));
1351 else if (*arc
== 'R')
1355 arc
+= strlen (arc
) + 1;
1363 if (!rename_directory (src
, dst
))
1367 /* FIXME: Make sure purge_directory(dst) will return
1376 /* Process deletes */
1378 for (cur
= current_dir
; *cur
; cur
+= strlen (cur
) + 1)
1384 p
= new_name (directory_name
, cur
);
1386 if (deref_stat (false, p
, &st
))
1388 if (errno
!= ENOENT
) /* FIXME: Maybe keep a list of renamed
1389 dirs and check it here? */
1392 WARN ((0, 0, _("%s: Not purging directory: unable to stat"),
1393 quotearg_colon (p
)));
1398 if (!(entry
= dumpdir_locate (current_stat_info
.dumpdir
, cur
))
1399 || (*entry
== 'D' && !S_ISDIR (st
.st_mode
))
1400 || (*entry
== 'Y' && S_ISDIR (st
.st_mode
)))
1402 if (one_file_system_option
&& st
.st_dev
!= root_device
)
1405 _("%s: directory is on a different device: not purging"),
1406 quotearg_colon (p
)));
1410 if (! interactive_option
|| confirm ("delete", p
))
1413 fprintf (stdlis
, _("%s: Deleting %s\n"),
1414 program_name
, quote (p
));
1415 if (! remove_any_file (p
, RECURSIVE_REMOVE_OPTION
))
1418 ERROR ((0, e
, _("%s: Cannot remove"), quotearg_colon (p
)));
1430 purge_directory (char const *directory_name
)
1432 if (!try_purge_directory (directory_name
))
1437 list_dumpdir (char *buffer
, size_t size
)
1450 fprintf (stdlis
, "%c", *buffer
);
1453 fprintf (stdlis
, " ");
1461 fputc ('\n', stdlis
);
1468 fputc (*buffer
, stdlis
);