Update option s2k-count to match the documentation.
[gnupg.git] / tools / gpgtar-create.c
1 /* gpgtar-create.c - Create a TAR archive
2  * Copyright (C) 2010 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <config.h>
21 #include <errno.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <dirent.h>
28 #ifdef HAVE_W32_SYSTEM
29 # define WIN32_LEAN_AND_MEAN
30 # include <windows.h>
31 #else /*!HAVE_W32_SYSTEM*/
32 # include <unistd.h>
33 # include <pwd.h>
34 # include <grp.h>
35 #endif /*!HAVE_W32_SYSTEM*/
36 #include <assert.h>
37
38 #include "i18n.h"
39 #include "../common/sysutils.h"
40 #include "gpgtar.h"
41
42 #ifndef HAVE_LSTAT
43 #define lstat(a,b) stat ((a), (b))
44 #endif
45
46
47 /* Object to control the file scanning.  */
48 struct scanctrl_s;
49 typedef struct scanctrl_s *scanctrl_t;
50 struct scanctrl_s
51 {
52   tar_header_t flist;
53   tar_header_t *flist_tail;
54   int nestlevel;
55 };
56
57
58
59
60 /* Given a fresh header object HDR with only the name field set, try
61    to gather all available info.  This is the W32 version.  */
62 #ifdef HAVE_W32_SYSTEM
63 static gpg_error_t
64 fillup_entry_w32 (tar_header_t hdr)
65 {
66   char *p;
67   wchar_t *wfname;
68   WIN32_FILE_ATTRIBUTE_DATA fad;
69   DWORD attr;
70
71   for (p=hdr->name; *p; p++)
72     if (*p == '/')
73       *p = '\\';
74   wfname = utf8_to_wchar (hdr->name);
75   for (p=hdr->name; *p; p++)
76     if (*p == '\\')
77       *p = '/';
78   if (!wfname)
79     {
80       log_error ("error utf8-ing `%s': %s\n", hdr->name, w32_strerror (-1));
81       return gpg_error_from_syserror ();
82     }
83   if (!GetFileAttributesExW (wfname, GetFileExInfoStandard, &fad))
84     {
85       log_error ("error stat-ing `%s': %s\n", hdr->name, w32_strerror (-1));
86       xfree (wfname);
87       return gpg_error_from_syserror ();
88     }
89   xfree (wfname);
90
91   attr = fad.dwFileAttributes;
92
93   if ((attr & FILE_ATTRIBUTE_NORMAL))
94     hdr->typeflag = TF_REGULAR;
95   else if ((attr & FILE_ATTRIBUTE_DIRECTORY))
96     hdr->typeflag = TF_DIRECTORY;
97   else if ((attr & FILE_ATTRIBUTE_DEVICE))
98     hdr->typeflag = TF_NOTSUP;
99   else if ((attr & (FILE_ATTRIBUTE_OFFLINE | FILE_ATTRIBUTE_TEMPORARY)))
100     hdr->typeflag = TF_NOTSUP;
101   else
102     hdr->typeflag = TF_REGULAR;
103
104   /* Map some attributes to  USTAR defined mode bits.  */
105   hdr->mode = 0640;      /* User may read and write, group only read.  */
106   if ((attr & FILE_ATTRIBUTE_DIRECTORY))
107     hdr->mode |= 0110;   /* Dirs are user and group executable.  */
108   if ((attr & FILE_ATTRIBUTE_READONLY))
109     hdr->mode &= ~0200;  /* Clear the user write bit.  */
110   if ((attr & FILE_ATTRIBUTE_HIDDEN))
111     hdr->mode &= ~0707;  /* Clear all user and other bits.  */ 
112   if ((attr & FILE_ATTRIBUTE_SYSTEM))
113     hdr->mode |= 0004;   /* Make it readable by other.  */ 
114
115   /* Only set the size for a regular file.  */
116   if (hdr->typeflag == TF_REGULAR)
117     hdr->size = (fad.nFileSizeHigh * (unsigned long long)(MAXDWORD+1)
118                  + fad.nFileSizeLow);
119
120   hdr->mtime = (((unsigned long long)fad.ftLastWriteTime.dwHighDateTime << 32)
121                 | fad.ftLastWriteTime.dwLowDateTime);
122   if (!hdr->mtime)
123     hdr->mtime = (((unsigned long long)fad.ftCreationTime.dwHighDateTime << 32)
124                   | fad.ftCreationTime.dwLowDateTime);
125   hdr->mtime -= 116444736000000000ULL; /* The filetime epoch is 1601-01-01.  */
126   hdr->mtime /= 10000000;  /* Convert from 0.1us to seconds. */
127
128   return 0;
129 }
130 #endif /*HAVE_W32_SYSTEM*/
131
132
133 /* Given a fresh header obje`<ct HDR with only the name field set, try
134    to gather all available info.  This is the POSIX version.  */
135 #ifndef HAVE_W32_SYSTEM
136 static gpg_error_t
137 fillup_entry_posix (tar_header_t hdr)
138 {
139   gpg_error_t err;
140   struct stat sbuf;
141
142   if (lstat (hdr->name, &sbuf))
143     {
144       err = gpg_error_from_syserror ();
145       log_error ("error stat-ing `%s': %s\n", hdr->name, gpg_strerror (err));
146       return err;
147     }
148   
149   if (S_ISREG (sbuf.st_mode))
150     hdr->typeflag = TF_REGULAR;
151   else if (S_ISDIR (sbuf.st_mode))
152     hdr->typeflag = TF_DIRECTORY;
153   else if (S_ISCHR (sbuf.st_mode))
154     hdr->typeflag = TF_CHARDEV;
155   else if (S_ISBLK (sbuf.st_mode))
156     hdr->typeflag = TF_BLOCKDEV;
157   else if (S_ISFIFO (sbuf.st_mode))
158     hdr->typeflag = TF_FIFO;
159   else if (S_ISLNK (sbuf.st_mode))
160     hdr->typeflag = TF_SYMLINK;
161   else 
162     hdr->typeflag = TF_NOTSUP;
163
164   /* FIXME: Save DEV and INO? */
165
166   /* Set the USTAR defined mode bits using the system macros.  */
167   if (sbuf.st_mode & S_IRUSR)
168     hdr->mode |= 0400;
169   if (sbuf.st_mode & S_IWUSR)
170     hdr->mode |= 0200;
171   if (sbuf.st_mode & S_IXUSR)
172     hdr->mode |= 0100;
173   if (sbuf.st_mode & S_IRGRP)
174     hdr->mode |= 0040;
175   if (sbuf.st_mode & S_IWGRP)
176     hdr->mode |= 0020;
177   if (sbuf.st_mode & S_IXGRP)
178     hdr->mode |= 0010;
179   if (sbuf.st_mode & S_IROTH)
180     hdr->mode |= 0004;
181   if (sbuf.st_mode & S_IWOTH)
182     hdr->mode |= 0002;
183   if (sbuf.st_mode & S_IXOTH)
184     hdr->mode |= 0001;
185 #ifdef S_IXUID
186   if (sbuf.st_mode & S_IXUID)
187     hdr->mode |= 04000;
188 #endif
189 #ifdef S_IXGID
190   if (sbuf.st_mode & S_IXGID)
191     hdr->mode |= 02000;
192 #endif
193 #ifdef S_ISVTX
194   if (sbuf.st_mode & S_ISVTX)
195     hdr->mode |= 01000;
196 #endif
197
198   hdr->nlink = sbuf.st_nlink;
199
200   hdr->uid = sbuf.st_uid;
201   hdr->gid = sbuf.st_gid;
202
203   /* Only set the size for a regular file.  */
204   if (hdr->typeflag == TF_REGULAR)
205     hdr->size = sbuf.st_size;
206
207   hdr->mtime = sbuf.st_mtime;
208   
209   return 0;
210 }
211 #endif /*!HAVE_W32_SYSTEM*/
212
213
214 /* Add a new entry.  The name of a director entry is ENTRYNAME; if
215    that is NULL, DNAME is the name of the directory itself.  Under
216    Windows ENTRYNAME shall have backslashes replaced by standard
217    slashes.  */
218 static gpg_error_t
219 add_entry (const char *dname, const char *entryname, scanctrl_t scanctrl)
220 {
221   gpg_error_t err;
222   tar_header_t hdr;
223   char *p;
224   size_t dnamelen = strlen (dname);
225
226   assert (dnamelen);
227
228   hdr = xtrycalloc (1, sizeof *hdr + dnamelen + 1
229                     + (entryname? strlen (entryname) : 0) + 1);
230   if (!hdr)
231     return gpg_error_from_syserror ();
232
233   p = stpcpy (hdr->name, dname);
234   if (entryname)
235     {
236       if (dname[dnamelen-1] != '/')
237         *p++ = '/';
238       strcpy (p, entryname);
239     }
240   else
241     {
242       if (hdr->name[dnamelen-1] == '/')
243         hdr->name[dnamelen-1] = 0;
244     }
245 #ifdef HAVE_DOSISH_SYSTEM
246   err = fillup_entry_w32 (hdr);
247 #else
248   err = fillup_entry_posix (hdr);
249 #endif
250   if (err)
251     xfree (hdr);
252   else
253     {
254       if (opt.verbose)
255         gpgtar_print_header (hdr, log_get_stream ());
256       *scanctrl->flist_tail = hdr;
257       scanctrl->flist_tail = &hdr->next;
258     }
259
260   return 0;
261 }
262
263
264 static gpg_error_t
265 scan_directory (const char *dname, scanctrl_t scanctrl)
266 {
267   gpg_error_t err = 0;
268
269 #ifdef HAVE_W32_SYSTEM
270   WIN32_FIND_DATAW fi;
271   HANDLE hd = INVALID_HANDLE_VALUE;
272   char *p;
273
274   if (!*dname)
275     return 0;  /* An empty directory name has no entries.  */
276
277   {
278     char *fname;
279     wchar_t *wfname;
280
281     fname = xtrymalloc (strlen (dname) + 2 + 2 + 1);
282     if (!fname)
283       {
284         err = gpg_error_from_syserror ();
285         goto leave;
286       }
287     if (!strcmp (dname, "/"))
288       strcpy (fname, "/*"); /* Trailing slash is not allowed.  */
289     else if (!strcmp (dname, "."))
290       strcpy (fname, "*");
291     else if (*dname && dname[strlen (dname)-1] == '/')
292       strcpy (stpcpy (fname, dname), "*");
293     else if (*dname && dname[strlen (dname)-1] != '*')
294       strcpy (stpcpy (fname, dname), "/*");
295     else
296       strcpy (fname, dname);
297
298     for (p=fname; *p; p++)
299       if (*p == '/')
300         *p = '\\';
301     wfname = utf8_to_wchar (fname);
302     xfree (fname);
303     if (!wfname)
304       {
305         err = gpg_error_from_syserror ();
306         log_error (_("error reading directory `%s': %s\n"),
307                    dname, gpg_strerror (err));
308         goto leave;
309       }
310     hd = FindFirstFileW (wfname, &fi);
311     if (hd == INVALID_HANDLE_VALUE)
312       {
313         err = gpg_error_from_syserror ();
314         log_error (_("error reading directory `%s': %s\n"),
315                    dname, w32_strerror (-1));
316         xfree (wfname);
317         goto leave;
318       }
319     xfree (wfname);
320   }
321
322   do 
323     {
324       char *fname = wchar_to_utf8 (fi.cFileName);
325       if (!fname)
326         {
327           err = gpg_error_from_syserror ();
328           log_error ("error utf8-ing filename: %s\n", w32_strerror (-1));
329           break;
330         }
331       for (p=fname; *p; p++)
332         if (*p == '\\')
333           *p = '/';
334       if (!strcmp (fname, "." ) || !strcmp (fname, ".."))
335         err = 0; /* Skip self and parent dir entry.  */
336       else if (!strncmp (dname, "./", 2) && dname[2])
337         err = add_entry (dname+2, fname, scanctrl);
338       else
339         err = add_entry (dname, fname, scanctrl);
340       xfree (fname);
341     }
342   while (!err && FindNextFileW (hd, &fi));
343   if (err)
344     ;
345   else if (GetLastError () == ERROR_NO_MORE_FILES)
346     err = 0;
347   else
348     {
349       err = gpg_error_from_syserror (); 
350       log_error (_("error reading directory `%s': %s\n"),
351                  dname, w32_strerror (-1));
352     }
353   
354  leave:
355   if (hd != INVALID_HANDLE_VALUE)
356     FindClose (hd);
357
358 #else /*!HAVE_W32_SYSTEM*/
359   DIR *dir;
360   struct dirent *de;
361
362   if (!*dname)
363     return 0;  /* An empty directory name has no entries.  */
364
365   dir = opendir (dname);
366   if (!dir)
367     {
368       err = gpg_error_from_syserror ();
369       log_error (_("error reading directory `%s': %s\n"),
370                  dname, gpg_strerror (err));
371       return err;
372     }
373   
374   while ((de = readdir (dir)))
375     {
376       if (!strcmp (de->d_name, "." ) || !strcmp (de->d_name, ".."))
377         continue; /* Skip self and parent dir entry.  */
378       
379       err = add_entry (dname, de->d_name, scanctrl);
380       if (err)
381         goto leave;
382      }
383
384  leave:
385   closedir (dir);
386 #endif /*!HAVE_W32_SYSTEM*/
387   return err;
388 }
389
390
391 static gpg_error_t
392 scan_recursive (const char *dname, scanctrl_t scanctrl)
393 {
394   gpg_error_t err = 0;
395   tar_header_t hdr, *start_tail, *stop_tail;
396
397   if (scanctrl->nestlevel > 200)
398     {
399       log_error ("directories too deeply nested\n");
400       return gpg_error (GPG_ERR_RESOURCE_LIMIT);
401     }
402   scanctrl->nestlevel++;
403
404   assert (scanctrl->flist_tail);
405   start_tail = scanctrl->flist_tail;
406   scan_directory (dname, scanctrl);
407   stop_tail = scanctrl->flist_tail;
408   hdr = *start_tail;
409   for (; hdr && hdr != *stop_tail; hdr = hdr->next)
410     if (hdr->typeflag == TF_DIRECTORY)
411       {
412         if (opt.verbose > 1)
413           log_info ("scanning directory `%s'\n", hdr->name);
414         scan_recursive (hdr->name, scanctrl);
415       }
416   
417   scanctrl->nestlevel--;
418   return err;
419 }
420
421
422 /* Returns true if PATTERN is acceptable.  */
423 static int
424 pattern_valid_p (const char *pattern)
425 {
426   if (!*pattern)
427     return 0;
428   if (*pattern == '.' && pattern[1] == '.')
429     return 0;
430   if (*pattern == '/' || *pattern == DIRSEP_C)
431     return 0; /* Absolute filenames are not supported.  */
432 #ifdef HAVE_DRIVE_LETTERS
433   if (((*pattern >= 'a' && *pattern <= 'z')
434        || (*pattern >= 'A' && *pattern <= 'Z'))
435       && pattern[1] == ':')
436     return 0; /* Drive letter are not allowed either.  */
437 #endif /*HAVE_DRIVE_LETTERS*/ 
438
439   return 1; /* Okay.  */
440 }
441
442
443 \f
444 static void
445 store_xoctal (char *buffer, size_t length, unsigned long long value)
446 {
447   char *p, *pend;
448   size_t n;
449   unsigned long long v;
450
451   assert (length > 1);
452
453   v = value;
454   n = length;
455   p = pend = buffer + length;
456   *--p = 0; /* Nul byte.  */
457   n--;
458   do
459     {
460       *--p = '0' + (v % 8);
461       v /= 8;
462       n--;
463     }
464   while (v && n);
465   if (!v)
466     {
467       /* Pad.  */
468       for ( ; n; n--)
469         *--p = '0';
470     }
471   else /* Does not fit into the field.  Store as binary number.  */
472     {
473       v = value;
474       n = length;
475       p = pend = buffer + length;
476       do
477         {
478           *--p = v;
479           v /= 256;
480           n--;
481         }
482       while (v && n);
483       if (!v)
484         {
485           /* Pad.  */
486           for ( ; n; n--)
487             *--p = 0;
488           if (*p & 0x80)
489             BUG ();
490           *p |= 0x80; /* Set binary flag.  */
491         }
492       else
493         BUG ();
494     }
495 }
496
497
498 static void
499 store_uname (char *buffer, size_t length, unsigned long uid)
500 {
501   static int initialized;
502   static unsigned long lastuid;
503   static char lastuname[32];
504
505   if (!initialized || uid != lastuid)
506     {
507 #ifdef HAVE_W32_SYSTEM
508       mem2str (lastuname, uid? "user":"root", sizeof lastuname); 
509 #else
510       struct passwd *pw = getpwuid (uid);
511
512       lastuid = uid;
513       initialized = 1;
514       if (pw)
515         mem2str (lastuname, pw->pw_name, sizeof lastuname); 
516       else
517         {
518           log_info ("failed to get name for uid %lu\n", uid);
519           *lastuname = 0;
520         }
521 #endif
522     }
523   mem2str (buffer, lastuname, length);
524 }
525
526
527 static void
528 store_gname (char *buffer, size_t length, unsigned long gid)
529 {
530   static int initialized;
531   static unsigned long lastgid;
532   static char lastgname[32];
533
534   if (!initialized || gid != lastgid)
535     {
536 #ifdef HAVE_W32_SYSTEM
537       mem2str (lastgname, gid? "users":"root", sizeof lastgname); 
538 #else
539       struct group *gr = getgrgid (gid);
540
541       lastgid = gid;
542       initialized = 1;
543       if (gr)
544         mem2str (lastgname, gr->gr_name, sizeof lastgname); 
545       else
546         {
547           log_info ("failed to get name for gid %lu\n", gid);
548           *lastgname = 0;
549         }
550 #endif
551     }
552   mem2str (buffer, lastgname, length);
553 }
554
555
556 static gpg_error_t
557 build_header (void *record, tar_header_t hdr)
558 {
559   gpg_error_t err;
560   struct ustar_raw_header *raw = record;
561   size_t namelen, n;
562   unsigned long chksum;
563   unsigned char *p;
564
565   memset (record, 0, RECORDSIZE);
566
567   /* Store name and prefix.  */
568   namelen = strlen (hdr->name);
569   if (namelen < sizeof raw->name)
570     memcpy (raw->name, hdr->name, namelen);
571   else 
572     {
573       n = (namelen < sizeof raw->prefix)? namelen : sizeof raw->prefix;
574       for (n--; n ; n--)
575         if (hdr->name[n] == '/')
576           break;
577       if (namelen - n < sizeof raw->name)
578         {
579           /* Note that the N is < sizeof prefix and that the
580              delimiting slash is not stored.  */
581           memcpy (raw->prefix, hdr->name, n);
582           memcpy (raw->name, hdr->name+n+1, namelen - n);
583         }
584       else
585         {
586           err = gpg_error (GPG_ERR_TOO_LARGE);
587           log_error ("error storing file `%s': %s\n", 
588                      hdr->name, gpg_strerror (err));
589           return err;
590         }
591     }
592   
593   store_xoctal (raw->mode,  sizeof raw->mode,  hdr->mode);
594   store_xoctal (raw->uid,   sizeof raw->uid,   hdr->uid);
595   store_xoctal (raw->gid,   sizeof raw->gid,   hdr->gid);
596   store_xoctal (raw->size,  sizeof raw->size,  hdr->size);
597   store_xoctal (raw->mtime, sizeof raw->mtime, hdr->mtime);
598
599   switch (hdr->typeflag)
600     {
601     case TF_REGULAR:   raw->typeflag[0] = '0'; break;
602     case TF_HARDLINK:  raw->typeflag[0] = '1'; break;
603     case TF_SYMLINK:   raw->typeflag[0] = '2'; break;
604     case TF_CHARDEV:   raw->typeflag[0] = '3'; break;
605     case TF_BLOCKDEV:  raw->typeflag[0] = '4'; break;
606     case TF_DIRECTORY: raw->typeflag[0] = '5'; break;
607     case TF_FIFO:      raw->typeflag[0] = '6'; break;
608     default: return gpg_error (GPG_ERR_NOT_SUPPORTED);
609     }
610
611   memcpy (raw->magic, "ustar", 6);
612   raw->version[0] = '0';
613   raw->version[1] = '0';
614
615   store_uname (raw->uname, sizeof raw->uname, hdr->uid);
616   store_gname (raw->gname, sizeof raw->gname, hdr->gid);
617
618 #ifndef HAVE_W32_SYSTEM
619   if (hdr->typeflag == TF_SYMLINK)
620     {
621       int nread;
622
623       nread = readlink (hdr->name, raw->linkname, sizeof raw->linkname -1);
624       if (nread < 0)
625         {
626           err = gpg_error_from_syserror ();
627           log_error ("error reading symlink `%s': %s\n", 
628                      hdr->name, gpg_strerror (err));
629           return err;
630         }
631       raw->linkname[nread] = 0;
632     }
633 #endif /*HAVE_W32_SYSTEM*/
634
635   /* Compute the checksum.  */
636   memset (raw->checksum, ' ', sizeof raw->checksum);
637   chksum = 0;
638   p = record;
639   for (n=0; n < RECORDSIZE; n++)
640     chksum += *p++;
641   store_xoctal (raw->checksum, sizeof raw->checksum - 1, chksum);
642   raw->checksum[7] = ' ';
643
644   return 0;
645 }
646
647
648 static gpg_error_t
649 write_file (estream_t stream, tar_header_t hdr)
650 {
651   gpg_error_t err;
652   char record[RECORDSIZE];
653   estream_t infp;
654   size_t nread, nbytes;
655   int any;
656
657   err = build_header (record, hdr);
658   if (err)
659     {
660       if (gpg_err_code (err) == GPG_ERR_NOT_SUPPORTED)
661         {
662           log_info ("skipping unsupported file `%s'\n", hdr->name);
663           err = 0;
664         }
665       return err;
666     }
667
668   if (hdr->typeflag == TF_REGULAR)
669     {
670       infp = es_fopen (hdr->name, "rb");
671       if (!infp)
672         {
673           err = gpg_error_from_syserror ();
674           log_error ("can't open `%s': %s - skipped\n",
675                      hdr->name, gpg_strerror (err));
676           return err;
677         }
678     }
679   else
680     infp = NULL;
681
682   err = write_record (stream, record);
683   if (err)
684     goto leave;
685
686   if (hdr->typeflag == TF_REGULAR)
687     {
688       hdr->nrecords = (hdr->size + RECORDSIZE-1)/RECORDSIZE;
689       any = 0;
690       while (hdr->nrecords--)
691         {
692           nbytes = hdr->nrecords? RECORDSIZE : (hdr->size % RECORDSIZE);
693           if (!nbytes)
694             nbytes = RECORDSIZE;
695           nread = es_fread (record, 1, nbytes, infp);
696           if (nread != nbytes)
697             {
698               err = gpg_error_from_syserror ();
699               log_error ("error reading file `%s': %s%s\n",
700                          hdr->name, gpg_strerror (err),
701                          any? " (file shrunk?)":"");
702               goto leave;
703             }
704           any = 1;
705           err = write_record (stream, record);
706           if (err)
707             goto leave;
708         }
709       nread = es_fread (record, 1, 1, infp);
710       if (nread)
711         log_info ("note: file `%s' has grown\n", hdr->name);
712     }
713
714  leave:
715   if (err)
716     es_fclose (infp);
717   else if ((err = es_fclose (infp)))
718     log_error ("error closing file `%s': %s\n", hdr->name, gpg_strerror (err));
719       
720   return err;
721 }
722
723
724 static gpg_error_t
725 write_eof_mark (estream_t stream)
726 {
727   gpg_error_t err;
728   char record[RECORDSIZE];
729
730   memset (record, 0, sizeof record);
731   err = write_record (stream, record);
732   if (!err)
733     err = write_record (stream, record);
734   return err;
735 }
736
737
738 \f
739 /* Create a new tarball using the names in the array INPATTERN.  If
740    INPATTERN is NULL take the pattern as null terminated strings from
741    stdin.  */
742 void
743 gpgtar_create (char **inpattern)
744 {
745   gpg_error_t err = 0;
746   struct scanctrl_s scanctrl_buffer;
747   scanctrl_t scanctrl = &scanctrl_buffer;
748   tar_header_t hdr, *start_tail;
749   estream_t outstream = NULL;
750   int eof_seen = 0;
751
752   if (!inpattern)
753     es_set_binary (es_stdin);
754
755   memset (scanctrl, 0, sizeof *scanctrl);
756   scanctrl->flist_tail = &scanctrl->flist;
757
758   while (!eof_seen)
759     {
760       char *pat, *p;
761       int skip_this = 0;
762
763       if (inpattern)
764         {
765           const char *pattern = *inpattern;
766
767           if (!pattern)
768             break; /* End of array.  */
769           inpattern++;
770           
771           if (!*pattern)
772             continue;
773
774           pat = xtrystrdup (pattern);
775         }
776       else /* Read null delimited pattern from stdin.  */
777         {
778           int c;
779           char namebuf[4096];
780           size_t n = 0;
781           
782           for (;;)
783             {
784               if ((c = es_getc (es_stdin)) == EOF)
785                 {
786                   if (es_ferror (es_stdin))
787                     {
788                       err = gpg_error_from_syserror ();
789                       log_error ("error reading `%s': %s\n",
790                                  "[stdin]", strerror (errno));
791                       goto leave;
792                     }
793                   /* Note: The Nul is a delimiter and not a terminator.  */
794                   c = 0;
795                   eof_seen = 1;
796                 }
797               if (n >= sizeof namebuf - 1)
798                 {
799                   if (!skip_this)
800                     {
801                       skip_this = 1;
802                       log_error ("error reading `%s': %s\n",
803                                  "[stdin]", "filename too long");
804                     }
805                 }
806               else
807                 namebuf[n++] = c;
808               if (!c)
809                 {
810                   namebuf[n] = 0;
811                   break;
812                 }
813             }
814           
815           if (skip_this || n < 2)
816             continue;
817
818           pat = xtrystrdup (namebuf);
819         }
820
821       if (!pat)
822         {
823           err = gpg_error_from_syserror ();
824           log_error ("memory allocation problem: %s\n", gpg_strerror (err));
825           goto leave;
826         }
827       for (p=pat; *p; p++)
828         if (*p == '\\')
829           *p = '/';
830
831       if (opt.verbose > 1)
832         log_info ("scanning `%s'\n", pat);
833
834       start_tail = scanctrl->flist_tail;
835       if (skip_this || !pattern_valid_p (pat))
836         log_error ("skipping invalid name `%s'\n", pat);
837       else if (!add_entry (pat, NULL, scanctrl)
838                && *start_tail && ((*start_tail)->typeflag & TF_DIRECTORY))
839         scan_recursive (pat, scanctrl);
840
841       xfree (pat);
842     }
843
844   if (opt.outfile)
845     {
846       if (!strcmp (opt.outfile, "-"))
847         outstream = es_stdout;
848       else
849         outstream = es_fopen (opt.outfile, "wb");
850       if (!outstream)
851         {
852           err = gpg_error_from_syserror ();
853           log_error (_("can't create `%s': %s\n"),
854                      opt.outfile, gpg_strerror (err));
855           goto leave;
856         }
857     }
858   else
859     {
860       outstream = es_stdout;
861     }
862
863   if (outstream == es_stdout)
864     es_set_binary (es_stdout);
865
866   for (hdr = scanctrl->flist; hdr; hdr = hdr->next)
867     {
868       err = write_file (outstream, hdr);
869       if (err)
870         goto leave;
871     }
872   err = write_eof_mark (outstream);
873
874  leave:
875   if (!err)
876     {
877       if (outstream != es_stdout)
878         err = es_fclose (outstream);
879       else
880         err = es_fflush (outstream);
881       outstream = NULL;
882     }
883   if (err)
884     {
885       log_error ("creating tarball `%s' failed: %s\n",
886                  es_fname_get (outstream), gpg_strerror (err));
887       if (outstream && outstream != es_stdout)
888         es_fclose (outstream);
889       if (opt.outfile)
890         gnupg_remove (opt.outfile);
891     }
892   scanctrl->flist_tail = NULL;
893   while ( (hdr = scanctrl->flist) )
894     {
895       scanctrl->flist = hdr->next;
896       xfree (hdr);
897     }
898 }