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