]> err.no Git - sope/blob - gnustep-make/user_home.c
Add libxml2-dev to libsope-xml4.7-dev deps
[sope] / gnustep-make / user_home.c
1 /*
2    user_home.c
3    Copyright (C) 2002 Free Software Foundation, Inc.
4
5    Author: Richard Frith-Macdonald <richard@brainstorm.co.uk>
6    Date: February 2002
7
8    This file is part of the GNUstep Makefile Package.
9
10    This library is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License
12    as published by the Free Software Foundation; either version 2
13    of the License, or (at your option) any later version.
14
15    You should have received a copy of the GNU General Public
16    License along with this library; see the file COPYING.LIB.
17    If not, write to the Free Software Foundation,
18    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
19
20 #include "config.h"
21
22 #ifdef __MINGW32__
23 #ifndef __MINGW__
24 #define __MINGW__
25 #endif
26 #ifndef __WIN32__
27 #define __WIN32__
28 #endif
29 #endif
30
31 #include <stdio.h>
32 #include <ctype.h>
33
34 #if defined(__MINGW__)
35 # include <windows.h>
36 #endif
37
38 #if HAVE_SYS_TYPES_H
39 # include <sys/types.h>
40 #endif
41
42 #if HAVE_STDLIB_H
43 # include <stdlib.h>
44 #endif
45
46 #if HAVE_UNISTD_H
47 # include <unistd.h>
48 #endif
49
50 #if HAVE_STRING_H
51 # include <string.h>
52 #endif
53
54 #if HAVE_PWD_H
55 # include <pwd.h>
56 #endif
57
58 #define lowlevelstringify(X) #X
59 #define stringify(X) lowlevelstringify(X)
60
61 #define SEP "/"
62
63 /*
64  * This tool is intended to produce a definitive form of the
65  * user specific root directories for a GNUstep user.  It must
66  * remain consistent with the code in the GNUstep base library
67  * which provides path information for all GNUstep applications.
68  *
69  *
70  * How to run this tool ...
71  *
72  * 1. With no arguments ... the tool should print the home directory of
73  * the current user to stdout.
74  *
75  * 2. With a 'user' argument ... the tool should print the
76  * GNUSTEP_USER_ROOT directory to stdout.
77  *
78  * 3. With a 'defaults' argument ... the tool should print the
79  * GNUSTEP_DEFAULTS_ROOT directory to stdout.
80  *
81  * Any other arguments will be ignored.
82  * On success the tool will terminate with an exit status of zero
83  * On failure, the tool will terminate with an exit status of one
84  * and will print an error message to stderr.
85  */
86
87 /* NOTE FOR DEVELOPERS.
88  * If you change the behavior of this method you must also change
89  * NSUser.m in the base library package to match.
90  */
91 int main (int argc, char** argv)
92 {
93   char          buf0[1024];
94   char          path[2048];
95   char          home[2048];
96   char          *loginName = 0;
97   enum { NONE, DEFS, USER } type = NONE;
98 #if defined(__MINGW__)
99   char          buf1[1024];
100   int           len0;
101   int           len1;
102 #else
103   struct passwd *pw;
104 #endif
105
106   if (argc > 1)
107     {
108       if (strcmp(argv[1], "defaults") == 0)
109         {
110           type = DEFS;
111         }
112       else if (strcmp(argv[1], "user") == 0)
113         {
114           type = USER;
115         }
116     }
117
118   if (loginName == 0)
119     {
120 #if defined(__WIN32__)
121       /* The GetUserName function returns the current user name */
122       DWORD     n = 1024;
123
124       len0 = GetEnvironmentVariable("LOGNAME", buf0, 1024);
125       if (len0 > 0 && len0 < 1024)
126         {
127           loginName = buf0;
128           loginName[len0] = '\0';
129         }
130       else if (GetUserName(buf0, &n))
131         {
132           loginName = buf0;
133         }
134 #else
135 #if HAVE_GETPWUID
136 #if HAVE_GETEUID
137       int uid = geteuid();
138 #else
139       int uid = getuid();
140 #endif /* HAVE_GETEUID */
141       struct passwd *pwent = getpwuid (uid);
142       loginName = pwent->pw_name;
143 #endif /* HAVE_GETPWUID */
144 #endif
145       if (loginName == 0)
146         {
147           fprintf(stderr, "Unable to determine current user name.\n");
148           return 1;
149         }
150     }
151
152 #if !defined(__MINGW__)
153   pw = getpwnam (loginName);
154   if (pw == 0)
155     {
156       fprintf(stderr, "Unable to locate home directory for '%s'\n", loginName);
157       return 1;
158     }
159   strncpy(home, pw->pw_dir, sizeof(home));
160 #else
161   home[0] = '\0';
162   /*
163    * The environment variable HOMEPATH holds the home directory
164    * for the user on Windows NT; Win95 has no concept of home.
165    * For OPENSTEP compatibility (and because USERPROFILE is usually
166    * unusable because it contains spaces), we use HOMEPATH in
167    * preference to USERPROFILE.
168    */
169   len0 = GetEnvironmentVariable("HOMEPATH", buf0, 1024);
170   if (len0 > 0 && len0 < 1024)
171     {
172       buf0[len0] = '\0';
173       /*
174        * Only use HOMEDRIVE is HOMEPATH does not already contain drive.
175        */
176       if (len0 < 2 || buf0[1] != ':')
177         {
178           len1 = GetEnvironmentVariable("HOMEDRIVE", buf1, 128);
179           if (len1 > 0 && len1 < 128)
180             {
181               buf1[len1] = '\0';
182               sprintf(home, "%s%s", buf1, buf0);
183             }
184           else
185             {
186               sprintf(home, "C:%s", buf0);
187             }
188         }
189       else
190         {
191           strcpy(home, buf0);
192         }
193     }
194   else
195     {
196       /* The environment variable USERPROFILE may hold the home directory
197          for the user on modern versions of windoze. */
198       len0 = GetEnvironmentVariable("USERPROFILE", buf0, 1024);
199       if (len0 > 0 && len0 < 1024)
200         {
201           buf0[len0] = '\0';
202           strcpy(home, buf0);
203         }
204     }
205   if (home[0] != '\0')
206     {
207       int       i;
208
209       for (i = 0; i < strlen(home); i++)
210         {
211           if (isspace((unsigned int)home[i]))
212             {
213               /*
214                * GNU make doesn't handle spaces in paths.
215                * Broken, wrong and totally unfixable.
216                */
217               fprintf(stderr, "Make cannot handle spaces in paths so the " \
218                           "home directory '%s' may cause problems!\n", home);
219               break;
220             }
221         }
222     }
223 #endif
224
225   if (type == NONE)
226     {
227       strcpy(path, home);
228     }
229   else
230     {
231       FILE      *fptr;
232       char      *user = "";
233       char      *defs = "";
234       int       forceD = 0;
235       int       forceU = 0;
236
237 #if defined (__MINGW32__)
238       len0 = GetEnvironmentVariable("GNUSTEP_SYSTEM_ROOT", buf0, sizeof(buf0));
239       if (len0 > 0)
240         {
241           strcpy(path, buf0);
242         }
243 #else 
244       {
245         const char *gnustep_system_root = (const char*)getenv("GNUSTEP_SYSTEM_ROOT");
246
247         if (gnustep_system_root != 0)
248           {
249             strcpy(path, gnustep_system_root);
250           }
251         else
252           {
253             /* On my machine the strcpy was segfaulting when
254              * gnustep_system_root == 0.  */
255             path[0] = '\0';
256           }
257       }
258 #endif
259       strcat(path, SEP);
260       strcat(path, ".GNUsteprc");
261       fptr = fopen(path, "r");
262       if (fptr != 0)
263         {
264           while (fgets(buf0, sizeof(buf0), fptr) != 0)
265             {
266               char      *pos = strchr(buf0, '=');
267               char      *key = buf0;
268               char      *val;
269
270               if (pos != 0)
271                 {
272                   val = pos;
273                   *val++ = '\0';
274                   while (isspace((int)*key))
275                     key++;
276                   while (strlen(key) > 0 && isspace((int)key[strlen(key)-1]))
277                     key[strlen(key)-1] = '\0';
278                   while (isspace(*val))
279                     val++;
280                   while (strlen(val) > 0 && isspace((int)val[strlen(val)-1]))
281                     val[strlen(val)-1] = '\0';
282                 }
283               else
284                 {
285                   while (isspace((int)*key))
286                     key++;
287                   while (strlen(key) > 0 && isspace((int)key[strlen(key)-1]))
288                     key[strlen(key)-1] = '\0';
289                   val = "";
290                 }
291                         
292               if (strcmp(key, "GNUSTEP_USER_ROOT") == 0)
293                 {
294                   if (*val == '~')
295                     {
296                       user = malloc(strlen(val) + strlen(home));
297                       strcpy(user, home);
298                       strcat(user, &val[1]);
299                     }
300                   else
301                     {
302                       user = malloc(strlen(val) + 1);
303                       strcpy(user, val);
304                     }
305                 }
306               else if (strcmp(key, "GNUSTEP_DEFAULTS_ROOT") == 0)
307                 {
308                   if (*val == '~')
309                     {
310                       defs = malloc(strlen(val) + strlen(home));
311                       strcpy(defs, home);
312                       strcat(defs, &val[1]);
313                     }
314                   else
315                     {
316                       defs = malloc(strlen(val) + 1);
317                       strcpy(defs, val);
318                     }
319                 }
320               else if (strcmp(key, "FORCE_USER_ROOT") == 0)
321                 {
322                   forceU = 1;
323                 }
324               else if (strcmp(key, "FORCE_DEFAULTS_ROOT") == 0)
325                 {
326                   forceD = 1;
327                 }
328             }
329           fclose(fptr);
330         }
331
332       if (*user == '\0' || forceU == 0 || *defs == '\0' || forceD == 0)
333         {
334           strcpy(path, home);
335           strcat(path, SEP);
336           strcat(path, ".GNUsteprc");
337           fptr = fopen(path, "r");
338           if (fptr != 0)
339             {
340               while (fgets(buf0, sizeof(buf0), fptr) != 0)
341                 {
342                   char  *pos = strchr(buf0, '=');
343
344                   if (pos != 0)
345                     {
346                       char      *key = buf0;
347                       char      *val = pos;
348
349                       *val++ = '\0';
350                       while (isspace((int)*key))
351                         key++;
352                       while (strlen(key) > 0
353                         && isspace((int)key[strlen(key)-1]))
354                         key[strlen(key)-1] = '\0';
355                       while (isspace((int)*val))
356                         val++;
357                       while (strlen(val) > 0
358                         && isspace((int)val[strlen(val)-1]))
359                         val[strlen(val)-1] = '\0';
360
361                       if (strcmp(key, "GNUSTEP_USER_ROOT") == 0)
362                         {
363                           if (*user == '\0' || forceU == 0)
364                             {
365                               if (*val == '~')
366                                 {
367                                   user = malloc(strlen(val) + strlen(home));
368                                   strcpy(user, home);
369                                   strcat(user, &val[1]);
370                                 }
371                               else
372                                 {
373                                   user = malloc(strlen(val) + 1);
374                                   strcpy(user, val);
375                                 }
376                             }
377                         }
378                       else if (strcmp(key, "GNUSTEP_DEFAULTS_ROOT") == 0)
379                         {
380                           if (*defs == '\0' || forceD == 0)
381                             {
382                               if (*val == '~')
383                                 {
384                                   defs = malloc(strlen(val) + strlen(home));
385                                   strcpy(defs, home);
386                                   strcat(defs, &val[1]);
387                                 }
388                               else
389                                 {
390                                   defs = malloc(strlen(val) + 1);
391                                   strcpy(defs, val);
392                                 }
393                             }
394                         }
395                     }
396                 }
397               fclose(fptr);
398             }
399         }
400
401       if (type == DEFS)
402         {
403           strcpy(path, defs);
404           if (*path == '\0')
405             {
406               strcpy(path, user);
407             }
408         }
409       else
410         {
411           strcpy(path, user);
412         }
413
414       if (*path == '\0')
415         {
416           strcpy(path, home);
417           strcat(path, SEP);
418           strcat(path, "GNUstep");
419         }
420     }
421 #if defined(__MINGW__)
422   /*
423    * We always want to use unix style paths.
424    */
425   if (strlen(path) > 1 && path[1] == ':')
426     {
427       char      *ptr = path;
428
429       while (*ptr != '\0')
430         {
431           if (*ptr == '\\')
432             {
433               *ptr = '/';
434             }
435           if (*ptr == '/' && ptr > path && ptr[-1] == '/')
436             {
437               memmove(ptr, &ptr[1], strlen(ptr)+1);
438             }
439           else
440             {
441               ptr++;
442             }
443         }
444       if (path[2] == '/' || path[2] == '\0')
445         {
446           path[1] = path[0];
447         }
448       else
449         {
450           memmove(&path[1], path, strlen(path)+1);
451           path[2] = '/';
452         }
453       path[0] = '/';
454     }
455 #endif
456   printf("%s", path);
457   return 0;
458 }
459