Remove autogenerated files
[debian/tar] / src / incremen.c
1 /* GNU dump extensions to tar.
2
3    Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1999, 2000, 2001,
4    2003, 2004, 2005, 2006 Free Software Foundation, Inc.
5
6    This program is free software; you can redistribute it and/or modify it
7    under the terms of the GNU General Public License as published by the
8    Free Software Foundation; either version 2, or (at your option) any later
9    version.
10
11    This program is distributed in the hope that it will be useful, but
12    WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
14    Public License for more details.
15
16    You should have received a copy of the GNU General Public License along
17    with this program; if not, write to the Free Software Foundation, Inc.,
18    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
19
20 #include <system.h>
21 #include <getline.h>
22 #include <hash.h>
23 #include <quotearg.h>
24 #include "common.h"
25
26 /* Incremental dump specialities.  */
27
28 /* Which child files to save under a directory.  */
29 enum children
30   {
31     NO_CHILDREN,
32     CHANGED_CHILDREN,
33     ALL_CHILDREN
34   };
35
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 */
43
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)
49
50 #define DIR_SET_FLAG(d,f) (d)->flags |= (f)
51 #define DIR_CLEAR_FLAG(d,f) (d)->flags &= ~(f)
52
53 /* Directory attributes.  */
54 struct directory
55   {
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
61                                    rescanned */
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 */
67   };
68
69 static Hash_table *directory_table;
70 static Hash_table *directory_meta_table;
71
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)
75 #else
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)
78 #endif
79
80 /* Calculate the hash of a directory.  */
81 static size_t
82 hash_directory_name (void const *entry, size_t n_buckets)
83 {
84   struct directory const *directory = entry;
85   return hash_string (directory->name, n_buckets);
86 }
87
88 /* Compare two directories for equality of their names. */
89 static bool
90 compare_directory_names (void const *entry1, void const *entry2)
91 {
92   struct directory const *directory1 = entry1;
93   struct directory const *directory2 = entry2;
94   return strcmp (directory1->name, directory2->name) == 0;
95 }
96
97 static size_t
98 hash_directory_meta (void const *entry, size_t n_buckets)
99 {
100   struct directory const *directory = entry;
101   /* FIXME: Work out a better algorytm */
102   return (directory->device_number + directory->inode_number) % n_buckets;
103 }
104
105 /* Compare two directories for equality of their device and inode numbers. */
106 static bool
107 compare_directory_meta (void const *entry1, void const *entry2)
108 {
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;
113 }
114
115 /* Make a directory entry for given NAME */
116 static struct directory *
117 make_directory (const char *name)
118 {
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;
128   return directory;
129 }
130
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)
138 {
139   struct directory *directory = make_directory (name);
140
141   directory->mtime = mtime;
142   directory->device_number = dev;
143   directory->inode_number = ino;
144   directory->children = CHANGED_CHILDREN;
145   if (nfs)
146     DIR_SET_FLAG (directory, DIRF_NFS);
147   if (found)
148     DIR_SET_FLAG (directory, DIRF_FOUND);
149   if (contents)
150     {
151       size_t size = dumpdir_size (contents);
152       directory->contents = xmalloc (size);
153       memcpy (directory->contents, contents, size);
154     }
155   else
156     directory->contents = NULL;
157
158   if (! ((directory_table
159           || (directory_table = hash_initialize (0, 0,
160                                                  hash_directory_name,
161                                                  compare_directory_names, 0)))
162          && hash_insert (directory_table, directory)))
163     xalloc_die ();
164
165   if (! ((directory_meta_table
166           || (directory_meta_table = hash_initialize (0, 0,
167                                                       hash_directory_meta,
168                                                       compare_directory_meta,
169                                                       0)))
170          && hash_insert (directory_meta_table, directory)))
171     xalloc_die ();
172
173   return directory;
174 }
175
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)
179 {
180   if (! directory_table)
181     return 0;
182   else
183     {
184       struct directory *dir = make_directory (name);
185       struct directory *ret = hash_lookup (directory_table, dir);
186       free (dir);
187       return ret;
188     }
189 }
190
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)
195 {
196   if (! directory_meta_table)
197     return 0;
198   else
199     {
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);
205       free (dir);
206       return ret;
207     }
208 }
209
210 void
211 update_parent_directory (const char *name)
212 {
213   struct directory *directory;
214   char *p;
215
216   p = dir_name (name);
217   directory = find_directory (p);
218   if (directory)
219     {
220       struct stat st;
221       if (deref_stat (dereference_option, p, &st) != 0)
222         stat_diag (name);
223       else
224         directory->mtime = get_stat_mtime (&st);
225     }
226   free (p);
227 }
228
229 static struct directory *
230 procdir (char *name_buffer, struct stat *stat_data,
231          dev_t device,
232          enum children children,
233          bool verbose)
234 {
235   struct directory *directory;
236   bool nfs = NFS_FILE_STAT (*stat_data);
237
238   if ((directory = find_directory (name_buffer)) != NULL)
239     {
240       if (DIR_IS_INITED (directory))
241         return directory;
242
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.  */
249
250       if (! (((DIR_IS_NFS (directory) & nfs)
251               || directory->device_number == stat_data->st_dev)
252              && directory->inode_number == stat_data->st_ino))
253         {
254           /* FIXME: find_directory_meta ignores nfs */
255           struct directory *d = find_directory_meta (stat_data->st_dev,
256                                                      stat_data->st_ino);
257           if (d)
258             {
259               if (verbose_option)
260                 WARN ((0, 0, _("%s: Directory has been renamed from %s"),
261                        quotearg_colon (name_buffer),
262                        quote_n (1, d->name)));
263               directory->orig = d;
264               DIR_SET_FLAG (directory, DIRF_RENAMED);
265               directory->children = CHANGED_CHILDREN;
266             }
267           else
268             {
269               if (verbose_option)
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;
275             }
276           if (nfs)
277             DIR_SET_FLAG (directory, DIRF_NFS);
278         }
279       else
280         directory->children = CHANGED_CHILDREN;
281
282       DIR_SET_FLAG (directory, DIRF_FOUND);
283     }
284   else
285     {
286       struct directory *d = find_directory_meta (stat_data->st_dev,
287                                                  stat_data->st_ino);
288
289       directory = note_directory (name_buffer,
290                                   get_stat_mtime(stat_data),
291                                   stat_data->st_dev,
292                                   stat_data->st_ino,
293                                   nfs,
294                                   true,
295                                   NULL);
296
297       if (d)
298         {
299           if (verbose)
300             WARN ((0, 0, _("%s: Directory has been renamed from %s"),
301                    quotearg_colon (name_buffer),
302                    quote_n (1, d->name)));
303           directory->orig = d;
304           DIR_SET_FLAG (directory, DIRF_RENAMED);
305           directory->children = CHANGED_CHILDREN;
306         }
307       else
308         {
309           DIR_SET_FLAG (directory, DIRF_NEW);
310           if (verbose)
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))))
318             ? ALL_CHILDREN
319             : CHANGED_CHILDREN;
320         }
321     }
322
323   /* If the directory is on another device and --one-file-system was given,
324      omit it... */
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;
331
332   DIR_SET_FLAG (directory, DIRF_INIT);
333
334   return directory;
335 }
336
337 /* Locate NAME in the dumpdir array DUMP.
338    Return pointer to the slot in the array, or NULL if not found */
339 const char *
340 dumpdir_locate (const char *dump, const char *name)
341 {
342   if (dump)
343     while (*dump)
344       {
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))
351           {
352             int rc = strcmp (dump + 1, name);
353             if (rc == 0)
354               return dump;
355             if (rc > 1)
356               break;
357           }
358         dump += strlen (dump) + 1;
359       }
360   return NULL;
361 }
362
363 /* Return size in bytes of the dumpdir array P */
364 size_t
365 dumpdir_size (const char *p)
366 {
367   size_t totsize = 0;
368
369   while (*p)
370     {
371       size_t size = strlen (p) + 1;
372       totsize += size;
373       p += size;
374     }
375   return totsize + 1;
376 }
377
378 static int
379 compare_dirnames (const void *first, const void *second)
380 {
381   return strcmp (*(const char**)first, *(const char**)second);
382 }
383
384 /* Compare dumpdir array from DIRECTORY with directory listing DIR and
385    build a new dumpdir template.
386
387    DIR must be returned by a previous call to savedir().
388
389    File names in DIRECTORY->contents must be sorted
390    alphabetically.
391
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. */
394
395 void
396 makedumpdir (struct directory *directory, const char *dir)
397 {
398   size_t i,
399          dirsize,  /* Number of elements in DIR */
400          len;      /* Length of DIR, including terminating nul */
401   const char *p;
402   char const **array;
403   char *new_dump, *new_dump_ptr;
404   const char *dump;
405
406   if (directory->children == ALL_CHILDREN)
407     dump = NULL;
408   else if (DIR_IS_RENAMED (directory))
409     dump = directory->orig->icontents ?
410               directory->orig->icontents : directory->orig->contents;
411   else
412     dump = directory->contents;
413
414   /* Count the size of DIR and the number of elements it contains */
415   dirsize = 0;
416   len = 0;
417   for (p = dir; *p; p += strlen (p) + 1, dirsize++)
418     len += strlen (p) + 2;
419   len++;
420
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++)
424     array[i] = p;
425
426   qsort (array, dirsize, sizeof (array[0]), compare_dirnames);
427
428   /* Prepare space for new dumpdir */
429   new_dump = xmalloc (len);
430   new_dump_ptr = new_dump;
431
432   /* Fill in the dumpdir template */
433   for (i = 0; i < dirsize; i++)
434     {
435       const char *loc = dumpdir_locate (dump, array[i]);
436       if (loc)
437         {
438           *new_dump_ptr++ = ' ';
439           dump = loc + strlen (loc) + 1;
440         }
441       else
442         *new_dump_ptr++ = 'Y'; /* New entry */
443
444       /* Copy the file name */
445       for (p = array[i]; (*new_dump_ptr++ = *p++); )
446         ;
447     }
448   *new_dump_ptr = 0;
449   directory->icontents = directory->contents;
450   directory->contents = new_dump;
451   free (array);
452 }
453
454 /* Recursively scan the given directory. */
455 static char *
456 scan_directory (char *dir_name, dev_t device)
457 {
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;
464
465   if (! dirp)
466     savedir_error (dir_name);
467
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);
474
475   if (deref_stat (dereference_option, name_buffer, &stat_data))
476     {
477       stat_diag (name_buffer);
478       /* FIXME: used to be
479            children = CHANGED_CHILDREN;
480          but changed to: */
481       free (name_buffer);
482       free (dirp);
483       return NULL;
484     }
485
486   directory = procdir (name_buffer, &stat_data, device, NO_CHILDREN, false);
487
488   if (dirp && directory->children != NO_CHILDREN)
489     {
490       char  *entry;     /* directory entry being scanned */
491       size_t entrylen;  /* length of directory entry */
492
493       makedumpdir (directory, dirp);
494
495       for (entry = directory->contents;
496            (entrylen = strlen (entry)) != 0;
497            entry += entrylen + 1)
498         {
499           if (name_buffer_size <= entrylen - 1 + name_length)
500             {
501               do
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);
505             }
506           strcpy (name_buffer + name_length, entry + 1);
507
508           if (excluded_name (name_buffer))
509             *entry = 'N';
510           else
511             {
512               if (deref_stat (dereference_option, name_buffer, &stat_data))
513                 {
514                   stat_diag (name_buffer);
515                   *entry = 'N';
516                   continue;
517                 }
518
519               if (S_ISDIR (stat_data.st_mode))
520                 {
521                   procdir (name_buffer, &stat_data, device,
522                            directory->children,
523                            verbose_option);
524                   *entry = 'D';
525                 }
526
527               else if (one_file_system_option && device != stat_data.st_dev)
528                 *entry = 'N';
529
530               else if (*entry == 'Y')
531                 /* New entry, skip further checks */;
532
533               /* FIXME: if (S_ISHIDDEN (stat_data.st_mode))?? */
534
535               else if (OLDER_STAT_TIME (stat_data, m)
536                        && (!after_date_option
537                            || OLDER_STAT_TIME (stat_data, c)))
538                 *entry = 'N';
539               else
540                 *entry = 'Y';
541             }
542         }
543     }
544
545   free (name_buffer);
546   if (dirp)
547     free (dirp);
548
549   return directory->contents;
550 }
551
552 char *
553 get_directory_contents (char *dir_name, dev_t device)
554 {
555   return scan_directory (dir_name, device);
556 }
557
558 \f
559 static void
560 obstack_code_rename (struct obstack *stk, char *from, char *to)
561 {
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);
566 }
567
568 static bool
569 rename_handler (void *data, void *proc_data)
570 {
571   struct directory *dir = data;
572   struct obstack *stk = proc_data;
573
574   if (DIR_IS_RENAMED (dir))
575     {
576       struct directory *prev, *p;
577
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);
585
586       if (prev == NULL)
587         {
588           for (p = dir; p && p->orig; p = p->orig)
589             obstack_code_rename (stk, p->orig->name, p->name);
590         }
591       else
592         {
593           char *temp_name;
594
595           DIR_CLEAR_FLAG (prev, DIRF_RENAMED);
596
597           /* Break the cycle by using a temporary name for one of its
598              elements.
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);
603
604           obstack_code_rename (stk, dir->name, "");
605
606           for (p = dir; p != prev; p = p->orig)
607             obstack_code_rename (stk, p->orig->name, p->name);
608
609           obstack_code_rename (stk, "", prev->name);
610         }
611     }
612   return true;
613 }
614
615 const char *
616 append_incremental_renames (const char *dump)
617 {
618   struct obstack stk;
619   size_t size;
620
621   if (directory_table == NULL)
622     return dump;
623
624   obstack_init (&stk);
625   if (dump)
626     {
627       size = dumpdir_size (dump) - 1;
628       obstack_grow (&stk, dump, size);
629     }
630   else
631     size = 0;
632
633   hash_do_for_each (directory_table, rename_handler, &stk);
634   if (obstack_object_size (&stk) != size)
635     {
636       obstack_1grow (&stk, 0);
637       dump = obstack_finish (&stk);
638     }
639   else
640     obstack_free (&stk, NULL);
641   return dump;
642 }
643
644 \f
645
646 static FILE *listed_incremental_stream;
647
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.
651
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 */
655
656 #define TAR_INCREMENTAL_VERSION 2
657
658 /* Read incremental snapshot formats 0 and 1 */
659 static void
660 read_incr_db_01 (int version, const char *initbuf)
661 {
662   int n;
663   uintmax_t u;
664   time_t sec;
665   long int nsec;
666   char *buf = 0;
667   size_t bufsize;
668   char *ebuf;
669   long lineno = 1;
670
671   if (version == 1)
672     {
673       if (getline (&buf, &bufsize, listed_incremental_stream) <= 0)
674         {
675           read_error (listed_incremental_option);
676           free (buf);
677           return;
678         }
679       ++lineno;
680     }
681   else
682     {
683       buf = strdup (initbuf);
684       bufsize = strlen (buf) + 1;
685     }
686
687   sec = TYPE_MINIMUM (time_t);
688   nsec = -1;
689   errno = 0;
690   u = strtoumax (buf, &ebuf, 10);
691   if (!errno && TYPE_MAXIMUM (time_t) < u)
692     errno = ERANGE;
693   if (errno || buf == ebuf)
694     ERROR ((0, errno, "%s:%ld: %s",
695             quotearg_colon (listed_incremental_option),
696             lineno,
697             _("Invalid time stamp")));
698   else
699     {
700       sec = u;
701
702       if (version == 1 && *ebuf)
703         {
704           char const *buf_ns = ebuf + 1;
705           errno = 0;
706           u = strtoumax (buf_ns, &ebuf, 10);
707           if (!errno && BILLION <= u)
708             errno = ERANGE;
709           if (errno || buf_ns == ebuf)
710             {
711               ERROR ((0, errno, "%s:%ld: %s",
712                       quotearg_colon (listed_incremental_option),
713                       lineno,
714                       _("Invalid time stamp")));
715               sec = TYPE_MINIMUM (time_t);
716             }
717           else
718             nsec = u;
719         }
720       else
721         {
722           /* pre-1 incremental format does not contain nanoseconds */
723           nsec = 0;
724         }
725     }
726   newer_mtime_option.tv_sec = sec;
727   newer_mtime_option.tv_nsec = nsec;
728
729
730   while (0 < (n = getline (&buf, &bufsize, listed_incremental_stream)))
731     {
732       dev_t dev;
733       ino_t ino;
734       bool nfs = buf[0] == '+';
735       char *strp = buf + nfs;
736       struct timespec mtime;
737
738       lineno++;
739
740       if (buf[n - 1] == '\n')
741         buf[n - 1] = '\0';
742
743       if (version == 1)
744         {
745           errno = 0;
746           u = strtoumax (strp, &ebuf, 10);
747           if (!errno && TYPE_MAXIMUM (time_t) < u)
748             errno = ERANGE;
749           if (errno || strp == ebuf || *ebuf != ' ')
750             {
751               ERROR ((0, errno, "%s:%ld: %s",
752                       quotearg_colon (listed_incremental_option), lineno,
753                       _("Invalid modification time (seconds)")));
754               sec = (time_t) -1;
755             }
756           else
757             sec = u;
758           strp = ebuf;
759
760           errno = 0;
761           u = strtoumax (strp, &ebuf, 10);
762           if (!errno && BILLION <= u)
763             errno = ERANGE;
764           if (errno || strp == ebuf || *ebuf != ' ')
765             {
766               ERROR ((0, errno, "%s:%ld: %s",
767                       quotearg_colon (listed_incremental_option), lineno,
768                       _("Invalid modification time (nanoseconds)")));
769               nsec = -1;
770             }
771           else
772             nsec = u;
773           mtime.tv_sec = sec;
774           mtime.tv_nsec = nsec;
775           strp = ebuf;
776         }
777       else
778         memset (&mtime, 0, sizeof mtime);
779
780       errno = 0;
781       u = strtoumax (strp, &ebuf, 10);
782       if (!errno && TYPE_MAXIMUM (dev_t) < u)
783         errno = ERANGE;
784       if (errno || strp == ebuf || *ebuf != ' ')
785         {
786           ERROR ((0, errno, "%s:%ld: %s",
787                   quotearg_colon (listed_incremental_option), lineno,
788                   _("Invalid device number")));
789           dev = (dev_t) -1;
790         }
791       else
792         dev = u;
793       strp = ebuf;
794
795       errno = 0;
796       u = strtoumax (strp, &ebuf, 10);
797       if (!errno && TYPE_MAXIMUM (ino_t) < u)
798         errno = ERANGE;
799       if (errno || strp == ebuf || *ebuf != ' ')
800         {
801           ERROR ((0, errno, "%s:%ld: %s",
802                   quotearg_colon (listed_incremental_option), lineno,
803                   _("Invalid inode number")));
804           ino = (ino_t) -1;
805         }
806       else
807         ino = u;
808       strp = ebuf;
809
810       strp++;
811       unquote_string (strp);
812       note_directory (strp, mtime, dev, ino, nfs, false, NULL);
813     }
814   free (buf);
815 }
816
817 /* Read a nul-terminated string from FP and store it in STK.
818    Store the number of bytes read (including nul terminator) in PCOUNT.
819
820    Return the last character read or EOF on end of file. */
821 static int
822 read_obstack (FILE *fp, struct obstack *stk, size_t *pcount)
823 {
824   int c;
825   size_t i;
826
827   for (i = 0, c = getc (fp); c != EOF && c != 0; c = getc (fp), i++)
828     obstack_1grow (stk, c);
829   obstack_1grow (stk, 0);
830
831   *pcount = i;
832   return c;
833 }
834
835 /* Read from file FP a nul-terminated string and convert it to
836    intmax_t.  Return the resulting value in PVAL.  Assume '-' has
837    already been read.
838
839    Throw a fatal error if the string cannot be converted or if the
840    converted value is less than MIN_VAL.  */
841
842 static void
843 read_negative_num (FILE *fp, intmax_t min_val, intmax_t *pval)
844 {
845   int c;
846   size_t i;
847   char buf[INT_BUFSIZE_BOUND (intmax_t)];
848   char *ep;
849   buf[0] = '-';
850
851   for (i = 1; ISDIGIT (c = getc (fp)); i++)
852     {
853       if (i == sizeof buf - 1)
854         FATAL_ERROR ((0, 0, _("Field too long while reading snapshot file")));
855       buf[i] = c;
856     }
857
858   if (c < 0)
859     {
860       if (ferror (fp))
861         FATAL_ERROR ((0, errno, _("Read error in snapshot file")));
862       else
863         FATAL_ERROR ((0, 0, _("Unexpected EOF in snapshot file")));
864     }
865
866   buf[i] = 0;
867   errno = 0;
868   *pval = strtoimax (buf, &ep, 10);
869   if (c || errno || *pval < min_val)
870     FATAL_ERROR ((0, errno, _("Unexpected field value in snapshot file")));
871 }
872
873 /* Read from file FP a nul-terminated string and convert it to
874    uintmax_t.  Return the resulting value in PVAL.  Assume C has
875    already been read.
876
877    Throw a fatal error if the string cannot be converted or if the
878    converted value exceeds MAX_VAL.
879
880    Return the last character read or EOF on end of file. */
881
882 static int
883 read_unsigned_num (int c, FILE *fp, uintmax_t max_val, uintmax_t *pval)
884 {
885   size_t i;
886   char buf[UINTMAX_STRSIZE_BOUND], *ep;
887
888   for (i = 0; ISDIGIT (c); i++)
889     {
890       if (i == sizeof buf - 1)
891         FATAL_ERROR ((0, 0, _("Field too long while reading snapshot file")));
892       buf[i] = c;
893       c = getc (fp);
894     }
895
896   if (c < 0)
897     {
898       if (ferror (fp))
899         FATAL_ERROR ((0, errno, _("Read error in snapshot file")));
900       else if (i == 0)
901         return c;
902       else
903         FATAL_ERROR ((0, 0, _("Unexpected EOF in snapshot file")));
904     }
905
906   buf[i] = 0;
907   errno = 0;
908   *pval = strtoumax (buf, &ep, 10);
909   if (c || errno || max_val < *pval)
910     FATAL_ERROR ((0, errno, _("Unexpected field value in snapshot file")));
911   return c;
912 }
913
914 /* Read from file FP a nul-terminated string and convert it to
915    uintmax_t.  Return the resulting value in PVAL.
916
917    Throw a fatal error if the string cannot be converted or if the
918    converted value exceeds MAX_VAL.
919
920    Return the last character read or EOF on end of file. */
921
922 static int
923 read_num (FILE *fp, uintmax_t max_val, uintmax_t *pval)
924 {
925   return read_unsigned_num (getc (fp), fp, max_val, pval);
926 }
927
928 /* Read from FP two NUL-terminated strings representing a struct
929    timespec.  Return the resulting value in PVAL.
930
931    Throw a fatal error if the string cannot be converted.  */
932
933 static void
934 read_timespec (FILE *fp, struct timespec *pval)
935 {
936   int c = getc (fp);
937   intmax_t i;
938   uintmax_t u;
939
940   if (c == '-')
941     {
942       read_negative_num (fp, TYPE_MINIMUM (time_t), &i);
943       c = 0;
944       pval->tv_sec = i;
945     }
946   else
947     {
948       c = read_unsigned_num (c, fp, TYPE_MAXIMUM (time_t), &u);
949       pval->tv_sec = u;
950     }
951
952   if (c || read_num (fp, BILLION - 1, &u))
953     FATAL_ERROR ((0, 0, "%s: %s",
954                   quotearg_colon (listed_incremental_option),
955                   _("Unexpected EOF in snapshot file")));
956   pval->tv_nsec = u;
957 }
958
959 /* Read incremental snapshot format 2 */
960 static void
961 read_incr_db_2 ()
962 {
963   uintmax_t u;
964   struct obstack stk;
965
966   obstack_init (&stk);
967
968   read_timespec (listed_incremental_stream, &newer_mtime_option);
969
970   for (;;)
971     {
972       struct timespec mtime;
973       dev_t dev;
974       ino_t ino;
975       bool nfs;
976       char *name;
977       char *content;
978       size_t s;
979
980       if (read_num (listed_incremental_stream, 1, &u))
981         return; /* Normal return */
982
983       nfs = u;
984
985       read_timespec (listed_incremental_stream, &mtime);
986
987       if (read_num (listed_incremental_stream, TYPE_MAXIMUM (dev_t), &u))
988         break;
989       dev = u;
990
991       if (read_num (listed_incremental_stream, TYPE_MAXIMUM (ino_t), &u))
992         break;
993       ino = u;
994
995       if (read_obstack (listed_incremental_stream, &stk, &s))
996         break;
997
998       name = obstack_finish (&stk);
999
1000       while (read_obstack (listed_incremental_stream, &stk, &s) == 0 && s > 1)
1001         ;
1002       if (getc (listed_incremental_stream) != 0)
1003         FATAL_ERROR ((0, 0, "%s: %s",
1004                       quotearg_colon (listed_incremental_option),
1005                       _("Missing record terminator")));
1006
1007       content = obstack_finish (&stk);
1008       note_directory (name, mtime, dev, ino, nfs, false, content);
1009       obstack_free (&stk, content);
1010     }
1011   FATAL_ERROR ((0, 0, "%s: %s",
1012                 quotearg_colon (listed_incremental_option),
1013                 _("Unexpected EOF in snapshot file")));
1014 }
1015
1016 /* Read incremental snapshot file (directory file).
1017    If the file has older incremental version, make sure that it is processed
1018    correctly and that tar will use the most conservative backup method among
1019    possible alternatives (i.e. prefer ALL_CHILDREN over CHANGED_CHILDREN,
1020    etc.) This ensures that the snapshots are updated to the recent version
1021    without any loss of data. */
1022 void
1023 read_directory_file (void)
1024 {
1025   int fd;
1026   char *buf = 0;
1027   size_t bufsize;
1028
1029   /* Open the file for both read and write.  That way, we can write
1030      it later without having to reopen it, and don't have to worry if
1031      we chdir in the meantime.  */
1032   fd = open (listed_incremental_option, O_RDWR | O_CREAT, MODE_RW);
1033   if (fd < 0)
1034     {
1035       open_error (listed_incremental_option);
1036       return;
1037     }
1038
1039   listed_incremental_stream = fdopen (fd, "r+");
1040   if (! listed_incremental_stream)
1041     {
1042       open_error (listed_incremental_option);
1043       close (fd);
1044       return;
1045     }
1046
1047   if (0 < getline (&buf, &bufsize, listed_incremental_stream))
1048     {
1049       char *ebuf;
1050       uintmax_t incremental_version;
1051
1052       if (strncmp (buf, PACKAGE_NAME, sizeof PACKAGE_NAME - 1) == 0)
1053         {
1054           ebuf = buf + sizeof PACKAGE_NAME - 1;
1055           if (*ebuf++ != '-')
1056             ERROR((1, 0, _("Bad incremental file format")));
1057           for (; *ebuf != '-'; ebuf++)
1058             if (!*ebuf)
1059               ERROR((1, 0, _("Bad incremental file format")));
1060
1061           incremental_version = strtoumax (ebuf + 1, NULL, 10);
1062         }
1063       else
1064         incremental_version = 0;
1065
1066       switch (incremental_version)
1067         {
1068         case 0:
1069         case 1:
1070           read_incr_db_01 (incremental_version, buf);
1071           break;
1072
1073         case TAR_INCREMENTAL_VERSION:
1074           read_incr_db_2 ();
1075           break;
1076
1077         default:
1078           ERROR ((1, 0, _("Unsupported incremental format version: %"PRIuMAX),
1079                   incremental_version));
1080         }
1081
1082     }
1083
1084   if (ferror (listed_incremental_stream))
1085     read_error (listed_incremental_option);
1086   if (buf)
1087     free (buf);
1088 }
1089
1090 /* Output incremental data for the directory ENTRY to the file DATA.
1091    Return nonzero if successful, preserving errno on write failure.  */
1092 static bool
1093 write_directory_file_entry (void *entry, void *data)
1094 {
1095   struct directory const *directory = entry;
1096   FILE *fp = data;
1097
1098   if (DIR_IS_FOUND (directory))
1099     {
1100       char buf[UINTMAX_STRSIZE_BOUND];
1101       char *s;
1102
1103       s = DIR_IS_NFS (directory) ? "1" : "0";
1104       fwrite (s, 2, 1, fp);
1105       s = (TYPE_SIGNED (time_t)
1106            ? imaxtostr (directory->mtime.tv_sec, buf)
1107            : umaxtostr (directory->mtime.tv_sec, buf));
1108       fwrite (s, strlen (s) + 1, 1, fp);
1109       s = umaxtostr (directory->mtime.tv_nsec, buf);
1110       fwrite (s, strlen (s) + 1, 1, fp);
1111       s = umaxtostr (directory->device_number, buf);
1112       fwrite (s, strlen (s) + 1, 1, fp);
1113       s = umaxtostr (directory->inode_number, buf);
1114       fwrite (s, strlen (s) + 1, 1, fp);
1115
1116       fwrite (directory->name, strlen (directory->name) + 1, 1, fp);
1117       if (directory->contents)
1118         {
1119           char *p;
1120           for (p = directory->contents; *p; p += strlen (p) + 1)
1121             {
1122               if (strchr ("YND", *p))
1123                 fwrite (p, strlen (p) + 1, 1, fp);
1124             }
1125         }
1126       fwrite ("\0\0", 2, 1, fp);
1127     }
1128
1129   return ! ferror (fp);
1130 }
1131
1132 void
1133 write_directory_file (void)
1134 {
1135   FILE *fp = listed_incremental_stream;
1136   char buf[UINTMAX_STRSIZE_BOUND];
1137   char *s;
1138
1139   if (! fp)
1140     return;
1141
1142   if (fseek (fp, 0L, SEEK_SET) != 0)
1143     seek_error (listed_incremental_option);
1144   if (sys_truncate (fileno (fp)) != 0)
1145     truncate_error (listed_incremental_option);
1146
1147   fprintf (fp, "%s-%s-%d\n", PACKAGE_NAME, PACKAGE_VERSION,
1148            TAR_INCREMENTAL_VERSION);
1149
1150   s = (TYPE_SIGNED (time_t)
1151        ? imaxtostr (start_time.tv_sec, buf)
1152        : umaxtostr (start_time.tv_sec, buf));
1153   fwrite (s, strlen (s) + 1, 1, fp);
1154   s = umaxtostr (start_time.tv_nsec, buf);
1155   fwrite (s, strlen (s) + 1, 1, fp);
1156
1157   if (! ferror (fp) && directory_table)
1158     hash_do_for_each (directory_table, write_directory_file_entry, fp);
1159
1160   if (ferror (fp))
1161     write_error (listed_incremental_option);
1162   if (fclose (fp) != 0)
1163     close_error (listed_incremental_option);
1164 }
1165
1166 \f
1167 /* Restoration of incremental dumps.  */
1168
1169 static void
1170 get_gnu_dumpdir (struct tar_stat_info *stat_info)
1171 {
1172   size_t size;
1173   size_t copied;
1174   union block *data_block;
1175   char *to;
1176   char *archive_dir;
1177
1178   size = stat_info->stat.st_size;
1179
1180   archive_dir = xmalloc (size);
1181   to = archive_dir;
1182
1183   set_next_block_after (current_header);
1184   mv_begin (stat_info);
1185
1186   for (; size > 0; size -= copied)
1187     {
1188       mv_size_left (size);
1189       data_block = find_next_block ();
1190       if (!data_block)
1191         ERROR ((1, 0, _("Unexpected EOF in archive")));
1192       copied = available_space_after (data_block);
1193       if (copied > size)
1194         copied = size;
1195       memcpy (to, data_block->buffer, copied);
1196       to += copied;
1197       set_next_block_after ((union block *)
1198                             (data_block->buffer + copied - 1));
1199     }
1200
1201   mv_end ();
1202
1203   stat_info->dumpdir = archive_dir;
1204   stat_info->skipped = true; /* For skip_member() and friends
1205                                 to work correctly */
1206 }
1207
1208 /* Return T if STAT_INFO represents a dumpdir archive member.
1209    Note: can invalidate current_header. It happens if flush_archive()
1210    gets called within get_gnu_dumpdir() */
1211 bool
1212 is_dumpdir (struct tar_stat_info *stat_info)
1213 {
1214   if (stat_info->is_dumpdir && !stat_info->dumpdir)
1215     get_gnu_dumpdir (stat_info);
1216   return stat_info->is_dumpdir;
1217 }
1218
1219 static bool
1220 dumpdir_ok (char *dumpdir)
1221 {
1222   char *p;
1223   int has_tempdir = 0;
1224   int expect = 0;
1225
1226   for (p = dumpdir; *p; p += strlen (p) + 1)
1227     {
1228       if (expect && *p != expect)
1229         {
1230           ERROR ((0, 0,
1231                   _("Malformed dumpdir: expected '%c' but found %#3o"),
1232                   expect, *p));
1233           return false;
1234         }
1235       switch (*p)
1236         {
1237         case 'X':
1238           if (has_tempdir)
1239             {
1240               ERROR ((0, 0,
1241                       _("Malformed dumpdir: 'X' duplicated")));
1242               return false;
1243             }
1244           else
1245             has_tempdir = 1;
1246           break;
1247
1248         case 'R':
1249           if (p[1] == 0)
1250             {
1251               if (!has_tempdir)
1252                 {
1253                   ERROR ((0, 0,
1254                           _("Malformed dumpdir: empty name in 'R'")));
1255                   return false;
1256                 }
1257               else
1258                 has_tempdir = 0;
1259             }
1260           expect = 'T';
1261           break;
1262
1263         case 'T':
1264           if (expect != 'T')
1265             {
1266               ERROR ((0, 0,
1267                       _("Malformed dumpdir: 'T' not preceeded by 'R'")));
1268               return false;
1269             }
1270           if (p[1] == 0 && !has_tempdir)
1271             {
1272               ERROR ((0, 0,
1273                       _("Malformed dumpdir: empty name in 'T'")));
1274               return false;
1275             }
1276           expect = 0;
1277           break;
1278
1279         case 'N':
1280         case 'Y':
1281         case 'D':
1282           break;
1283
1284         default:
1285           /* FIXME: bail out? */
1286           break;
1287         }
1288     }
1289
1290   if (expect)
1291     {
1292       ERROR ((0, 0,
1293               _("Malformed dumpdir: expected '%c' but found end of data"),
1294               expect));
1295       return false;
1296     }
1297
1298   if (has_tempdir)
1299     WARN ((0, 0, _("Malformed dumpdir: 'X' never used")));
1300
1301   return true;
1302 }
1303
1304 /* Examine the directories under directory_name and delete any
1305    files that were not there at the time of the back-up. */
1306 static bool
1307 try_purge_directory (char const *directory_name)
1308 {
1309   char *current_dir;
1310   char *cur, *arc, *p;
1311   char *temp_stub = NULL;
1312
1313   if (!is_dumpdir (&current_stat_info))
1314     return false;
1315
1316   current_dir = savedir (directory_name);
1317
1318   if (!current_dir)
1319     /* The directory doesn't exist now.  It'll be created.  In any
1320        case, we don't have to delete any files out of it.  */
1321     return false;
1322
1323   /* Verify if dump directory is sane */
1324   if (!dumpdir_ok (current_stat_info.dumpdir))
1325     return false;
1326
1327   /* Process renames */
1328   for (arc = current_stat_info.dumpdir; *arc; arc += strlen (arc) + 1)
1329     {
1330       if (*arc == 'X')
1331         {
1332 #define TEMP_DIR_TEMPLATE "tar.XXXXXX"
1333           size_t len = strlen (arc + 1);
1334           temp_stub = xrealloc (temp_stub, len + 1 + sizeof TEMP_DIR_TEMPLATE);
1335           memcpy (temp_stub, arc + 1, len);
1336           temp_stub[len] = '/';
1337           memcpy (temp_stub + len + 1, TEMP_DIR_TEMPLATE,
1338                   sizeof TEMP_DIR_TEMPLATE);
1339           if (!mkdtemp (temp_stub))
1340             {
1341               ERROR ((0, errno,
1342                       _("Cannot create temporary directory using template %s"),
1343                       quote (temp_stub)));
1344               free (temp_stub);
1345               free (current_dir);
1346               return false;
1347             }
1348         }
1349       else if (*arc == 'R')
1350         {
1351           char *src, *dst;
1352           src = arc + 1;
1353           arc += strlen (arc) + 1;
1354           dst = arc + 1;
1355
1356           if (*src == 0)
1357             src = temp_stub;
1358           else if (*dst == 0)
1359             dst = temp_stub;
1360
1361           if (!rename_directory (src, dst))
1362             {
1363               free (temp_stub);
1364               free (current_dir);
1365               /* FIXME: Make sure purge_directory(dst) will return
1366                  immediately */
1367               return false;
1368             }
1369         }
1370     }
1371
1372   free (temp_stub);
1373
1374   /* Process deletes */
1375   p = NULL;
1376   for (cur = current_dir; *cur; cur += strlen (cur) + 1)
1377     {
1378       const char *entry;
1379       struct stat st;
1380       if (p)
1381         free (p);
1382       p = new_name (directory_name, cur);
1383
1384       if (deref_stat (false, p, &st))
1385         {
1386           if (errno != ENOENT) /* FIXME: Maybe keep a list of renamed
1387                                   dirs and check it here? */
1388             {
1389               stat_diag (p);
1390               WARN ((0, 0, _("%s: Not purging directory: unable to stat"),
1391                      quotearg_colon (p)));
1392             }
1393           continue;
1394         }
1395
1396       if (!(entry = dumpdir_locate (current_stat_info.dumpdir, cur))
1397           || (*entry == 'D' && !S_ISDIR (st.st_mode))
1398           || (*entry == 'Y' && S_ISDIR (st.st_mode)))
1399         {
1400           if (one_file_system_option && st.st_dev != root_device)
1401             {
1402               WARN ((0, 0,
1403                      _("%s: directory is on a different device: not purging"),
1404                      quotearg_colon (p)));
1405               continue;
1406             }
1407
1408           if (! interactive_option || confirm ("delete", p))
1409             {
1410               if (verbose_option)
1411                 fprintf (stdlis, _("%s: Deleting %s\n"),
1412                          program_name, quote (p));
1413               if (! remove_any_file (p, RECURSIVE_REMOVE_OPTION))
1414                 {
1415                   int e = errno;
1416                   ERROR ((0, e, _("%s: Cannot remove"), quotearg_colon (p)));
1417                 }
1418             }
1419         }
1420     }
1421   free (p);
1422
1423   free (current_dir);
1424   return true;
1425 }
1426
1427 void
1428 purge_directory (char const *directory_name)
1429 {
1430   if (!try_purge_directory (directory_name))
1431     skip_member ();
1432 }
1433
1434 void
1435 list_dumpdir (char *buffer, size_t size)
1436 {
1437   while (size)
1438     {
1439       switch (*buffer)
1440         {
1441         case 'Y':
1442         case 'N':
1443         case 'D':
1444         case 'R':
1445         case 'T':
1446         case 'X':
1447           fprintf (stdlis, "%c ", *buffer);
1448           buffer++;
1449           size--;
1450           break;
1451
1452         case 0:
1453           fputc ('\n', stdlis);
1454           buffer++;
1455           size--;
1456           break;
1457
1458         default:
1459           fputc (*buffer, stdlis);
1460           buffer++;
1461           size--;
1462         }
1463     }
1464 }