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