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