Fix some problems with negative and out-of-range integers.
[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, 2007, 2008, 2009 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 3, 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 <hash.h>
22 #include <quotearg.h>
23 #include "common.h"
24
25 /* Incremental dump specialities.  */
26
27 /* Which child files to save under a directory.  */
28 enum children
29   {
30     NO_CHILDREN,
31     CHANGED_CHILDREN,
32     ALL_CHILDREN
33   };
34
35 #define DIRF_INIT     0x0001    /* directory structure is initialized
36                                    (procdir called at least once) */
37 #define DIRF_NFS      0x0002    /* directory is mounted on nfs */
38 #define DIRF_FOUND    0x0004    /* directory is found on fs */
39 #define DIRF_NEW      0x0008    /* directory is new (not found
40                                    in the previous dump) */
41 #define DIRF_RENAMED  0x0010    /* directory is renamed */
42
43 #define DIR_IS_INITED(d) ((d)->flags & DIRF_INIT)
44 #define DIR_IS_NFS(d) ((d)->flags & DIRF_NFS)
45 #define DIR_IS_FOUND(d) ((d)->flags & DIRF_FOUND)
46 /* #define DIR_IS_NEW(d) ((d)->flags & DIRF_NEW) FIXME: not used */
47 #define DIR_IS_RENAMED(d) ((d)->flags & DIRF_RENAMED)
48
49 #define DIR_SET_FLAG(d,f) (d)->flags |= (f)
50 #define DIR_CLEAR_FLAG(d,f) (d)->flags &= ~(f)
51
52 struct dumpdir                 /* Dump directory listing */
53 {
54   char *contents;              /* Actual contents */
55   size_t total;                /* Total number of elements */
56   size_t elc;                  /* Number of D/N/Y elements. */
57   char **elv;                  /* Array of D/N/Y elements */
58 };
59
60 /* Directory attributes.  */
61 struct directory
62   {
63     struct directory *next;
64     struct timespec mtime;      /* Modification time */
65     dev_t device_number;        /* device number for directory */
66     ino_t inode_number;         /* inode number for directory */
67     struct dumpdir *dump;       /* Directory contents */
68     struct dumpdir *idump;      /* Initial contents if the directory was
69                                    rescanned */
70     enum children children;     /* What to save under this directory */
71     unsigned flags;             /* See DIRF_ macros above */
72     struct directory *orig;     /* If the directory was renamed, points to
73                                    the original directory structure */
74     const char *tagfile;        /* Tag file, if the directory falls under
75                                    exclusion_tag_under */
76     char *caname;               /* canonical name */
77     char *name;                 /* file name of directory */
78   };
79
80 static struct dumpdir *
81 dumpdir_create0 (const char *contents, const char *cmask)
82 {
83   struct dumpdir *dump;
84   size_t i, total, ctsize, len;
85   char *p;
86   const char *q;
87
88   for (i = 0, total = 0, ctsize = 1, q = contents; *q; total++, q += len)
89     {
90       len = strlen (q) + 1;
91       ctsize += len;
92       if (!cmask || strchr (cmask, *q))
93         i++;
94     }
95   dump = xmalloc (sizeof (*dump) + ctsize);
96   dump->contents = (char*)(dump + 1);
97   memcpy (dump->contents, contents, ctsize);
98   dump->total = total;
99   dump->elc = i;
100   dump->elv = xcalloc (i + 1, sizeof (dump->elv[0]));
101
102   for (i = 0, p = dump->contents; *p; p += strlen (p) + 1)
103     {
104       if (!cmask || strchr (cmask, *p))
105         dump->elv[i++] = p + 1;
106     }
107   dump->elv[i] = NULL;
108   return dump;
109 }
110
111 static struct dumpdir *
112 dumpdir_create (const char *contents)
113 {
114   return dumpdir_create0 (contents, "YND");
115 }
116
117 static void
118 dumpdir_free (struct dumpdir *dump)
119 {
120   free (dump->elv);
121   free (dump);
122 }
123
124 static int
125 compare_dirnames (const void *first, const void *second)
126 {
127   char const *const *name1 = first;
128   char const *const *name2 = second;
129   return strcmp (*name1, *name2);
130 }
131
132 /* Locate NAME in the dumpdir array DUMP.
133    Return pointer to the slot in DUMP->contents, or NULL if not found */
134 static char *
135 dumpdir_locate (struct dumpdir *dump, const char *name)
136 {
137   char **ptr;
138   if (!dump)
139     return NULL;
140
141   ptr = bsearch (&name, dump->elv, dump->elc, sizeof (dump->elv[0]),
142                  compare_dirnames);
143   return ptr ? *ptr - 1: NULL;
144 }
145
146 struct dumpdir_iter
147 {
148   struct dumpdir *dump; /* Dumpdir being iterated */
149   int all;              /* Iterate over all entries, not only D/N/Y */
150   size_t next;          /* Index of the next element */
151 };
152
153 static char *
154 dumpdir_next (struct dumpdir_iter *itr)
155 {
156   size_t cur = itr->next;
157   char *ret = NULL;
158
159   if (itr->all)
160     {
161       ret = itr->dump->contents + cur;
162       if (*ret == 0)
163         return NULL;
164       itr->next += strlen (ret) + 1;
165     }
166   else if (cur < itr->dump->elc)
167     {
168       ret = itr->dump->elv[cur] - 1;
169       itr->next++;
170     }
171
172   return ret;
173 }
174
175 static char *
176 dumpdir_first (struct dumpdir *dump, int all, struct dumpdir_iter **pitr)
177 {
178   struct dumpdir_iter *itr = xmalloc (sizeof (*itr));
179   itr->dump = dump;
180   itr->all = all;
181   itr->next = 0;
182   *pitr = itr;
183   return dumpdir_next (itr);
184 }
185
186 /* Return size in bytes of the dumpdir array P */
187 size_t
188 dumpdir_size (const char *p)
189 {
190   size_t totsize = 0;
191
192   while (*p)
193     {
194       size_t size = strlen (p) + 1;
195       totsize += size;
196       p += size;
197     }
198   return totsize + 1;
199 }
200
201 \f
202 static struct directory *dirhead, *dirtail;
203 static Hash_table *directory_table;
204 static Hash_table *directory_meta_table;
205
206 #if HAVE_ST_FSTYPE_STRING
207   static char const nfs_string[] = "nfs";
208 # define NFS_FILE_STAT(st) (strcmp ((st).st_fstype, nfs_string) == 0)
209 #else
210 # define ST_DEV_MSB(st) (~ (dev_t) 0 << (sizeof (st).st_dev * CHAR_BIT - 1))
211 # define NFS_FILE_STAT(st) (((st).st_dev & ST_DEV_MSB (st)) != 0)
212 #endif
213
214 /* Calculate the hash of a directory.  */
215 static size_t
216 hash_directory_canonical_name (void const *entry, size_t n_buckets)
217 {
218   struct directory const *directory = entry;
219   return hash_string (directory->caname, n_buckets);
220 }
221
222 /* Compare two directories for equality of their names. */
223 static bool
224 compare_directory_canonical_names (void const *entry1, void const *entry2)
225 {
226   struct directory const *directory1 = entry1;
227   struct directory const *directory2 = entry2;
228   return strcmp (directory1->caname, directory2->caname) == 0;
229 }
230
231 static size_t
232 hash_directory_meta (void const *entry, size_t n_buckets)
233 {
234   struct directory const *directory = entry;
235   /* FIXME: Work out a better algorytm */
236   return (directory->device_number + directory->inode_number) % n_buckets;
237 }
238
239 /* Compare two directories for equality of their device and inode numbers. */
240 static bool
241 compare_directory_meta (void const *entry1, void const *entry2)
242 {
243   struct directory const *directory1 = entry1;
244   struct directory const *directory2 = entry2;
245   return directory1->device_number == directory2->device_number
246             && directory1->inode_number == directory2->inode_number;
247 }
248
249 /* Make a directory entry for given relative NAME and canonical name CANAME.
250    The latter is "stolen", i.e. the returned directory contains pointer to
251    it. */
252 static struct directory *
253 make_directory (const char *name, char *caname)
254 {
255   size_t namelen = strlen (name);
256   struct directory *directory = xmalloc (sizeof (*directory));
257   directory->next = NULL;
258   directory->dump = directory->idump = NULL;
259   directory->orig = NULL;
260   directory->flags = false;
261   if (namelen > 1 && ISSLASH (name[namelen - 1]))
262     namelen--;
263   directory->name = xmalloc (namelen + 1);
264   memcpy (directory->name, name, namelen);
265   directory->name[namelen] = 0;
266   directory->caname = caname;
267   directory->tagfile = NULL;
268   return directory;
269 }
270
271 static void
272 free_directory (struct directory *dir)
273 {
274   free (dir->caname);
275   free (dir->name);
276   free (dir);
277 }
278
279 static struct directory *
280 attach_directory (const char *name)
281 {
282   char *cname = normalize_filename (name);
283   struct directory *dir = make_directory (name, cname);
284   if (dirtail)
285     dirtail->next = dir;
286   else
287     dirhead = dir;
288   dirtail = dir;
289   return dir;
290 }
291
292 \f
293 static void
294 dirlist_replace_prefix (const char *pref, const char *repl)
295 {
296   struct directory *dp;
297   size_t pref_len = strlen (pref);
298   size_t repl_len = strlen (repl);
299   for (dp = dirhead; dp; dp = dp->next)
300     replace_prefix (&dp->name, pref, pref_len, repl, repl_len);
301 }
302
303 void
304 clear_directory_table (void)
305 {
306   struct directory *dp;
307
308   if (directory_table)
309     hash_clear (directory_table);
310   if (directory_meta_table)
311     hash_clear (directory_meta_table);
312   for (dp = dirhead; dp; )
313     {
314       struct directory *next = dp->next;
315       free_directory (dp);
316       dp = next;
317     }
318   dirhead = dirtail = NULL;
319 }
320
321 /* Create and link a new directory entry for directory NAME, having a
322    device number DEV and an inode number INO, with NFS indicating
323    whether it is an NFS device and FOUND indicating whether we have
324    found that the directory exists.  */
325 static struct directory *
326 note_directory (char const *name, struct timespec mtime,
327                 dev_t dev, ino_t ino, bool nfs, bool found,
328                 const char *contents)
329 {
330   struct directory *directory = attach_directory (name);
331
332   directory->mtime = mtime;
333   directory->device_number = dev;
334   directory->inode_number = ino;
335   directory->children = CHANGED_CHILDREN;
336   if (nfs)
337     DIR_SET_FLAG (directory, DIRF_NFS);
338   if (found)
339     DIR_SET_FLAG (directory, DIRF_FOUND);
340   if (contents)
341     directory->dump = dumpdir_create (contents);
342   else
343     directory->dump = NULL;
344
345   if (! ((directory_table
346           || (directory_table = hash_initialize (0, 0,
347                                                  hash_directory_canonical_name,
348                                                  compare_directory_canonical_names,
349                                                  0)))
350          && hash_insert (directory_table, directory)))
351     xalloc_die ();
352
353   if (! ((directory_meta_table
354           || (directory_meta_table = hash_initialize (0, 0,
355                                                       hash_directory_meta,
356                                                       compare_directory_meta,
357                                                       0)))
358          && hash_insert (directory_meta_table, directory)))
359     xalloc_die ();
360
361   return directory;
362 }
363
364 /* Return a directory entry for a given file NAME, or zero if none found.  */
365 static struct directory *
366 find_directory (const char *name)
367 {
368   if (! directory_table)
369     return 0;
370   else
371     {
372       char *caname = normalize_filename (name);
373       struct directory *dir = make_directory (name, caname);
374       struct directory *ret = hash_lookup (directory_table, dir);
375       free_directory (dir);
376       return ret;
377     }
378 }
379
380 #if 0
381 /* Remove directory entry for the given CANAME */
382 void
383 remove_directory (const char *caname)
384 {
385   struct directory *dir = make_directory (caname, xstrdup (caname));
386   struct directory *ret = hash_delete (directory_table, dir);
387   if (ret)
388     free_directory (ret);
389   free_directory (dir);
390 }
391 #endif
392
393 /* If first OLD_PREFIX_LEN bytes of DIR->NAME name match OLD_PREFIX,
394    replace them with NEW_PREFIX. */
395 void
396 rebase_directory (struct directory *dir,
397                   const char *old_prefix, size_t old_prefix_len,
398                   const char *new_prefix, size_t new_prefix_len)
399 {
400   replace_prefix (&dir->name, old_prefix, old_prefix_len,
401                   new_prefix, new_prefix_len);
402 }
403
404 /* Return a directory entry for a given combination of device and inode
405    numbers, or zero if none found.  */
406 static struct directory *
407 find_directory_meta (dev_t dev, ino_t ino)
408 {
409   if (! directory_meta_table)
410     return 0;
411   else
412     {
413       struct directory *dir = make_directory ("", NULL);
414       struct directory *ret;
415       dir->device_number = dev;
416       dir->inode_number = ino;
417       ret = hash_lookup (directory_meta_table, dir);
418       free_directory (dir);
419       return ret;
420     }
421 }
422
423 void
424 update_parent_directory (struct tar_stat_info *parent)
425 {
426   struct directory *directory = find_directory (parent->orig_file_name);
427   if (directory)
428     {
429       struct stat st;
430       if (fstat (parent->fd, &st) != 0)
431         stat_diag (directory->name);
432       else
433         directory->mtime = get_stat_mtime (&st);
434     }
435 }
436
437 #define PD_FORCE_CHILDREN 0x10
438 #define PD_FORCE_INIT     0x20
439 #define PD_CHILDREN(f) ((f) & 3)
440
441 static struct directory *
442 procdir (const char *name_buffer, struct tar_stat_info *st,
443          int flag,
444          char *entry)
445 {
446   struct directory *directory;
447   struct stat *stat_data = &st->stat;
448   bool nfs = NFS_FILE_STAT (*stat_data);
449   bool perhaps_renamed = false;
450
451   if ((directory = find_directory (name_buffer)) != NULL)
452     {
453       if (DIR_IS_INITED (directory))
454         {
455           if (flag & PD_FORCE_INIT)
456             {
457               assign_string (&directory->name, name_buffer);
458             }
459           else
460             {
461               *entry = 'N'; /* Avoid duplicating this directory */
462               return directory;
463             }
464         }
465
466       if (strcmp (directory->name, name_buffer))
467         {
468           *entry = 'N';
469           return directory;
470         }
471
472       /* With NFS, the same file can have two different devices
473          if an NFS directory is mounted in multiple locations,
474          which is relatively common when automounting.
475          To avoid spurious incremental redumping of
476          directories, consider all NFS devices as equal,
477          relying on the i-node to establish differences.  */
478
479       if (! ((!check_device_option
480               || (DIR_IS_NFS (directory) && nfs)
481               || directory->device_number == stat_data->st_dev)
482              && directory->inode_number == stat_data->st_ino))
483         {
484           /* FIXME: find_directory_meta ignores nfs */
485           struct directory *d = find_directory_meta (stat_data->st_dev,
486                                                      stat_data->st_ino);
487           if (d)
488             {
489               if (strcmp (d->name, name_buffer))
490                 {
491                   WARNOPT (WARN_RENAME_DIRECTORY,
492                            (0, 0,
493                             _("%s: Directory has been renamed from %s"),
494                             quotearg_colon (name_buffer),
495                             quote_n (1, d->name)));
496                   directory->orig = d;
497                   DIR_SET_FLAG (directory, DIRF_RENAMED);
498                   dirlist_replace_prefix (d->name, name_buffer);
499                 }
500               directory->children = CHANGED_CHILDREN;
501             }
502           else
503             {
504               perhaps_renamed = true;
505               directory->children = ALL_CHILDREN;
506               directory->device_number = stat_data->st_dev;
507               directory->inode_number = stat_data->st_ino;
508             }
509           if (nfs)
510             DIR_SET_FLAG (directory, DIRF_NFS);
511         }
512       else
513         directory->children = CHANGED_CHILDREN;
514
515       DIR_SET_FLAG (directory, DIRF_FOUND);
516     }
517   else
518     {
519       struct directory *d = find_directory_meta (stat_data->st_dev,
520                                                  stat_data->st_ino);
521
522       directory = note_directory (name_buffer,
523                                   get_stat_mtime (stat_data),
524                                   stat_data->st_dev,
525                                   stat_data->st_ino,
526                                   nfs,
527                                   true,
528                                   NULL);
529
530       if (d)
531         {
532           if (strcmp (d->name, name_buffer))
533             {
534               WARNOPT (WARN_RENAME_DIRECTORY,
535                        (0, 0, _("%s: Directory has been renamed from %s"),
536                         quotearg_colon (name_buffer),
537                         quote_n (1, d->name)));
538               directory->orig = d;
539               DIR_SET_FLAG (directory, DIRF_RENAMED);
540               dirlist_replace_prefix (d->name, name_buffer);
541             }
542           directory->children = CHANGED_CHILDREN;
543         }
544       else
545         {
546           DIR_SET_FLAG (directory, DIRF_NEW);
547           WARNOPT (WARN_NEW_DIRECTORY,
548                    (0, 0, _("%s: Directory is new"),
549                     quotearg_colon (name_buffer)));
550           directory->children =
551             (listed_incremental_option
552              || (OLDER_STAT_TIME (*stat_data, m)
553                  || (after_date_option
554                      && OLDER_STAT_TIME (*stat_data, c))))
555             ? ALL_CHILDREN
556             : CHANGED_CHILDREN;
557         }
558     }
559
560   if (one_file_system_option && st->parent
561       && stat_data->st_dev != st->parent->stat.st_dev)
562     {
563       WARNOPT (WARN_XDEV,
564                (0, 0,
565                 _("%s: directory is on a different filesystem; not dumped"),
566                 quotearg_colon (directory->name)));
567       directory->children = NO_CHILDREN;
568       /* If there is any dumpdir info in that directory, remove it */
569       if (directory->dump)
570         {
571           dumpdir_free (directory->dump);
572           directory->dump = NULL;
573         }
574       perhaps_renamed = false;
575     }
576
577   else if (flag & PD_FORCE_CHILDREN)
578     {
579       directory->children = PD_CHILDREN(flag);
580       if (directory->children == NO_CHILDREN)
581         *entry = 'N';
582     }
583
584   if (perhaps_renamed)
585     WARNOPT (WARN_RENAME_DIRECTORY,
586              (0, 0, _("%s: Directory has been renamed"),
587               quotearg_colon (name_buffer)));
588
589   DIR_SET_FLAG (directory, DIRF_INIT);
590
591   if (directory->children != NO_CHILDREN)
592     {
593       const char *tag_file_name;
594
595       switch (check_exclusion_tags (st, &tag_file_name))
596         {
597         case exclusion_tag_all:
598           /* This warning can be duplicated by code in dump_file0, but only
599              in case when the topmost directory being archived contains
600              an exclusion tag. */
601           exclusion_tag_warning (name_buffer, tag_file_name,
602                                  _("directory not dumped"));
603           *entry = 'N';
604           directory->children = NO_CHILDREN;
605           break;
606
607         case exclusion_tag_contents:
608           exclusion_tag_warning (name_buffer, tag_file_name,
609                                  _("contents not dumped"));
610           directory->children = NO_CHILDREN;
611           break;
612
613         case exclusion_tag_under:
614           exclusion_tag_warning (name_buffer, tag_file_name,
615                                  _("contents not dumped"));
616           directory->tagfile = tag_file_name;
617           break;
618
619         case exclusion_tag_none:
620           break;
621         }
622     }
623
624   return directory;
625 }
626
627 /* Compare dumpdir array from DIRECTORY with directory listing DIR and
628    build a new dumpdir template.
629
630    DIR must be returned by a previous call to savedir().
631
632    File names in DIRECTORY->dump->contents must be sorted
633    alphabetically.
634
635    DIRECTORY->dump is replaced with the created template. Each entry is
636    prefixed with ' ' if it was present in DUMP and with 'Y' otherwise. */
637
638 static void
639 makedumpdir (struct directory *directory, const char *dir)
640 {
641   size_t i,
642          dirsize,  /* Number of elements in DIR */
643          len;      /* Length of DIR, including terminating nul */
644   const char *p;
645   char const **array;
646   char *new_dump, *new_dump_ptr;
647   struct dumpdir *dump;
648
649   if (directory->children == ALL_CHILDREN)
650     dump = NULL;
651   else if (DIR_IS_RENAMED (directory))
652     dump = directory->orig->idump ?
653            directory->orig->idump : directory->orig->dump;
654   else
655     dump = directory->dump;
656
657   /* Count the size of DIR and the number of elements it contains */
658   dirsize = 0;
659   len = 0;
660   for (p = dir; *p; p += strlen (p) + 1, dirsize++)
661     len += strlen (p) + 2;
662   len++;
663
664   /* Create a sorted directory listing */
665   array = xcalloc (dirsize, sizeof array[0]);
666   for (i = 0, p = dir; *p; p += strlen (p) + 1, i++)
667     array[i] = p;
668
669   qsort (array, dirsize, sizeof (array[0]), compare_dirnames);
670
671   /* Prepare space for new dumpdir */
672   new_dump = xmalloc (len);
673   new_dump_ptr = new_dump;
674
675   /* Fill in the dumpdir template */
676   for (i = 0; i < dirsize; i++)
677     {
678       const char *loc = dumpdir_locate (dump, array[i]);
679       if (loc)
680         {
681           if (directory->tagfile)
682             *new_dump_ptr = strcmp (directory->tagfile, array[i]) == 0 ?
683                                 ' ' : 'I';
684           else
685             *new_dump_ptr = ' ';
686           new_dump_ptr++;
687         }
688       else if (directory->tagfile)
689         *new_dump_ptr++ = strcmp (directory->tagfile, array[i]) == 0 ?
690                                ' ' : 'I';
691       else
692         *new_dump_ptr++ = 'Y'; /* New entry */
693
694       /* Copy the file name */
695       for (p = array[i]; (*new_dump_ptr++ = *p++); )
696         ;
697     }
698   *new_dump_ptr = 0;
699   directory->idump = directory->dump;
700   directory->dump = dumpdir_create0 (new_dump, NULL);
701   free (array);
702 }
703
704 /* Recursively scan the directory identified by ST.  */
705 struct directory *
706 scan_directory (struct tar_stat_info *st)
707 {
708   char const *dir = st->orig_file_name;
709   char *dirp = get_directory_entries (st);
710   dev_t device = st->stat.st_dev;
711   bool cmdline = ! st->parent;
712   namebuf_t nbuf;
713   char *tmp;
714   struct directory *directory;
715   char ch;
716
717   if (! dirp)
718     savedir_error (dir);
719
720   tmp = xstrdup (dir);
721   zap_slashes (tmp);
722
723   directory = procdir (tmp, st,
724                        (cmdline ? PD_FORCE_INIT : 0),
725                        &ch);
726
727   free (tmp);
728
729   nbuf = namebuf_create (dir);
730
731   if (dirp && directory->children != NO_CHILDREN)
732     {
733       char *entry;      /* directory entry being scanned */
734       struct dumpdir_iter *itr;
735
736       makedumpdir (directory, dirp);
737
738       for (entry = dumpdir_first (directory->dump, 1, &itr);
739            entry;
740            entry = dumpdir_next (itr))
741         {
742           char *full_name = namebuf_name (nbuf, entry + 1);
743
744           if (*entry == 'I') /* Ignored entry */
745             *entry = 'N';
746           else if (excluded_name (full_name))
747             *entry = 'N';
748           else
749             {
750               int fd = st->fd;
751               void (*diag) (char const *) = 0;
752               struct tar_stat_info stsub;
753               tar_stat_init (&stsub);
754
755               if (fd < 0)
756                 {
757                   errno = - fd;
758                   diag = open_diag;
759                 }
760               else if (fstatat (fd, entry + 1, &stsub.stat, fstatat_flags) != 0)
761                 diag = stat_diag;
762               else if (S_ISDIR (stsub.stat.st_mode))
763                 {
764                   int subfd = subfile_open (st, entry + 1, open_read_flags);
765                   if (subfd < 0)
766                     diag = open_diag;
767                   else
768                     {
769                       stsub.fd = subfd;
770                       if (fstat (subfd, &stsub.stat) != 0)
771                         diag = stat_diag;
772                     }
773                 }
774
775               if (diag)
776                 {
777                   file_removed_diag (full_name, false, diag);
778                   *entry = 'N';
779                 }
780               else if (S_ISDIR (stsub.stat.st_mode))
781                 {
782                   int pd_flag = 0;
783                   if (!recursion_option)
784                     pd_flag |= PD_FORCE_CHILDREN | NO_CHILDREN;
785                   else if (directory->children == ALL_CHILDREN)
786                     pd_flag |= PD_FORCE_CHILDREN | ALL_CHILDREN;
787                   *entry = 'D';
788
789                   stsub.parent = st;
790                   procdir (full_name, &stsub, pd_flag, entry);
791                   restore_parent_fd (&stsub);
792                 }
793               else if (one_file_system_option && device != stsub.stat.st_dev)
794                 *entry = 'N';
795               else if (*entry == 'Y')
796                 /* New entry, skip further checks */;
797               /* FIXME: if (S_ISHIDDEN (stat_data.st_mode))?? */
798               else if (OLDER_STAT_TIME (stsub.stat, m)
799                        && (!after_date_option
800                            || OLDER_STAT_TIME (stsub.stat, c)))
801                 *entry = 'N';
802               else
803                 *entry = 'Y';
804
805               tar_stat_destroy (&stsub);
806             }
807         }
808       free (itr);
809     }
810
811   namebuf_free (nbuf);
812
813   free (dirp);
814
815   return directory;
816 }
817
818 /* Return pointer to the contents of the directory DIR */
819 const char *
820 directory_contents (struct directory *dir)
821 {
822   if (!dir)
823     return NULL;
824   return dir->dump ? dir->dump->contents : NULL;
825 }
826
827 /* A "safe" version of directory_contents, which never returns NULL. */
828 const char *
829 safe_directory_contents (struct directory *dir)
830 {
831   const char *ret = directory_contents (dir);
832   return ret ? ret : "\0\0\0\0";
833 }
834
835 \f
836 static void
837 obstack_code_rename (struct obstack *stk, char const *from, char const *to)
838 {
839   char const *s;
840
841   s = from[0] == 0 ? from :
842                      safer_name_suffix (from, false, absolute_names_option);
843   obstack_1grow (stk, 'R');
844   obstack_grow (stk, s, strlen (s) + 1);
845
846   s = to[0] == 0 ? to:
847                    safer_name_suffix (to, false, absolute_names_option);
848   obstack_1grow (stk, 'T');
849   obstack_grow (stk, s, strlen (s) + 1);
850 }
851
852 static void
853 store_rename (struct directory *dir, struct obstack *stk)
854 {
855   if (DIR_IS_RENAMED (dir))
856     {
857       struct directory *prev, *p;
858
859       /* Detect eventual cycles and clear DIRF_RENAMED flag, so these entries
860          are ignored when hit by this function next time.
861          If the chain forms a cycle, prev points to the entry DIR is renamed
862          from. In this case it still retains DIRF_RENAMED flag, which will be
863          cleared in the 'else' branch below */
864       for (prev = dir; prev && prev->orig != dir; prev = prev->orig)
865         DIR_CLEAR_FLAG (prev, DIRF_RENAMED);
866
867       if (prev == NULL)
868         {
869           for (p = dir; p && p->orig; p = p->orig)
870             obstack_code_rename (stk, p->orig->name, p->name);
871         }
872       else
873         {
874           char *temp_name;
875
876           DIR_CLEAR_FLAG (prev, DIRF_RENAMED);
877
878           /* Break the cycle by using a temporary name for one of its
879              elements.
880              First, create a temp name stub entry. */
881           temp_name = dir_name (dir->name);
882           obstack_1grow (stk, 'X');
883           obstack_grow (stk, temp_name, strlen (temp_name) + 1);
884
885           obstack_code_rename (stk, dir->name, "");
886
887           for (p = dir; p != prev; p = p->orig)
888             obstack_code_rename (stk, p->orig->name, p->name);
889
890           obstack_code_rename (stk, "", prev->name);
891         }
892     }
893 }
894
895 void
896 append_incremental_renames (struct directory *dir)
897 {
898   struct obstack stk;
899   size_t size;
900   struct directory *dp;
901   const char *dump;
902
903   if (dirhead == NULL)
904     return;
905
906   obstack_init (&stk);
907   dump = directory_contents (dir);
908   if (dump)
909     {
910       size = dumpdir_size (dump) - 1;
911       obstack_grow (&stk, dump, size);
912     }
913   else
914     size = 0;
915
916   for (dp = dirhead; dp; dp = dp->next)
917     store_rename (dp, &stk);
918
919   /* FIXME: Is this the right thing to do when DIR is null?  */
920   if (dir && obstack_object_size (&stk) != size)
921     {
922       obstack_1grow (&stk, 0);
923       dumpdir_free (dir->dump);
924       dir->dump = dumpdir_create (obstack_finish (&stk));
925     }
926   obstack_free (&stk, NULL);
927 }
928
929 \f
930
931 static FILE *listed_incremental_stream;
932
933 /* Version of incremental format snapshots (directory files) used by this
934    tar. Currently it is supposed to be a single decimal number. 0 means
935    incremental snapshots as per tar version before 1.15.2.
936
937    The current tar version supports incremental versions from
938    0 up to TAR_INCREMENTAL_VERSION, inclusive.
939    It is able to create only snapshots of TAR_INCREMENTAL_VERSION */
940
941 #define TAR_INCREMENTAL_VERSION 2
942
943 /* Read incremental snapshot formats 0 and 1 */
944 static void
945 read_incr_db_01 (int version, const char *initbuf)
946 {
947   int n;
948   uintmax_t u;
949   char *buf = NULL;
950   size_t bufsize = 0;
951   char *ebuf;
952   long lineno = 1;
953
954   if (version == 1)
955     {
956       if (getline (&buf, &bufsize, listed_incremental_stream) <= 0)
957         {
958           read_error (listed_incremental_option);
959           free (buf);
960           return;
961         }
962       ++lineno;
963     }
964   else
965     {
966       buf = strdup (initbuf);
967       bufsize = strlen (buf) + 1;
968     }
969
970   newer_mtime_option = decode_timespec (buf, &ebuf, false);
971
972   if (! valid_timespec (newer_mtime_option))
973     ERROR ((0, errno, "%s:%ld: %s",
974             quotearg_colon (listed_incremental_option),
975             lineno,
976             _("Invalid time stamp")));
977   else
978     {
979       if (version == 1 && *ebuf)
980         {
981           char const *buf_ns = ebuf + 1;
982           errno = 0;
983           u = strtoumax (buf_ns, &ebuf, 10);
984           if (!errno && BILLION <= u)
985             errno = ERANGE;
986           if (errno || buf_ns == ebuf)
987             {
988               ERROR ((0, errno, "%s:%ld: %s",
989                       quotearg_colon (listed_incremental_option),
990                       lineno,
991                       _("Invalid time stamp")));
992               newer_mtime_option.tv_sec = TYPE_MINIMUM (time_t);
993               newer_mtime_option.tv_nsec = -1;
994             }
995           else
996             newer_mtime_option.tv_nsec = u;
997         }
998     }
999
1000   while (0 < (n = getline (&buf, &bufsize, listed_incremental_stream)))
1001     {
1002       dev_t dev;
1003       ino_t ino;
1004       bool nfs = buf[0] == '+';
1005       char *strp = buf + nfs;
1006       struct timespec mtime;
1007
1008       lineno++;
1009
1010       if (buf[n - 1] == '\n')
1011         buf[n - 1] = '\0';
1012
1013       if (version == 1)
1014         {
1015           mtime = decode_timespec (strp, &ebuf, false);
1016           strp = ebuf;
1017           if (!valid_timespec (mtime) || *strp != ' ')
1018             ERROR ((0, errno, "%s:%ld: %s",
1019                     quotearg_colon (listed_incremental_option), lineno,
1020                     _("Invalid modification time")));
1021
1022           errno = 0;
1023           u = strtoumax (strp, &ebuf, 10);
1024           if (!errno && BILLION <= u)
1025             errno = ERANGE;
1026           if (errno || strp == ebuf || *ebuf != ' ')
1027             {
1028               ERROR ((0, errno, "%s:%ld: %s",
1029                       quotearg_colon (listed_incremental_option), lineno,
1030                       _("Invalid modification time (nanoseconds)")));
1031               mtime.tv_nsec = -1;
1032             }
1033           else
1034             mtime.tv_nsec = u;
1035           strp = ebuf;
1036         }
1037       else
1038         mtime.tv_sec = mtime.tv_nsec = 0;
1039
1040       dev = strtosysint (strp, &ebuf,
1041                          TYPE_MINIMUM (dev_t), TYPE_MAXIMUM (dev_t));
1042       strp = ebuf;
1043       if (errno || *strp != ' ')
1044         ERROR ((0, errno, "%s:%ld: %s",
1045                 quotearg_colon (listed_incremental_option), lineno,
1046                 _("Invalid device number")));
1047
1048       ino = strtosysint (strp, &ebuf,
1049                          TYPE_MINIMUM (ino_t), TYPE_MAXIMUM (ino_t));
1050       strp = ebuf;
1051       if (errno || *strp != ' ')
1052         ERROR ((0, errno, "%s:%ld: %s",
1053                 quotearg_colon (listed_incremental_option), lineno,
1054                 _("Invalid inode number")));
1055
1056       strp++;
1057       unquote_string (strp);
1058       note_directory (strp, mtime, dev, ino, nfs, false, NULL);
1059     }
1060   free (buf);
1061 }
1062
1063 /* Read a nul-terminated string from FP and store it in STK.
1064    Store the number of bytes read (including nul terminator) in PCOUNT.
1065
1066    Return the last character read or EOF on end of file. */
1067 static int
1068 read_obstack (FILE *fp, struct obstack *stk, size_t *pcount)
1069 {
1070   int c;
1071   size_t i;
1072
1073   for (i = 0, c = getc (fp); c != EOF && c != 0; c = getc (fp), i++)
1074     obstack_1grow (stk, c);
1075   obstack_1grow (stk, 0);
1076
1077   *pcount = i;
1078   return c;
1079 }
1080
1081 /* Read from file FP a nul-terminated string and convert it to
1082    intmax_t.  Return the resulting value in PVAL.  Assume '-' has
1083    already been read.
1084
1085    Throw a fatal error if the string cannot be converted or if the
1086    converted value is less than MIN_VAL.  */
1087
1088 static void
1089 read_negative_num (FILE *fp, intmax_t min_val, intmax_t *pval)
1090 {
1091   int c;
1092   size_t i;
1093   char buf[INT_BUFSIZE_BOUND (intmax_t)];
1094   char *ep;
1095   buf[0] = '-';
1096
1097   for (i = 1; ISDIGIT (c = getc (fp)); i++)
1098     {
1099       if (i == sizeof buf - 1)
1100         FATAL_ERROR ((0, 0, _("Field too long while reading snapshot file")));
1101       buf[i] = c;
1102     }
1103
1104   if (c < 0)
1105     {
1106       if (ferror (fp))
1107         FATAL_ERROR ((0, errno, _("Read error in snapshot file")));
1108       else
1109         FATAL_ERROR ((0, 0, _("Unexpected EOF in snapshot file")));
1110     }
1111
1112   buf[i] = 0;
1113   errno = 0;
1114   *pval = strtoimax (buf, &ep, 10);
1115   if (c || errno || *pval < min_val)
1116     FATAL_ERROR ((0, errno, _("Unexpected field value in snapshot file")));
1117 }
1118
1119 /* Read from file FP a nul-terminated string and convert it to
1120    uintmax_t.  Return the resulting value in PVAL.  Assume C has
1121    already been read.
1122
1123    Throw a fatal error if the string cannot be converted or if the
1124    converted value exceeds MAX_VAL.
1125
1126    Return the last character read or EOF on end of file. */
1127
1128 static int
1129 read_unsigned_num (int c, FILE *fp, uintmax_t max_val, uintmax_t *pval)
1130 {
1131   size_t i;
1132   char buf[UINTMAX_STRSIZE_BOUND], *ep;
1133
1134   for (i = 0; ISDIGIT (c); i++)
1135     {
1136       if (i == sizeof buf - 1)
1137         FATAL_ERROR ((0, 0, _("Field too long while reading snapshot file")));
1138       buf[i] = c;
1139       c = getc (fp);
1140     }
1141
1142   if (c < 0)
1143     {
1144       if (ferror (fp))
1145         FATAL_ERROR ((0, errno, _("Read error in snapshot file")));
1146       else if (i == 0)
1147         return c;
1148       else
1149         FATAL_ERROR ((0, 0, _("Unexpected EOF in snapshot file")));
1150     }
1151
1152   buf[i] = 0;
1153   errno = 0;
1154   *pval = strtoumax (buf, &ep, 10);
1155   if (c || errno || max_val < *pval)
1156     FATAL_ERROR ((0, errno, _("Unexpected field value in snapshot file")));
1157   return c;
1158 }
1159
1160 /* Read from file FP a nul-terminated string and convert it to
1161    uintmax_t.  Return the resulting value in PVAL.
1162
1163    Throw a fatal error if the string cannot be converted or if the
1164    converted value exceeds MAX_VAL.
1165
1166    Return the last character read or EOF on end of file. */
1167
1168 static int
1169 read_num (FILE *fp, uintmax_t max_val, uintmax_t *pval)
1170 {
1171   return read_unsigned_num (getc (fp), fp, max_val, pval);
1172 }
1173
1174 /* Read from FP two NUL-terminated strings representing a struct
1175    timespec.  Return the resulting value in PVAL.
1176
1177    Throw a fatal error if the string cannot be converted.  */
1178
1179 static void
1180 read_timespec (FILE *fp, struct timespec *pval)
1181 {
1182   int c = getc (fp);
1183   intmax_t i;
1184   uintmax_t u;
1185
1186   if (c == '-')
1187     {
1188       read_negative_num (fp, TYPE_MINIMUM (time_t), &i);
1189       c = 0;
1190       pval->tv_sec = i;
1191     }
1192   else
1193     {
1194       c = read_unsigned_num (c, fp, TYPE_MAXIMUM (time_t), &u);
1195       pval->tv_sec = u;
1196     }
1197
1198   if (c || read_num (fp, BILLION - 1, &u))
1199     FATAL_ERROR ((0, 0, "%s: %s",
1200                   quotearg_colon (listed_incremental_option),
1201                   _("Unexpected EOF in snapshot file")));
1202   pval->tv_nsec = u;
1203 }
1204
1205 /* Read incremental snapshot format 2 */
1206 static void
1207 read_incr_db_2 (void)
1208 {
1209   uintmax_t u;
1210   struct obstack stk;
1211
1212   obstack_init (&stk);
1213
1214   read_timespec (listed_incremental_stream, &newer_mtime_option);
1215
1216   for (;;)
1217     {
1218       struct timespec mtime;
1219       dev_t dev;
1220       ino_t ino;
1221       bool nfs;
1222       char *name;
1223       char *content;
1224       size_t s;
1225
1226       if (read_num (listed_incremental_stream, 1, &u))
1227         return; /* Normal return */
1228
1229       nfs = u;
1230
1231       read_timespec (listed_incremental_stream, &mtime);
1232
1233       if (read_num (listed_incremental_stream, TYPE_MAXIMUM (dev_t), &u))
1234         break;
1235       dev = u;
1236
1237       if (read_num (listed_incremental_stream, TYPE_MAXIMUM (ino_t), &u))
1238         break;
1239       ino = u;
1240
1241       if (read_obstack (listed_incremental_stream, &stk, &s))
1242         break;
1243
1244       name = obstack_finish (&stk);
1245
1246       while (read_obstack (listed_incremental_stream, &stk, &s) == 0 && s > 1)
1247         ;
1248       if (getc (listed_incremental_stream) != 0)
1249         FATAL_ERROR ((0, 0, "%s: %s",
1250                       quotearg_colon (listed_incremental_option),
1251                       _("Missing record terminator")));
1252
1253       content = obstack_finish (&stk);
1254       note_directory (name, mtime, dev, ino, nfs, false, content);
1255       obstack_free (&stk, content);
1256     }
1257   FATAL_ERROR ((0, 0, "%s: %s",
1258                 quotearg_colon (listed_incremental_option),
1259                 _("Unexpected EOF in snapshot file")));
1260 }
1261
1262 /* Read incremental snapshot file (directory file).
1263    If the file has older incremental version, make sure that it is processed
1264    correctly and that tar will use the most conservative backup method among
1265    possible alternatives (i.e. prefer ALL_CHILDREN over CHANGED_CHILDREN,
1266    etc.) This ensures that the snapshots are updated to the recent version
1267    without any loss of data. */
1268 void
1269 read_directory_file (void)
1270 {
1271   int fd;
1272   char *buf = NULL;
1273   size_t bufsize = 0;
1274   int flags = O_RDWR | O_CREAT;
1275
1276   if (incremental_level == 0)
1277     flags |= O_TRUNC;
1278   /* Open the file for both read and write.  That way, we can write
1279      it later without having to reopen it, and don't have to worry if
1280      we chdir in the meantime.  */
1281   fd = open (listed_incremental_option, flags, MODE_RW);
1282   if (fd < 0)
1283     {
1284       open_error (listed_incremental_option);
1285       return;
1286     }
1287
1288   listed_incremental_stream = fdopen (fd, "r+");
1289   if (! listed_incremental_stream)
1290     {
1291       open_error (listed_incremental_option);
1292       close (fd);
1293       return;
1294     }
1295
1296   /* Consume the first name from the name list and reset the
1297      list afterwards.  This is done to change to the new
1298      directory, if the first name is a chdir request (-C dir),
1299      which is necessary to recreate absolute file names. */
1300   name_from_list ();
1301   blank_name_list ();
1302
1303   if (0 < getline (&buf, &bufsize, listed_incremental_stream))
1304     {
1305       char *ebuf;
1306       uintmax_t incremental_version;
1307
1308       if (strncmp (buf, PACKAGE_NAME, sizeof PACKAGE_NAME - 1) == 0)
1309         {
1310           ebuf = buf + sizeof PACKAGE_NAME - 1;
1311           if (*ebuf++ != '-')
1312             ERROR((1, 0, _("Bad incremental file format")));
1313           for (; *ebuf != '-'; ebuf++)
1314             if (!*ebuf)
1315               ERROR((1, 0, _("Bad incremental file format")));
1316
1317           incremental_version = strtoumax (ebuf + 1, NULL, 10);
1318         }
1319       else
1320         incremental_version = 0;
1321
1322       switch (incremental_version)
1323         {
1324         case 0:
1325         case 1:
1326           read_incr_db_01 (incremental_version, buf);
1327           break;
1328
1329         case TAR_INCREMENTAL_VERSION:
1330           read_incr_db_2 ();
1331           break;
1332
1333         default:
1334           ERROR ((1, 0, _("Unsupported incremental format version: %"PRIuMAX),
1335                   incremental_version));
1336         }
1337
1338     }
1339
1340   if (ferror (listed_incremental_stream))
1341     read_error (listed_incremental_option);
1342   free (buf);
1343 }
1344
1345 /* Output incremental data for the directory ENTRY to the file DATA.
1346    Return nonzero if successful, preserving errno on write failure.  */
1347 static bool
1348 write_directory_file_entry (void *entry, void *data)
1349 {
1350   struct directory const *directory = entry;
1351   FILE *fp = data;
1352
1353   if (DIR_IS_FOUND (directory))
1354     {
1355       char buf[max (SYSINT_BUFSIZE, INT_BUFSIZE_BOUND (intmax_t))];
1356       char const *s;
1357
1358       s = DIR_IS_NFS (directory) ? "1" : "0";
1359       fwrite (s, 2, 1, fp);
1360       s = sysinttostr (directory->mtime.tv_sec, TYPE_MINIMUM (time_t),
1361                        TYPE_MAXIMUM (time_t), buf);
1362       fwrite (s, strlen (s) + 1, 1, fp);
1363       s = imaxtostr (directory->mtime.tv_nsec, buf);
1364       fwrite (s, strlen (s) + 1, 1, fp);
1365       s = sysinttostr (directory->device_number,
1366                        TYPE_MINIMUM (dev_t), TYPE_MAXIMUM (dev_t), buf);
1367       fwrite (s, strlen (s) + 1, 1, fp);
1368       s = sysinttostr (directory->inode_number,
1369                        TYPE_MINIMUM (ino_t), TYPE_MAXIMUM (ino_t), buf);
1370       fwrite (s, strlen (s) + 1, 1, fp);
1371
1372       fwrite (directory->name, strlen (directory->name) + 1, 1, fp);
1373       if (directory->dump)
1374         {
1375           const char *p;
1376           struct dumpdir_iter *itr;
1377
1378           for (p = dumpdir_first (directory->dump, 0, &itr);
1379                p;
1380                p = dumpdir_next (itr))
1381             fwrite (p, strlen (p) + 1, 1, fp);
1382           free (itr);
1383         }
1384       fwrite ("\0\0", 2, 1, fp);
1385     }
1386
1387   return ! ferror (fp);
1388 }
1389
1390 void
1391 write_directory_file (void)
1392 {
1393   FILE *fp = listed_incremental_stream;
1394   char buf[UINTMAX_STRSIZE_BOUND];
1395   char *s;
1396
1397   if (! fp)
1398     return;
1399
1400   if (fseeko (fp, 0L, SEEK_SET) != 0)
1401     seek_error (listed_incremental_option);
1402   if (sys_truncate (fileno (fp)) != 0)
1403     truncate_error (listed_incremental_option);
1404
1405   fprintf (fp, "%s-%s-%d\n", PACKAGE_NAME, PACKAGE_VERSION,
1406            TAR_INCREMENTAL_VERSION);
1407
1408   s = (TYPE_SIGNED (time_t)
1409        ? imaxtostr (start_time.tv_sec, buf)
1410        : umaxtostr (start_time.tv_sec, buf));
1411   fwrite (s, strlen (s) + 1, 1, fp);
1412   s = umaxtostr (start_time.tv_nsec, buf);
1413   fwrite (s, strlen (s) + 1, 1, fp);
1414
1415   if (! ferror (fp) && directory_table)
1416     hash_do_for_each (directory_table, write_directory_file_entry, fp);
1417
1418   if (ferror (fp))
1419     write_error (listed_incremental_option);
1420   if (fclose (fp) != 0)
1421     close_error (listed_incremental_option);
1422 }
1423
1424 \f
1425 /* Restoration of incremental dumps.  */
1426
1427 static void
1428 get_gnu_dumpdir (struct tar_stat_info *stat_info)
1429 {
1430   size_t size;
1431   size_t copied;
1432   union block *data_block;
1433   char *to;
1434   char *archive_dir;
1435
1436   size = stat_info->stat.st_size;
1437
1438   archive_dir = xmalloc (size);
1439   to = archive_dir;
1440
1441   set_next_block_after (current_header);
1442   mv_begin_read (stat_info);
1443
1444   for (; size > 0; size -= copied)
1445     {
1446       mv_size_left (size);
1447       data_block = find_next_block ();
1448       if (!data_block)
1449         ERROR ((1, 0, _("Unexpected EOF in archive")));
1450       copied = available_space_after (data_block);
1451       if (copied > size)
1452         copied = size;
1453       memcpy (to, data_block->buffer, copied);
1454       to += copied;
1455       set_next_block_after ((union block *)
1456                             (data_block->buffer + copied - 1));
1457     }
1458
1459   mv_end ();
1460
1461   stat_info->dumpdir = archive_dir;
1462   stat_info->skipped = true; /* For skip_member() and friends
1463                                 to work correctly */
1464 }
1465
1466 /* Return T if STAT_INFO represents a dumpdir archive member.
1467    Note: can invalidate current_header. It happens if flush_archive()
1468    gets called within get_gnu_dumpdir() */
1469 bool
1470 is_dumpdir (struct tar_stat_info *stat_info)
1471 {
1472   if (stat_info->is_dumpdir && !stat_info->dumpdir)
1473     get_gnu_dumpdir (stat_info);
1474   return stat_info->is_dumpdir;
1475 }
1476
1477 static bool
1478 dumpdir_ok (char *dumpdir)
1479 {
1480   char *p;
1481   int has_tempdir = 0;
1482   int expect = 0;
1483
1484   for (p = dumpdir; *p; p += strlen (p) + 1)
1485     {
1486       if (expect && *p != expect)
1487         {
1488           ERROR ((0, 0,
1489                   _("Malformed dumpdir: expected '%c' but found %#3o"),
1490                   expect, *p));
1491           return false;
1492         }
1493       switch (*p)
1494         {
1495         case 'X':
1496           if (has_tempdir)
1497             {
1498               ERROR ((0, 0,
1499                       _("Malformed dumpdir: 'X' duplicated")));
1500               return false;
1501             }
1502           else
1503             has_tempdir = 1;
1504           break;
1505
1506         case 'R':
1507           if (p[1] == 0)
1508             {
1509               if (!has_tempdir)
1510                 {
1511                   ERROR ((0, 0,
1512                           _("Malformed dumpdir: empty name in 'R'")));
1513                   return false;
1514                 }
1515               else
1516                 has_tempdir = 0;
1517             }
1518           expect = 'T';
1519           break;
1520
1521         case 'T':
1522           if (expect != 'T')
1523             {
1524               ERROR ((0, 0,
1525                       _("Malformed dumpdir: 'T' not preceeded by 'R'")));
1526               return false;
1527             }
1528           if (p[1] == 0 && !has_tempdir)
1529             {
1530               ERROR ((0, 0,
1531                       _("Malformed dumpdir: empty name in 'T'")));
1532               return false;
1533             }
1534           expect = 0;
1535           break;
1536
1537         case 'N':
1538         case 'Y':
1539         case 'D':
1540           break;
1541
1542         default:
1543           /* FIXME: bail out? */
1544           break;
1545         }
1546     }
1547
1548   if (expect)
1549     {
1550       ERROR ((0, 0,
1551               _("Malformed dumpdir: expected '%c' but found end of data"),
1552               expect));
1553       return false;
1554     }
1555
1556   if (has_tempdir)
1557     WARNOPT (WARN_BAD_DUMPDIR,
1558              (0, 0, _("Malformed dumpdir: 'X' never used")));
1559
1560   return true;
1561 }
1562
1563 /* Examine the directories under directory_name and delete any
1564    files that were not there at the time of the back-up. */
1565 static bool
1566 try_purge_directory (char const *directory_name)
1567 {
1568   char *current_dir;
1569   char *cur, *arc, *p;
1570   char *temp_stub = NULL;
1571   struct dumpdir *dump;
1572
1573   if (!is_dumpdir (&current_stat_info))
1574     return false;
1575
1576   current_dir = savedir (directory_name);
1577
1578   if (!current_dir)
1579     /* The directory doesn't exist now.  It'll be created.  In any
1580        case, we don't have to delete any files out of it.  */
1581     return false;
1582
1583   /* Verify if dump directory is sane */
1584   if (!dumpdir_ok (current_stat_info.dumpdir))
1585     return false;
1586
1587   /* Process renames */
1588   for (arc = current_stat_info.dumpdir; *arc; arc += strlen (arc) + 1)
1589     {
1590       if (*arc == 'X')
1591         {
1592 #define TEMP_DIR_TEMPLATE "tar.XXXXXX"
1593           size_t len = strlen (arc + 1);
1594           temp_stub = xrealloc (temp_stub, len + 1 + sizeof TEMP_DIR_TEMPLATE);
1595           memcpy (temp_stub, arc + 1, len);
1596           temp_stub[len] = '/';
1597           memcpy (temp_stub + len + 1, TEMP_DIR_TEMPLATE,
1598                   sizeof TEMP_DIR_TEMPLATE);
1599           if (!mkdtemp (temp_stub))
1600             {
1601               ERROR ((0, errno,
1602                       _("Cannot create temporary directory using template %s"),
1603                       quote (temp_stub)));
1604               free (temp_stub);
1605               free (current_dir);
1606               return false;
1607             }
1608         }
1609       else if (*arc == 'R')
1610         {
1611           char *src, *dst;
1612           src = arc + 1;
1613           arc += strlen (arc) + 1;
1614           dst = arc + 1;
1615
1616           /* Ensure that neither source nor destination are absolute file
1617              names (unless permitted by -P option), and that they do not
1618              contain dubious parts (e.g. ../).
1619
1620              This is an extra safety precaution. Besides, it might be
1621              necessary to extract from archives created with tar versions
1622              prior to 1.19. */
1623
1624           if (*src)
1625             src = safer_name_suffix (src, false, absolute_names_option);
1626           if (*dst)
1627             dst = safer_name_suffix (dst, false, absolute_names_option);
1628
1629           if (*src == 0)
1630             src = temp_stub;
1631           else if (*dst == 0)
1632             dst = temp_stub;
1633
1634           if (!rename_directory (src, dst))
1635             {
1636               free (temp_stub);
1637               free (current_dir);
1638               /* FIXME: Make sure purge_directory(dst) will return
1639                  immediately */
1640               return false;
1641             }
1642         }
1643     }
1644
1645   free (temp_stub);
1646
1647   /* Process deletes */
1648   dump = dumpdir_create (current_stat_info.dumpdir);
1649   p = NULL;
1650   for (cur = current_dir; *cur; cur += strlen (cur) + 1)
1651     {
1652       const char *entry;
1653       struct stat st;
1654       free (p);
1655       p = new_name (directory_name, cur);
1656
1657       if (deref_stat (p, &st) != 0)
1658         {
1659           if (errno != ENOENT) /* FIXME: Maybe keep a list of renamed
1660                                   dirs and check it here? */
1661             {
1662               stat_diag (p);
1663               WARN ((0, 0, _("%s: Not purging directory: unable to stat"),
1664                      quotearg_colon (p)));
1665             }
1666           continue;
1667         }
1668
1669       if (!(entry = dumpdir_locate (dump, cur))
1670           || (*entry == 'D' && !S_ISDIR (st.st_mode))
1671           || (*entry == 'Y' && S_ISDIR (st.st_mode)))
1672         {
1673           if (one_file_system_option && st.st_dev != root_device)
1674             {
1675               WARN ((0, 0,
1676                      _("%s: directory is on a different device: not purging"),
1677                      quotearg_colon (p)));
1678               continue;
1679             }
1680
1681           if (! interactive_option || confirm ("delete", p))
1682             {
1683               if (verbose_option)
1684                 fprintf (stdlis, _("%s: Deleting %s\n"),
1685                          program_name, quote (p));
1686               if (! remove_any_file (p, RECURSIVE_REMOVE_OPTION))
1687                 {
1688                   int e = errno;
1689                   ERROR ((0, e, _("%s: Cannot remove"), quotearg_colon (p)));
1690                 }
1691             }
1692         }
1693     }
1694   free (p);
1695   dumpdir_free (dump);
1696
1697   free (current_dir);
1698   return true;
1699 }
1700
1701 void
1702 purge_directory (char const *directory_name)
1703 {
1704   if (!try_purge_directory (directory_name))
1705     skip_member ();
1706 }
1707
1708 void
1709 list_dumpdir (char *buffer, size_t size)
1710 {
1711   int state = 0;
1712   while (size)
1713     {
1714       switch (*buffer)
1715         {
1716         case 'Y':
1717         case 'N':
1718         case 'D':
1719         case 'R':
1720         case 'T':
1721         case 'X':
1722           fprintf (stdlis, "%c", *buffer);
1723           if (state == 0)
1724             {
1725               fprintf (stdlis, " ");
1726               state = 1;
1727             }
1728           buffer++;
1729           size--;
1730           break;
1731
1732         case 0:
1733           fputc ('\n', stdlis);
1734           buffer++;
1735           size--;
1736           state = 0;
1737           break;
1738
1739         default:
1740           fputc (*buffer, stdlis);
1741           buffer++;
1742           size--;
1743         }
1744     }
1745 }