Fixed a problem in estream-printf.c.
[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 #ifdef HAVE_W32_SYSTEM
130 static const char *
131 w32_rootdir (void)
132 {
133   static int got_dir;
134   static char dir[MAX_PATH+5];
135
136   if (!got_dir)
137     {
138       char *p;
139
140       if ( !GetModuleFileName ( NULL, dir, MAX_PATH) )
141         {
142           log_debug ("GetModuleFileName failed: %s\n", w32_strerror (0));
143           *dir = 0;
144         }
145       got_dir = 1;
146       p = strrchr (dir, DIRSEP_C);
147       if (p)
148         *p = 0;
149       else
150         {
151           log_debug ("bad filename `%s' returned for this process\n", dir);
152           *dir = 0; 
153         }
154     }
155
156   if (*dir)
157     return dir;
158   /* Fallback to the hardwired value. */
159   return GNUPG_LIBEXECDIR;
160 }
161 #endif /*HAVE_W32_SYSTEM*/
162
163
164
165
166 /* Return the name of the sysconfdir.  This is a static string.  This
167    function is required because under Windows we can't simply compile
168    it in.  */
169 const char *
170 gnupg_sysconfdir (void)
171 {
172 #ifdef HAVE_W32_SYSTEM
173   static char *name;
174
175   if (!name)
176     {
177       const char *s1, *s2;
178       s1 = w32_rootdir ();
179       s2 = DIRSEP_S "etc" DIRSEP_S "gnupg";
180       name = xmalloc (strlen (s1) + strlen (s2) + 1);
181       strcpy (stpcpy (name, s1), s2);
182     }
183   return name;
184 #else /*!HAVE_W32_SYSTEM*/
185   return GNUPG_SYSCONFDIR;
186 #endif /*!HAVE_W32_SYSTEM*/
187 }
188
189
190 const char *
191 gnupg_bindir (void)
192 {
193 #ifdef HAVE_W32_SYSTEM
194   return w32_rootdir ();
195 #else /*!HAVE_W32_SYSTEM*/
196   return GNUPG_BINDIR;
197 #endif /*!HAVE_W32_SYSTEM*/
198 }
199
200
201 /* Return the name of the libexec directory.  The name is allocated in
202    a static area on the first use.  This function won't fail. */
203 const char *
204 gnupg_libexecdir (void)
205 {
206 #ifdef HAVE_W32_SYSTEM
207   return w32_rootdir ();
208 #else /*!HAVE_W32_SYSTEM*/
209   return GNUPG_LIBEXECDIR;
210 #endif /*!HAVE_W32_SYSTEM*/
211 }
212
213 const char *
214 gnupg_libdir (void)
215 {
216 #ifdef HAVE_W32_SYSTEM
217   static char *name;
218
219   if (!name)
220     {
221       const char *s1, *s2;
222       s1 = w32_rootdir ();
223       s2 = DIRSEP_S "lib" DIRSEP_S "gnupg";
224       name = xmalloc (strlen (s1) + strlen (s2) + 1);
225       strcpy (stpcpy (name, s1), s2);
226     }
227   return name;
228 #else /*!HAVE_W32_SYSTEM*/
229   return GNUPG_LIBDIR;
230 #endif /*!HAVE_W32_SYSTEM*/
231 }
232
233 const char *
234 gnupg_datadir (void)
235 {
236 #ifdef HAVE_W32_SYSTEM
237   static char *name;
238
239   if (!name)
240     {
241       const char *s1, *s2;
242       s1 = w32_rootdir ();
243       s2 = DIRSEP_S "share" DIRSEP_S "gnupg";
244       name = xmalloc (strlen (s1) + strlen (s2) + 1);
245       strcpy (stpcpy (name, s1), s2);
246     }
247   return name;
248 #else /*!HAVE_W32_SYSTEM*/
249   return GNUPG_DATADIR;
250 #endif /*!HAVE_W32_SYSTEM*/
251 }
252
253
254 /* Return the file name of a helper tool.  WHICH is one of the
255    GNUPG_MODULE_NAME_foo constants.  */
256 const char *
257 gnupg_module_name (int which)
258 {
259   const char *s, *s2;
260
261 #define X(a,b) do {                                          \
262         static char *name;                                   \
263         if (!name)                                           \
264           {                                                  \
265             s = gnupg_ ## a ();                              \
266             s2 = DIRSEP_S b EXEEXT_S;                        \
267             name = xmalloc (strlen (s) + strlen (s2) + 1);   \
268             strcpy (stpcpy (name, s), s2);                   \
269           }                                                  \
270         return name;                                         \
271       } while (0)                                                     
272
273   switch (which)
274     {
275     case GNUPG_MODULE_NAME_AGENT:
276 #ifdef GNUPG_DEFAULT_AGENT
277       return GNUPG_DEFAULT_AGENT;
278 #else 
279       X(bindir, "gpg-agent");
280 #endif
281       
282     case GNUPG_MODULE_NAME_PINENTRY:
283 #ifdef GNUPG_DEFAULT_PINENTRY
284       return GNUPG_DEFAULT_PINENTRY;
285 #else 
286       X(bindir, "pinentry");
287 #endif
288
289     case GNUPG_MODULE_NAME_SCDAEMON:
290 #ifdef GNUPG_DEFAULT_SCDAEMON
291       return GNUPG_DEFAULT_SCDAEMON;
292 #else 
293       X(bindir, "scdaemon");
294 #endif
295
296     case GNUPG_MODULE_NAME_DIRMNGR:
297 #ifdef GNUPG_DEFAULT_DIRMNGR
298       return GNUPG_DEFAULT_DIRMNGR;
299 #else 
300       X(bindir, "dirmngr");
301 #endif
302
303     case GNUPG_MODULE_NAME_PROTECT_TOOL:
304 #ifdef GNUPG_DEFAULT_PROTECT_TOOL
305       return GNUPG_DEFAULT_PROTECT_TOOL;
306 #else 
307       X(libexecdir, "gpg-protect-tool");
308 #endif
309
310     default: 
311       BUG ();
312     }
313 #undef X
314 }