2007-07-16 Marcus Brinkmann <marcus@g10code.de>
[gnupg.git] / common / homedir.c
blob212c3509d09e406abc168df095635682dadc161f
1 /* homedir.c - Setup the home directory.
2 * Copyright (C) 2004, 2006, 2007 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
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.
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.
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/>.
20 #include <config.h>
21 #include <stdlib.h>
22 #include <errno.h>
23 #include <fcntl.h>
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_FLAG_CREATE
34 #define CSIDL_FLAG_CREATE 0x8000
35 #endif
36 #endif /*HAVE_W32_SYSTEM*/
40 #include "util.h"
41 #include "sysutils.h"
44 /* This is a helper function to load a Windows function from either of
45 one DLLs. */
46 #ifdef HAVE_W32_SYSTEM
47 static HRESULT
48 w32_shgetfolderpath (HWND a, int b, HANDLE c, DWORD d, LPSTR e)
50 static int initialized;
51 static HRESULT (WINAPI * func)(HWND,int,HANDLE,DWORD,LPSTR);
53 if (!initialized)
55 static char *dllnames[] = { "shell32.dll", "shfolder.dll", NULL };
56 void *handle;
57 int i;
59 initialized = 1;
61 for (i=0, handle = NULL; !handle && dllnames[i]; i++)
63 handle = dlopen (dllnames[i], RTLD_LAZY);
64 if (handle)
66 func = dlsym (handle, "SHGetFolderPathA");
67 if (!func)
69 dlclose (handle);
70 handle = NULL;
76 if (func)
77 return func (a,b,c,d,e);
78 else
79 return -1;
81 #endif /*HAVE_W32_SYSTEM*/
84 /* Get the standard home directory. In general this function should
85 not be used as it does not consider a registry value (under W32) or
86 the GNUPGHOME encironment variable. It is better to use
87 default_homedir(). */
88 const char *
89 standard_homedir (void)
91 #ifdef HAVE_W32_SYSTEM
92 static const char *dir;
94 if (!dir)
96 char path[MAX_PATH];
98 /* It might be better to use LOCAL_APPDATA because this is
99 defined as "non roaming" and thus more likely to be kept
100 locally. For private keys this is desired. However, given
101 that many users copy private keys anyway forth and back,
102 using a system roaming services might be better than to let
103 them do it manually. A security conscious user will anyway
104 use the registry entry to have better control. */
105 if (w32_shgetfolderpath (NULL, CSIDL_APPDATA|CSIDL_FLAG_CREATE,
106 NULL, 0, path) >= 0)
108 char *tmp = xmalloc (strlen (path) + 6 +1);
109 strcpy (stpcpy (tmp, path), "\\gnupg");
110 dir = tmp;
112 /* Try to create the directory if it does not yet exists. */
113 if (access (dir, F_OK))
114 CreateDirectory (dir, NULL);
116 else
117 dir = GNUPG_DEFAULT_HOMEDIR;
119 return dir;
120 #else/*!HAVE_W32_SYSTEM*/
121 return GNUPG_DEFAULT_HOMEDIR;
122 #endif /*!HAVE_W32_SYSTEM*/
125 /* Set up the default home directory. The usual --homedir option
126 should be parsed later. */
127 const char *
128 default_homedir (void)
130 const char *dir;
132 dir = getenv ("GNUPGHOME");
133 #ifdef HAVE_W32_SYSTEM
134 if (!dir || !*dir)
136 static const char *saved_dir;
138 if (!saved_dir)
140 if (!dir || !*dir)
142 char *tmp;
144 tmp = read_w32_registry_string (NULL, "Software\\GNU\\GnuPG",
145 "HomeDir");
146 if (tmp && *tmp)
148 xfree (tmp);
149 tmp = NULL;
151 if (tmp)
152 saved_dir = tmp;
155 if (!saved_dir)
156 saved_dir = standard_homedir ();
158 dir = saved_dir;
160 #endif /*HAVE_W32_SYSTEM*/
161 if (!dir || !*dir)
162 dir = GNUPG_DEFAULT_HOMEDIR;
164 return dir;
168 #ifdef HAVE_W32_SYSTEM
169 static const char *
170 w32_rootdir (void)
172 static int got_dir;
173 static char dir[MAX_PATH+5];
175 if (!got_dir)
177 char *p;
179 if ( !GetModuleFileName ( NULL, dir, MAX_PATH) )
181 log_debug ("GetModuleFileName failed: %s\n", w32_strerror (0));
182 *dir = 0;
184 got_dir = 1;
185 p = strrchr (dir, DIRSEP_C);
186 if (p)
187 *p = 0;
188 else
190 log_debug ("bad filename `%s' returned for this process\n", dir);
191 *dir = 0;
195 if (*dir)
196 return dir;
197 /* Fallback to the hardwired value. */
198 return GNUPG_LIBEXECDIR;
200 #endif /*HAVE_W32_SYSTEM*/
205 /* Return the name of the sysconfdir. This is a static string. This
206 function is required because under Windows we can't simply compile
207 it in. */
208 const char *
209 gnupg_sysconfdir (void)
211 #ifdef HAVE_W32_SYSTEM
212 static char *name;
214 if (!name)
216 const char *s1, *s2;
217 s1 = w32_rootdir ();
218 s2 = DIRSEP_S "etc" DIRSEP_S "gnupg";
219 name = xmalloc (strlen (s1) + strlen (s2) + 1);
220 strcpy (stpcpy (name, s1), s2);
222 return name;
223 #else /*!HAVE_W32_SYSTEM*/
224 return GNUPG_SYSCONFDIR;
225 #endif /*!HAVE_W32_SYSTEM*/
229 const char *
230 gnupg_bindir (void)
232 #ifdef HAVE_W32_SYSTEM
233 return w32_rootdir ();
234 #else /*!HAVE_W32_SYSTEM*/
235 return GNUPG_BINDIR;
236 #endif /*!HAVE_W32_SYSTEM*/
240 /* Return the name of the libexec directory. The name is allocated in
241 a static area on the first use. This function won't fail. */
242 const char *
243 gnupg_libexecdir (void)
245 #ifdef HAVE_W32_SYSTEM
246 return w32_rootdir ();
247 #else /*!HAVE_W32_SYSTEM*/
248 return GNUPG_LIBEXECDIR;
249 #endif /*!HAVE_W32_SYSTEM*/
252 const char *
253 gnupg_libdir (void)
255 #ifdef HAVE_W32_SYSTEM
256 static char *name;
258 if (!name)
260 const char *s1, *s2;
261 s1 = w32_rootdir ();
262 s2 = DIRSEP_S "lib" DIRSEP_S "gnupg";
263 name = xmalloc (strlen (s1) + strlen (s2) + 1);
264 strcpy (stpcpy (name, s1), s2);
266 return name;
267 #else /*!HAVE_W32_SYSTEM*/
268 return GNUPG_LIBDIR;
269 #endif /*!HAVE_W32_SYSTEM*/
272 const char *
273 gnupg_datadir (void)
275 #ifdef HAVE_W32_SYSTEM
276 static char *name;
278 if (!name)
280 const char *s1, *s2;
281 s1 = w32_rootdir ();
282 s2 = DIRSEP_S "share" DIRSEP_S "gnupg";
283 name = xmalloc (strlen (s1) + strlen (s2) + 1);
284 strcpy (stpcpy (name, s1), s2);
286 return name;
287 #else /*!HAVE_W32_SYSTEM*/
288 return GNUPG_DATADIR;
289 #endif /*!HAVE_W32_SYSTEM*/
293 /* Return the file name of a helper tool. WHICH is one of the
294 GNUPG_MODULE_NAME_foo constants. */
295 const char *
296 gnupg_module_name (int which)
298 const char *s, *s2;
300 #define X(a,b) do { \
301 static char *name; \
302 if (!name) \
304 s = gnupg_ ## a (); \
305 s2 = DIRSEP_S b EXEEXT_S; \
306 name = xmalloc (strlen (s) + strlen (s2) + 1); \
307 strcpy (stpcpy (name, s), s2); \
309 return name; \
310 } while (0)
312 switch (which)
314 case GNUPG_MODULE_NAME_AGENT:
315 #ifdef GNUPG_DEFAULT_AGENT
316 return GNUPG_DEFAULT_AGENT;
317 #else
318 X(bindir, "gpg-agent");
319 #endif
321 case GNUPG_MODULE_NAME_PINENTRY:
322 #ifdef GNUPG_DEFAULT_PINENTRY
323 return GNUPG_DEFAULT_PINENTRY;
324 #else
325 X(bindir, "pinentry");
326 #endif
328 case GNUPG_MODULE_NAME_SCDAEMON:
329 #ifdef GNUPG_DEFAULT_SCDAEMON
330 return GNUPG_DEFAULT_SCDAEMON;
331 #else
332 X(bindir, "scdaemon");
333 #endif
335 case GNUPG_MODULE_NAME_DIRMNGR:
336 #ifdef GNUPG_DEFAULT_DIRMNGR
337 return GNUPG_DEFAULT_DIRMNGR;
338 #else
339 X(bindir, "dirmngr");
340 #endif
342 case GNUPG_MODULE_NAME_PROTECT_TOOL:
343 #ifdef GNUPG_DEFAULT_PROTECT_TOOL
344 return GNUPG_DEFAULT_PROTECT_TOOL;
345 #else
346 X(libexecdir, "gpg-protect-tool");
347 #endif
349 default:
350 BUG ();
352 #undef X