* exec.c (make_tempdir) [_WIN32]: Modified to properly handle
[gnupg.git] / g10 / openfile.c
blob16afaf1675073f0c53a586dd5a56d7ae665169fa
1 /* openfile.c
2 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
3 * 2005 Free Software Foundation, Inc.
5 * This file is part of GnuPG.
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.
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.
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.
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"
41 #ifdef USE_ONLY_8DOT3
42 #define SKELEXT ".skl"
43 #else
44 #define SKELEXT EXTSEP_S "skel"
45 #endif
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
53 #ifdef MKDIR_TAKES_ONE_ARG
54 #undef mkdir
55 #define mkdir(a,b) mkdir(a)
56 #endif
58 /* FIXME: Implement opt.interactive. */
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
66 int
67 overwrite_filep( const char *fname )
69 if( iobuf_is_pipe_filename (fname) )
70 return 1; /* Writing to stdout is always okay */
72 if( access( fname, F_OK ) )
73 return 1; /* does not exist */
75 #ifndef HAVE_DOSISH_SYSTEM
76 if ( !strcmp ( fname, "/dev/null" ) )
77 return 1; /* does not do any harm */
78 #endif
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 */
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;
96 /****************
97 * Strip know extensions from iname and return a newly allocated
98 * filename. Return NULL if we can't do that.
100 char *
101 make_outfile_name( const char *iname )
103 size_t n;
105 if ( iobuf_is_pipe_filename (iname) )
106 return xstrdup("-");
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;
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;
123 log_info(_("%s: unknown suffix\n"), iname );
124 return NULL;
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.
133 char *
134 ask_outfile_name( const char *name, size_t namelen )
136 size_t n;
137 const char *s;
138 char *prompt;
139 char *fname;
140 char *defname;
142 if( opt.batch )
143 return NULL;
145 s = _("Enter new filename");
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;
163 xfree(defname);
164 if (fname)
165 trim_spaces (fname);
166 return fname;
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"
178 open_outfile( const char *iname, int mode, IOBUF *a )
180 int rc = 0;
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;
189 else if( opt.verbose )
190 log_info(_("writing to stdout\n"));
192 else {
193 char *buf = NULL;
194 const char *name;
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)
204 /* It is quite common 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 execpt in cases where the suffix is
207 * larger than 3 characters and not the same as.
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
211 char *dot;
212 const char *newsfx = mode==1 ? ".asc" :
213 mode==2 ? ".sig" : ".gpg";
215 buf = xmalloc(strlen(iname)+4+1);
216 strcpy(buf,iname);
217 dot = strchr(buf, '.' );
218 if ( dot && dot > buf && dot[1] && strlen(dot) <= 4
219 && CMP_FILENAME(newsfx, dot) )
221 strcpy(dot, newsfx );
223 else if ( dot && !dot[1] ) /* don't duplicate a dot */
224 strcpy( dot, newsfx+1 );
225 else
226 strcat ( buf, newsfx );
228 if (!buf)
229 #endif /* USE_ONLY_8DOT3 */
231 buf = xmalloc(strlen(iname)+4+1);
232 strcpy(stpcpy(buf,iname), mode==1 ? EXTSEP_S "asc" :
233 mode==2 ? EXTSEP_S "sig" : EXTSEP_S "gpg");
235 name = buf;
238 rc = 0;
239 while( !overwrite_filep (name) )
241 char *tmp = ask_outfile_name (NULL, 0);
242 if ( !tmp || !*tmp )
244 xfree (tmp);
245 rc = G10ERR_FILE_EXISTS;
246 break;
248 xfree (buf);
249 name = buf = tmp;
252 if( !rc )
254 if (is_secured_filename (name) )
256 *a = NULL;
257 errno = EPERM;
259 else
260 *a = iobuf_create( name );
261 if( !*a )
263 log_error(_("can't create `%s': %s\n"), name, strerror(errno) );
264 rc = G10ERR_CREATE_FILE;
266 else if( opt.verbose )
267 log_info(_("writing to `%s'\n"), name );
269 xfree(buf);
272 if (*a)
273 iobuf_ioctl (*a,3,1,NULL); /* disable fd caching */
275 return rc;
279 /****************
280 * Try to open a file without the extension ".sig" or ".asc"
281 * Return NULL if such a file is not available.
283 IOBUF
284 open_sigfile( const char *iname, progress_filter_context_t *pfx )
286 IOBUF a = NULL;
287 size_t len;
289 if( !iobuf_is_pipe_filename (iname) ) {
290 len = strlen(iname);
291 if( len > 4 && ( !strcmp(iname + len - 4, EXTSEP_S "sig")
292 || ( len > 5 && !strcmp(iname + len - 5, EXTSEP_S "sign") )
293 || !strcmp(iname + len - 4, EXTSEP_S "asc")) ) {
294 char *buf;
295 buf = xstrdup(iname);
296 buf[len-(buf[len-1]=='n'?5:4)] = 0 ;
297 a = iobuf_open( buf );
298 if (a && is_secured_file (iobuf_get_fd (a)))
300 iobuf_close (a);
301 a = NULL;
302 errno = EPERM;
304 if( a && opt.verbose )
305 log_info(_("assuming signed data in `%s'\n"), buf );
306 if (a && pfx)
307 handle_progress (pfx, a, buf);
308 xfree(buf);
311 return a;
314 /****************
315 * Copy the option file skeleton to the given directory.
317 static void
318 copy_options_file( const char *destdir )
320 const char *datadir = GNUPG_DATADIR;
321 char *fname;
322 FILE *src, *dst;
323 int linefeeds=0;
324 int c;
325 mode_t oldmask;
326 int esc = 0;
327 int any_option = 0;
329 if( opt.dry_run )
330 return;
332 fname = xmalloc( strlen(datadir) + strlen(destdir) + 15 );
333 strcpy(stpcpy(fname, datadir), DIRSEP_S "options" SKELEXT );
334 src = fopen( fname, "r" );
335 if (src && is_secured_file (fileno (src)))
337 fclose (src);
338 src = NULL;
339 errno = EPERM;
341 if( !src ) {
342 log_error(_("can't open `%s': %s\n"), fname, strerror(errno) );
343 xfree(fname);
344 return;
346 strcpy(stpcpy(fname, destdir), DIRSEP_S "gpg" EXTSEP_S "conf" );
347 oldmask=umask(077);
348 if ( is_secured_filename (fname) )
350 dst = NULL;
351 errno = EPERM;
353 else
354 dst = fopen( fname, "w" );
355 umask(oldmask);
356 if( !dst ) {
357 log_error(_("can't create `%s': %s\n"), fname, strerror(errno) );
358 fclose( src );
359 xfree(fname);
360 return;
363 while( (c=getc(src)) != EOF ) {
364 if( linefeeds < 3 ) {
365 if( c == '\n' )
366 linefeeds++;
368 else {
369 putc( c, dst );
370 if (c== '\n')
371 esc = 1;
372 else if (esc == 1) {
373 if (c == ' ' || c == '\t')
375 else if (c == '#')
376 esc = 2;
377 else
378 any_option = 1;
382 fclose( dst );
383 fclose( src );
384 log_info(_("new configuration file `%s' created\n"), fname );
385 if (any_option)
386 log_info (_("WARNING: options in `%s'"
387 " are not yet active during this run\n"),
388 fname);
389 xfree(fname);
393 void
394 try_make_homedir( const char *fname )
396 const char *defhome = GNUPG_HOMEDIR;
398 /* Create the directory only if the supplied directory name
399 * is the same as the default one. This way we avoid to create
400 * arbitrary directories when a non-default homedirectory is used.
401 * To cope with HOME, we do compare only the suffix if we see that
402 * the default homedir does start with a tilde.
404 if( opt.dry_run || opt.no_homedir_creation )
405 return;
407 if ( ( *defhome == '~'
408 && ( strlen(fname) >= strlen (defhome+1)
409 && !strcmp(fname+strlen(fname)-strlen(defhome+1),
410 defhome+1 ) ))
411 || ( *defhome != '~'
412 && !compare_filenames( fname, defhome ) )
414 if( mkdir( fname, S_IRUSR|S_IWUSR|S_IXUSR ) )
415 log_fatal( _("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 copy_options_file( fname );
420 /* log_info(_("you have to start GnuPG again, " */
421 /* "so it can read the new configuration file\n") ); */
422 /* g10_exit(1); */