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