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 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 return strcmp (*(const char**)first
, *(const char**)second
);
384 /* Compare dumpdir array from DIRECTORY with directory listing DIR and
385 build a new dumpdir template.
387 DIR must be returned by a previous call to savedir().
389 File names in DIRECTORY->contents must be sorted
392 DIRECTORY->contents is replaced with the created template. Each entry is
393 prefixed with ' ' if it was present in DUMP and with 'Y' otherwise. */
396 makedumpdir (struct directory
*directory
, const char *dir
)
399 dirsize
, /* Number of elements in DIR */
400 len
; /* Length of DIR, including terminating nul */
403 char *new_dump
, *new_dump_ptr
;
406 if (directory
->children
== ALL_CHILDREN
)
408 else if (DIR_IS_RENAMED (directory
))
409 dump
= directory
->orig
->icontents
?
410 directory
->orig
->icontents
: directory
->orig
->contents
;
412 dump
= directory
->contents
;
414 /* Count the size of DIR and the number of elements it contains */
417 for (p
= dir
; *p
; p
+= strlen (p
) + 1, dirsize
++)
418 len
+= strlen (p
) + 2;
421 /* Create a sorted directory listing */
422 array
= xcalloc (dirsize
, sizeof array
[0]);
423 for (i
= 0, p
= dir
; *p
; p
+= strlen (p
) + 1, i
++)
426 qsort (array
, dirsize
, sizeof (array
[0]), compare_dirnames
);
428 /* Prepare space for new dumpdir */
429 new_dump
= xmalloc (len
);
430 new_dump_ptr
= new_dump
;
432 /* Fill in the dumpdir template */
433 for (i
= 0; i
< dirsize
; i
++)
435 const char *loc
= dumpdir_locate (dump
, array
[i
]);
438 *new_dump_ptr
++ = ' ';
439 dump
= loc
+ strlen (loc
) + 1;
442 *new_dump_ptr
++ = 'Y'; /* New entry */
444 /* Copy the file name */
445 for (p
= array
[i
]; (*new_dump_ptr
++ = *p
++); )
449 directory
->icontents
= directory
->contents
;
450 directory
->contents
= new_dump
;
454 /* Recursively scan the given directory. */
456 scan_directory (char *dir_name
, dev_t device
)
458 char *dirp
= savedir (dir_name
); /* for scanning directory */
459 char *name_buffer
; /* directory, `/', and directory member */
460 size_t name_buffer_size
; /* allocated size of name_buffer, minus 2 */
461 size_t name_length
; /* used length in name_buffer */
462 struct stat stat_data
;
463 struct directory
*directory
;
466 savedir_error (dir_name
);
468 name_buffer_size
= strlen (dir_name
) + NAME_FIELD_SIZE
;
469 name_buffer
= xmalloc (name_buffer_size
+ 2);
470 strcpy (name_buffer
, dir_name
);
471 if (! ISSLASH (dir_name
[strlen (dir_name
) - 1]))
472 strcat (name_buffer
, "/");
473 name_length
= strlen (name_buffer
);
475 if (deref_stat (dereference_option
, name_buffer
, &stat_data
))
477 stat_diag (name_buffer
);
479 children = CHANGED_CHILDREN;
486 directory
= procdir (name_buffer
, &stat_data
, device
, NO_CHILDREN
, false);
488 if (dirp
&& directory
->children
!= NO_CHILDREN
)
490 char *entry
; /* directory entry being scanned */
491 size_t entrylen
; /* length of directory entry */
493 makedumpdir (directory
, dirp
);
495 for (entry
= directory
->contents
;
496 (entrylen
= strlen (entry
)) != 0;
497 entry
+= entrylen
+ 1)
499 if (name_buffer_size
<= entrylen
- 1 + name_length
)
502 name_buffer_size
+= NAME_FIELD_SIZE
;
503 while (name_buffer_size
<= entrylen
- 1 + name_length
);
504 name_buffer
= xrealloc (name_buffer
, name_buffer_size
+ 2);
506 strcpy (name_buffer
+ name_length
, entry
+ 1);
508 if (excluded_name (name_buffer
))
512 if (deref_stat (dereference_option
, name_buffer
, &stat_data
))
514 stat_diag (name_buffer
);
519 if (S_ISDIR (stat_data
.st_mode
))
521 procdir (name_buffer
, &stat_data
, device
,
527 else if (one_file_system_option
&& device
!= stat_data
.st_dev
)
530 else if (*entry
== 'Y')
531 /* New entry, skip further checks */;
533 /* FIXME: if (S_ISHIDDEN (stat_data.st_mode))?? */
535 else if (OLDER_STAT_TIME (stat_data
, m
)
536 && (!after_date_option
537 || OLDER_STAT_TIME (stat_data
, c
)))
549 return directory
->contents
;
553 get_directory_contents (char *dir_name
, dev_t device
)
555 return scan_directory (dir_name
, device
);
560 obstack_code_rename (struct obstack
*stk
, char *from
, char *to
)
562 obstack_1grow (stk
, 'R');
563 obstack_grow (stk
, from
, strlen (from
) + 1);
564 obstack_1grow (stk
, 'T');
565 obstack_grow (stk
, to
, strlen (to
) + 1);
569 rename_handler (void *data
, void *proc_data
)
571 struct directory
*dir
= data
;
572 struct obstack
*stk
= proc_data
;
574 if (DIR_IS_RENAMED (dir
))
576 struct directory
*prev
, *p
;
578 /* Detect eventual cycles and clear DIRF_RENAMED flag, so this entries
579 are ignored when hit by this function next time.
580 If the chain forms a cycle, prev points to the entry DIR is renamed
581 from. In this case it still retains DIRF_RENAMED flag, which will be
582 cleared in the `else' branch below */
583 for (prev
= dir
; prev
&& prev
->orig
!= dir
; prev
= prev
->orig
)
584 DIR_CLEAR_FLAG (prev
, DIRF_RENAMED
);
588 for (p
= dir
; p
&& p
->orig
; p
= p
->orig
)
589 obstack_code_rename (stk
, p
->orig
->name
, p
->name
);
595 DIR_CLEAR_FLAG (prev
, DIRF_RENAMED
);
597 /* Break the cycle by using a temporary name for one of its
599 First, create a temp name stub entry. */
600 temp_name
= dir_name (dir
->name
);
601 obstack_1grow (stk
, 'X');
602 obstack_grow (stk
, temp_name
, strlen (temp_name
) + 1);
604 obstack_code_rename (stk
, dir
->name
, "");
606 for (p
= dir
; p
!= prev
; p
= p
->orig
)
607 obstack_code_rename (stk
, p
->orig
->name
, p
->name
);
609 obstack_code_rename (stk
, "", prev
->name
);
616 append_incremental_renames (const char *dump
)
621 if (directory_table
== NULL
)
627 size
= dumpdir_size (dump
) - 1;
628 obstack_grow (&stk
, dump
, size
);
633 hash_do_for_each (directory_table
, rename_handler
, &stk
);
634 if (obstack_object_size (&stk
) != size
)
636 obstack_1grow (&stk
, 0);
637 dump
= obstack_finish (&stk
);
640 obstack_free (&stk
, NULL
);
646 static FILE *listed_incremental_stream
;
648 /* Version of incremental format snapshots (directory files) used by this
649 tar. Currently it is supposed to be a single decimal number. 0 means
650 incremental snapshots as per tar version before 1.15.2.
652 The current tar version supports incremental versions from
653 0 up to TAR_INCREMENTAL_VERSION, inclusive.
654 It is able to create only snapshots of TAR_INCREMENTAL_VERSION */
656 #define TAR_INCREMENTAL_VERSION 2
658 /* Read incremental snapshot formats 0 and 1 */
660 read_incr_db_01 (int version
, const char *initbuf
)
672 if (getline (&buf
, &bufsize
, listed_incremental_stream
) <= 0)
674 read_error (listed_incremental_option
);
682 buf
= strdup (initbuf
);
683 bufsize
= strlen (buf
) + 1;
686 t
= u
= (errno
= 0, strtoumax (buf
, &ebuf
, 10));
687 if (buf
== ebuf
|| (u
== 0 && errno
== EINVAL
))
688 ERROR ((0, 0, "%s:%ld: %s",
689 quotearg_colon (listed_incremental_option
),
691 _("Invalid time stamp")));
693 ERROR ((0, 0, "%s:%ld: %s",
694 quotearg_colon (listed_incremental_option
),
696 _("Time stamp out of range")));
697 else if (version
== 1)
699 newer_mtime_option
.tv_sec
= t
;
701 t
= u
= (errno
= 0, strtoumax (buf
, &ebuf
, 10));
702 if (buf
== ebuf
|| (u
== 0 && errno
== EINVAL
))
703 ERROR ((0, 0, "%s:%ld: %s",
704 quotearg_colon (listed_incremental_option
),
706 _("Invalid time stamp")));
708 ERROR ((0, 0, "%s:%ld: %s",
709 quotearg_colon (listed_incremental_option
),
711 _("Time stamp out of range")));
712 newer_mtime_option
.tv_nsec
= t
;
716 /* pre-1 incremental format does not contain nanoseconds */
717 newer_mtime_option
.tv_sec
= t
;
718 newer_mtime_option
.tv_nsec
= 0;
721 while (0 < (n
= getline (&buf
, &bufsize
, listed_incremental_stream
)))
725 bool nfs
= buf
[0] == '+';
726 char *strp
= buf
+ nfs
;
727 struct timespec mtime
;
731 if (buf
[n
- 1] == '\n')
737 mtime
.tv_sec
= u
= strtoumax (strp
, &ebuf
, 10);
738 if (!isspace (*ebuf
))
739 ERROR ((0, 0, "%s:%ld: %s",
740 quotearg_colon (listed_incremental_option
), lineno
,
741 _("Invalid modification time (seconds)")));
742 else if (mtime
.tv_sec
!= u
)
743 ERROR ((0, 0, "%s:%ld: %s",
744 quotearg_colon (listed_incremental_option
), lineno
,
745 _("Modification time (seconds) out of range")));
749 mtime
.tv_nsec
= u
= strtoumax (strp
, &ebuf
, 10);
750 if (!isspace (*ebuf
))
751 ERROR ((0, 0, "%s:%ld: %s",
752 quotearg_colon (listed_incremental_option
), lineno
,
753 _("Invalid modification time (nanoseconds)")));
754 else if (mtime
.tv_nsec
!= u
)
755 ERROR ((0, 0, "%s:%ld: %s",
756 quotearg_colon (listed_incremental_option
), lineno
,
757 _("Modification time (nanoseconds) out of range")));
761 memset (&mtime
, 0, sizeof mtime
);
764 dev
= u
= strtoumax (strp
, &ebuf
, 10);
765 if (!isspace (*ebuf
))
766 ERROR ((0, 0, "%s:%ld: %s",
767 quotearg_colon (listed_incremental_option
), lineno
,
768 _("Invalid device number")));
770 ERROR ((0, 0, "%s:%ld: %s",
771 quotearg_colon (listed_incremental_option
), lineno
,
772 _("Device number out of range")));
776 ino
= u
= strtoumax (strp
, &ebuf
, 10);
777 if (!isspace (*ebuf
))
778 ERROR ((0, 0, "%s:%ld: %s",
779 quotearg_colon (listed_incremental_option
), lineno
,
780 _("Invalid inode number")));
782 ERROR ((0, 0, "%s:%ld: %s",
783 quotearg_colon (listed_incremental_option
), lineno
,
784 _("Inode number out of range")));
788 unquote_string (strp
);
789 note_directory (strp
, mtime
, dev
, ino
, nfs
, false, NULL
);
794 /* Read a nul-terminated string from FP and store it in STK.
795 Store the number of bytes read (including nul terminator) in PCOUNT.
797 Return the last character read or EOF on end of file. */
799 read_obstack (FILE *fp
, struct obstack
*stk
, size_t *pcount
)
804 for (i
= 0, c
= getc (fp
); c
!= EOF
&& c
!= 0; c
= getc (fp
), i
++)
805 obstack_1grow (stk
, c
);
806 obstack_1grow (stk
, 0);
812 /* Read from file FP a nul-terminated string and convert it to
813 uintmax_t. Return the resulting value in PVAL.
815 Throw fatal error if the string cannot be converted.
817 Return the last character read or EOF on end of file. */
820 read_num (FILE *fp
, uintmax_t *pval
)
824 char buf
[UINTMAX_STRSIZE_BOUND
], *ep
;
826 for (i
= 0, c
= getc (fp
); c
!= EOF
&& c
!= 0; c
= getc (fp
), i
++)
828 if (i
== sizeof buf
- 1)
829 FATAL_ERROR ((0, 0, _("Field too long while reading snapshot file")));
833 *pval
= strtoumax (buf
, &ep
, 10);
835 FATAL_ERROR ((0, 0, _("Unexpected field value in snapshot file")));
839 /* Read incremental snapshot format 2 */
848 if (read_num (listed_incremental_stream
, &u
))
849 FATAL_ERROR ((0, 0, "%s: %s",
850 quotearg_colon (listed_incremental_option
),
851 _("Error reading time stamp")));
852 newer_mtime_option
.tv_sec
= u
;
853 if (newer_mtime_option
.tv_sec
!= u
)
854 FATAL_ERROR ((0, 0, "%s: %s",
855 quotearg_colon (listed_incremental_option
),
856 _("Time stamp out of range")));
858 if (read_num (listed_incremental_stream
, &u
))
859 FATAL_ERROR ((0, 0, "%s: %s",
860 quotearg_colon (listed_incremental_option
),
861 _("Error reading time stamp")));
862 newer_mtime_option
.tv_nsec
= u
;
863 if (newer_mtime_option
.tv_nsec
!= u
)
864 FATAL_ERROR ((0, 0, "%s: %s",
865 quotearg_colon (listed_incremental_option
),
866 _("Time stamp out of range")));
870 struct timespec mtime
;
878 if (read_num (listed_incremental_stream
, &u
))
879 return; /* Normal return */
883 if (read_num (listed_incremental_stream
, &u
))
886 if (mtime
.tv_sec
!= u
)
887 FATAL_ERROR ((0, 0, "%s: %s",
888 quotearg_colon (listed_incremental_option
),
889 _("Modification time (seconds) out of range")));
891 if (read_num (listed_incremental_stream
, &u
))
894 if (mtime
.tv_nsec
!= u
)
895 FATAL_ERROR ((0, 0, "%s: %s",
896 quotearg_colon (listed_incremental_option
),
897 _("Modification time (nanoseconds) out of range")));
899 if (read_num (listed_incremental_stream
, &u
))
903 FATAL_ERROR ((0, 0, "%s: %s",
904 quotearg_colon (listed_incremental_option
),
905 _("Device number out of range")));
907 if (read_num (listed_incremental_stream
, &u
))
911 FATAL_ERROR ((0, 0, "%s: %s",
912 quotearg_colon (listed_incremental_option
),
913 _("Inode number out of range")));
915 if (read_obstack (listed_incremental_stream
, &stk
, &s
))
918 name
= obstack_finish (&stk
);
920 while (read_obstack (listed_incremental_stream
, &stk
, &s
) == 0 && s
> 1)
922 if (getc (listed_incremental_stream
) != 0)
923 FATAL_ERROR ((0, 0, "%s: %s",
924 quotearg_colon (listed_incremental_option
),
925 _("Missing record terminator")));
927 content
= obstack_finish (&stk
);
928 note_directory (name
, mtime
, dev
, ino
, nfs
, false, content
);
929 obstack_free (&stk
, content
);
931 FATAL_ERROR ((0, 0, "%s: %s",
932 quotearg_colon (listed_incremental_option
),
933 _("Unexpected EOF")));
936 /* Read incremental snapshot file (directory file).
937 If the file has older incremental version, make sure that it is processed
938 correctly and that tar will use the most conservative backup method among
939 possible alternatives (i.e. prefer ALL_CHILDREN over CHANGED_CHILDREN,
940 etc.) This ensures that the snapshots are updated to the recent version
941 without any loss of data. */
943 read_directory_file (void)
949 /* Open the file for both read and write. That way, we can write
950 it later without having to reopen it, and don't have to worry if
951 we chdir in the meantime. */
952 fd
= open (listed_incremental_option
, O_RDWR
| O_CREAT
, MODE_RW
);
955 open_error (listed_incremental_option
);
959 listed_incremental_stream
= fdopen (fd
, "r+");
960 if (! listed_incremental_stream
)
962 open_error (listed_incremental_option
);
967 if (0 < getline (&buf
, &bufsize
, listed_incremental_stream
))
970 int incremental_version
;
972 if (strncmp (buf
, PACKAGE_NAME
, sizeof PACKAGE_NAME
- 1) == 0)
974 ebuf
= buf
+ sizeof PACKAGE_NAME
- 1;
976 ERROR((1, 0, _("Bad incremental file format")));
977 for (; *ebuf
!= '-'; ebuf
++)
979 ERROR((1, 0, _("Bad incremental file format")));
981 incremental_version
= (errno
= 0, strtoumax (ebuf
+1, &ebuf
, 10));
984 incremental_version
= 0;
986 switch (incremental_version
)
990 read_incr_db_01 (incremental_version
, buf
);
993 case TAR_INCREMENTAL_VERSION
:
998 ERROR ((1, 0, _("Unsupported incremental format version: %d"),
999 incremental_version
));
1004 if (ferror (listed_incremental_stream
))
1005 read_error (listed_incremental_option
);
1010 /* Output incremental data for the directory ENTRY to the file DATA.
1011 Return nonzero if successful, preserving errno on write failure. */
1013 write_directory_file_entry (void *entry
, void *data
)
1015 struct directory
const *directory
= entry
;
1018 if (DIR_IS_FOUND (directory
))
1020 char buf
[UINTMAX_STRSIZE_BOUND
];
1023 s
= DIR_IS_NFS (directory
) ? "1" : "0";
1024 fwrite (s
, 2, 1, fp
);
1025 s
= umaxtostr (directory
->mtime
.tv_sec
, buf
);
1026 fwrite (s
, strlen (s
) + 1, 1, fp
);
1027 s
= umaxtostr (directory
->mtime
.tv_nsec
, buf
);
1028 fwrite (s
, strlen (s
) + 1, 1, fp
);
1029 s
= umaxtostr (directory
->device_number
, buf
);
1030 fwrite (s
, strlen (s
) + 1, 1, fp
);
1031 s
= umaxtostr (directory
->inode_number
, buf
);
1032 fwrite (s
, strlen (s
) + 1, 1, fp
);
1034 fwrite (directory
->name
, strlen (directory
->name
) + 1, 1, fp
);
1035 if (directory
->contents
)
1038 for (p
= directory
->contents
; *p
; p
+= strlen (p
) + 1)
1040 if (strchr ("YND", *p
))
1041 fwrite (p
, strlen (p
) + 1, 1, fp
);
1044 fwrite ("\0\0", 2, 1, fp
);
1047 return ! ferror (fp
);
1051 write_directory_file (void)
1053 FILE *fp
= listed_incremental_stream
;
1054 char buf
[UINTMAX_STRSIZE_BOUND
];
1060 if (fseek (fp
, 0L, SEEK_SET
) != 0)
1061 seek_error (listed_incremental_option
);
1062 if (sys_truncate (fileno (fp
)) != 0)
1063 truncate_error (listed_incremental_option
);
1065 fprintf (fp
, "%s-%s-%d\n", PACKAGE_NAME
, PACKAGE_VERSION
,
1066 TAR_INCREMENTAL_VERSION
);
1068 s
= umaxtostr (start_time
.tv_sec
, buf
);
1069 fwrite (s
, strlen (s
) + 1, 1, fp
);
1070 s
= umaxtostr (start_time
.tv_nsec
, buf
);
1071 fwrite (s
, strlen (s
) + 1, 1, fp
);
1073 if (! ferror (fp
) && directory_table
)
1074 hash_do_for_each (directory_table
, write_directory_file_entry
, fp
);
1077 write_error (listed_incremental_option
);
1078 if (fclose (fp
) != 0)
1079 close_error (listed_incremental_option
);
1083 /* Restoration of incremental dumps. */
1086 get_gnu_dumpdir (struct tar_stat_info
*stat_info
)
1090 union block
*data_block
;
1094 size
= stat_info
->stat
.st_size
;
1096 archive_dir
= xmalloc (size
);
1099 set_next_block_after (current_header
);
1100 mv_begin (stat_info
);
1102 for (; size
> 0; size
-= copied
)
1104 mv_size_left (size
);
1105 data_block
= find_next_block ();
1107 ERROR ((1, 0, _("Unexpected EOF in archive")));
1108 copied
= available_space_after (data_block
);
1111 memcpy (to
, data_block
->buffer
, copied
);
1113 set_next_block_after ((union block
*)
1114 (data_block
->buffer
+ copied
- 1));
1119 stat_info
->dumpdir
= archive_dir
;
1120 stat_info
->skipped
= true; /* For skip_member() and friends
1121 to work correctly */
1124 /* Return T if STAT_INFO represents a dumpdir archive member.
1125 Note: can invalidate current_header. It happens if flush_archive()
1126 gets called within get_gnu_dumpdir() */
1128 is_dumpdir (struct tar_stat_info
*stat_info
)
1130 if (stat_info
->is_dumpdir
&& !stat_info
->dumpdir
)
1131 get_gnu_dumpdir (stat_info
);
1132 return stat_info
->is_dumpdir
;
1136 dumpdir_ok (char *dumpdir
)
1139 int has_tempdir
= 0;
1142 for (p
= dumpdir
; *p
; p
+= strlen (p
) + 1)
1144 if (expect
&& *p
!= expect
)
1147 _("Malformed dumpdir: expected '%c' but found %#3o"),
1157 _("Malformed dumpdir: 'X' duplicated")));
1170 _("Malformed dumpdir: empty name in 'R'")));
1183 _("Malformed dumpdir: 'T' not preceeded by 'R'")));
1186 if (p
[1] == 0 && !has_tempdir
)
1189 _("Malformed dumpdir: empty name in 'T'")));
1201 /* FIXME: bail out? */
1209 _("Malformed dumpdir: expected '%c' but found end of data"),
1215 WARN ((0, 0, _("Malformed dumpdir: 'X' never used")));
1220 /* Examine the directories under directory_name and delete any
1221 files that were not there at the time of the back-up. */
1223 try_purge_directory (char const *directory_name
)
1226 char *cur
, *arc
, *p
;
1227 char *temp_stub
= NULL
;
1229 if (!is_dumpdir (¤t_stat_info
))
1232 current_dir
= savedir (directory_name
);
1235 /* The directory doesn't exist now. It'll be created. In any
1236 case, we don't have to delete any files out of it. */
1239 /* Verify if dump directory is sane */
1240 if (!dumpdir_ok (current_stat_info
.dumpdir
))
1243 /* Process renames */
1244 for (arc
= current_stat_info
.dumpdir
; *arc
; arc
+= strlen (arc
) + 1)
1248 #define TEMP_DIR_TEMPLATE "tar.XXXXXX"
1249 size_t len
= strlen (arc
+ 1);
1250 temp_stub
= xrealloc (temp_stub
, len
+ 1 + sizeof TEMP_DIR_TEMPLATE
);
1251 memcpy (temp_stub
, arc
+ 1, len
);
1252 temp_stub
[len
] = '/';
1253 memcpy (temp_stub
+ len
+ 1, TEMP_DIR_TEMPLATE
,
1254 sizeof TEMP_DIR_TEMPLATE
);
1255 if (!mkdtemp (temp_stub
))
1258 _("Cannot create temporary directory using template %s"),
1259 quote (temp_stub
)));
1265 else if (*arc
== 'R')
1269 arc
+= strlen (arc
) + 1;
1277 if (!rename_directory (src
, dst
))
1281 /* FIXME: Make sure purge_directory(dst) will return
1290 /* Process deletes */
1292 for (cur
= current_dir
; *cur
; cur
+= strlen (cur
) + 1)
1298 p
= new_name (directory_name
, cur
);
1300 if (!(entry
= dumpdir_locate (current_stat_info
.dumpdir
, cur
))
1301 || (*entry
== 'D' && S_ISDIR (st
.st_mode
))
1302 || (*entry
== 'Y' && !S_ISDIR (st
.st_mode
)))
1304 if (deref_stat (false, p
, &st
))
1306 if (errno
!= ENOENT
) /* FIXME: Maybe keep a list of renamed
1307 dirs and check it here? */
1310 WARN ((0, 0, _("%s: Not purging directory: unable to stat"),
1311 quotearg_colon (p
)));
1315 else if (one_file_system_option
&& st
.st_dev
!= root_device
)
1318 _("%s: directory is on a different device: not purging"),
1319 quotearg_colon (p
)));
1323 if (! interactive_option
|| confirm ("delete", p
))
1326 fprintf (stdlis
, _("%s: Deleting %s\n"),
1327 program_name
, quote (p
));
1328 if (! remove_any_file (p
, RECURSIVE_REMOVE_OPTION
))
1331 ERROR ((0, e
, _("%s: Cannot remove"), quotearg_colon (p
)));
1343 purge_directory (char const *directory_name
)
1345 if (!try_purge_directory (directory_name
))
1350 list_dumpdir (char *buffer
, size_t size
)
1362 fprintf (stdlis
, "%c ", *buffer
);
1368 fputc ('\n', stdlis
);
1374 fputc (*buffer
, stdlis
);