Add parameter checks and extend documentation of estream.
[gnupg.git] / common / homedir.c
1 /* homedir.c - Setup the home directory.
2  * Copyright (C) 2004, 2006, 2007, 2010 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <config.h>
21 #include <stdlib.h>
22 #include <errno.h>
23 #include <fcntl.h>
24
25 #ifdef HAVE_W32_SYSTEM
26 #include <shlobj.h>
27 #ifndef CSIDL_APPDATA
28 #define CSIDL_APPDATA 0x001a
29 #endif
30 #ifndef CSIDL_LOCAL_APPDATA
31 #define CSIDL_LOCAL_APPDATA 0x001c
32 #endif
33 #ifndef CSIDL_COMMON_APPDATA
34 #define CSIDL_COMMON_APPDATA 0x0023
35 #endif
36 #ifndef CSIDL_FLAG_CREATE
37 #define CSIDL_FLAG_CREATE 0x8000
38 #endif
39 #endif /*HAVE_W32_SYSTEM*/
40
41
42
43 #include "util.h"
44 #include "sysutils.h"
45
46
47 #ifdef HAVE_W32_SYSTEM
48 static void
49 w32_try_mkdir (const char *dir)
50 {
51 #ifdef HAVE_W32CE_SYSTEM
52   wchar_t *wdir = utf8_to_wchar (dir);
53   if (wdir)
54     {
55       CreateDirectory (wdir, NULL);
56       xfree (wdir);
57     }
58 #else
59   CreateDirectory (dir, NULL);
60 #endif
61 }
62 #endif
63
64
65 /* This is a helper function to load a Windows function from either of
66    one DLLs. */
67 #ifdef HAVE_W32_SYSTEM
68 static HRESULT
69 w32_shgetfolderpath (HWND a, int b, HANDLE c, DWORD d, LPSTR e)
70 {
71   static int initialized;
72   static HRESULT (WINAPI * func)(HWND,int,HANDLE,DWORD,LPSTR);
73
74   if (!initialized)
75     {
76       static char *dllnames[] = { "shell32.dll", "shfolder.dll", NULL };
77       void *handle;
78       int i;
79
80       initialized = 1;
81
82       for (i=0, handle = NULL; !handle && dllnames[i]; i++)
83         {
84           handle = dlopen (dllnames[i], RTLD_LAZY);
85           if (handle)
86             {
87               func = dlsym (handle, "SHGetFolderPathA");
88               if (!func)
89                 {
90                   dlclose (handle);
91                   handle = NULL;
92                 }
93             }
94         }
95     }
96
97   if (func)
98     return func (a,b,c,d,e);
99   else
100     return -1;
101 }
102 #endif /*HAVE_W32_SYSTEM*/
103
104
105 /* Get the standard home directory.  In general this function should
106    not be used as it does not consider a registry value (under W32) or
107    the GNUPGHOME environment variable.  It is better to use
108    default_homedir(). */
109 const char *
110 standard_homedir (void)
111 {
112 #ifdef HAVE_W32_SYSTEM
113   static const char *dir;
114
115   if (!dir)
116     {
117       char path[MAX_PATH];
118
119       /* It might be better to use LOCAL_APPDATA because this is
120          defined as "non roaming" and thus more likely to be kept
121          locally.  For private keys this is desired.  However, given
122          that many users copy private keys anyway forth and back,
123          using a system roaming services might be better than to let
124          them do it manually.  A security conscious user will anyway
125          use the registry entry to have better control.  */
126       if (w32_shgetfolderpath (NULL, CSIDL_APPDATA|CSIDL_FLAG_CREATE,
127                                NULL, 0, path) >= 0)
128         {
129           char *tmp = xmalloc (strlen (path) + 6 +1);
130           strcpy (stpcpy (tmp, path), "\\gnupg");
131           dir = tmp;
132
133           /* Try to create the directory if it does not yet exists.  */
134           if (access (dir, F_OK))
135             w32_try_mkdir (dir);
136         }
137       else
138         dir = GNUPG_DEFAULT_HOMEDIR;
139     }
140   return dir;
141 #else/*!HAVE_W32_SYSTEM*/
142   return GNUPG_DEFAULT_HOMEDIR;
143 #endif /*!HAVE_W32_SYSTEM*/
144 }
145
146 /* Set up the default home directory.  The usual --homedir option
147    should be parsed later. */
148 const char *
149 default_homedir (void)
150 {
151   const char *dir;
152
153   dir = getenv ("GNUPGHOME");
154 #ifdef HAVE_W32_SYSTEM
155   if (!dir || !*dir)
156     {
157       static const char *saved_dir;
158
159       if (!saved_dir)
160         {
161           if (!dir || !*dir)
162             {
163               char *tmp;
164
165               tmp = read_w32_registry_string (NULL, "Software\\GNU\\GnuPG",
166                                               "HomeDir");
167               if (tmp && !*tmp)
168                 {
169                   xfree (tmp);
170                   tmp = NULL;
171                 }
172               if (tmp)
173                 saved_dir = tmp;
174             }
175
176           if (!saved_dir)
177             saved_dir = standard_homedir ();
178         }
179       dir = saved_dir;
180     }
181 #endif /*HAVE_W32_SYSTEM*/
182   if (!dir || !*dir)
183     dir = GNUPG_DEFAULT_HOMEDIR;
184
185   return dir;
186 }
187
188
189 #ifdef HAVE_W32_SYSTEM
190 static const char *
191 w32_rootdir (void)
192 {
193   static int got_dir;
194   static char dir[MAX_PATH+5];
195
196   if (!got_dir)
197     {
198       char *p;
199       int rc;
200
201 #ifdef HAVE_W32CE_SYSTEM
202       {
203         wchar_t wdir [MAX_PATH+5];
204         rc = GetModuleFileName (NULL, wdir, MAX_PATH);
205         if (rc && WideCharToMultiByte (CP_UTF8, 0, wdir, -1, dir, MAX_PATH-4,
206                                        NULL, NULL) < 0)
207           rc = 0;
208       }
209 #else
210       rc = GetModuleFileName (NULL, dir, MAX_PATH);
211 #endif
212       if (!rc)
213         {
214           log_debug ("GetModuleFileName failed: %s\n", w32_strerror (0));
215           *dir = 0;
216         }
217       got_dir = 1;
218       p = strrchr (dir, DIRSEP_C);
219       if (p)
220         {
221           *p = 0;
222           /* If we are installed below "bin" we strip that and use
223              the top directory instead.  */
224           p = strrchr (dir, DIRSEP_C);
225           if (p && !strcmp (p+1, "bin"))
226             *p = 0;
227         }
228       if (!p)
229         {
230           log_debug ("bad filename `%s' returned for this process\n", dir);
231           *dir = 0;
232         }
233     }
234
235   if (*dir)
236     return dir;
237   /* Fallback to the hardwired value. */
238   return GNUPG_LIBEXECDIR;
239 }
240
241 static const char *
242 w32_commondir (void)
243 {
244   static char *dir;
245
246   if (!dir)
247     {
248       char path[MAX_PATH];
249
250       if (w32_shgetfolderpath (NULL, CSIDL_COMMON_APPDATA,
251                                NULL, 0, path) >= 0)
252         {
253           char *tmp = xmalloc (strlen (path) + 4 +1);
254           strcpy (stpcpy (tmp, path), "\\GNU");
255           dir = tmp;
256           /* No auto create of the directory.  Either the installer or
257              the admin has to create these directories.  */
258         }
259       else
260         {
261           /* Ooops: Not defined - probably an old Windows version.
262              Use the installation directory instead.  */
263           dir = xstrdup (w32_rootdir ());
264         }
265     }
266
267   return dir;
268 }
269 #endif /*HAVE_W32_SYSTEM*/
270
271
272
273
274 /* Return the name of the sysconfdir.  This is a static string.  This
275    function is required because under Windows we can't simply compile
276    it in.  */
277 const char *
278 gnupg_sysconfdir (void)
279 {
280 #ifdef HAVE_W32_SYSTEM
281   static char *name;
282
283   if (!name)
284     {
285       const char *s1, *s2;
286       s1 = w32_commondir ();
287       s2 = DIRSEP_S "etc" DIRSEP_S "gnupg";
288       name = xmalloc (strlen (s1) + strlen (s2) + 1);
289       strcpy (stpcpy (name, s1), s2);
290     }
291   return name;
292 #else /*!HAVE_W32_SYSTEM*/
293   return GNUPG_SYSCONFDIR;
294 #endif /*!HAVE_W32_SYSTEM*/
295 }
296
297
298 const char *
299 gnupg_bindir (void)
300 {
301 #if defined (HAVE_W32CE_SYSTEM)
302   static char *name;
303
304   if (!name)
305     name = xstrconcat (w32_rootdir (), DIRSEP_S "bin", NULL);
306   return name;
307 #elif defined(HAVE_W32_SYSTEM)
308   return w32_rootdir ();
309 #else /*!HAVE_W32_SYSTEM*/
310   return GNUPG_BINDIR;
311 #endif /*!HAVE_W32_SYSTEM*/
312 }
313
314
315 /* Return the name of the libexec directory.  The name is allocated in
316    a static area on the first use.  This function won't fail. */
317 const char *
318 gnupg_libexecdir (void)
319 {
320 #ifdef HAVE_W32_SYSTEM
321   return gnupg_bindir ();
322 #else /*!HAVE_W32_SYSTEM*/
323   return GNUPG_LIBEXECDIR;
324 #endif /*!HAVE_W32_SYSTEM*/
325 }
326
327 const char *
328 gnupg_libdir (void)
329 {
330 #ifdef HAVE_W32_SYSTEM
331   static char *name;
332
333   if (!name)
334     name = xstrconcat (w32_rootdir (), DIRSEP_S "lib" DIRSEP_S "gnupg", NULL);
335   return name;
336 #else /*!HAVE_W32_SYSTEM*/
337   return GNUPG_LIBDIR;
338 #endif /*!HAVE_W32_SYSTEM*/
339 }
340
341 const char *
342 gnupg_datadir (void)
343 {
344 #ifdef HAVE_W32_SYSTEM
345   static char *name;
346
347   if (!name)
348     name = xstrconcat (w32_rootdir (), DIRSEP_S "share" DIRSEP_S "gnupg", NULL);
349   return name;
350 #else /*!HAVE_W32_SYSTEM*/
351   return GNUPG_DATADIR;
352 #endif /*!HAVE_W32_SYSTEM*/
353 }
354
355
356 const char *
357 gnupg_localedir (void)
358 {
359 #ifdef HAVE_W32_SYSTEM
360   static char *name;
361
362   if (!name)
363     name = xstrconcat (w32_rootdir (), DIRSEP_S "share" DIRSEP_S "locale",
364                        NULL);
365   return name;
366 #else /*!HAVE_W32_SYSTEM*/
367   return LOCALEDIR;
368 #endif /*!HAVE_W32_SYSTEM*/
369 }
370
371
372 /* Return the name of the cache directory.  The name is allocated in a
373    static area on the first use.  Windows only: If the directory does
374    not exist it is created.  */
375 const char *
376 gnupg_cachedir (void)
377 {
378 #ifdef HAVE_W32_SYSTEM
379   static const char *dir;
380
381   if (!dir)
382     {
383       char path[MAX_PATH];
384       const char *s1[] = { "GNU", "cache", "gnupg", NULL };
385       int s1_len;
386       const char **comp;
387
388       s1_len = 0;
389       for (comp = s1; *comp; comp++)
390         s1_len += 1 + strlen (*comp);
391
392       if (w32_shgetfolderpath (NULL, CSIDL_LOCAL_APPDATA|CSIDL_FLAG_CREATE,
393                                NULL, 0, path) >= 0)
394         {
395           char *tmp = xmalloc (strlen (path) + s1_len + 1);
396           char *p;
397
398           p = stpcpy (tmp, path);
399           for (comp = s1; *comp; comp++)
400             {
401               p = stpcpy (p, "\\");
402               p = stpcpy (p, *comp);
403
404               if (access (tmp, F_OK))
405                 w32_try_mkdir (tmp);
406             }
407
408           dir = tmp;
409         }
410       else
411         {
412           dir = "c:\\temp\\cache\\gnupg";
413 #ifdef HAVE_W32CE_SYSTEM
414           dir += 2;
415           w32_try_mkdir ("\\temp\\cache");
416           w32_try_mkdir ("\\temp\\cache\\gnupg");
417 #endif
418         }
419     }
420   return dir;
421 #else /*!HAVE_W32_SYSTEM*/
422   return GNUPG_LOCALSTATEDIR "/cache/" PACKAGE_NAME;
423 #endif /*!HAVE_W32_SYSTEM*/
424 }
425
426
427 /* Return the default socket name used by DirMngr. */
428 const char *
429 dirmngr_socket_name (void)
430 {
431 #ifdef HAVE_W32_SYSTEM
432   static char *name;
433
434   if (!name)
435     {
436       char *p;
437 # ifdef HAVE_W32CE_SYSTEM
438       const char *s1, *s2;
439
440       s1 = default_homedir ();
441 # else
442       char s1[MAX_PATH];
443       const char *s2;
444
445       /* We need something akin CSIDL_COMMON_PROGRAMS, but local
446          (non-roaming).  This is becuase the file needs to be on the
447          local machine and makes only sense on that machine.
448          CSIDL_WINDOWS seems to be the only location which guarantees
449          that. */
450       if (w32_shgetfolderpath (NULL, CSIDL_WINDOWS, NULL, 0, s1) < 0)
451         strcpy (s1, "C:\\WINDOWS");
452 # endif
453       s2 = DIRSEP_S "S.dirmngr";
454       name = xmalloc (strlen (s1) + strlen (s2) + 1);
455       strcpy (stpcpy (name, s1), s2);
456       for (p=name; *p; p++)
457         if (*p == '/')
458           *p = '\\';
459     }
460   return name;
461 #else /*!HAVE_W32_SYSTEM*/
462   return GNUPG_LOCALSTATEDIR "/run/" PACKAGE_NAME "/S.dirmngr";
463 #endif /*!HAVE_W32_SYSTEM*/
464 }
465
466
467
468 /* Return the file name of a helper tool.  WHICH is one of the
469    GNUPG_MODULE_NAME_foo constants.  */
470 const char *
471 gnupg_module_name (int which)
472 {
473 #define X(a,b) do {                                                     \
474     static char *name;                                                  \
475     if (!name)                                                          \
476       name = xstrconcat (gnupg_ ## a (), DIRSEP_S b EXEEXT_S, NULL);    \
477     return name;                                                        \
478   } while (0)
479
480   switch (which)
481     {
482     case GNUPG_MODULE_NAME_AGENT:
483 #ifdef GNUPG_DEFAULT_AGENT
484       return GNUPG_DEFAULT_AGENT;
485 #else
486       X(bindir, "gpg-agent");
487 #endif
488
489     case GNUPG_MODULE_NAME_PINENTRY:
490 #ifdef GNUPG_DEFAULT_PINENTRY
491       return GNUPG_DEFAULT_PINENTRY;
492 #else
493       X(bindir, "pinentry");
494 #endif
495
496     case GNUPG_MODULE_NAME_SCDAEMON:
497 #ifdef GNUPG_DEFAULT_SCDAEMON
498       return GNUPG_DEFAULT_SCDAEMON;
499 #else
500       X(bindir, "scdaemon");
501 #endif
502
503     case GNUPG_MODULE_NAME_DIRMNGR:
504 #ifdef GNUPG_DEFAULT_DIRMNGR
505       return GNUPG_DEFAULT_DIRMNGR;
506 #else
507       X(bindir, "dirmngr");
508 #endif
509
510     case GNUPG_MODULE_NAME_PROTECT_TOOL:
511 #ifdef GNUPG_DEFAULT_PROTECT_TOOL
512       return GNUPG_DEFAULT_PROTECT_TOOL;
513 #else
514       X(libexecdir, "gpg-protect-tool");
515 #endif
516
517     case GNUPG_MODULE_NAME_DIRMNGR_LDAP:
518 #ifdef GNUPG_DEFAULT_DIRMNGR_LDAP
519       return GNUPG_DEFAULT_DIRMNGR_LDAP;
520 #else
521       X(libexecdir, "dirmngr_ldap");
522 #endif
523
524     case GNUPG_MODULE_NAME_CHECK_PATTERN:
525       X(libexecdir, "gpg-check-pattern");
526
527     case GNUPG_MODULE_NAME_GPGSM:
528       X(bindir, "gpgsm");
529
530     case GNUPG_MODULE_NAME_GPG:
531       X(bindir, NAME_OF_INSTALLED_GPG);
532
533     case GNUPG_MODULE_NAME_CONNECT_AGENT:
534       X(bindir, "gpg-connect-agent");
535
536     case GNUPG_MODULE_NAME_GPGCONF:
537       X(bindir, "gpgconf");
538
539     default:
540       BUG ();
541     }
542 #undef X
543 }