2006-10-24 Marcus Brinkmann <marcus@g10code.de>
[gnupg.git] / common / homedir.c
blob39d6dce200c88a8db1fc14210a30a5c067e8b0ba
1 /* homedir.c - Setup the home directory.
2 * Copyright (C) 2004, 2006 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 2 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, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19 * USA.
22 #include <config.h>
23 #include <stdlib.h>
24 #include <errno.h>
25 #include <fcntl.h>
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*/
42 #include "util.h"
43 #include "sysutils.h"
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)
52 static int initialized;
53 static HRESULT (WINAPI * func)(HWND,int,HANDLE,DWORD,LPSTR);
55 if (!initialized)
57 static char *dllnames[] = { "shell32.dll", "shfolder.dll", NULL };
58 void *handle;
59 int i;
61 initialized = 1;
63 for (i=0, handle = NULL; !handle && dllnames[i]; i++)
65 handle = dlopen (dllnames[i], RTLD_LAZY);
66 if (handle)
68 func = dlsym (handle, "SHGetFolderPathA");
69 if (!func)
71 dlclose (handle);
72 handle = NULL;
78 if (func)
79 return func (a,b,c,d,e);
80 else
81 return -1;
83 #endif /*HAVE_W32_SYSTEM*/
86 /* Set up the default home directory. The usual --homedir option
87 should be parsed later. */
88 const char *
89 default_homedir (void)
91 const char *dir;
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)
99 char path[MAX_PATH];
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)
111 char *tmp = xmalloc (strlen (path) + 6 +1);
112 strcpy (stpcpy (tmp, path), "\\gnupg");
113 dir = tmp;
115 /* Try to create the directory if it does not yet
116 exists. */
117 if (access (dir, F_OK))
118 CreateDirectory (dir, NULL);
121 #endif /*HAVE_W32_SYSTEM*/
122 if (!dir || !*dir)
123 dir = GNUPG_DEFAULT_HOMEDIR;
125 return dir;