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
;
214 char *p
, *name_buffer
;
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
);
239 if ((directory
= find_directory (name_buffer
)) != NULL
)
241 if (DIR_IS_INITED (directory
))
244 /* With NFS, the same file can have two different devices
245 if an NFS directory is mounted in multiple locations,
246 which is relatively common when automounting.
247 To avoid spurious incremental redumping of
248 directories, consider all NFS devices as equal,
249 relying on the i-node to establish differences. */
251 if (! (((DIR_IS_NFS (directory
) & nfs
)
252 || directory
->device_number
== stat_data
->st_dev
)
253 && directory
->inode_number
== stat_data
->st_ino
))
255 /* FIXME: find_directory_meta ignores nfs */
256 struct directory
*d
= find_directory_meta (stat_data
->st_dev
,
261 WARN ((0, 0, _("%s: Directory has been renamed from %s"),
262 quotearg_colon (name_buffer
),
263 quote_n (1, d
->name
)));
265 DIR_SET_FLAG (directory
, DIRF_RENAMED
);
266 directory
->children
= CHANGED_CHILDREN
;
271 WARN ((0, 0, _("%s: Directory has been renamed"),
272 quotearg_colon (name_buffer
)));
273 directory
->children
= ALL_CHILDREN
;
274 directory
->device_number
= stat_data
->st_dev
;
275 directory
->inode_number
= stat_data
->st_ino
;
278 DIR_SET_FLAG (directory
, DIRF_NFS
);
281 directory
->children
= CHANGED_CHILDREN
;
283 DIR_SET_FLAG (directory
, DIRF_FOUND
);
287 struct directory
*d
= find_directory_meta (stat_data
->st_dev
,
290 directory
= note_directory (name_buffer
,
291 get_stat_mtime(stat_data
),
301 WARN ((0, 0, _("%s: Directory has been renamed from %s"),
302 quotearg_colon (name_buffer
),
303 quote_n (1, d
->name
)));
305 DIR_SET_FLAG (directory
, DIRF_RENAMED
);
306 directory
->children
= CHANGED_CHILDREN
;
310 DIR_SET_FLAG (directory
, DIRF_NEW
);
312 WARN ((0, 0, _("%s: Directory is new"),
313 quotearg_colon (name_buffer
)));
314 directory
->children
=
315 (listed_incremental_option
316 || (OLDER_STAT_TIME (*stat_data
, m
)
317 || (after_date_option
318 && OLDER_STAT_TIME (*stat_data
, c
))))
324 /* If the directory is on another device and --one-file-system was given,
326 if (one_file_system_option
&& device
!= stat_data
->st_dev
327 /* ... except if it was explicitely given in the command line */
328 && !((np
= name_scan (name_buffer
, true)) && np
->explicit))
329 directory
->children
= NO_CHILDREN
;
330 else if (children
== ALL_CHILDREN
)
331 directory
->children
= ALL_CHILDREN
;
333 DIR_SET_FLAG (directory
, DIRF_INIT
);
338 /* Locate NAME in the dumpdir array DUMP.
339 Return pointer to the slot in the array, or NULL if not found */
341 dumpdir_locate (const char *dump
, const char *name
)
346 /* Ignore 'R' (rename) entries, since they break 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. */
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 try_pos (char *name
, int pos
, const char *dumpdir
)
563 static char namechars
[] =
564 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
567 for (i
= 0; i
< sizeof namechars
; i
++)
569 name
[pos
] = namechars
[i
];
570 if (!dumpdir_locate (dumpdir
, name
)
571 || try_pos (name
, pos
-1, dumpdir
))
579 create_temp_name (char *name
, const char *dumpdir
)
581 size_t pos
= strlen (name
) - 6;
582 return try_pos (name
+ pos
, 5, dumpdir
);
586 make_tmp_dir_name (const char *name
)
588 char *dirname
= dir_name (name
);
589 char *tmp_name
= NULL
;
590 struct directory
*dir
= find_directory (dirname
);
592 tmp_name
= new_name (dirname
, "000000");
593 if (!create_temp_name (tmp_name
, dir
? dir
->contents
: NULL
))
603 obstack_code_rename (struct obstack
*stk
, char *from
, char *to
)
605 obstack_1grow (stk
, 'R');
606 obstack_grow (stk
, from
, strlen (from
) + 1);
607 obstack_1grow (stk
, 'T');
608 obstack_grow (stk
, to
, strlen (to
) + 1);
612 rename_handler (void *data
, void *proc_data
)
614 struct directory
*dir
= data
;
615 struct obstack
*stk
= proc_data
;
617 if (DIR_IS_RENAMED (dir
))
619 struct directory
*prev
, *p
;
621 /* Detect eventual cycles and clear DIRF_RENAMED flag, so this entries
622 are ignored when hit by this function next time.
623 If the chain forms a cycle, prev points to the entry DIR is renamed
624 from. In this case it still retains DIRF_RENAMED flag, which will be
625 cleared in the `else' branch below */
626 for (prev
= dir
; prev
&& prev
->orig
!= dir
; prev
= prev
->orig
)
627 DIR_CLEAR_FLAG (prev
, DIRF_RENAMED
);
631 for (p
= dir
; p
&& p
->orig
; p
= p
->orig
)
632 obstack_code_rename (stk
, p
->orig
->name
, p
->name
);
638 DIR_CLEAR_FLAG (prev
, DIRF_RENAMED
);
640 /* Break the cycle by using a temporary name for one of its
642 FIXME: Leave the choice of the name to the extractor. */
643 temp_name
= make_tmp_dir_name (dir
->name
);
644 obstack_code_rename (stk
, dir
->name
, temp_name
);
646 for (p
= dir
; p
!= prev
; p
= p
->orig
)
647 obstack_code_rename (stk
, p
->orig
->name
, p
->name
);
649 obstack_code_rename (stk
, temp_name
, prev
->name
);
656 append_incremental_renames (const char *dump
)
661 if (directory_table
== NULL
)
667 size
= dumpdir_size (dump
) - 1;
668 obstack_grow (&stk
, dump
, size
);
673 hash_do_for_each (directory_table
, rename_handler
, &stk
);
674 if (obstack_object_size (&stk
) != size
)
676 obstack_1grow (&stk
, 0);
677 dump
= obstack_finish (&stk
);
680 obstack_free (&stk
, NULL
);
686 static FILE *listed_incremental_stream
;
688 /* Version of incremental format snapshots (directory files) used by this
689 tar. Currently it is supposed to be a single decimal number. 0 means
690 incremental snapshots as per tar version before 1.15.2.
692 The current tar version supports incremental versions from
693 0 up to TAR_INCREMENTAL_VERSION, inclusive.
694 It is able to create only snapshots of TAR_INCREMENTAL_VERSION */
696 #define TAR_INCREMENTAL_VERSION 2
698 /* Read incremental snapshot formats 0 and 1 */
700 read_incr_db_01 (int version
, const char *initbuf
)
712 if (getline (&buf
, &bufsize
, listed_incremental_stream
) <= 0)
714 read_error (listed_incremental_option
);
722 buf
= strdup (initbuf
);
723 bufsize
= strlen (buf
) + 1;
726 t
= u
= (errno
= 0, strtoumax (buf
, &ebuf
, 10));
727 if (buf
== ebuf
|| (u
== 0 && errno
== EINVAL
))
728 ERROR ((0, 0, "%s:%ld: %s",
729 quotearg_colon (listed_incremental_option
),
731 _("Invalid time stamp")));
733 ERROR ((0, 0, "%s:%ld: %s",
734 quotearg_colon (listed_incremental_option
),
736 _("Time stamp out of range")));
737 else if (version
== 1)
739 newer_mtime_option
.tv_sec
= t
;
741 t
= u
= (errno
= 0, strtoumax (buf
, &ebuf
, 10));
742 if (buf
== ebuf
|| (u
== 0 && errno
== EINVAL
))
743 ERROR ((0, 0, "%s:%ld: %s",
744 quotearg_colon (listed_incremental_option
),
746 _("Invalid time stamp")));
748 ERROR ((0, 0, "%s:%ld: %s",
749 quotearg_colon (listed_incremental_option
),
751 _("Time stamp out of range")));
752 newer_mtime_option
.tv_nsec
= t
;
756 /* pre-1 incremental format does not contain nanoseconds */
757 newer_mtime_option
.tv_sec
= t
;
758 newer_mtime_option
.tv_nsec
= 0;
761 while (0 < (n
= getline (&buf
, &bufsize
, listed_incremental_stream
)))
765 bool nfs
= buf
[0] == '+';
766 char *strp
= buf
+ nfs
;
767 struct timespec mtime
;
771 if (buf
[n
- 1] == '\n')
777 mtime
.tv_sec
= u
= strtoumax (strp
, &ebuf
, 10);
778 if (!isspace (*ebuf
))
779 ERROR ((0, 0, "%s:%ld: %s",
780 quotearg_colon (listed_incremental_option
), lineno
,
781 _("Invalid modification time (seconds)")));
782 else if (mtime
.tv_sec
!= u
)
783 ERROR ((0, 0, "%s:%ld: %s",
784 quotearg_colon (listed_incremental_option
), lineno
,
785 _("Modification time (seconds) out of range")));
789 mtime
.tv_nsec
= u
= strtoumax (strp
, &ebuf
, 10);
790 if (!isspace (*ebuf
))
791 ERROR ((0, 0, "%s:%ld: %s",
792 quotearg_colon (listed_incremental_option
), lineno
,
793 _("Invalid modification time (nanoseconds)")));
794 else if (mtime
.tv_nsec
!= u
)
795 ERROR ((0, 0, "%s:%ld: %s",
796 quotearg_colon (listed_incremental_option
), lineno
,
797 _("Modification time (nanoseconds) out of range")));
801 memset (&mtime
, 0, sizeof mtime
);
804 dev
= u
= strtoumax (strp
, &ebuf
, 10);
805 if (!isspace (*ebuf
))
806 ERROR ((0, 0, "%s:%ld: %s",
807 quotearg_colon (listed_incremental_option
), lineno
,
808 _("Invalid device number")));
810 ERROR ((0, 0, "%s:%ld: %s",
811 quotearg_colon (listed_incremental_option
), lineno
,
812 _("Device number out of range")));
816 ino
= u
= strtoumax (strp
, &ebuf
, 10);
817 if (!isspace (*ebuf
))
818 ERROR ((0, 0, "%s:%ld: %s",
819 quotearg_colon (listed_incremental_option
), lineno
,
820 _("Invalid inode number")));
822 ERROR ((0, 0, "%s:%ld: %s",
823 quotearg_colon (listed_incremental_option
), lineno
,
824 _("Inode number out of range")));
828 unquote_string (strp
);
829 note_directory (strp
, mtime
, dev
, ino
, nfs
, false, NULL
);
834 /* Read a nul-terminated string from FP and store it in STK.
835 Store the number of bytes read (including nul terminator) in PCOUNT.
837 Return the last character read or EOF on end of file. */
839 read_obstack (FILE *fp
, struct obstack
*stk
, size_t *pcount
)
844 for (i
= 0, c
= getc (fp
); c
!= EOF
&& c
!= 0; c
= getc (fp
), i
++)
845 obstack_1grow (stk
, c
);
846 obstack_1grow (stk
, 0);
852 /* Read from file FP a nul-terminated string and convert it to
853 uintmax_t. Return the resulting value in PVAL.
855 Throw fatal error if the string cannot be converted.
857 Return the last character read or EOF on end of file. */
860 read_num (FILE *fp
, uintmax_t *pval
)
864 char buf
[UINTMAX_STRSIZE_BOUND
], *ep
;
866 for (i
= 0, c
= getc (fp
); c
!= EOF
&& c
!= 0; c
= getc (fp
), i
++)
868 if (i
== sizeof buf
- 1)
869 FATAL_ERROR ((0, 0, _("Field too long while reading snapshot file")));
873 *pval
= strtoumax (buf
, &ep
, 10);
875 FATAL_ERROR ((0, 0, _("Unexpected field value in snapshot file")));
879 /* Read incremental snapshot format 2 */
888 if (read_num (listed_incremental_stream
, &u
))
889 FATAL_ERROR ((0, 0, "%s: %s",
890 quotearg_colon (listed_incremental_option
),
891 _("Error reading time stamp")));
892 newer_mtime_option
.tv_sec
= u
;
893 if (newer_mtime_option
.tv_sec
!= u
)
894 FATAL_ERROR ((0, 0, "%s: %s",
895 quotearg_colon (listed_incremental_option
),
896 _("Time stamp out of range")));
898 if (read_num (listed_incremental_stream
, &u
))
899 FATAL_ERROR ((0, 0, "%s: %s",
900 quotearg_colon (listed_incremental_option
),
901 _("Error reading time stamp")));
902 newer_mtime_option
.tv_nsec
= u
;
903 if (newer_mtime_option
.tv_nsec
!= u
)
904 FATAL_ERROR ((0, 0, "%s: %s",
905 quotearg_colon (listed_incremental_option
),
906 _("Time stamp out of range")));
910 struct timespec mtime
;
918 if (read_num (listed_incremental_stream
, &u
))
919 return; /* Normal return */
923 if (read_num (listed_incremental_stream
, &u
))
926 if (mtime
.tv_sec
!= u
)
927 FATAL_ERROR ((0, 0, "%s: %s",
928 quotearg_colon (listed_incremental_option
),
929 _("Modification time (seconds) out of range")));
931 if (read_num (listed_incremental_stream
, &u
))
934 if (mtime
.tv_nsec
!= u
)
935 FATAL_ERROR ((0, 0, "%s: %s",
936 quotearg_colon (listed_incremental_option
),
937 _("Modification time (nanoseconds) out of range")));
939 if (read_num (listed_incremental_stream
, &u
))
943 FATAL_ERROR ((0, 0, "%s: %s",
944 quotearg_colon (listed_incremental_option
),
945 _("Device number out of range")));
947 if (read_num (listed_incremental_stream
, &u
))
951 FATAL_ERROR ((0, 0, "%s: %s",
952 quotearg_colon (listed_incremental_option
),
953 _("Inode number out of range")));
955 if (read_obstack (listed_incremental_stream
, &stk
, &s
))
958 name
= obstack_finish (&stk
);
960 while (read_obstack (listed_incremental_stream
, &stk
, &s
) == 0 && s
> 1)
962 if (getc (listed_incremental_stream
) != 0)
963 FATAL_ERROR ((0, 0, "%s: %s",
964 quotearg_colon (listed_incremental_option
),
965 _("Missing record terminator")));
967 content
= obstack_finish (&stk
);
968 note_directory (name
, mtime
, dev
, ino
, nfs
, false, content
);
969 obstack_free (&stk
, content
);
971 FATAL_ERROR ((0, 0, "%s: %s",
972 quotearg_colon (listed_incremental_option
),
973 _("Unexpected EOF")));
976 /* Read incremental snapshot file (directory file).
977 If the file has older incremental version, make sure that it is processed
978 correctly and that tar will use the most conservative backup method among
979 possible alternatives (i.e. prefer ALL_CHILDREN over CHANGED_CHILDREN,
980 etc.) This ensures that the snapshots are updated to the recent version
981 without any loss of data. */
983 read_directory_file (void)
990 /* Open the file for both read and write. That way, we can write
991 it later without having to reopen it, and don't have to worry if
992 we chdir in the meantime. */
993 fd
= open (listed_incremental_option
, O_RDWR
| O_CREAT
, MODE_RW
);
996 open_error (listed_incremental_option
);
1000 listed_incremental_stream
= fdopen (fd
, "r+");
1001 if (! listed_incremental_stream
)
1003 open_error (listed_incremental_option
);
1008 if (0 < getline (&buf
, &bufsize
, listed_incremental_stream
))
1011 int incremental_version
;
1013 if (strncmp (buf
, PACKAGE_NAME
, sizeof PACKAGE_NAME
- 1) == 0)
1015 ebuf
= buf
+ sizeof PACKAGE_NAME
- 1;
1017 ERROR((1, 0, _("Bad incremental file format")));
1018 for (; *ebuf
!= '-'; ebuf
++)
1020 ERROR((1, 0, _("Bad incremental file format")));
1022 incremental_version
= (errno
= 0, strtoumax (ebuf
+1, &ebuf
, 10));
1025 incremental_version
= 0;
1027 switch (incremental_version
)
1031 read_incr_db_01 (incremental_version
, buf
);
1034 case TAR_INCREMENTAL_VERSION
:
1039 ERROR ((1, 0, _("Unsupported incremental format version: %d"),
1040 incremental_version
));
1045 if (ferror (listed_incremental_stream
))
1046 read_error (listed_incremental_option
);
1051 /* Output incremental data for the directory ENTRY to the file DATA.
1052 Return nonzero if successful, preserving errno on write failure. */
1054 write_directory_file_entry (void *entry
, void *data
)
1056 struct directory
const *directory
= entry
;
1059 if (DIR_IS_FOUND (directory
))
1061 char buf
[UINTMAX_STRSIZE_BOUND
];
1064 s
= DIR_IS_NFS (directory
) ? "1" : "0";
1065 fwrite (s
, 2, 1, fp
);
1066 s
= umaxtostr (directory
->mtime
.tv_sec
, buf
);
1067 fwrite (s
, strlen (s
) + 1, 1, fp
);
1068 s
= umaxtostr (directory
->mtime
.tv_nsec
, buf
);
1069 fwrite (s
, strlen (s
) + 1, 1, fp
);
1070 s
= umaxtostr (directory
->device_number
, buf
);
1071 fwrite (s
, strlen (s
) + 1, 1, fp
);
1072 s
= umaxtostr (directory
->inode_number
, buf
);
1073 fwrite (s
, strlen (s
) + 1, 1, fp
);
1075 fwrite (directory
->name
, strlen (directory
->name
) + 1, 1, fp
);
1076 if (directory
->contents
)
1079 for (p
= directory
->contents
; *p
; p
+= strlen (p
) + 1)
1081 if (strchr ("YND", *p
))
1082 fwrite (p
, strlen (p
) + 1, 1, fp
);
1085 fwrite ("\0\0", 2, 1, fp
);
1088 return ! ferror (fp
);
1092 write_directory_file (void)
1094 FILE *fp
= listed_incremental_stream
;
1095 char buf
[UINTMAX_STRSIZE_BOUND
];
1101 if (fseek (fp
, 0L, SEEK_SET
) != 0)
1102 seek_error (listed_incremental_option
);
1103 if (sys_truncate (fileno (fp
)) != 0)
1104 truncate_error (listed_incremental_option
);
1106 fprintf (fp
, "%s-%s-%d\n", PACKAGE_NAME
, PACKAGE_VERSION
,
1107 TAR_INCREMENTAL_VERSION
);
1109 s
= umaxtostr (start_time
.tv_sec
, buf
);
1110 fwrite (s
, strlen (s
) + 1, 1, fp
);
1111 s
= umaxtostr (start_time
.tv_nsec
, buf
);
1112 fwrite (s
, strlen (s
) + 1, 1, fp
);
1114 if (! ferror (fp
) && directory_table
)
1115 hash_do_for_each (directory_table
, write_directory_file_entry
, fp
);
1118 write_error (listed_incremental_option
);
1119 if (fclose (fp
) != 0)
1120 close_error (listed_incremental_option
);
1124 /* Restoration of incremental dumps. */
1127 get_gnu_dumpdir (struct tar_stat_info
*stat_info
)
1131 union block
*data_block
;
1135 size
= stat_info
->stat
.st_size
;
1137 archive_dir
= xmalloc (size
);
1140 set_next_block_after (current_header
);
1141 mv_begin (stat_info
);
1143 for (; size
> 0; size
-= copied
)
1145 mv_size_left (size
);
1146 data_block
= find_next_block ();
1148 ERROR ((1, 0, _("Unexpected EOF in archive")));
1149 copied
= available_space_after (data_block
);
1152 memcpy (to
, data_block
->buffer
, copied
);
1154 set_next_block_after ((union block
*)
1155 (data_block
->buffer
+ copied
- 1));
1160 stat_info
->dumpdir
= archive_dir
;
1161 stat_info
->skipped
= true; /* For skip_member() and friends
1162 to work correctly */
1165 /* Return T if STAT_INFO represents a dumpdir archive member.
1166 Note: can invalidate current_header. It happens if flush_archive()
1167 gets called within get_gnu_dumpdir() */
1169 is_dumpdir (struct tar_stat_info
*stat_info
)
1171 if (stat_info
->is_dumpdir
&& !stat_info
->dumpdir
)
1172 get_gnu_dumpdir (stat_info
);
1173 return stat_info
->is_dumpdir
;
1176 /* Examine the directories under directory_name and delete any
1177 files that were not there at the time of the back-up. */
1179 purge_directory (char const *directory_name
)
1182 char *cur
, *arc
, *p
;
1184 if (!is_dumpdir (¤t_stat_info
))
1190 current_dir
= savedir (directory_name
);
1194 /* The directory doesn't exist now. It'll be created. In any
1195 case, we don't have to delete any files out of it. */
1201 /* Process renames */
1202 for (arc
= current_stat_info
.dumpdir
; *arc
; arc
+= strlen (arc
) + 1)
1208 arc
+= strlen (arc
) + 1;
1211 if (!rename_directory (src
, dst
))
1214 /* FIXME: Make sure purge_directory(dst) will return
1221 /* Process deletes */
1223 for (cur
= current_dir
; *cur
; cur
+= strlen (cur
) + 1)
1229 p
= new_name (directory_name
, cur
);
1231 if (!(entry
= dumpdir_locate (current_stat_info
.dumpdir
, cur
))
1232 || (*entry
== 'D' && S_ISDIR (st
.st_mode
))
1233 || (*entry
== 'Y' && !S_ISDIR (st
.st_mode
)))
1235 if (deref_stat (false, p
, &st
))
1237 if (errno
!= ENOENT
) /* FIXME: Maybe keep a list of renamed
1238 dirs and check it here? */
1241 WARN ((0, 0, _("%s: Not purging directory: unable to stat"),
1242 quotearg_colon (p
)));
1246 else if (one_file_system_option
&& st
.st_dev
!= root_device
)
1249 _("%s: directory is on a different device: not purging"),
1250 quotearg_colon (p
)));
1254 if (! interactive_option
|| confirm ("delete", p
))
1257 fprintf (stdlis
, _("%s: Deleting %s\n"),
1258 program_name
, quote (p
));
1259 if (! remove_any_file (p
, RECURSIVE_REMOVE_OPTION
))
1262 ERROR ((0, e
, _("%s: Cannot remove"), quotearg_colon (p
)));
1273 list_dumpdir (char *buffer
, size_t size
)
1284 fprintf (stdlis
, "%c ", *buffer
);
1290 fputc ('\n', stdlis
);
1296 fputc (*buffer
, stdlis
);