Rewritten handling of member names in the command
[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   strcpy (directory->name, name);
123   if (ISSLASH (directory->name[namelen-1]))
124     directory->name[namelen-1] = 0;
125   directory->flags = false;
126   return directory;
127 }
128   
129 /* Create and link a new directory entry for directory NAME, having a
130    device number DEV and an inode number INO, with NFS indicating
131    whether it is an NFS device and FOUND indicating whether we have
132    found that the directory exists.  */
133 static struct directory *
134 note_directory (char const *name, struct timespec mtime,
135                 dev_t dev, ino_t ino, bool nfs, bool found, char *contents)
136 {
137   struct directory *directory = make_directory (name);
138
139   directory->mtime = mtime;
140   directory->device_number = dev;
141   directory->inode_number = ino;
142   directory->children = CHANGED_CHILDREN;
143   if (nfs)
144     DIR_SET_FLAG (directory, DIRF_NFS);
145   if (found)
146     DIR_SET_FLAG (directory, DIRF_FOUND);
147   if (contents)
148     {
149       size_t size = dumpdir_size (contents);
150       directory->contents = xmalloc (size);
151       memcpy (directory->contents, contents, size);
152     }
153   else
154     directory->contents = NULL;
155   
156   if (! ((directory_table
157           || (directory_table = hash_initialize (0, 0,
158                                                  hash_directory_name,
159                                                  compare_directory_names, 0)))
160          && hash_insert (directory_table, directory)))
161     xalloc_die ();
162
163   if (! ((directory_meta_table
164           || (directory_meta_table = hash_initialize (0, 0,
165                                                       hash_directory_meta,
166                                                       compare_directory_meta,
167                                                       0)))
168          && hash_insert (directory_meta_table, directory)))
169     xalloc_die ();
170
171   return directory;
172 }
173
174 /* Return a directory entry for a given file NAME, or zero if none found.  */
175 static struct directory *
176 find_directory (const char *name)
177 {
178   if (! directory_table)
179     return 0;
180   else
181     {
182       struct directory *dir = make_directory (name);
183       struct directory *ret = hash_lookup (directory_table, dir);
184       free (dir);
185       return ret;
186     }
187 }
188
189 /* Return a directory entry for a given combination of device and inode
190    numbers, or zero if none found.  */
191 static struct directory *
192 find_directory_meta (dev_t dev, ino_t ino)
193 {
194   if (! directory_meta_table)
195     return 0;
196   else
197     {
198       struct directory *dir = make_directory ("");
199       struct directory *ret;
200       dir->device_number = dev;
201       dir->inode_number = ino;
202       ret = hash_lookup (directory_meta_table, dir);
203       free (dir);
204       return ret;
205     }
206 }
207
208 void
209 update_parent_directory (const char *name)
210 {
211   struct directory *directory;
212   char *p, *name_buffer;
213
214   p = dir_name (name);
215   directory = find_directory (p);
216   if (directory)
217     {
218       struct stat st;
219       if (deref_stat (dereference_option, p, &st) != 0)
220         stat_diag (name);
221       else
222         directory->mtime = get_stat_mtime (&st);
223     }
224   free (p);
225 }
226
227 static struct directory *
228 procdir (char *name_buffer, struct stat *stat_data,
229          dev_t device,
230          enum children children,
231          bool verbose)
232 {
233   struct directory *directory;
234   bool nfs = NFS_FILE_STAT (*stat_data);
235   struct name *np;
236
237   if ((directory = find_directory (name_buffer)) != NULL)
238     {
239       if (DIR_IS_INITED (directory))
240         return directory;
241       
242       /* With NFS, the same file can have two different devices
243          if an NFS directory is mounted in multiple locations,
244          which is relatively common when automounting.
245          To avoid spurious incremental redumping of
246          directories, consider all NFS devices as equal,
247          relying on the i-node to establish differences.  */
248
249       if (! (((DIR_IS_NFS (directory) & nfs)
250               || directory->device_number == stat_data->st_dev)
251              && directory->inode_number == stat_data->st_ino))
252         {
253           /* FIXME: find_directory_meta ignores nfs */
254           struct directory *d = find_directory_meta (stat_data->st_dev,
255                                                      stat_data->st_ino);
256           if (d)
257             {
258               if (verbose_option)
259                 WARN ((0, 0, _("%s: Directory has been renamed from %s"),
260                        quotearg_colon (name_buffer),
261                        quote_n (1, d->name)));
262               directory->orig = d;
263               DIR_SET_FLAG (directory, DIRF_RENAMED);
264               directory->children = CHANGED_CHILDREN;
265             }
266           else
267             {
268               if (verbose_option)
269                 WARN ((0, 0, _("%s: Directory has been renamed"),
270                        quotearg_colon (name_buffer)));
271               directory->children = ALL_CHILDREN;
272               directory->device_number = stat_data->st_dev;
273               directory->inode_number = stat_data->st_ino;
274             }
275           if (nfs)
276             DIR_SET_FLAG (directory, DIRF_NFS);
277         }
278       else
279         directory->children = CHANGED_CHILDREN;
280       
281       DIR_SET_FLAG (directory, DIRF_FOUND);
282     }
283   else
284     {
285       struct directory *d = find_directory_meta (stat_data->st_dev,
286                                                  stat_data->st_ino);
287
288       directory = note_directory (name_buffer,
289                                   get_stat_mtime(stat_data),
290                                   stat_data->st_dev,
291                                   stat_data->st_ino,
292                                   nfs,
293                                   true,
294                                   NULL);
295
296       if (d)
297         {
298           if (verbose)
299             WARN ((0, 0, _("%s: Directory has been renamed from %s"),
300                    quotearg_colon (name_buffer),
301                    quote_n (1, d->name)));
302           directory->orig = d;
303           DIR_SET_FLAG (directory, DIRF_RENAMED);
304           directory->children = CHANGED_CHILDREN;
305         }
306       else
307         {
308           DIR_SET_FLAG (directory, DIRF_NEW);
309           if (verbose)
310             WARN ((0, 0, _("%s: Directory is new"),
311                    quotearg_colon (name_buffer)));
312           directory->children = 
313             (listed_incremental_option
314              || (OLDER_STAT_TIME (*stat_data, m)
315                  || (after_date_option
316                      && OLDER_STAT_TIME (*stat_data, c))))
317             ? ALL_CHILDREN
318             : CHANGED_CHILDREN;
319         }
320     }
321
322   /* If the directory is on another device and --one-file-system was given,
323      omit it... */
324   if (one_file_system_option && device != stat_data->st_dev
325       /* ... except if it was explicitely given in the command line */
326       && !((np = name_scan (name_buffer, true)) && np->explicit))
327     directory->children = NO_CHILDREN;
328   else if (children == ALL_CHILDREN) 
329     directory->children = ALL_CHILDREN;
330
331   DIR_SET_FLAG (directory, DIRF_INIT);
332   
333   return directory;
334 }
335
336 /* Locate NAME in the dumpdir array DUMP.
337    Return pointer to the slot in the array, or NULL if not found */
338 const char *
339 dumpdir_locate (const char *dump, const char *name)
340 {
341   if (dump)
342     while (*dump)
343       {
344         /* Ignore 'R' (rename) entries, since they break alphabetical ordering.
345            They normally do not occur in dumpdirs from the snapshot files,
346            but this function is also used by purge_directory, which operates
347            on a dumpdir from the archive, hence the need for this test. */
348         if (*dump != 'R')
349           {
350             int rc = strcmp (dump + 1, name);
351             if (rc == 0)
352               return dump;
353             if (rc > 1)
354               break;
355           }
356         dump += strlen (dump) + 1;
357       }
358   return NULL;
359 }
360
361 /* Return size in bytes of the dumpdir array P */
362 size_t
363 dumpdir_size (const char *p)
364 {
365   size_t totsize = 0;
366
367   while (*p)
368     {
369       size_t size = strlen (p) + 1;
370       totsize += size;
371       p += size;
372     }
373   return totsize + 1;
374 }
375
376 static int
377 compare_dirnames (const void *first, const void *second)
378 {
379   return strcmp (*(const char**)first, *(const char**)second);
380 }
381
382 /* Compare dumpdir array from DIRECTORY with directory listing DIR and
383    build a new dumpdir template.
384
385    DIR must be returned by a previous call to savedir().
386
387    File names in DIRECTORY->contents must be sorted
388    alphabetically. 
389
390    DIRECTORY->contents is replaced with the created template. Each entry is
391    prefixed with ' ' if it was present in DUMP and with 'Y' otherwise. */
392
393 void
394 makedumpdir (struct directory *directory, const char *dir)
395 {
396   size_t i,
397          dirsize,  /* Number of elements in DIR */
398          len;      /* Length of DIR, including terminating nul */
399   const char *p;
400   char const **array;
401   char *new_dump, *new_dump_ptr;
402   const char *dump;
403
404   if (directory->children == ALL_CHILDREN)
405     dump = NULL;
406   else if (DIR_IS_RENAMED (directory))
407     dump = directory->orig->icontents ?
408               directory->orig->icontents : directory->orig->contents;
409   else
410     dump = directory->contents;
411
412   /* Count the size of DIR and the number of elements it contains */
413   dirsize = 0;
414   len = 0;
415   for (p = dir; *p; p += strlen (p) + 1, dirsize++)
416     len += strlen (p) + 2;
417   len++;
418
419   /* Create a sorted directory listing */
420   array = xcalloc (dirsize, sizeof array[0]);
421   for (i = 0, p = dir; *p; p += strlen (p) + 1, i++)
422     array[i] = p;
423
424   qsort (array, dirsize, sizeof (array[0]), compare_dirnames);
425
426   /* Prepare space for new dumpdir */
427   new_dump = xmalloc (len);
428   new_dump_ptr = new_dump;
429
430   /* Fill in the dumpdir template */
431   for (i = 0; i < dirsize; i++)
432     {
433       const char *loc = dumpdir_locate (dump, array[i]);
434       if (loc)
435         {
436           *new_dump_ptr++ = ' ';
437           dump = loc + strlen (loc) + 1;
438         }
439       else
440         *new_dump_ptr++ = 'Y'; /* New entry */
441
442       /* Copy the file name */
443       for (p = array[i]; (*new_dump_ptr++ = *p++); )
444         ;
445     }
446   *new_dump_ptr = 0;
447   directory->icontents = directory->contents;
448   directory->contents = new_dump;
449   free (array);
450 }
451
452 /* Recursively scan the given directory. */
453 static char *
454 scan_directory (char *dir_name, dev_t device)
455 {
456   char *dirp = savedir (dir_name);      /* for scanning directory */
457   char *name_buffer;            /* directory, `/', and directory member */
458   size_t name_buffer_size;      /* allocated size of name_buffer, minus 2 */
459   size_t name_length;           /* used length in name_buffer */
460   struct stat stat_data;
461   struct directory *directory;
462   
463   if (! dirp)
464     savedir_error (dir_name);
465
466   name_buffer_size = strlen (dir_name) + NAME_FIELD_SIZE;
467   name_buffer = xmalloc (name_buffer_size + 2);
468   strcpy (name_buffer, dir_name);
469   if (! ISSLASH (dir_name[strlen (dir_name) - 1]))
470     strcat (name_buffer, "/");
471   name_length = strlen (name_buffer);
472
473   if (deref_stat (dereference_option, name_buffer, &stat_data))
474     {
475       stat_diag (name_buffer);
476       /* FIXME: used to be 
477            children = CHANGED_CHILDREN;
478          but changed to: */
479       free (name_buffer);
480       free (dirp);
481       return NULL;
482     }
483
484   directory = procdir (name_buffer, &stat_data, device, NO_CHILDREN, false);
485     
486   if (dirp && directory->children != NO_CHILDREN)
487     {
488       char  *entry;     /* directory entry being scanned */
489       size_t entrylen;  /* length of directory entry */
490
491       makedumpdir (directory, dirp);
492
493       for (entry = directory->contents;
494            (entrylen = strlen (entry)) != 0;
495            entry += entrylen + 1)
496         {
497           if (name_buffer_size <= entrylen - 1 + name_length)
498             {
499               do
500                 name_buffer_size += NAME_FIELD_SIZE;
501               while (name_buffer_size <= entrylen - 1 + name_length);
502               name_buffer = xrealloc (name_buffer, name_buffer_size + 2);
503             }
504           strcpy (name_buffer + name_length, entry + 1);
505           
506           if (excluded_name (name_buffer))
507             *entry = 'N';
508           else
509             {
510               if (deref_stat (dereference_option, name_buffer, &stat_data))
511                 {
512                   stat_diag (name_buffer);
513                   *entry = 'N';
514                   continue;
515                 }
516               
517               if (S_ISDIR (stat_data.st_mode))
518                 {
519                   procdir (name_buffer, &stat_data, device,
520                            directory->children,
521                            verbose_option);
522                   *entry = 'D';
523                 }
524               
525               else if (one_file_system_option && device != stat_data.st_dev)
526                 *entry = 'N';
527
528               else if (*entry == 'Y')
529                 /* New entry, skip further checks */;
530               
531               /* FIXME: if (S_ISHIDDEN (stat_data.st_mode))?? */
532               
533               else if (OLDER_STAT_TIME (stat_data, m)
534                        && (!after_date_option
535                            || OLDER_STAT_TIME (stat_data, c)))
536                 *entry = 'N';
537               else
538                 *entry = 'Y';
539             }
540         }
541     }
542   
543   free (name_buffer);
544   if (dirp)
545     free (dirp);
546
547   return directory->contents;
548 }
549
550 char *
551 get_directory_contents (char *dir_name, dev_t device)
552 {
553   return scan_directory (dir_name, device);
554 }
555
556 \f
557 static bool
558 try_pos (char *name, int pos, const char *dumpdir)
559 {
560   int i;
561   static char namechars[] =
562     "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
563
564   if (pos > 0)
565     for (i = 0; i < sizeof namechars; i++)
566       {
567         name[pos] = namechars[i];
568         if (!dumpdir_locate (dumpdir, name)
569             || try_pos (name, pos-1, dumpdir))
570           return true;
571       }
572   
573   return false;
574 }
575   
576 static bool
577 create_temp_name (char *name, const char *dumpdir)
578 {
579   size_t pos = strlen (name) - 6;
580   return try_pos (name + pos, 5, dumpdir);
581 }
582
583 char *
584 make_tmp_dir_name (const char *name)
585 {
586   char *dirname = dir_name (name);
587   char *tmp_name = NULL;
588   struct directory *dir = find_directory (dirname);
589       
590   tmp_name = new_name (dirname, "000000");
591   if (!create_temp_name (tmp_name, dir ? dir->contents : NULL))
592     {
593       free (tmp_name);
594       tmp_name = NULL;
595     }
596   free (dirname);
597   return tmp_name;
598 }
599
600 static void
601 obstack_code_rename (struct obstack *stk, char *from, char *to)
602 {
603   obstack_1grow (stk, 'R');
604   obstack_grow (stk, from, strlen (from) + 1);
605   obstack_1grow (stk, 'T');
606   obstack_grow (stk, to, strlen (to) + 1);
607 }
608
609 static bool
610 rename_handler (void *data, void *proc_data)
611 {
612   struct directory *dir = data;
613   struct obstack *stk = proc_data;
614   
615   if (DIR_IS_RENAMED (dir))
616     {
617       struct directory *prev, *p;
618
619       /* Detect eventual cycles and clear DIRF_RENAMED flag, so this entries
620          are ignored when hit by this function next time.
621          If the chain forms a cycle, prev points to the entry DIR is renamed
622          from. In this case it still retains DIRF_RENAMED flag, which will be
623          cleared in the `else' branch below */
624       for (prev = dir; prev && prev->orig != dir; prev = prev->orig)
625         DIR_CLEAR_FLAG (prev, DIRF_RENAMED);
626
627       if (prev == NULL)
628         {
629           for (p = dir; p && p->orig; p = p->orig)
630             obstack_code_rename (stk, p->orig->name, p->name);
631         }
632       else
633         {
634           char *temp_name;
635
636           DIR_CLEAR_FLAG (prev, DIRF_RENAMED);
637
638           /* Break the cycle by using a temporary name for one of its
639              elements.
640              FIXME: Leave the choice of the name to the extractor. */
641           temp_name = make_tmp_dir_name (dir->name);
642           obstack_code_rename (stk, dir->name, temp_name);
643
644           for (p = dir; p != prev; p = p->orig)
645             obstack_code_rename (stk, p->orig->name, p->name);
646
647           obstack_code_rename (stk, temp_name, prev->name);
648         }
649     }
650   return true;
651 }
652
653 const char *
654 append_incremental_renames (const char *dump)
655 {
656   struct obstack stk;
657   size_t size;
658
659   if (directory_table == NULL)
660     return dump;
661   
662   obstack_init (&stk);
663   if (dump)
664     {
665       size = dumpdir_size (dump) - 1;
666       obstack_grow (&stk, dump, size);
667     }
668   else
669     size = 0;
670   
671   hash_do_for_each (directory_table, rename_handler, &stk);
672   if (obstack_object_size (&stk) != size)
673     {
674       obstack_1grow (&stk, 0);
675       dump = obstack_finish (&stk);
676     }
677   else
678     obstack_free (&stk, NULL);
679   return dump;
680 }
681
682 \f
683
684 static FILE *listed_incremental_stream;
685
686 /* Version of incremental format snapshots (directory files) used by this
687    tar. Currently it is supposed to be a single decimal number. 0 means
688    incremental snapshots as per tar version before 1.15.2.
689
690    The current tar version supports incremental versions from
691    0 up to TAR_INCREMENTAL_VERSION, inclusive.
692    It is able to create only snapshots of TAR_INCREMENTAL_VERSION */
693
694 #define TAR_INCREMENTAL_VERSION 2
695
696 /* Read incremental snapshot formats 0 and 1 */
697 static void
698 read_incr_db_01 (int version, const char *initbuf)
699 {
700   int n;
701   uintmax_t u;
702   time_t t = u;
703   char *buf = 0;
704   size_t bufsize;
705   char *ebuf;
706   long lineno = 1;
707
708   if (version == 1)
709     {
710       if (getline (&buf, &bufsize, listed_incremental_stream) <= 0)
711         {
712           read_error (listed_incremental_option);
713           free (buf);
714           return;
715         }
716       ++lineno;
717     }
718   else
719     {
720       buf = strdup (initbuf);
721       bufsize = strlen (buf) + 1;
722     }
723   
724   t = u = (errno = 0, strtoumax (buf, &ebuf, 10));
725   if (buf == ebuf || (u == 0 && errno == EINVAL))
726     ERROR ((0, 0, "%s:%ld: %s",
727             quotearg_colon (listed_incremental_option),
728             lineno,
729             _("Invalid time stamp")));
730   else if (t != u)
731     ERROR ((0, 0, "%s:%ld: %s",
732             quotearg_colon (listed_incremental_option),
733             lineno,
734             _("Time stamp out of range")));
735   else if (version == 1)
736     {
737       newer_mtime_option.tv_sec = t;
738
739       t = u = (errno = 0, strtoumax (buf, &ebuf, 10));
740       if (buf == ebuf || (u == 0 && errno == EINVAL))
741         ERROR ((0, 0, "%s:%ld: %s",
742                 quotearg_colon (listed_incremental_option),
743                 lineno,
744                 _("Invalid time stamp")));
745       else if (t != u)
746         ERROR ((0, 0, "%s:%ld: %s",
747                 quotearg_colon (listed_incremental_option),
748                 lineno,
749                 _("Time stamp out of range")));
750       newer_mtime_option.tv_nsec = t;
751     }
752   else
753     {
754       /* pre-1 incremental format does not contain nanoseconds */
755       newer_mtime_option.tv_sec = t;
756       newer_mtime_option.tv_nsec = 0;
757     }
758
759   while (0 < (n = getline (&buf, &bufsize, listed_incremental_stream)))
760     {
761       dev_t dev;
762       ino_t ino;
763       bool nfs = buf[0] == '+';
764       char *strp = buf + nfs;
765       struct timespec mtime;
766       
767       lineno++;
768       
769       if (buf[n - 1] == '\n')
770         buf[n - 1] = '\0';
771       
772       if (version == 1)
773         {
774           errno = 0;
775           mtime.tv_sec = u = strtoumax (strp, &ebuf, 10);
776           if (!isspace (*ebuf))
777             ERROR ((0, 0, "%s:%ld: %s",
778                     quotearg_colon (listed_incremental_option), lineno,
779                     _("Invalid modification time (seconds)")));
780           else if (mtime.tv_sec != u)
781             ERROR ((0, 0, "%s:%ld: %s",
782                     quotearg_colon (listed_incremental_option), lineno,
783                     _("Modification time (seconds) out of range")));
784           strp = ebuf;
785           
786           errno = 0;
787           mtime.tv_nsec = u = strtoumax (strp, &ebuf, 10);
788           if (!isspace (*ebuf))
789             ERROR ((0, 0, "%s:%ld: %s",
790                     quotearg_colon (listed_incremental_option), lineno,
791                     _("Invalid modification time (nanoseconds)")));
792           else if (mtime.tv_nsec != u)
793             ERROR ((0, 0, "%s:%ld: %s",
794                     quotearg_colon (listed_incremental_option), lineno,
795                     _("Modification time (nanoseconds) out of range")));
796           strp = ebuf;
797         }
798       else
799         memset (&mtime, 0, sizeof mtime);
800       
801       errno = 0;
802       dev = u = strtoumax (strp, &ebuf, 10);
803       if (!isspace (*ebuf))
804         ERROR ((0, 0, "%s:%ld: %s",
805                 quotearg_colon (listed_incremental_option), lineno,
806                 _("Invalid device number")));
807       else if (dev != u)
808         ERROR ((0, 0, "%s:%ld: %s",
809                 quotearg_colon (listed_incremental_option), lineno,
810                 _("Device number out of range")));
811       strp = ebuf;
812
813       errno = 0;
814       ino = u = strtoumax (strp, &ebuf, 10);
815       if (!isspace (*ebuf))
816         ERROR ((0, 0, "%s:%ld: %s",
817                 quotearg_colon (listed_incremental_option), lineno,
818                 _("Invalid inode number")));
819       else if (ino != u)
820         ERROR ((0, 0, "%s:%ld: %s",
821                 quotearg_colon (listed_incremental_option), lineno,
822                 _("Inode number out of range")));
823       strp = ebuf;
824       
825       strp++;
826       unquote_string (strp);
827       note_directory (strp, mtime, dev, ino, nfs, false, NULL);
828     }
829   free (buf);
830 }
831
832 /* Read a nul-terminated string from FP and store it in STK.
833    Store the number of bytes read (including nul terminator) in PCOUNT.
834
835    Return the last character read or EOF on end of file. */
836 static int
837 read_obstack (FILE *fp, struct obstack *stk, size_t *pcount)
838 {
839   int c;
840   size_t i;
841
842   for (i = 0, c = getc (fp); c != EOF && c != 0; c = getc (fp), i++)
843     obstack_1grow (stk, c);
844   obstack_1grow (stk, 0);
845
846   *pcount = i;
847   return c;
848 }
849
850 /* Read from file FP a nul-terminated string and convert it to
851    uintmax_t. Return the resulting value in PVAL.
852
853    Throw fatal error if the string cannot be converted.
854    
855    Return the last character read or EOF on end of file. */
856
857 static int
858 read_num (FILE *fp, uintmax_t *pval)
859 {
860   int c;
861   size_t i;
862   char buf[UINTMAX_STRSIZE_BOUND], *ep;
863
864   for (i = 0, c = getc (fp); c != EOF && c != 0; c = getc (fp), i++)
865     {
866       if (i == sizeof buf - 1)
867         FATAL_ERROR ((0, 0, _("Field too long while reading snapshot file")));
868       buf[i] = c;
869     }
870   buf[i] = 0;
871   *pval = strtoumax (buf, &ep, 10);
872   if (*ep)
873     FATAL_ERROR ((0, 0, _("Unexpected field value in snapshot file")));
874   return c;
875 }  
876
877 /* Read incremental snapshot format 2 */
878 static void
879 read_incr_db_2 ()
880 {
881   uintmax_t u;
882   struct obstack stk;
883   
884   obstack_init (&stk);
885
886   if (read_num (listed_incremental_stream, &u))
887     FATAL_ERROR ((0, 0, "%s: %s",
888                   quotearg_colon (listed_incremental_option), 
889                   _("Error reading time stamp")));
890   newer_mtime_option.tv_sec = u;
891   if (newer_mtime_option.tv_sec != u)
892     FATAL_ERROR ((0, 0, "%s: %s",
893                   quotearg_colon (listed_incremental_option),
894                   _("Time stamp out of range")));
895
896   if (read_num (listed_incremental_stream, &u))
897     FATAL_ERROR ((0, 0, "%s: %s",
898                   quotearg_colon (listed_incremental_option), 
899                   _("Error reading time stamp")));
900   newer_mtime_option.tv_nsec = u;
901   if (newer_mtime_option.tv_nsec != u)
902     FATAL_ERROR ((0, 0, "%s: %s",
903                   quotearg_colon (listed_incremental_option),
904                   _("Time stamp out of range")));
905
906   for (;;)
907     {
908       struct timespec mtime;
909       dev_t dev;
910       ino_t ino;
911       bool nfs;
912       char *name;
913       char *content;
914       size_t s;
915       
916       if (read_num (listed_incremental_stream, &u))
917         return; /* Normal return */
918
919       nfs = u;
920       
921       if (read_num (listed_incremental_stream, &u))
922         break;
923       mtime.tv_sec = u;
924       if (mtime.tv_sec != u)
925         FATAL_ERROR ((0, 0, "%s: %s",
926                       quotearg_colon (listed_incremental_option), 
927                       _("Modification time (seconds) out of range")));
928       
929       if (read_num (listed_incremental_stream, &u))
930         break;
931       mtime.tv_nsec = u;
932       if (mtime.tv_nsec != u)
933         FATAL_ERROR ((0, 0, "%s: %s",
934                       quotearg_colon (listed_incremental_option), 
935                       _("Modification time (nanoseconds) out of range")));
936
937       if (read_num (listed_incremental_stream, &u))
938         break;
939       dev = u;
940       if (dev != u)
941         FATAL_ERROR ((0, 0, "%s: %s",
942                       quotearg_colon (listed_incremental_option), 
943                       _("Device number out of range")));
944
945       if (read_num (listed_incremental_stream, &u))
946         break;
947       ino = u;
948       if (ino != u)
949         FATAL_ERROR ((0, 0, "%s: %s",
950                       quotearg_colon (listed_incremental_option), 
951                       _("Inode number out of range")));
952
953       if (read_obstack (listed_incremental_stream, &stk, &s))
954         break;
955
956       name = obstack_finish (&stk);
957
958       while (read_obstack (listed_incremental_stream, &stk, &s) == 0 && s > 1)
959         ;
960       if (getc (listed_incremental_stream) != 0)
961         FATAL_ERROR ((0, 0, "%s: %s",
962                       quotearg_colon (listed_incremental_option), 
963                       _("Missing record terminator")));
964       
965       content = obstack_finish (&stk);
966       note_directory (name, mtime, dev, ino, nfs, false, content);
967       obstack_free (&stk, content);
968     }
969   FATAL_ERROR ((0, 0, "%s: %s",
970                 quotearg_colon (listed_incremental_option), 
971                 _("Unexpected EOF")));
972 }
973
974 /* Read incremental snapshot file (directory file).
975    If the file has older incremental version, make sure that it is processed
976    correctly and that tar will use the most conservative backup method among
977    possible alternatives (i.e. prefer ALL_CHILDREN over CHANGED_CHILDREN,
978    etc.) This ensures that the snapshots are updated to the recent version
979    without any loss of data. */
980 void
981 read_directory_file (void)
982 {
983   int fd;
984   char *buf = 0;
985   size_t bufsize;
986   long lineno = 1;
987
988   /* Open the file for both read and write.  That way, we can write
989      it later without having to reopen it, and don't have to worry if
990      we chdir in the meantime.  */
991   fd = open (listed_incremental_option, O_RDWR | O_CREAT, MODE_RW);
992   if (fd < 0)
993     {
994       open_error (listed_incremental_option);
995       return;
996     }
997
998   listed_incremental_stream = fdopen (fd, "r+");
999   if (! listed_incremental_stream)
1000     {
1001       open_error (listed_incremental_option);
1002       close (fd);
1003       return;
1004     }
1005
1006   if (0 < getline (&buf, &bufsize, listed_incremental_stream))
1007     {
1008       char *ebuf;
1009       int incremental_version;
1010
1011       if (strncmp (buf, PACKAGE_NAME, sizeof PACKAGE_NAME - 1) == 0)
1012         {
1013           ebuf = buf + sizeof PACKAGE_NAME - 1;
1014           if (*ebuf++ != '-')
1015             ERROR((1, 0, _("Bad incremental file format")));
1016           for (; *ebuf != '-'; ebuf++)
1017             if (!*ebuf)
1018               ERROR((1, 0, _("Bad incremental file format")));
1019
1020           incremental_version = (errno = 0, strtoumax (ebuf+1, &ebuf, 10));
1021         }
1022       else
1023         incremental_version = 0;
1024
1025       switch (incremental_version)
1026         {
1027         case 0:
1028         case 1:
1029           read_incr_db_01 (incremental_version, buf);
1030           break;
1031
1032         case TAR_INCREMENTAL_VERSION:
1033           read_incr_db_2 ();
1034           break;
1035           
1036         default:
1037           ERROR ((1, 0, _("Unsupported incremental format version: %d"),
1038                   incremental_version));
1039         }
1040       
1041     }
1042
1043   if (ferror (listed_incremental_stream))
1044     read_error (listed_incremental_option);
1045   if (buf)
1046     free (buf);
1047 }
1048
1049 /* Output incremental data for the directory ENTRY to the file DATA.
1050    Return nonzero if successful, preserving errno on write failure.  */
1051 static bool
1052 write_directory_file_entry (void *entry, void *data)
1053 {
1054   struct directory const *directory = entry;
1055   FILE *fp = data;
1056
1057   if (DIR_IS_FOUND (directory))
1058     {
1059       char buf[UINTMAX_STRSIZE_BOUND];
1060       char *s;
1061
1062       s = DIR_IS_NFS (directory) ? "1" : "0";
1063       fwrite (s, 2, 1, fp);
1064       s = umaxtostr (directory->mtime.tv_sec, buf);
1065       fwrite (s, strlen (s) + 1, 1, fp);
1066       s = umaxtostr (directory->mtime.tv_nsec, buf);
1067       fwrite (s, strlen (s) + 1, 1, fp);
1068       s = umaxtostr (directory->device_number, buf);
1069       fwrite (s, strlen (s) + 1, 1, fp);
1070       s = umaxtostr (directory->inode_number, buf);
1071       fwrite (s, strlen (s) + 1, 1, fp);
1072
1073       fwrite (directory->name, strlen (directory->name) + 1, 1, fp);
1074       if (directory->contents)
1075         {
1076           char *p;
1077           for (p = directory->contents; *p; p += strlen (p) + 1)
1078             {
1079               if (strchr ("YND", *p))
1080                 fwrite (p, strlen (p) + 1, 1, fp);
1081             }
1082         }
1083       fwrite ("\0\0", 2, 1, fp);
1084     }
1085
1086   return ! ferror (fp);
1087 }
1088
1089 void
1090 write_directory_file (void)
1091 {
1092   FILE *fp = listed_incremental_stream;
1093   char buf[UINTMAX_STRSIZE_BOUND];
1094   char *s;
1095
1096   if (! fp)
1097     return;
1098
1099   if (fseek (fp, 0L, SEEK_SET) != 0)
1100     seek_error (listed_incremental_option);
1101   if (sys_truncate (fileno (fp)) != 0)
1102     truncate_error (listed_incremental_option);
1103
1104   fprintf (fp, "%s-%s-%d\n", PACKAGE_NAME, PACKAGE_VERSION,
1105            TAR_INCREMENTAL_VERSION);
1106
1107   s = umaxtostr (start_time.tv_sec, buf);
1108   fwrite (s, strlen (s) + 1, 1, fp);
1109   s = umaxtostr (start_time.tv_nsec, buf);
1110   fwrite (s, strlen (s) + 1, 1, fp);
1111
1112   if (! ferror (fp) && directory_table)
1113     hash_do_for_each (directory_table, write_directory_file_entry, fp);
1114
1115   if (ferror (fp))
1116     write_error (listed_incremental_option);
1117   if (fclose (fp) != 0)
1118     close_error (listed_incremental_option);
1119 }
1120
1121 \f
1122 /* Restoration of incremental dumps.  */
1123
1124 static void
1125 get_gnu_dumpdir (struct tar_stat_info *stat_info)
1126 {
1127   size_t size;
1128   size_t copied;
1129   union block *data_block;
1130   char *to;
1131   char *archive_dir;
1132
1133   size = stat_info->stat.st_size;
1134
1135   archive_dir = xmalloc (size);
1136   to = archive_dir;
1137
1138   set_next_block_after (current_header);
1139   mv_begin (stat_info);
1140
1141   for (; size > 0; size -= copied)
1142     {
1143       mv_size_left (size);
1144       data_block = find_next_block ();
1145       if (!data_block)
1146         ERROR ((1, 0, _("Unexpected EOF in archive")));
1147       copied = available_space_after (data_block);
1148       if (copied > size)
1149         copied = size;
1150       memcpy (to, data_block->buffer, copied);
1151       to += copied;
1152       set_next_block_after ((union block *)
1153                             (data_block->buffer + copied - 1));
1154     }
1155
1156   mv_end ();
1157
1158   stat_info->dumpdir = archive_dir;
1159   stat_info->skipped = true; /* For skip_member() and friends
1160                                 to work correctly */
1161 }
1162
1163 /* Return T if STAT_INFO represents a dumpdir archive member.
1164    Note: can invalidate current_header. It happens if flush_archive()
1165    gets called within get_gnu_dumpdir() */
1166 bool
1167 is_dumpdir (struct tar_stat_info *stat_info)
1168 {
1169   if (stat_info->is_dumpdir && !stat_info->dumpdir)
1170     get_gnu_dumpdir (stat_info);
1171   return stat_info->is_dumpdir;
1172 }
1173
1174 /* Examine the directories under directory_name and delete any
1175    files that were not there at the time of the back-up. */
1176 void
1177 purge_directory (char const *directory_name)
1178 {
1179   char *current_dir;
1180   char *cur, *arc, *p;
1181
1182   if (!is_dumpdir (&current_stat_info))
1183     {
1184       skip_member ();
1185       return;
1186     }
1187
1188   current_dir = savedir (directory_name);
1189
1190   if (!current_dir)
1191     {
1192       /* The directory doesn't exist now.  It'll be created.  In any
1193          case, we don't have to delete any files out of it.  */
1194
1195       skip_member ();
1196       return;
1197     }
1198
1199   /* Process renames */
1200   for (arc = current_stat_info.dumpdir; *arc; arc += strlen (arc) + 1)
1201     {
1202       if (*arc == 'R')
1203         {
1204           char *src, *dst;
1205           src = arc + 1;
1206           arc += strlen (arc) + 1;
1207           dst = arc + 1;
1208
1209           if (!rename_directory (src, dst))
1210             {
1211               free (current_dir);
1212               /* FIXME: Make sure purge_directory(dst) will return
1213                  immediately */
1214               return;
1215             }
1216         }
1217     }
1218   
1219   /* Process deletes */
1220   p = NULL;
1221   for (cur = current_dir; *cur; cur += strlen (cur) + 1)
1222     {
1223       const char *entry;
1224       struct stat st;
1225       if (p)
1226         free (p);
1227       p = new_name (directory_name, cur);
1228
1229       if (!(entry = dumpdir_locate (current_stat_info.dumpdir, cur))
1230           || (*entry == 'D' && S_ISDIR (st.st_mode))
1231           || (*entry == 'Y' && !S_ISDIR (st.st_mode)))
1232         {
1233           if (deref_stat (false, p, &st))
1234             {
1235               if (errno != ENOENT) /* FIXME: Maybe keep a list of renamed
1236                                       dirs and check it here? */
1237                 {
1238                   stat_diag (p);
1239                   WARN ((0, 0, _("%s: Not purging directory: unable to stat"),
1240                          quotearg_colon (p)));
1241                 }
1242               continue;
1243             }
1244           else if (one_file_system_option && st.st_dev != root_device)
1245             {
1246               WARN ((0, 0,
1247                      _("%s: directory is on a different device: not purging"),
1248                      quotearg_colon (p)));
1249               continue;
1250             }
1251
1252           if (! interactive_option || confirm ("delete", p))
1253             {
1254               if (verbose_option)
1255                 fprintf (stdlis, _("%s: Deleting %s\n"),
1256                          program_name, quote (p));
1257               if (! remove_any_file (p, RECURSIVE_REMOVE_OPTION))
1258                 {
1259                   int e = errno;
1260                   ERROR ((0, e, _("%s: Cannot remove"), quotearg_colon (p)));
1261                 }
1262             }
1263         }
1264     }
1265   free (p);
1266   
1267   free (current_dir);
1268 }
1269
1270 void
1271 list_dumpdir (char *buffer, size_t size)
1272 {
1273   while (size)
1274     {
1275       switch (*buffer)
1276         {
1277         case 'Y':
1278         case 'N':
1279         case 'D':
1280         case 'R':
1281         case 'T':
1282           fprintf (stdlis, "%c ", *buffer);
1283           buffer++;
1284           size--;
1285           break;
1286
1287         case 0:
1288           fputc ('\n', stdlis);
1289           buffer++;
1290           size--;
1291           break;
1292
1293         default:
1294           fputc (*buffer, stdlis);
1295           buffer++;
1296           size--;
1297         }
1298     }
1299 }