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