5adf46a628dda88038041625220f9198c5815472
[gnupg.git] / common / homedir.c
1 /* homedir.c - Setup the home directory.
2  *      Copyright (C) 2004, 2006, 2007 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 # ifdef HAVE_WINSOCK2_H
27 #  include <winsock2.h>
28 # endif
29 #include <shlobj.h>
30 #ifndef CSIDL_APPDATA
31 #define CSIDL_APPDATA 0x001a
32 #endif
33 #ifndef CSIDL_LOCAL_APPDATA
34 #define CSIDL_LOCAL_APPDATA 0x001c
35 #endif
36 #ifndef CSIDL_COMMON_APPDATA
37 #define CSIDL_COMMON_APPDATA 0x0023
38 #endif
39 #ifndef CSIDL_FLAG_CREATE
40 #define CSIDL_FLAG_CREATE 0x8000
41 #endif
42 #endif /*HAVE_W32_SYSTEM*/
43
44
45
46 #include "util.h"
47 #include "sysutils.h"
48
49
50 /* This is a helper function to load a Windows function from either of
51    one DLLs. */
52 #ifdef HAVE_W32_SYSTEM
53 static HRESULT
54 w32_shgetfolderpath (HWND a, int b, HANDLE c, DWORD d, LPSTR e)
55 {
56   static int initialized;
57   static HRESULT (WINAPI * func)(HWND,int,HANDLE,DWORD,LPSTR);
58
59   if (!initialized)
60     {
61       static char *dllnames[] = { "shell32.dll", "shfolder.dll", NULL };
62       void *handle;
63       int i;
64
65       initialized = 1;
66
67       for (i=0, handle = NULL; !handle && dllnames[i]; i++)
68         {
69           handle = dlopen (dllnames[i], RTLD_LAZY);
70           if (handle)
71             {
72               func = dlsym (handle, "SHGetFolderPathA");
73               if (!func)
74                 {
75                   dlclose (handle);
76                   handle = NULL;
77                 }
78             }
79         }
80     }
81
82   if (func)
83     return func (a,b,c,d,e);
84   else
85     return -1;
86 }
87 #endif /*HAVE_W32_SYSTEM*/
88
89
90 /* Get the standard home directory.  In general this function should
91    not be used as it does not consider a registry value (under W32) or
92    the GNUPGHOME environment variable.  It is better to use
93    default_homedir(). */
94 const char *
95 standard_homedir (void)
96 {
97 #ifdef HAVE_W32_SYSTEM
98   static const char *dir;
99
100   if (!dir)
101     {
102       char path[MAX_PATH];
103
104       /* It might be better to use LOCAL_APPDATA because this is
105          defined as "non roaming" and thus more likely to be kept
106          locally.  For private keys this is desired.  However, given
107          that many users copy private keys anyway forth and back,
108          using a system roaming services might be better than to let
109          them do it manually.  A security conscious user will anyway
110          use the registry entry to have better control.  */
111       if (w32_shgetfolderpath (NULL, CSIDL_APPDATA|CSIDL_FLAG_CREATE,
112                                NULL, 0, path) >= 0)
113         {
114           char *tmp = xmalloc (strlen (path) + 6 +1);
115           strcpy (stpcpy (tmp, path), "\\gnupg");
116           dir = tmp;
117
118           /* Try to create the directory if it does not yet exists.  */
119           if (access (dir, F_OK))
120             CreateDirectory (dir, NULL);
121         }
122       else
123         dir = GNUPG_DEFAULT_HOMEDIR;
124     }
125   return dir;
126 #else/*!HAVE_W32_SYSTEM*/
127   return GNUPG_DEFAULT_HOMEDIR;
128 #endif /*!HAVE_W32_SYSTEM*/
129 }
130
131 /* Set up the default home directory.  The usual --homedir option
132    should be parsed later. */
133 const char *
134 default_homedir (void)
135 {
136   const char *dir;
137
138   dir = getenv ("GNUPGHOME");
139 #ifdef HAVE_W32_SYSTEM
140   if (!dir || !*dir)
141     {
142       static const char *saved_dir;
143
144       if (!saved_dir)
145         {
146           if (!dir || !*dir)
147             {
148               char *tmp;
149
150               tmp = read_w32_registry_string (NULL, "Software\\GNU\\GnuPG",
151                                               "HomeDir");
152               if (tmp && !*tmp)
153                 {
154                   xfree (tmp);
155                   tmp = NULL;
156                 }
157               if (tmp)
158                 saved_dir = tmp;
159             }
160
161           if (!saved_dir)
162             saved_dir = standard_homedir ();
163         }
164       dir = saved_dir;
165     }
166 #endif /*HAVE_W32_SYSTEM*/
167   if (!dir || !*dir)
168     dir = GNUPG_DEFAULT_HOMEDIR;
169
170   return dir;
171 }
172
173
174 #ifdef HAVE_W32_SYSTEM
175 static const char *
176 w32_rootdir (void)
177 {
178   static int got_dir;
179   static char dir[MAX_PATH+5];
180
181   if (!got_dir)
182     {
183       char *p;
184
185       if ( !GetModuleFileName ( NULL, dir, MAX_PATH) )
186         {
187           log_debug ("GetModuleFileName failed: %s\n", w32_strerror (0));
188           *dir = 0;
189         }
190       got_dir = 1;
191       p = strrchr (dir, DIRSEP_C);
192       if (p)
193         *p = 0;
194       else
195         {
196           log_debug ("bad filename `%s' returned for this process\n", dir);
197           *dir = 0;
198         }
199     }
200
201   if (*dir)
202     return dir;
203   /* Fallback to the hardwired value. */
204   return GNUPG_LIBEXECDIR;
205 }
206
207 static const char *
208 w32_commondir (void)
209 {
210   static char *dir;
211
212   if (!dir)
213     {
214       char path[MAX_PATH];
215
216       if (w32_shgetfolderpath (NULL, CSIDL_COMMON_APPDATA,
217                                NULL, 0, path) >= 0)
218         {
219           char *tmp = xmalloc (strlen (path) + 4 +1);
220           strcpy (stpcpy (tmp, path), "\\GNU");
221           dir = tmp;
222           /* No auto create of the directory.  Either the installer or
223              the admin has to create these directories.  */
224         }
225       else
226         {
227           /* Ooops: Not defined - probably an old Windows version.
228              Use the installation directory instead.  */
229           dir = xstrdup (w32_rootdir ());
230         }
231     }
232
233   return dir;
234 }
235 #endif /*HAVE_W32_SYSTEM*/
236
237
238
239
240 /* Return the name of the sysconfdir.  This is a static string.  This
241    function is required because under Windows we can't simply compile
242    it in.  */
243 const char *
244 gnupg_sysconfdir (void)
245 {
246 #ifdef HAVE_W32_SYSTEM
247   static char *name;
248
249   if (!name)
250     {
251       const char *s1, *s2;
252       s1 = w32_commondir ();
253       s2 = DIRSEP_S "etc" DIRSEP_S "gnupg";
254       name = xmalloc (strlen (s1) + strlen (s2) + 1);
255       strcpy (stpcpy (name, s1), s2);
256     }
257   return name;
258 #else /*!HAVE_W32_SYSTEM*/
259   return GNUPG_SYSCONFDIR;
260 #endif /*!HAVE_W32_SYSTEM*/
261 }
262
263
264 const char *
265 gnupg_bindir (void)
266 {
267 #ifdef HAVE_W32_SYSTEM
268   return w32_rootdir ();
269 #else /*!HAVE_W32_SYSTEM*/
270   return GNUPG_BINDIR;
271 #endif /*!HAVE_W32_SYSTEM*/
272 }
273
274
275 /* Return the name of the libexec directory.  The name is allocated in
276    a static area on the first use.  This function won't fail. */
277 const char *
278 gnupg_libexecdir (void)
279 {
280 #ifdef HAVE_W32_SYSTEM
281   return w32_rootdir ();
282 #else /*!HAVE_W32_SYSTEM*/
283   return GNUPG_LIBEXECDIR;
284 #endif /*!HAVE_W32_SYSTEM*/
285 }
286
287 const char *
288 gnupg_libdir (void)
289 {
290 #ifdef HAVE_W32_SYSTEM
291   static char *name;
292
293   if (!name)
294     {
295       const char *s1, *s2;
296       s1 = w32_rootdir ();
297       s2 = DIRSEP_S "lib" DIRSEP_S "gnupg";
298       name = xmalloc (strlen (s1) + strlen (s2) + 1);
299       strcpy (stpcpy (name, s1), s2);
300     }
301   return name;
302 #else /*!HAVE_W32_SYSTEM*/
303   return GNUPG_LIBDIR;
304 #endif /*!HAVE_W32_SYSTEM*/
305 }
306
307 const char *
308 gnupg_datadir (void)
309 {
310 #ifdef HAVE_W32_SYSTEM
311   static char *name;
312
313   if (!name)
314     {
315       const char *s1, *s2;
316       s1 = w32_rootdir ();
317       s2 = DIRSEP_S "share" DIRSEP_S "gnupg";
318       name = xmalloc (strlen (s1) + strlen (s2) + 1);
319       strcpy (stpcpy (name, s1), s2);
320     }
321   return name;
322 #else /*!HAVE_W32_SYSTEM*/
323   return GNUPG_DATADIR;
324 #endif /*!HAVE_W32_SYSTEM*/
325 }
326
327
328 const char *
329 gnupg_localedir (void)
330 {
331 #ifdef HAVE_W32_SYSTEM
332   static char *name;
333
334   if (!name)
335     {
336       const char *s1, *s2;
337       s1 = w32_rootdir ();
338       s2 = DIRSEP_S "share" DIRSEP_S "locale";
339       name = xmalloc (strlen (s1) + strlen (s2) + 1);
340       strcpy (stpcpy (name, s1), s2);
341     }
342   return name;
343 #else /*!HAVE_W32_SYSTEM*/
344   return LOCALEDIR;
345 #endif /*!HAVE_W32_SYSTEM*/
346 }
347
348
349 /* Return the default socket name used by DirMngr. */
350 const char *
351 dirmngr_socket_name (void)
352 {
353 #ifdef HAVE_W32_SYSTEM
354   static char *name;
355
356   if (!name)
357     {
358       char s1[MAX_PATH];
359       const char *s2;
360
361       /* We need something akin CSIDL_COMMON_PROGRAMS, but local
362          (non-roaming).  */
363       if (w32_shgetfolderpath (NULL, CSIDL_WINDOWS, NULL, 0, s1) < 0)
364         strcpy (s1, "C:\\WINDOWS");
365       s2 = DIRSEP_S "S.dirmngr";
366       name = xmalloc (strlen (s1) + strlen (s2) + 1);
367       strcpy (stpcpy (name, s1), s2);
368     }
369   return name;
370 #else /*!HAVE_W32_SYSTEM*/
371   return "/var/run/dirmngr/socket";
372 #endif /*!HAVE_W32_SYSTEM*/
373 }
374
375
376
377 /* Return the file name of a helper tool.  WHICH is one of the
378    GNUPG_MODULE_NAME_foo constants.  */
379 const char *
380 gnupg_module_name (int which)
381 {
382   const char *s, *s2;
383
384 #define X(a,b) do {                                          \
385         static char *name;                                   \
386         if (!name)                                           \
387           {                                                  \
388             s = gnupg_ ## a ();                              \
389             s2 = DIRSEP_S b EXEEXT_S;                        \
390             name = xmalloc (strlen (s) + strlen (s2) + 1);   \
391             strcpy (stpcpy (name, s), s2);                   \
392           }                                                  \
393         return name;                                         \
394       } while (0)
395
396   switch (which)
397     {
398     case GNUPG_MODULE_NAME_AGENT:
399 #ifdef GNUPG_DEFAULT_AGENT
400       return GNUPG_DEFAULT_AGENT;
401 #else
402       X(bindir, "gpg-agent");
403 #endif
404
405     case GNUPG_MODULE_NAME_PINENTRY:
406 #ifdef GNUPG_DEFAULT_PINENTRY
407       return GNUPG_DEFAULT_PINENTRY;
408 #else
409       X(bindir, "pinentry");
410 #endif
411
412     case GNUPG_MODULE_NAME_SCDAEMON:
413 #ifdef GNUPG_DEFAULT_SCDAEMON
414       return GNUPG_DEFAULT_SCDAEMON;
415 #else
416       X(libexecdir, "scdaemon");
417 #endif
418
419     case GNUPG_MODULE_NAME_DIRMNGR:
420 #ifdef GNUPG_DEFAULT_DIRMNGR
421       return GNUPG_DEFAULT_DIRMNGR;
422 #else
423       X(bindir, "dirmngr");
424 #endif
425
426     case GNUPG_MODULE_NAME_PROTECT_TOOL:
427 #ifdef GNUPG_DEFAULT_PROTECT_TOOL
428       return GNUPG_DEFAULT_PROTECT_TOOL;
429 #else
430       X(libexecdir, "gpg-protect-tool");
431 #endif
432
433     case GNUPG_MODULE_NAME_CHECK_PATTERN:
434       X(libexecdir, "gpg-check-pattern");
435
436     case GNUPG_MODULE_NAME_GPGSM:
437       X(bindir, "gpgsm");
438
439     case GNUPG_MODULE_NAME_GPG:
440       X(bindir, "gpg2");
441
442     case GNUPG_MODULE_NAME_CONNECT_AGENT:
443       X(bindir, "gpg-connect-agent");
444
445     case GNUPG_MODULE_NAME_GPGCONF:
446       X(bindir, "gpgconf");
447
448     default:
449       BUG ();
450     }
451 #undef X
452 }