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