chiark / gitweb /
2e8c102fd0945e468e380abfde02632d27b5de43
[gnupg2.git] / g10 / openfile.c
1 /* openfile.c
2  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2009,
3  *               2010 Free Software Foundation, Inc.
4  *
5  * This file is part of GnuPG.
6  *
7  * GnuPG is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * GnuPG is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, see <https://www.gnu.org/licenses/>.
19  */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <fcntl.h>
29 #include <unistd.h>
30
31 #include "gpg.h"
32 #include "util.h"
33 #include "ttyio.h"
34 #include "options.h"
35 #include "main.h"
36 #include "status.h"
37 #include "i18n.h"
38
39 #ifdef HAVE_W32_SYSTEM
40 #define NAME_OF_DEV_NULL "nul"
41 #else
42 #define NAME_OF_DEV_NULL "/dev/null"
43 #endif
44
45
46 #if defined (HAVE_DRIVE_LETTERS) || defined (__riscos__)
47 #define CMP_FILENAME(a,b) ascii_strcasecmp( (a), (b) )
48 #else
49 #define CMP_FILENAME(a,b) strcmp( (a), (b) )
50 #endif
51
52
53 /* FIXME:  Implement opt.interactive. */
54
55 /*
56  * Check whether FNAME exists and ask if it's okay to overwrite an
57  * existing one.
58  * Returns: True: it's okay to overwrite or the file does not exist
59  *          False: Do not overwrite
60  */
61 int
62 overwrite_filep( const char *fname )
63 {
64   if ( iobuf_is_pipe_filename (fname) )
65     return 1; /* Writing to stdout is always okay.  */
66
67   if ( access( fname, F_OK ) )
68     return 1; /* Does not exist.  */
69
70   if ( !compare_filenames (fname, NAME_OF_DEV_NULL) )
71     return 1; /* Does not do any harm.  */
72
73   if (opt.answer_yes)
74     return 1;
75   if (opt.answer_no || opt.batch)
76     return 0;  /* Do not overwrite.  */
77
78   tty_printf (_("File '%s' exists. "), fname);
79   if (cpr_enabled ())
80     tty_printf ("\n");
81   if (cpr_get_answer_is_yes ("openfile.overwrite.okay",
82                              _("Overwrite? (y/N) ")) )
83     return 1;
84   return 0;
85 }
86
87
88 /*
89  * Strip known extensions from iname and return a newly allocated
90  * filename.  Return NULL if we can't do that.
91  */
92 char *
93 make_outfile_name (const char *iname)
94 {
95   size_t n;
96
97   if (iobuf_is_pipe_filename (iname))
98     return xstrdup ("-");
99
100   n = strlen (iname);
101   if (n > 4 && (!CMP_FILENAME(iname+n-4, EXTSEP_S GPGEXT_GPG)
102                 || !CMP_FILENAME(iname+n-4, EXTSEP_S "pgp")
103                 || !CMP_FILENAME(iname+n-4, EXTSEP_S "sig")
104                 || !CMP_FILENAME(iname+n-4, EXTSEP_S "asc")))
105     {
106       char *buf = xstrdup (iname);
107       buf[n-4] = 0;
108       return buf;
109     }
110   else if (n > 5 && !CMP_FILENAME(iname+n-5, EXTSEP_S "sign"))
111     {
112       char *buf = xstrdup (iname);
113       buf[n-5] = 0;
114       return buf;
115     }
116
117   log_info (_("%s: unknown suffix\n"), iname);
118   return NULL;
119 }
120
121
122 /* Ask for an output filename; use the given one as default.  Return
123    NULL if no file has been given or if it is not possible to ask the
124    user.  NAME is the template len which might conatin enbedded Nuls.
125    NAMELEN is its actual length.
126  */
127 char *
128 ask_outfile_name( const char *name, size_t namelen )
129 {
130   size_t n;
131   const char *s;
132   char *prompt;
133   char *fname;
134   char *defname;
135
136   if ( opt.batch )
137     return NULL;
138
139   defname = name && namelen? make_printable_string (name, namelen, 0) : NULL;
140
141   s = _("Enter new filename");
142   n = strlen(s) + (defname?strlen (defname):0) + 10;
143   prompt = xmalloc (n);
144   if (defname)
145     snprintf (prompt, n, "%s [%s]: ", s, defname );
146   else
147     snprintf (prompt, n, "%s: ", s );
148   tty_enable_completion(NULL);
149   fname = cpr_get ("openfile.askoutname", prompt );
150   cpr_kill_prompt ();
151   tty_disable_completion ();
152   xfree (prompt);
153   if ( !*fname )
154     {
155       xfree (fname);
156       fname = defname;
157       defname = NULL;
158     }
159   xfree (defname);
160   if (fname)
161     trim_spaces (fname);
162   return fname;
163 }
164
165
166 /*
167  * Make an output filename for the inputfile INAME.
168  * Returns an IOBUF and an errorcode
169  * Mode 0 = use ".gpg"
170  *      1 = use ".asc"
171  *      2 = use ".sig"
172  *      3 = use ".rev"
173  *
174  * If INP_FD is not -1 the function simply creates an IOBUF for that
175  * file descriptor and ignore INAME and MODE.  Note that INP_FD won't
176  * be closed if the returned IOBUF is closed.  With RESTRICTEDPERM a
177  * file will be created with mode 700 if possible.
178  */
179 int
180 open_outfile (int inp_fd, const char *iname, int mode, int restrictedperm,
181               iobuf_t *a)
182 {
183   int rc = 0;
184
185   *a = NULL;
186   if (inp_fd != -1)
187     {
188       char xname[64];
189
190       *a = iobuf_fdopen_nc (inp_fd, "wb");
191       if (!*a)
192         {
193           rc = gpg_error_from_syserror ();
194           snprintf (xname, sizeof xname, "[fd %d]", inp_fd);
195           log_error (_("can't open '%s': %s\n"), xname, gpg_strerror (rc));
196         }
197       else if (opt.verbose)
198         {
199           snprintf (xname, sizeof xname, "[fd %d]", inp_fd);
200           log_info (_("writing to '%s'\n"), xname);
201         }
202     }
203   else if (iobuf_is_pipe_filename (iname) && !opt.outfile)
204     {
205       *a = iobuf_create (NULL, 0);
206       if ( !*a )
207         {
208           rc = gpg_error_from_syserror ();
209           log_error (_("can't open '%s': %s\n"), "[stdout]", strerror(errno) );
210         }
211       else if ( opt.verbose )
212         log_info (_("writing to stdout\n"));
213     }
214   else
215     {
216       char *buf = NULL;
217       const char *name;
218
219       if (opt.dry_run)
220         name = NAME_OF_DEV_NULL;
221       else if (opt.outfile)
222         name = opt.outfile;
223       else
224         {
225 #ifdef USE_ONLY_8DOT3
226           if (opt.mangle_dos_filenames)
227             {
228               /* It is quite common for DOS systems to have only one
229                  dot in a filename.  If we have something like this,
230                  we simple replace the suffix except in cases where
231                  the suffix is larger than 3 characters and not the
232                  same as the new one.  We don't map the filenames to
233                  8.3 because this is a duty of the file system.  */
234               char *dot;
235               const char *newsfx;
236
237               newsfx = (mode==1 ? ".asc" :
238                         mode==2 ? ".sig" :
239                         mode==3 ? ".rev" : ".gpg");
240
241               buf = xmalloc (strlen(iname)+4+1);
242               strcpy (buf, iname);
243               dot = strchr (buf, '.' );
244               if ( dot && dot > buf && dot[1] && strlen(dot) <= 4
245                    && CMP_FILENAME (newsfx, dot) )
246                 strcpy (dot, newsfx);
247               else if (dot && !dot[1]) /* Do not duplicate a dot.  */
248                 strcpy (dot, newsfx+1);
249               else
250                 strcat (buf, newsfx);
251             }
252           if (!buf)
253 #endif /* USE_ONLY_8DOT3 */
254             {
255               buf = xstrconcat (iname,
256                                 (mode==1 ? EXTSEP_S "asc" :
257                                  mode==2 ? EXTSEP_S "sig" :
258                                  mode==3 ? EXTSEP_S "rev" :
259                                  /*     */ EXTSEP_S GPGEXT_GPG),
260                                 NULL);
261             }
262           name = buf;
263         }
264
265       rc = 0;
266       while ( !overwrite_filep (name) )
267         {
268           char *tmp = ask_outfile_name (NULL, 0);
269           if ( !tmp || !*tmp )
270             {
271               xfree (tmp);
272               rc = gpg_error (GPG_ERR_EEXIST);
273               break;
274             }
275           xfree (buf);
276           name = buf = tmp;
277         }
278
279       if ( !rc )
280         {
281           if (is_secured_filename (name) )
282             {
283               *a = NULL;
284               gpg_err_set_errno (EPERM);
285             }
286           else
287             *a = iobuf_create (name, restrictedperm);
288           if (!*a)
289             {
290               rc = gpg_error_from_syserror ();
291               log_error(_("can't create '%s': %s\n"), name, strerror(errno) );
292             }
293           else if( opt.verbose )
294             log_info (_("writing to '%s'\n"), name );
295         }
296       xfree(buf);
297     }
298
299   if (*a)
300     iobuf_ioctl (*a, IOBUF_IOCTL_NO_CACHE, 1, NULL);
301
302   return rc;
303 }
304
305
306 /* Find a matching data file for the signature file SIGFILENAME and
307    return it as a malloced string.  If no matching data file is found,
308    return NULL.  */
309 char *
310 get_matching_datafile (const char *sigfilename)
311 {
312   char *fname = NULL;
313   size_t len;
314
315   if (iobuf_is_pipe_filename (sigfilename))
316     return NULL;
317
318   len = strlen (sigfilename);
319   if (len > 4
320       && (!strcmp (sigfilename + len - 4, EXTSEP_S "sig")
321           || (len > 5 && !strcmp(sigfilename + len - 5, EXTSEP_S "sign"))
322           || !strcmp(sigfilename + len - 4, EXTSEP_S "asc")))
323     {
324
325       fname = xstrdup (sigfilename);
326       fname[len-(fname[len-1]=='n'?5:4)] = 0 ;
327       if (access (fname, R_OK ))
328         {
329           /* Not found or other error.  */
330           xfree (fname);
331           fname = NULL;
332         }
333     }
334
335   return fname;
336 }
337
338
339 /*
340  * Try to open a file without the extension ".sig" or ".asc"
341  * Return NULL if such a file is not available.
342  */
343 iobuf_t
344 open_sigfile (const char *sigfilename, progress_filter_context_t *pfx)
345 {
346   iobuf_t a = NULL;
347   char *buf;
348
349   buf = get_matching_datafile (sigfilename);
350   if (buf)
351     {
352       a = iobuf_open (buf);
353       if (a && is_secured_file (iobuf_get_fd (a)))
354         {
355           iobuf_close (a);
356           a = NULL;
357           gpg_err_set_errno (EPERM);
358         }
359       if (a)
360         log_info (_("assuming signed data in '%s'\n"), buf);
361       if (a && pfx)
362         handle_progress (pfx, a, buf);
363       xfree (buf);
364     }
365
366   return a;
367 }
368
369
370 void
371 try_make_homedir (const char *fname)
372 {
373   const char *defhome = standard_homedir ();
374
375   /* Create the directory only if the supplied directory name is the
376      same as the default one.  This way we avoid to create arbitrary
377      directories when a non-default home directory is used.  To cope
378      with HOME, we do compare only the suffix if we see that the
379      default homedir does start with a tilde.  */
380   if ( opt.dry_run || opt.no_homedir_creation )
381     return;
382
383   if (
384 #ifdef HAVE_W32_SYSTEM
385       ( !compare_filenames (fname, defhome) )
386 #else
387       ( *defhome == '~'
388         && (strlen(fname) >= strlen (defhome+1)
389             && !strcmp(fname+strlen(fname)-strlen(defhome+1), defhome+1 ) ))
390       || (*defhome != '~'  && !compare_filenames( fname, defhome ) )
391 #endif
392       )
393     {
394       if (gnupg_mkdir (fname, "-rwx"))
395         log_fatal ( _("can't create directory '%s': %s\n"),
396                     fname, strerror(errno) );
397       else if (!opt.quiet )
398         log_info ( _("directory '%s' created\n"), fname );
399     }
400 }
401
402
403 /* Get and if needed create a string with the directory used to store
404    openpgp revocations.  */
405 char *
406 get_openpgp_revocdir (const char *home)
407 {
408   char *fname;
409   struct stat statbuf;
410
411   fname = make_filename (home, GNUPG_OPENPGP_REVOC_DIR, NULL);
412   if (stat (fname, &statbuf) && errno == ENOENT)
413     {
414       if (gnupg_mkdir (fname, "-rwx"))
415         log_error (_("can't create directory '%s': %s\n"),
416                    fname, strerror (errno) );
417       else if (!opt.quiet)
418         log_info (_("directory '%s' created\n"), fname);
419     }
420   return fname;
421 }