654c96becb1e0bb7256e11d373993d0438b6d498
[gnupg.git] / common / homedir.c
1 /* homedir.c - Setup the home directory.
2  *      Copyright (C) 2004, 2006 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 2 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, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19  * USA.
20  */
21
22 #include <config.h>
23 #include <stdlib.h>
24 #include <errno.h>
25 #include <fcntl.h>
26
27 #ifdef HAVE_W32_SYSTEM
28 #include <shlobj.h>
29 #ifndef CSIDL_APPDATA
30 #define CSIDL_APPDATA 0x001a
31 #endif
32 #ifndef CSIDL_LOCAL_APPDATA
33 #define CSIDL_LOCAL_APPDATA 0x001c
34 #endif
35 #ifndef CSIDL_FLAG_CREATE
36 #define CSIDL_FLAG_CREATE 0x8000
37 #endif
38 #endif /*HAVE_W32_SYSTEM*/
39
40
41
42 #include "util.h"
43 #include "sysutils.h"
44
45
46 /* This is a helper function to load a Windows function from either of
47    one DLLs. */
48 #ifdef HAVE_W32_SYSTEM
49 static HRESULT
50 w32_shgetfolderpath (HWND a, int b, HANDLE c, DWORD d, LPSTR e)
51 {
52   static int initialized;
53   static HRESULT (WINAPI * func)(HWND,int,HANDLE,DWORD,LPSTR);
54
55   if (!initialized)
56     {
57       static char *dllnames[] = { "shell32.dll", "shfolder.dll", NULL };
58       void *handle;
59       int i;
60
61       initialized = 1;
62
63       for (i=0, handle = NULL; !handle && dllnames[i]; i++)
64         {
65           handle = dlopen (dllnames[i], RTLD_LAZY);
66           if (handle)
67             {
68               func = dlsym (handle, "SHGetFolderPathA");
69               if (!func)
70                 {
71                   dlclose (handle);
72                   handle = NULL;
73                 }
74             }
75         }
76     }
77
78   if (func)
79     return func (a,b,c,d,e);
80   else
81     return -1;
82 }
83 #endif /*HAVE_W32_SYSTEM*/
84
85
86 /* Set up the default home directory.  The usual --homedir option
87    should be parsed later. */
88 const char *
89 default_homedir (void)
90 {
91   const char *dir;
92
93   dir = getenv("GNUPGHOME");
94 #ifdef HAVE_W32_SYSTEM
95   if (!dir || !*dir)
96     dir = read_w32_registry_string (NULL, "Software\\GNU\\GnuPG", "HomeDir");
97   if (!dir || !*dir)
98     {
99       char path[MAX_PATH];
100       
101       /* It might be better to use LOCAL_APPDATA because this is
102          defined as "non roaming" and thus more likely to be kept
103          locally.  For private keys this is desired.  However, given
104          that many users copy private keys anyway forth and back,
105          using a system roaming services might be better than to let
106          them do it manually.  A security conscious user will anyway
107          use the registry entry to have better control.  */
108       if (w32_shgetfolderpath (NULL, CSIDL_APPDATA|CSIDL_FLAG_CREATE, 
109                                NULL, 0, path) >= 0) 
110         {
111           char *tmp = xmalloc (strlen (path) + 6 +1);
112           strcpy (stpcpy (tmp, path), "\\gnupg");
113           dir = tmp;
114           
115           /* Try to create the directory if it does not yet
116              exists.  */
117           if (access (dir, F_OK))
118             CreateDirectory (dir, NULL);
119         }
120     }
121 #endif /*HAVE_W32_SYSTEM*/
122   if (!dir || !*dir)
123     dir = GNUPG_DEFAULT_HOMEDIR;
124
125   return dir;
126 }
127
128
129 /* Return the name of the sysconfdir.  This is a static string.  This
130    function is required because under Windows we can't simply compile
131    it in.  */
132 const char *
133 gnupg_sysconfdir (void)
134 {
135 #ifdef HAVE_W32_SYSTEM
136 #warning get the sysconfdir from somewhere else
137   return GNUPG_SYSCONFDIR;
138 #else /*!HAVE_W32_SYSTEM*/
139   return GNUPG_SYSCONFDIR;
140 #endif /*!HAVE_W32_SYSTEM*/
141 }
142
143
144 const char *
145 gnupg_bindir (void)
146 {
147 #ifdef HAVE_W32_SYSTEM
148   return gnupg_libexecdir ();
149 #else /*!HAVE_W32_SYSTEM*/
150   return GNUPG_BINDIR;
151 #endif /*!HAVE_W32_SYSTEM*/
152 }
153
154
155 /* Return the name of the libexec directory.  The name is allocated in
156    a static area on the first use.  This function won't fail. */
157 const char *
158 gnupg_libexecdir (void)
159 {
160 #ifdef HAVE_W32_SYSTEM
161   static int got_dir;
162   static char dir[MAX_PATH+5];
163
164   if (!got_dir)
165     {
166       char *p;
167
168       if ( !GetModuleFileName ( NULL, dir, MAX_PATH) )
169         {
170           log_debug ("GetModuleFileName failed: %s\n", w32_strerror (0));
171           *dir = 0;
172         }
173       got_dir = 1;
174       p = strrchr (dir, DIRSEP_C);
175       if (p)
176         *p = 0;
177       else
178         {
179           log_debug ("bad filename `%s' returned for this process\n", dir);
180           *dir = 0; 
181         }
182     }
183
184   if (*dir)
185     return dir;
186   /* Fallback to the hardwired value. */
187 #endif /*HAVE_W32_SYSTEM*/
188
189   return GNUPG_LIBEXECDIR;
190 }
191
192 const char *
193 gnupg_libdir (void)
194 {
195 #ifdef HAVE_W32_SYSTEM
196 #warning get the libdir from somewhere else
197   return GNUPG_LIBDIR;
198 #else /*!HAVE_W32_SYSTEM*/
199   return GNUPG_LIBDIR;
200 #endif /*!HAVE_W32_SYSTEM*/
201 }
202
203 const char *
204 gnupg_datadir (void)
205 {
206 #ifdef HAVE_W32_SYSTEM
207 #warning get the datadir from somewhere else
208   return GNUPG_DATADIR;
209 #else /*!HAVE_W32_SYSTEM*/
210   return GNUPG_DATADIR;
211 #endif /*!HAVE_W32_SYSTEM*/
212 }
213
214
215 /* Return the file name of a helper tool.  WHICH is one of the
216    GNUPG_MODULE_NAME_foo constants.  */
217 const char *
218 gnupg_module_name (int which)
219 {
220   const char *s, *s2;
221
222 #define X(a,b) do {                                          \
223         static char *name;                                   \
224         if (!name)                                           \
225           {                                                  \
226             s = gnupg_ ## a ();                              \
227             s2 = DIRSEP_S b EXEEXT_S;                        \
228             name = xmalloc (strlen (s) + strlen (s2) + 1);   \
229             strcpy (stpcpy (name, s), s2);                   \
230           }                                                  \
231         return name;                                         \
232       } while (0)                                                     
233
234   switch (which)
235     {
236     case GNUPG_MODULE_NAME_AGENT:
237 #ifdef GNUPG_DEFAULT_AGENT
238       return GNUPG_DEFAULT_AGENT;
239 #else 
240       X(bindir, "gpg-agent");
241 #endif
242       
243     case GNUPG_MODULE_NAME_PINENTRY:
244 #ifdef GNUPG_DEFAULT_PINENTRY
245       return GNUPG_DEFAULT_PINENTRY;
246 #else 
247       X(bindir, "pinentry");
248 #endif
249
250     case GNUPG_MODULE_NAME_SCDAEMON:
251 #ifdef GNUPG_DEFAULT_SCDAEMON
252       return GNUPG_DEFAULT_SCDAEMON;
253 #else 
254       X(bindir, "scdaemon");
255 #endif
256
257     case GNUPG_MODULE_NAME_DIRMNGR:
258 #ifdef GNUPG_DEFAULT_DIRMNGR
259       return GNUPG_DEFAULT_DIRMNGR;
260 #else 
261       X(bindir, "dirmngr");
262 #endif
263
264     case GNUPG_MODULE_NAME_PROTECT_TOOL:
265 #ifdef GNUPG_DEFAULT_PROTECT_TOOL
266       return GNUPG_DEFAULT_PROTECT_TOOL;
267 #else 
268       X(libexecdir, "gpg-protect-tool");
269 #endif
270
271     default: 
272       BUG ();
273     }
274 #undef X
275 }