Take care of already existing bogus 0x1f signatures.
[gnupg.git] / g10 / openfile.c
1 /* openfile.c
2  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
3  *               2005 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 <http://www.gnu.org/licenses/>.
19  */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <assert.h>
26 #include <errno.h>
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <fcntl.h>
30 #include <unistd.h>
31
32 #include "gpg.h"
33 #include "util.h"
34 #include "ttyio.h"
35 #include "options.h"
36 #include "main.h"
37 #include "status.h"
38 #include "i18n.h"
39
40 #ifdef USE_ONLY_8DOT3
41 #define SKELEXT ".skl"
42 #else
43 #define SKELEXT EXTSEP_S "skel"
44 #endif
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 #ifdef MKDIR_TAKES_ONE_ARG
53 #undef mkdir
54 #define mkdir(a,b) mkdir(a)
55 #endif
56
57 /* FIXME:  Implement opt.interactive. */
58
59 /****************
60  * Check whether FNAME exists and ask if it's okay to overwrite an
61  * existing one.
62  * Returns: True: it's okay to overwrite or the file does not exist
63  *          False: Do not overwrite
64  */
65 int
66 overwrite_filep( const char *fname )
67 {
68     if( iobuf_is_pipe_filename (fname) )
69         return 1; /* Writing to stdout is always okay */
70
71     if( access( fname, F_OK ) )
72         return 1; /* does not exist */
73
74 #ifndef HAVE_DOSISH_SYSTEM
75     if ( !strcmp ( fname, "/dev/null" ) )
76         return 1; /* does not do any harm */
77 #endif
78 #ifdef HAVE_W32_SYSTEM
79     if ( !strcmp ( fname, "nul" ) )
80         return 1;
81 #endif
82
83     /* fixme: add some backup stuff in case of overwrite */
84     if( opt.answer_yes )
85         return 1;
86     if( opt.answer_no || opt.batch )
87         return 0;  /* do not overwrite */
88
89     tty_printf(_("File `%s' exists. "), fname);
90     if( cpr_enabled () )
91         tty_printf ("\n");
92     if( cpr_get_answer_is_yes("openfile.overwrite.okay",
93                                _("Overwrite? (y/N) ")) )
94         return 1;
95     return 0;
96 }
97
98
99 /****************
100  * Strip known extensions from iname and return a newly allocated
101  * filename.  Return NULL if we can't do that.
102  */
103 char *
104 make_outfile_name( const char *iname )
105 {
106     size_t n;
107
108     if ( iobuf_is_pipe_filename (iname) )
109         return xstrdup("-");
110
111     n = strlen(iname);
112     if( n > 4 && (    !CMP_FILENAME(iname+n-4, EXTSEP_S "gpg")
113                    || !CMP_FILENAME(iname+n-4, EXTSEP_S "pgp")
114                    || !CMP_FILENAME(iname+n-4, EXTSEP_S "sig")
115                    || !CMP_FILENAME(iname+n-4, EXTSEP_S "asc") ) ) {
116         char *buf = xstrdup( iname );
117         buf[n-4] = 0;
118         return buf;
119     }
120     else if( n > 5 && !CMP_FILENAME(iname+n-5, EXTSEP_S "sign") ) {
121         char *buf = xstrdup( iname );
122         buf[n-5] = 0;
123         return buf;
124     }
125
126     log_info(_("%s: unknown suffix\n"), iname );
127     return NULL;
128 }
129
130
131 /* Ask for an output filename; use the given one as default.  Return
132    NULL if no file has been given or if it is not possible to ask the
133    user.  NAME is the template len which might conatin enbedded Nuls.
134    NAMELEN is its actual length.
135  */
136 char *
137 ask_outfile_name( const char *name, size_t namelen )
138 {
139   size_t n;
140   const char *s;
141   char *prompt;
142   char *fname;
143   char *defname;
144
145   if ( opt.batch )
146     return NULL;
147   
148   defname = name && namelen? make_printable_string (name, namelen, 0) : NULL;
149
150   s = _("Enter new filename");
151   n = strlen(s) + (defname?strlen (defname):0) + 10;
152   prompt = xmalloc (n);
153   if (defname)
154     snprintf (prompt, n-1, "%s [%s]: ", s, defname );
155   else
156     snprintf (prompt, n-1, "%s: ", s );
157   tty_enable_completion(NULL);
158   fname = cpr_get ("openfile.askoutname", prompt );
159   cpr_kill_prompt ();
160   tty_disable_completion ();
161   xfree (prompt);
162   if ( !*fname ) 
163     {
164       xfree (fname); 
165       fname = defname;
166       defname = NULL;
167     }
168   xfree (defname);
169   if (fname)
170     trim_spaces (fname);
171   return fname;
172 }
173
174
175 /****************
176  * Make an output filename for the inputfile INAME.
177  * Returns an IOBUF and an errorcode
178  * Mode 0 = use ".gpg"
179  *      1 = use ".asc"
180  *      2 = use ".sig"
181  */
182 int
183 open_outfile( const char *iname, int mode, IOBUF *a )
184 {
185   int rc = 0;
186
187   *a = NULL;
188   if( iobuf_is_pipe_filename (iname) && !opt.outfile ) {
189     *a = iobuf_create(NULL);
190     if( !*a ) {
191       rc = gpg_error_from_syserror ();
192       log_error(_("can't open `%s': %s\n"), "[stdout]", strerror(errno) );
193     }
194     else if( opt.verbose )
195       log_info(_("writing to stdout\n"));
196   }
197   else {
198     char *buf = NULL;
199     const char *name;
200     
201     if ( opt.dry_run )
202       {
203 #ifdef HAVE_W32_SYSTEM
204         name = "nul";
205 #else
206         name = "/dev/null";
207 #endif
208       }
209     else if( opt.outfile )
210       name = opt.outfile;
211     else {
212 #ifdef USE_ONLY_8DOT3
213       if (opt.mangle_dos_filenames)
214         {
215           /* It is quite common DOS system to have only one dot in a
216            * a filename So if we have something like this, we simple
217            * replace the suffix execpt in cases where the suffix is
218            * larger than 3 characters and not the same as.
219            * We should really map the filenames to 8.3 but this tends to
220            * be more complicated and is probaly a duty of the filesystem
221            */
222           char *dot;
223           const char *newsfx = mode==1 ? ".asc" :
224                                mode==2 ? ".sig" : ".gpg";
225           
226           buf = xmalloc(strlen(iname)+4+1);
227           strcpy(buf,iname);
228           dot = strchr(buf, '.' );
229           if ( dot && dot > buf && dot[1] && strlen(dot) <= 4
230                                   && CMP_FILENAME(newsfx, dot) )
231             {
232               strcpy(dot, newsfx );
233             }
234           else if ( dot && !dot[1] ) /* don't duplicate a dot */
235             strcpy( dot, newsfx+1 );
236           else
237             strcat ( buf, newsfx );
238         }
239       if (!buf)
240 #endif /* USE_ONLY_8DOT3 */
241         {
242           buf = xmalloc(strlen(iname)+4+1);
243           strcpy(stpcpy(buf,iname), mode==1 ? EXTSEP_S "asc" :
244                                    mode==2 ? EXTSEP_S "sig" : EXTSEP_S "gpg");
245         }
246       name = buf;
247     }
248
249     rc = 0;
250     while( !overwrite_filep (name) )
251       {
252         char *tmp = ask_outfile_name (NULL, 0);
253         if ( !tmp || !*tmp )
254           {
255             xfree (tmp);
256             rc = gpg_error (GPG_ERR_EEXIST);
257             break;
258           }
259         xfree (buf);
260         name = buf = tmp;
261       }
262     
263     if( !rc )
264       {
265         if (is_secured_filename (name) )
266           {
267             *a = NULL;
268             errno = EPERM;
269           }
270         else
271           *a = iobuf_create( name );
272         if( !*a )
273           {
274             rc = gpg_error_from_syserror ();
275             log_error(_("can't create `%s': %s\n"), name, strerror(errno) );
276           }
277         else if( opt.verbose )
278           log_info(_("writing to `%s'\n"), name );
279       }
280     xfree(buf);
281   }
282
283   if (*a)
284     iobuf_ioctl (*a,3,1,NULL); /* disable fd caching */
285
286   return rc;
287 }
288
289
290 /****************
291  * Try to open a file without the extension ".sig" or ".asc"
292  * Return NULL if such a file is not available.
293  */
294 IOBUF
295 open_sigfile( const char *iname, progress_filter_context_t *pfx )
296 {
297     IOBUF a = NULL;
298     size_t len;
299
300     if( !iobuf_is_pipe_filename (iname) ) {
301         len = strlen(iname);
302         if( len > 4 && ( !strcmp(iname + len - 4, EXTSEP_S "sig")
303                         || ( len > 5 && !strcmp(iname + len - 5, EXTSEP_S "sign") )
304                         || !strcmp(iname + len - 4, EXTSEP_S "asc")) ) {
305             char *buf;
306             buf = xstrdup(iname);
307             buf[len-(buf[len-1]=='n'?5:4)] = 0 ;
308             a = iobuf_open( buf );
309             if (a && is_secured_file (iobuf_get_fd (a)))
310               {
311                 iobuf_close (a);
312                 a = NULL;
313                 errno = EPERM;
314               }
315             if( a && opt.verbose )
316                 log_info(_("assuming signed data in `%s'\n"), buf );
317             if (a && pfx)
318               handle_progress (pfx, a, buf);
319             xfree(buf);
320         }
321     }
322     return a;
323 }
324
325 /****************
326  * Copy the option file skeleton to the given directory.
327  */
328 static void
329 copy_options_file( const char *destdir )
330 {
331     const char *datadir = gnupg_datadir ();
332     char *fname;
333     FILE *src, *dst;
334     int linefeeds=0;
335     int c;
336     mode_t oldmask;
337     int esc = 0;
338     int any_option = 0;
339
340     if( opt.dry_run )
341         return;
342
343     fname = xmalloc( strlen(datadir) + strlen(destdir) + 15 );
344     strcpy(stpcpy(fname, datadir), DIRSEP_S "gpg-conf" SKELEXT );
345     src = fopen( fname, "r" );
346     if (src && is_secured_file (fileno (src)))
347       {
348         fclose (src);
349         src = NULL;
350         errno = EPERM;
351       }
352     if( !src ) {
353         log_info (_("can't open `%s': %s\n"), fname, strerror(errno) );
354         xfree(fname);
355         return;
356     }
357     strcpy(stpcpy(fname, destdir), DIRSEP_S "gpg" EXTSEP_S "conf" );
358     oldmask=umask(077);
359     if ( is_secured_filename (fname) )
360       {
361         dst = NULL;
362         errno = EPERM;
363       }
364     else
365       dst = fopen( fname, "w" );
366     umask(oldmask);
367     if( !dst ) {
368         log_info (_("can't create `%s': %s\n"), fname, strerror(errno) );
369         fclose( src );
370         xfree(fname);
371         return;
372     }
373
374     while( (c=getc(src)) != EOF ) {
375         if( linefeeds < 3 ) {
376             if( c == '\n' )
377                 linefeeds++;
378         }
379         else {
380             putc( c, dst );
381             if (c== '\n')
382                 esc = 1;
383             else if (esc == 1) {
384                 if (c == ' ' || c == '\t')
385                     ;
386                 else if (c == '#')
387                     esc = 2;
388                 else 
389                     any_option = 1;
390             }
391         }
392     }
393     fclose( dst );
394     fclose( src );
395     log_info(_("new configuration file `%s' created\n"), fname );
396     if (any_option)
397         log_info (_("WARNING: options in `%s'"
398                     " are not yet active during this run\n"),
399                   fname);
400     xfree(fname);
401 }
402
403
404 void
405 try_make_homedir (const char *fname)
406 {
407   const char *defhome = standard_homedir ();
408
409   /* Create the directory only if the supplied directory name is the
410      same as the default one.  This way we avoid to create arbitrary
411      directories when a non-default home directory is used.  To cope
412      with HOME, we do compare only the suffix if we see that the
413      default homedir does start with a tilde.  */
414   if ( opt.dry_run || opt.no_homedir_creation )
415     return;
416
417   if (
418 #ifdef HAVE_W32_SYSTEM
419       ( !compare_filenames (fname, defhome) )
420 #else
421       ( *defhome == '~'
422         && (strlen(fname) >= strlen (defhome+1)
423             && !strcmp(fname+strlen(fname)-strlen(defhome+1), defhome+1 ) ))
424       || (*defhome != '~'  && !compare_filenames( fname, defhome ) )
425 #endif
426       )
427     {
428       if ( mkdir (fname, S_IRUSR|S_IWUSR|S_IXUSR) )
429         log_fatal ( _("can't create directory `%s': %s\n"),
430                     fname, strerror(errno) );
431       else if (!opt.quiet )
432         log_info ( _("directory `%s' created\n"), fname );
433       copy_options_file( fname );
434       
435     }
436 }