1 /* GNU dump extensions to tar.
3 Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001,
4 2003, 2004, 2005, 2006 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 strcpy (directory
->name
, name
);
123 if (ISSLASH (directory
->name
[namelen
-1]))
124 directory
->name
[namelen
-1] = 0;
125 directory
->flags
= false;
129 /* Create and link a new directory entry for directory NAME, having a
130 device number DEV and an inode number INO, with NFS indicating
131 whether it is an NFS device and FOUND indicating whether we have
132 found that the directory exists. */
133 static struct directory
*
134 note_directory (char const *name
, struct timespec mtime
,
135 dev_t dev
, ino_t ino
, bool nfs
, bool found
, char *contents
)
137 struct directory
*directory
= make_directory (name
);
139 directory
->mtime
= mtime
;
140 directory
->device_number
= dev
;
141 directory
->inode_number
= ino
;
142 directory
->children
= CHANGED_CHILDREN
;
144 DIR_SET_FLAG (directory
, DIRF_NFS
);
146 DIR_SET_FLAG (directory
, DIRF_FOUND
);
149 size_t size
= dumpdir_size (contents
);
150 directory
->contents
= xmalloc (size
);
151 memcpy (directory
->contents
, contents
, size
);
154 directory
->contents
= NULL
;
156 if (! ((directory_table
157 || (directory_table
= hash_initialize (0, 0,
159 compare_directory_names
, 0)))
160 && hash_insert (directory_table
, directory
)))
163 if (! ((directory_meta_table
164 || (directory_meta_table
= hash_initialize (0, 0,
166 compare_directory_meta
,
168 && hash_insert (directory_meta_table
, directory
)))
174 /* Return a directory entry for a given file NAME, or zero if none found. */
175 static struct directory
*
176 find_directory (const char *name
)
178 if (! directory_table
)
182 struct directory
*dir
= make_directory (name
);
183 struct directory
*ret
= hash_lookup (directory_table
, dir
);
189 /* Return a directory entry for a given combination of device and inode
190 numbers, or zero if none found. */
191 static struct directory
*
192 find_directory_meta (dev_t dev
, ino_t ino
)
194 if (! directory_meta_table
)
198 struct directory
*dir
= make_directory ("");
199 dir
->device_number
= dev
;
200 dir
->inode_number
= ino
;
201 struct directory
*ret
= hash_lookup (directory_meta_table
, dir
);
208 update_parent_directory (const char *name
)
210 struct directory
*directory
;
211 char *p
, *name_buffer
;
214 directory
= find_directory (p
);
218 if (deref_stat (dereference_option
, p
, &st
) != 0)
221 directory
->mtime
= get_stat_mtime (&st
);
226 static struct directory
*
227 procdir (char *name_buffer
, struct stat
*stat_data
,
229 enum children children
,
232 struct directory
*directory
;
233 bool nfs
= NFS_FILE_STAT (*stat_data
);
236 if ((directory
= find_directory (name_buffer
)) != NULL
)
238 if (DIR_IS_INITED (directory
))
241 /* With NFS, the same file can have two different devices
242 if an NFS directory is mounted in multiple locations,
243 which is relatively common when automounting.
244 To avoid spurious incremental redumping of
245 directories, consider all NFS devices as equal,
246 relying on the i-node to establish differences. */
248 if (! (((DIR_IS_NFS (directory
) & nfs
)
249 || directory
->device_number
== stat_data
->st_dev
)
250 && directory
->inode_number
== stat_data
->st_ino
))
252 /* FIXME: find_directory_meta ignores nfs */
253 struct directory
*d
= find_directory_meta (stat_data
->st_dev
,
258 WARN ((0, 0, _("%s: Directory has been renamed from %s"),
259 quotearg_colon (name_buffer
),
260 quote_n (1, d
->name
)));
262 DIR_SET_FLAG (directory
, DIRF_RENAMED
);
263 directory
->children
= CHANGED_CHILDREN
;
268 WARN ((0, 0, _("%s: Directory has been renamed"),
269 quotearg_colon (name_buffer
)));
270 directory
->children
= ALL_CHILDREN
;
271 directory
->device_number
= stat_data
->st_dev
;
272 directory
->inode_number
= stat_data
->st_ino
;
275 DIR_SET_FLAG (directory
, DIRF_NFS
);
278 directory
->children
= CHANGED_CHILDREN
;
280 DIR_SET_FLAG (directory
, DIRF_FOUND
);
284 struct directory
*d
= find_directory_meta (stat_data
->st_dev
,
287 directory
= note_directory (name_buffer
,
288 get_stat_mtime(stat_data
),
298 WARN ((0, 0, _("%s: Directory has been renamed from %s"),
299 quotearg_colon (name_buffer
),
300 quote_n (1, d
->name
)));
302 DIR_SET_FLAG (directory
, DIRF_RENAMED
);
303 directory
->children
= CHANGED_CHILDREN
;
307 DIR_SET_FLAG (directory
, DIRF_NEW
);
309 WARN ((0, 0, _("%s: Directory is new"),
310 quotearg_colon (name_buffer
)));
311 directory
->children
=
312 (listed_incremental_option
313 || (OLDER_STAT_TIME (*stat_data
, m
)
314 || (after_date_option
315 && OLDER_STAT_TIME (*stat_data
, c
))))
321 /* If the directory is on another device and --one-file-system was given,
323 if (one_file_system_option
&& device
!= stat_data
->st_dev
324 /* ... except if it was explicitely given in the command line */
325 && !((np
= name_scan (name_buffer
, true)) && np
->explicit))
326 directory
->children
= NO_CHILDREN
;
327 else if (children
== ALL_CHILDREN
)
328 directory
->children
= ALL_CHILDREN
;
330 DIR_SET_FLAG (directory
, DIRF_INIT
);
335 /* Locate NAME in the dumpdir array DUMP.
336 Return pointer to the slot in the array, or NULL if not found */
338 dumpdir_locate (const char *dump
, const char *name
)
343 /* Ignore 'R' (rename) entries, since they break alphabetical ordering.
344 They normally do not occur in dumpdirs from the snapshot files,
345 but this function is also used by purge_directory, which operates
346 on a dumpdir from the archive, hence the need for this test. */
349 int rc
= strcmp (dump
+ 1, name
);
355 dump
+= strlen (dump
) + 1;
360 /* Return size in bytes of the dumpdir array P */
362 dumpdir_size (const char *p
)
368 size_t size
= strlen (p
) + 1;
376 compare_dirnames (const void *first
, const void *second
)
378 return strcmp (*(const char**)first
, *(const char**)second
);
381 /* Compare dumpdir array from DIRECTORY with directory listing DIR and
382 build a new dumpdir template.
384 DIR must be returned by a previous call to savedir().
386 File names in DIRECTORY->contents must be sorted
389 DIRECTORY->contents is replaced with the created template. Each entry is
390 prefixed with ' ' if it was present in DUMP and with 'Y' otherwise. */
393 makedumpdir (struct directory
*directory
, const char *dir
)
396 dirsize
, /* Number of elements in DIR */
397 len
; /* Length of DIR, including terminating nul */
400 char *new_dump
, *new_dump_ptr
;
403 if (directory
->children
== ALL_CHILDREN
)
405 else if (DIR_IS_RENAMED (directory
))
406 dump
= directory
->orig
->icontents
?
407 directory
->orig
->icontents
: directory
->orig
->contents
;
409 dump
= directory
->contents
;
411 /* Count the size of DIR and the number of elements it contains */
414 for (p
= dir
; *p
; p
+= strlen (p
) + 1, dirsize
++)
415 len
+= strlen (p
) + 2;
418 /* Create a sorted directory listing */
419 array
= xcalloc (dirsize
, sizeof array
[0]);
420 for (i
= 0, p
= dir
; *p
; p
+= strlen (p
) + 1, i
++)
423 qsort (array
, dirsize
, sizeof (array
[0]), compare_dirnames
);
425 /* Prepare space for new dumpdir */
426 new_dump
= xmalloc (len
);
427 new_dump_ptr
= new_dump
;
429 /* Fill in the dumpdir template */
430 for (i
= 0; i
< dirsize
; i
++)
432 const char *loc
= dumpdir_locate (dump
, array
[i
]);
435 *new_dump_ptr
++ = ' ';
436 dump
= loc
+ strlen (loc
) + 1;
439 *new_dump_ptr
++ = 'Y'; /* New entry */
441 /* Copy the file name */
442 for (p
= array
[i
]; (*new_dump_ptr
++ = *p
++); )
446 directory
->icontents
= directory
->contents
;
447 directory
->contents
= new_dump
;
451 /* Recursively scan the given directory. */
453 scan_directory (char *dir_name
, dev_t device
)
455 char *dirp
= savedir (dir_name
); /* for scanning directory */
456 char *name_buffer
; /* directory, `/', and directory member */
457 size_t name_buffer_size
; /* allocated size of name_buffer, minus 2 */
458 size_t name_length
; /* used length in name_buffer */
459 struct stat stat_data
;
460 struct directory
*directory
;
463 savedir_error (dir_name
);
465 name_buffer_size
= strlen (dir_name
) + NAME_FIELD_SIZE
;
466 name_buffer
= xmalloc (name_buffer_size
+ 2);
467 strcpy (name_buffer
, dir_name
);
468 if (! ISSLASH (dir_name
[strlen (dir_name
) - 1]))
469 strcat (name_buffer
, "/");
470 name_length
= strlen (name_buffer
);
472 if (deref_stat (dereference_option
, name_buffer
, &stat_data
))
474 stat_diag (name_buffer
);
476 children = CHANGED_CHILDREN;
483 directory
= procdir (name_buffer
, &stat_data
, device
, NO_CHILDREN
, false);
485 if (dirp
&& directory
->children
!= NO_CHILDREN
)
487 char *entry
; /* directory entry being scanned */
488 size_t entrylen
; /* length of directory entry */
490 makedumpdir (directory
, dirp
);
492 for (entry
= directory
->contents
;
493 (entrylen
= strlen (entry
)) != 0;
494 entry
+= entrylen
+ 1)
496 if (name_buffer_size
<= entrylen
- 1 + name_length
)
499 name_buffer_size
+= NAME_FIELD_SIZE
;
500 while (name_buffer_size
<= entrylen
- 1 + name_length
);
501 name_buffer
= xrealloc (name_buffer
, name_buffer_size
+ 2);
503 strcpy (name_buffer
+ name_length
, entry
+ 1);
505 if (excluded_name (name_buffer
))
509 if (deref_stat (dereference_option
, name_buffer
, &stat_data
))
511 stat_diag (name_buffer
);
516 if (S_ISDIR (stat_data
.st_mode
))
518 procdir (name_buffer
, &stat_data
, device
,
524 else if (one_file_system_option
&& device
!= stat_data
.st_dev
)
527 else if (*entry
== 'Y')
528 /* New entry, skip further checks */;
530 /* FIXME: if (S_ISHIDDEN (stat_data.st_mode))?? */
532 else if (OLDER_STAT_TIME (stat_data
, m
)
533 && (!after_date_option
534 || OLDER_STAT_TIME (stat_data
, c
)))
546 return directory
->contents
;
550 get_directory_contents (char *dir_name
, dev_t device
)
552 return scan_directory (dir_name
, device
);
557 try_pos (char *name
, int pos
, const char *dumpdir
)
560 static char namechars
[] =
561 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
564 for (i
= 0; i
< sizeof namechars
; i
++)
566 name
[pos
] = namechars
[i
];
567 if (!dumpdir_locate (dumpdir
, name
)
568 || try_pos (name
, pos
-1, dumpdir
))
576 create_temp_name (char *name
, const char *dumpdir
)
578 size_t pos
= strlen (name
) - 6;
579 return try_pos (name
+ pos
, 5, dumpdir
);
583 make_tmp_dir_name (const char *name
)
585 char *dirname
= dir_name (name
);
586 char *tmp_name
= NULL
;
587 struct directory
*dir
= find_directory (dirname
);
589 tmp_name
= new_name (dirname
, "000000");
590 if (!create_temp_name (tmp_name
, dir
? dir
->contents
: NULL
))
600 obstack_code_rename (struct obstack
*stk
, char *from
, char *to
)
602 obstack_1grow (stk
, 'R');
603 obstack_grow (stk
, from
, strlen (from
) + 1);
604 obstack_1grow (stk
, 'T');
605 obstack_grow (stk
, to
, strlen (to
) + 1);
609 rename_handler (void *data
, void *proc_data
)
611 struct directory
*dir
= data
;
612 struct obstack
*stk
= proc_data
;
614 if (DIR_IS_RENAMED (dir
))
616 struct directory
*prev
, *p
;
618 /* Detect eventual cycles and clear DIRF_RENAMED flag, so this entries
619 are ignored when hit by this function next time.
620 If the chain forms a cycle, prev points to the entry DIR is renamed
621 from. In this case it still retains DIRF_RENAMED flag, which will be
622 cleared in the `else' branch below */
623 for (prev
= dir
; prev
&& prev
->orig
!= dir
; prev
= prev
->orig
)
624 DIR_CLEAR_FLAG (prev
, DIRF_RENAMED
);
628 for (p
= dir
; p
&& p
->orig
; p
= p
->orig
)
629 obstack_code_rename (stk
, p
->orig
->name
, p
->name
);
635 DIR_CLEAR_FLAG (prev
, DIRF_RENAMED
);
637 /* Break the cycle by using a temporary name for one of its
639 FIXME: Leave the choice of the name to the extractor. */
640 temp_name
= make_tmp_dir_name (dir
->name
);
641 obstack_code_rename (stk
, dir
->name
, temp_name
);
643 for (p
= dir
; p
!= prev
; p
= p
->orig
)
644 obstack_code_rename (stk
, p
->orig
->name
, p
->name
);
646 obstack_code_rename (stk
, temp_name
, prev
->name
);
653 append_incremental_renames (const char *dump
)
658 if (directory_table
== NULL
)
664 size
= dumpdir_size (dump
) - 1;
665 obstack_grow (&stk
, dump
, size
);
670 hash_do_for_each (directory_table
, rename_handler
, &stk
);
671 if (obstack_object_size (&stk
) != size
)
673 obstack_1grow (&stk
, 0);
674 dump
= obstack_finish (&stk
);
677 obstack_free (&stk
, NULL
);
683 static FILE *listed_incremental_stream
;
685 /* Version of incremental format snapshots (directory files) used by this
686 tar. Currently it is supposed to be a single decimal number. 0 means
687 incremental snapshots as per tar version before 1.15.2.
689 The current tar version supports incremental versions from
690 0 up to TAR_INCREMENTAL_VERSION, inclusive.
691 It is able to create only snapshots of TAR_INCREMENTAL_VERSION */
693 #define TAR_INCREMENTAL_VERSION 2
695 /* Read incremental snapshot formats 0 and 1 */
697 read_incr_db_01 (int version
, const char *initbuf
)
709 if (getline (&buf
, &bufsize
, listed_incremental_stream
) <= 0)
711 read_error (listed_incremental_option
);
719 buf
= strdup (initbuf
);
720 bufsize
= strlen (buf
) + 1;
723 t
= u
= (errno
= 0, strtoumax (buf
, &ebuf
, 10));
724 if (buf
== ebuf
|| (u
== 0 && errno
== EINVAL
))
725 ERROR ((0, 0, "%s:%ld: %s",
726 quotearg_colon (listed_incremental_option
),
728 _("Invalid time stamp")));
730 ERROR ((0, 0, "%s:%ld: %s",
731 quotearg_colon (listed_incremental_option
),
733 _("Time stamp out of range")));
734 else if (version
== 1)
736 newer_mtime_option
.tv_sec
= t
;
738 t
= u
= (errno
= 0, strtoumax (buf
, &ebuf
, 10));
739 if (buf
== ebuf
|| (u
== 0 && errno
== EINVAL
))
740 ERROR ((0, 0, "%s:%ld: %s",
741 quotearg_colon (listed_incremental_option
),
743 _("Invalid time stamp")));
745 ERROR ((0, 0, "%s:%ld: %s",
746 quotearg_colon (listed_incremental_option
),
748 _("Time stamp out of range")));
749 newer_mtime_option
.tv_nsec
= t
;
753 /* pre-1 incremental format does not contain nanoseconds */
754 newer_mtime_option
.tv_sec
= t
;
755 newer_mtime_option
.tv_nsec
= 0;
758 while (0 < (n
= getline (&buf
, &bufsize
, listed_incremental_stream
)))
762 bool nfs
= buf
[0] == '+';
763 char *strp
= buf
+ nfs
;
764 struct timespec mtime
;
768 if (buf
[n
- 1] == '\n')
774 mtime
.tv_sec
= u
= strtoumax (strp
, &ebuf
, 10);
775 if (!isspace (*ebuf
))
776 ERROR ((0, 0, "%s:%ld: %s",
777 quotearg_colon (listed_incremental_option
), lineno
,
778 _("Invalid modification time (seconds)")));
779 else if (mtime
.tv_sec
!= u
)
780 ERROR ((0, 0, "%s:%ld: %s",
781 quotearg_colon (listed_incremental_option
), lineno
,
782 _("Modification time (seconds) out of range")));
786 mtime
.tv_nsec
= u
= strtoumax (strp
, &ebuf
, 10);
787 if (!isspace (*ebuf
))
788 ERROR ((0, 0, "%s:%ld: %s",
789 quotearg_colon (listed_incremental_option
), lineno
,
790 _("Invalid modification time (nanoseconds)")));
791 else if (mtime
.tv_nsec
!= u
)
792 ERROR ((0, 0, "%s:%ld: %s",
793 quotearg_colon (listed_incremental_option
), lineno
,
794 _("Modification time (nanoseconds) out of range")));
798 memset (&mtime
, 0, sizeof mtime
);
801 dev
= u
= strtoumax (strp
, &ebuf
, 10);
802 if (!isspace (*ebuf
))
803 ERROR ((0, 0, "%s:%ld: %s",
804 quotearg_colon (listed_incremental_option
), lineno
,
805 _("Invalid device number")));
807 ERROR ((0, 0, "%s:%ld: %s",
808 quotearg_colon (listed_incremental_option
), lineno
,
809 _("Device number out of range")));
813 ino
= u
= strtoumax (strp
, &ebuf
, 10);
814 if (!isspace (*ebuf
))
815 ERROR ((0, 0, "%s:%ld: %s",
816 quotearg_colon (listed_incremental_option
), lineno
,
817 _("Invalid inode number")));
819 ERROR ((0, 0, "%s:%ld: %s",
820 quotearg_colon (listed_incremental_option
), lineno
,
821 _("Inode number out of range")));
825 unquote_string (strp
);
826 note_directory (strp
, mtime
, dev
, ino
, nfs
, false, NULL
);
831 /* Read a nul-terminated string from FP and store it in STK.
832 Store the number of bytes read (including nul terminator) in PCOUNT.
834 Return the last character read or EOF on end of file. */
836 read_obstack (FILE *fp
, struct obstack
*stk
, size_t *pcount
)
841 for (i
= 0, c
= getc (fp
); c
!= EOF
&& c
!= 0; c
= getc (fp
), i
++)
842 obstack_1grow (stk
, c
);
843 obstack_1grow (stk
, 0);
849 /* Read from file FP a nul-terminated string and convert it to
850 uintmax_t. Return the resulting value in PVAL.
852 Throw fatal error if the string cannot be converted.
854 Return the last character read or EOF on end of file. */
857 read_num (FILE *fp
, uintmax_t *pval
)
861 char buf
[UINTMAX_STRSIZE_BOUND
], *ep
;
863 for (i
= 0, c
= getc (fp
); c
!= EOF
&& c
!= 0; c
= getc (fp
), i
++)
865 if (i
== sizeof buf
- 1)
866 FATAL_ERROR ((0, 0, _("Field too long while reading snapshot file")));
870 *pval
= strtoumax (buf
, &ep
, 10);
872 FATAL_ERROR ((0, 0, _("Unexpected field value in snapshot file")));
876 /* Read incremental snapshot format 2 */
885 if (read_num (listed_incremental_stream
, &u
))
886 FATAL_ERROR ((0, 0, "%s: %s",
887 quotearg_colon (listed_incremental_option
),
888 _("Error reading time stamp")));
889 newer_mtime_option
.tv_sec
= u
;
890 if (newer_mtime_option
.tv_sec
!= u
)
891 FATAL_ERROR ((0, 0, "%s: %s",
892 quotearg_colon (listed_incremental_option
),
893 _("Time stamp out of range")));
895 if (read_num (listed_incremental_stream
, &u
))
896 FATAL_ERROR ((0, 0, "%s: %s",
897 quotearg_colon (listed_incremental_option
),
898 _("Error reading time stamp")));
899 newer_mtime_option
.tv_nsec
= u
;
900 if (newer_mtime_option
.tv_nsec
!= u
)
901 FATAL_ERROR ((0, 0, "%s: %s",
902 quotearg_colon (listed_incremental_option
),
903 _("Time stamp out of range")));
907 struct timespec mtime
;
915 if (read_num (listed_incremental_stream
, &u
))
916 return; /* Normal return */
920 if (read_num (listed_incremental_stream
, &u
))
923 if (mtime
.tv_sec
!= u
)
924 FATAL_ERROR ((0, 0, "%s: %s",
925 quotearg_colon (listed_incremental_option
),
926 _("Modification time (seconds) out of range")));
928 if (read_num (listed_incremental_stream
, &u
))
931 if (mtime
.tv_nsec
!= u
)
932 FATAL_ERROR ((0, 0, "%s: %s",
933 quotearg_colon (listed_incremental_option
),
934 _("Modification time (nanoseconds) out of range")));
936 if (read_num (listed_incremental_stream
, &u
))
940 FATAL_ERROR ((0, 0, "%s: %s",
941 quotearg_colon (listed_incremental_option
),
942 _("Device number out of range")));
944 if (read_num (listed_incremental_stream
, &u
))
948 FATAL_ERROR ((0, 0, "%s: %s",
949 quotearg_colon (listed_incremental_option
),
950 _("Inode number out of range")));
952 if (read_obstack (listed_incremental_stream
, &stk
, &s
))
955 name
= obstack_finish (&stk
);
957 while (read_obstack (listed_incremental_stream
, &stk
, &s
) == 0 && s
> 1)
959 if (getc (listed_incremental_stream
) != 0)
960 FATAL_ERROR ((0, 0, "%s: %s",
961 quotearg_colon (listed_incremental_option
),
962 _("Missing record terminator")));
964 content
= obstack_finish (&stk
);
965 note_directory (name
, mtime
, dev
, ino
, nfs
, false, content
);
966 obstack_free (&stk
, content
);
968 FATAL_ERROR ((0, 0, "%s: %s",
969 quotearg_colon (listed_incremental_option
),
970 _("Unexpected EOF")));
973 /* Read incremental snapshot file (directory file).
974 If the file has older incremental version, make sure that it is processed
975 correctly and that tar will use the most conservative backup method among
976 possible alternatives (i.e. prefer ALL_CHILDREN over CHANGED_CHILDREN,
977 etc.) This ensures that the snapshots are updated to the recent version
978 without any loss of data. */
980 read_directory_file (void)
987 /* Open the file for both read and write. That way, we can write
988 it later without having to reopen it, and don't have to worry if
989 we chdir in the meantime. */
990 fd
= open (listed_incremental_option
, O_RDWR
| O_CREAT
, MODE_RW
);
993 open_error (listed_incremental_option
);
997 listed_incremental_stream
= fdopen (fd
, "r+");
998 if (! listed_incremental_stream
)
1000 open_error (listed_incremental_option
);
1005 if (0 < getline (&buf
, &bufsize
, listed_incremental_stream
))
1008 int incremental_version
;
1010 if (strncmp (buf
, PACKAGE_NAME
, sizeof PACKAGE_NAME
- 1) == 0)
1012 ebuf
= buf
+ sizeof PACKAGE_NAME
- 1;
1014 ERROR((1, 0, _("Bad incremental file format")));
1015 for (; *ebuf
!= '-'; ebuf
++)
1017 ERROR((1, 0, _("Bad incremental file format")));
1019 incremental_version
= (errno
= 0, strtoumax (ebuf
+1, &ebuf
, 10));
1022 incremental_version
= 0;
1024 switch (incremental_version
)
1028 read_incr_db_01 (incremental_version
, buf
);
1031 case TAR_INCREMENTAL_VERSION
:
1036 ERROR ((1, 0, _("Unsupported incremental format version: %d"),
1037 incremental_version
));
1042 if (ferror (listed_incremental_stream
))
1043 read_error (listed_incremental_option
);
1048 /* Output incremental data for the directory ENTRY to the file DATA.
1049 Return nonzero if successful, preserving errno on write failure. */
1051 write_directory_file_entry (void *entry
, void *data
)
1053 struct directory
const *directory
= entry
;
1056 if (DIR_IS_FOUND (directory
))
1058 char buf
[UINTMAX_STRSIZE_BOUND
];
1061 s
= DIR_IS_NFS (directory
) ? "1" : "0";
1062 fwrite (s
, 2, 1, fp
);
1063 s
= umaxtostr (directory
->mtime
.tv_sec
, buf
);
1064 fwrite (s
, strlen (s
) + 1, 1, fp
);
1065 s
= umaxtostr (directory
->mtime
.tv_nsec
, buf
);
1066 fwrite (s
, strlen (s
) + 1, 1, fp
);
1067 s
= umaxtostr (directory
->device_number
, buf
);
1068 fwrite (s
, strlen (s
) + 1, 1, fp
);
1069 s
= umaxtostr (directory
->inode_number
, buf
);
1070 fwrite (s
, strlen (s
) + 1, 1, fp
);
1072 fwrite (directory
->name
, strlen (directory
->name
) + 1, 1, fp
);
1073 if (directory
->contents
)
1076 for (p
= directory
->contents
; *p
; p
+= strlen (p
) + 1)
1078 if (strchr ("YND", *p
))
1079 fwrite (p
, strlen (p
) + 1, 1, fp
);
1082 fwrite ("\0\0", 2, 1, fp
);
1085 return ! ferror (fp
);
1089 write_directory_file (void)
1091 FILE *fp
= listed_incremental_stream
;
1092 char buf
[UINTMAX_STRSIZE_BOUND
];
1098 if (fseek (fp
, 0L, SEEK_SET
) != 0)
1099 seek_error (listed_incremental_option
);
1100 if (sys_truncate (fileno (fp
)) != 0)
1101 truncate_error (listed_incremental_option
);
1103 fprintf (fp
, "%s-%s-%d\n", PACKAGE_NAME
, PACKAGE_VERSION
,
1104 TAR_INCREMENTAL_VERSION
);
1106 s
= umaxtostr (start_time
.tv_sec
, buf
);
1107 fwrite (s
, strlen (s
) + 1, 1, fp
);
1108 s
= umaxtostr (start_time
.tv_nsec
, buf
);
1109 fwrite (s
, strlen (s
) + 1, 1, fp
);
1111 if (! ferror (fp
) && directory_table
)
1112 hash_do_for_each (directory_table
, write_directory_file_entry
, fp
);
1115 write_error (listed_incremental_option
);
1116 if (fclose (fp
) != 0)
1117 close_error (listed_incremental_option
);
1121 /* Restoration of incremental dumps. */
1124 get_gnu_dumpdir (struct tar_stat_info
*stat_info
)
1128 union block
*data_block
;
1132 size
= stat_info
->stat
.st_size
;
1134 archive_dir
= xmalloc (size
);
1137 set_next_block_after (current_header
);
1138 mv_begin (stat_info
);
1140 for (; size
> 0; size
-= copied
)
1142 mv_size_left (size
);
1143 data_block
= find_next_block ();
1145 ERROR ((1, 0, _("Unexpected EOF in archive")));
1146 copied
= available_space_after (data_block
);
1149 memcpy (to
, data_block
->buffer
, copied
);
1151 set_next_block_after ((union block
*)
1152 (data_block
->buffer
+ copied
- 1));
1157 stat_info
->dumpdir
= archive_dir
;
1158 stat_info
->skipped
= true; /* For skip_member() and friends
1159 to work correctly */
1162 /* Return T if STAT_INFO represents a dumpdir archive member.
1163 Note: can invalidate current_header. It happens if flush_archive()
1164 gets called within get_gnu_dumpdir() */
1166 is_dumpdir (struct tar_stat_info
*stat_info
)
1168 if (stat_info
->is_dumpdir
&& !stat_info
->dumpdir
)
1169 get_gnu_dumpdir (stat_info
);
1170 return stat_info
->is_dumpdir
;
1173 /* Examine the directories under directory_name and delete any
1174 files that were not there at the time of the back-up. */
1176 purge_directory (char const *directory_name
)
1179 char *cur
, *arc
, *p
;
1181 if (!is_dumpdir (¤t_stat_info
))
1187 current_dir
= savedir (directory_name
);
1191 /* The directory doesn't exist now. It'll be created. In any
1192 case, we don't have to delete any files out of it. */
1198 /* Process renames */
1199 for (arc
= current_stat_info
.dumpdir
; *arc
; arc
+= strlen (arc
) + 1)
1205 arc
+= strlen (arc
) + 1;
1208 if (!rename_directory (src
, dst
))
1211 /* FIXME: Make sure purge_directory(dst) will return
1218 /* Process deletes */
1220 for (cur
= current_dir
; *cur
; cur
+= strlen (cur
) + 1)
1222 if (!dumpdir_locate (current_stat_info
.dumpdir
, cur
))
1227 p
= new_name (directory_name
, cur
);
1229 if (deref_stat (false, p
, &st
))
1231 if (errno
!= ENOENT
) /* FIXME: Maybe keep a list of renamed
1232 dirs and check it here? */
1235 WARN ((0, 0, _("%s: Not purging directory: unable to stat"),
1236 quotearg_colon (p
)));
1240 else if (one_file_system_option
&& st
.st_dev
!= root_device
)
1243 _("%s: directory is on a different device: not purging"),
1244 quotearg_colon (p
)));
1248 if (! interactive_option
|| confirm ("delete", p
))
1251 fprintf (stdlis
, _("%s: Deleting %s\n"),
1252 program_name
, quote (p
));
1253 if (! remove_any_file (p
, RECURSIVE_REMOVE_OPTION
))
1256 ERROR ((0, e
, _("%s: Cannot remove"), quotearg_colon (p
)));
1267 list_dumpdir (char *buffer
, size_t size
)
1278 fprintf (stdlis
, "%c ", *buffer
);
1284 fputc ('\n', stdlis
);
1290 fputc (*buffer
, stdlis
);