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