Declare glib_top_share_dir and exe_top_share_dir only in G_OS_WIN32.
[platform/upstream/glib.git] / glib / gutils.c
1 /* GLIB - Library of useful routines for C programming
2  * Copyright (C) 1995-1998  Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 /*
21  * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
22  * file for a list of people on the GLib Team.  See the ChangeLog
23  * files for a list of changes.  These files are distributed with
24  * GLib at ftp://ftp.gtk.org/pub/gtk/. 
25  */
26
27 /* 
28  * MT safe for the unix part, FIXME: make the win32 part MT safe as well.
29  */
30
31 #include "config.h"
32
33 #ifdef HAVE_UNISTD_H
34 #include <unistd.h>
35 #endif
36 #include <stdarg.h>
37 #include <stdlib.h>
38 #include <stdio.h>
39 #include <locale.h>
40 #include <string.h>
41 #include <errno.h>
42 #ifdef HAVE_PWD_H
43 #include <pwd.h>
44 #endif
45 #include <sys/types.h>
46 #ifdef HAVE_SYS_PARAM_H
47 #include <sys/param.h>
48 #endif
49
50 /* implement gutils's inline functions
51  */
52 #define G_IMPLEMENT_INLINES 1
53 #define __G_UTILS_C__
54 #include "glib.h"
55 #include "gprintfint.h"
56 #include "gthreadinit.h"
57 #include "galias.h"
58
59 #ifdef  MAXPATHLEN
60 #define G_PATH_LENGTH   MAXPATHLEN
61 #elif   defined (PATH_MAX)
62 #define G_PATH_LENGTH   PATH_MAX
63 #elif   defined (_PC_PATH_MAX)
64 #define G_PATH_LENGTH   sysconf(_PC_PATH_MAX)
65 #else   
66 #define G_PATH_LENGTH   2048
67 #endif
68
69 #ifdef G_PLATFORM_WIN32
70 #  define STRICT                /* Strict typing, please */
71 #  include <windows.h>
72 #  undef STRICT
73 #  include <lmcons.h>           /* For UNLEN */
74 #endif /* G_PLATFORM_WIN32 */
75
76 #ifdef G_OS_WIN32
77 #  include <direct.h>
78 #  include <shlobj.h>
79    /* older SDK (e.g. msvc 5.0) does not have these*/
80 #  ifndef CSIDL_INTERNET_CACHE
81 #    define CSIDL_INTERNET_CACHE 32
82 #  endif
83 #  ifndef CSIDL_COMMON_APPDATA
84 #    define CSIDL_COMMON_APPDATA 35
85 #  endif
86 #  ifndef CSIDL_COMMON_DOCUMENTS
87 #    define CSIDL_COMMON_DOCUMENTS 46
88 #  endif
89 #  ifndef CSIDL_PROFILE
90 #    define CSIDL_PROFILE 40
91 #  endif
92 #endif
93
94 #ifdef HAVE_CODESET
95 #include <langinfo.h>
96 #endif
97
98 #ifdef HAVE_BIND_TEXTDOMAIN_CODESET
99 #include <libintl.h>
100 #endif
101
102 const guint glib_major_version = GLIB_MAJOR_VERSION;
103 const guint glib_minor_version = GLIB_MINOR_VERSION;
104 const guint glib_micro_version = GLIB_MICRO_VERSION;
105 const guint glib_interface_age = GLIB_INTERFACE_AGE;
106 const guint glib_binary_age = GLIB_BINARY_AGE;
107
108 #ifdef G_PLATFORM_WIN32
109
110 G_WIN32_DLLMAIN_FOR_DLL_NAME (static, dll_name)
111
112 #endif
113
114 /**
115  * glib_check_version:
116  * @required_major: the required major version.
117  * @required_minor: the required major version.
118  * @required_micro: the required major version.
119  *
120  * Checks that the GLib library in use is compatible with the
121  * given version. Generally you would pass in the constants
122  * #GLIB_MAJOR_VERSION, #GLIB_MINOR_VERSION, #GLIB_MICRO_VERSION
123  * as the three arguments to this function; that produces
124  * a check that the library in use is compatible with
125  * the version of GLib the application or module was compiled
126  * against.
127  *
128  * Compatibility is defined by two things: first the version
129  * of the running library is newer than the version
130  * @required_major.required_minor.@required_micro. Second
131  * the running library must be binary compatible with the
132  * version @required_major.required_minor.@required_micro
133  * (same major version.)
134  *
135  * Return value: %NULL if the GLib library is compatible with the
136  *   given version, or a string describing the version mismatch.
137  *   The returned string is owned by GLib and must not be modified
138  *   or freed.
139  *
140  * Since: 2.6
141  **/
142 const gchar *
143 glib_check_version (guint required_major,
144                     guint required_minor,
145                     guint required_micro)
146 {
147   gint glib_effective_micro = 100 * GLIB_MINOR_VERSION + GLIB_MICRO_VERSION;
148   gint required_effective_micro = 100 * required_minor + required_micro;
149
150   if (required_major > GLIB_MAJOR_VERSION)
151     return "GLib version too old (major mismatch)";
152   if (required_major < GLIB_MAJOR_VERSION)
153     return "GLib version too new (major mismatch)";
154   if (required_effective_micro < glib_effective_micro - GLIB_BINARY_AGE)
155     return "GLib version too new (micro mismatch)";
156   if (required_effective_micro > glib_effective_micro)
157     return "GLib version too old (micro mismatch)";
158   return NULL;
159 }
160
161 #if !defined (HAVE_MEMMOVE) && !defined (HAVE_WORKING_BCOPY)
162 /**
163  * g_memmove: 
164  * @dest: the destination address to copy the bytes to.
165  * @src: the source address to copy the bytes from.
166  * @len: the number of bytes to copy.
167  *
168  * Copies a block of memory @len bytes long, from @src to @dest.
169  * The source and destination areas may overlap.
170  *
171  * In order to use this function, you must include 
172  * <filename>string.h</filename> yourself, because this macro will 
173  * typically simply resolve to memmove() and GLib does not include 
174  * <filename>string.h</filename> for you.
175  */
176 void 
177 g_memmove (gpointer      dest, 
178            gconstpointer src, 
179            gulong        len)
180 {
181   gchar* destptr = dest;
182   const gchar* srcptr = src;
183   if (src + len < dest || dest + len < src)
184     {
185       bcopy (src, dest, len);
186       return;
187     }
188   else if (dest <= src)
189     {
190       while (len--)
191         *(destptr++) = *(srcptr++);
192     }
193   else
194     {
195       destptr += len;
196       srcptr += len;
197       while (len--)
198         *(--destptr) = *(--srcptr);
199     }
200 }
201 #endif /* !HAVE_MEMMOVE && !HAVE_WORKING_BCOPY */
202
203 /**
204  * g_atexit:
205  * @func: the function to call on normal program termination.
206  * 
207  * Specifies a function to be called at normal program termination.
208  */
209 void
210 g_atexit (GVoidFunc func)
211 {
212   gint result;
213   const gchar *error = NULL;
214
215   /* keep this in sync with glib.h */
216
217 #ifdef  G_NATIVE_ATEXIT
218   result = ATEXIT (func);
219   if (result)
220     error = g_strerror (errno);
221 #elif defined (HAVE_ATEXIT)
222 #  ifdef NeXT /* @#%@! NeXTStep */
223   result = !atexit ((void (*)(void)) func);
224   if (result)
225     error = g_strerror (errno);
226 #  else
227   result = atexit ((void (*)(void)) func);
228   if (result)
229     error = g_strerror (errno);
230 #  endif /* NeXT */
231 #elif defined (HAVE_ON_EXIT)
232   result = on_exit ((void (*)(int, void *)) func, NULL);
233   if (result)
234     error = g_strerror (errno);
235 #else
236   result = 0;
237   error = "no implementation";
238 #endif /* G_NATIVE_ATEXIT */
239
240   if (error)
241     g_error ("Could not register atexit() function: %s", error);
242 }
243
244 /* Based on execvp() from GNU Libc.
245  * Some of this code is cut-and-pasted into gspawn.c
246  */
247
248 static gchar*
249 my_strchrnul (const gchar *str, 
250               gchar        c)
251 {
252   gchar *p = (gchar*)str;
253   while (*p && (*p != c))
254     ++p;
255
256   return p;
257 }
258
259 #ifdef G_OS_WIN32
260
261 static gchar *inner_find_program_in_path (const gchar *program);
262
263 gchar*
264 g_find_program_in_path (const gchar *program)
265 {
266   const gchar *last_dot = strrchr (program, '.');
267
268   if (last_dot == NULL ||
269       strchr (last_dot, '\\') != NULL ||
270       strchr (last_dot, '/') != NULL)
271     {
272       const gint program_length = strlen (program);
273       gchar *pathext = g_build_path (";",
274                                      ".exe;.cmd;.bat;.com",
275                                      g_getenv ("PATHEXT"),
276                                      NULL);
277       gchar *p;
278       gchar *decorated_program;
279       gchar *retval;
280
281       p = pathext;
282       do
283         {
284           gchar *q = my_strchrnul (p, ';');
285
286           decorated_program = g_malloc (program_length + (q-p) + 1);
287           memcpy (decorated_program, program, program_length);
288           memcpy (decorated_program+program_length, p, q-p);
289           decorated_program [program_length + (q-p)] = '\0';
290           
291           retval = inner_find_program_in_path (decorated_program);
292           g_free (decorated_program);
293
294           if (retval != NULL)
295             {
296               g_free (pathext);
297               return retval;
298             }
299           p = q;
300         } while (*p++ != '\0');
301       g_free (pathext);
302       return NULL;
303     }
304   else
305     return inner_find_program_in_path (program);
306 }
307
308 #endif
309
310 /**
311  * g_find_program_in_path:
312  * @program: a program name in the GLib file name encoding
313  * 
314  * Locates the first executable named @program in the user's path, in the
315  * same way that execvp() would locate it. Returns an allocated string
316  * with the absolute path name, or %NULL if the program is not found in
317  * the path. If @program is already an absolute path, returns a copy of
318  * @program if @program exists and is executable, and %NULL otherwise.
319  *  
320  * On Windows, if @program does not have a file type suffix, tries
321  * with the suffixes .exe, .cmd, .bat and .com, and the suffixes in
322  * the <envar>PATHEXT</envar> environment variable. 
323  * 
324  * On Windows, it looks for the file in the same way as CreateProcess() 
325  * would. This means first in the directory where the executing
326  * program was loaded from, then in the current directory, then in the
327  * Windows 32-bit system directory, then in the Windows directory, and
328  * finally in the directories in the <envar>PATH</envar> environment 
329  * variable. If the program is found, the return value contains the 
330  * full name including the type suffix.
331  *
332  * Return value: absolute path, or %NULL
333  **/
334 #ifdef G_OS_WIN32
335 static gchar *
336 inner_find_program_in_path (const gchar *program)
337 #else
338 gchar*
339 g_find_program_in_path (const gchar *program)
340 #endif
341 {
342   const gchar *path, *p;
343   gchar *name, *freeme;
344 #ifdef G_OS_WIN32
345   const gchar *path_copy;
346   gchar *filename = NULL, *appdir = NULL;
347   gchar *sysdir = NULL, *windir = NULL;
348 #endif
349   size_t len;
350   size_t pathlen;
351
352   g_return_val_if_fail (program != NULL, NULL);
353
354   /* If it is an absolute path, or a relative path including subdirectories,
355    * don't look in PATH.
356    */
357   if (g_path_is_absolute (program)
358       || strchr (program, G_DIR_SEPARATOR) != NULL
359 #ifdef G_OS_WIN32
360       || strchr (program, '/') != NULL
361 #endif
362       )
363     {
364       if (g_file_test (program, G_FILE_TEST_IS_EXECUTABLE) &&
365           !g_file_test (program, G_FILE_TEST_IS_DIR))
366         return g_strdup (program);
367       else
368         return NULL;
369     }
370   
371   path = g_getenv ("PATH");
372 #ifdef G_OS_UNIX
373   if (path == NULL)
374     {
375       /* There is no `PATH' in the environment.  The default
376        * search path in GNU libc is the current directory followed by
377        * the path `confstr' returns for `_CS_PATH'.
378        */
379       
380       /* In GLib we put . last, for security, and don't use the
381        * unportable confstr(); UNIX98 does not actually specify
382        * what to search if PATH is unset. POSIX may, dunno.
383        */
384       
385       path = "/bin:/usr/bin:.";
386     }
387 #else
388   if (G_WIN32_HAVE_WIDECHAR_API ())
389     {
390       int n;
391       wchar_t wfilename[MAXPATHLEN], wsysdir[MAXPATHLEN],
392         wwindir[MAXPATHLEN];
393       
394       n = GetModuleFileNameW (NULL, wfilename, MAXPATHLEN);
395       if (n > 0 && n < MAXPATHLEN)
396         filename = g_utf16_to_utf8 (wfilename, -1, NULL, NULL, NULL);
397       
398       n = GetSystemDirectoryW (wsysdir, MAXPATHLEN);
399       if (n > 0 && n < MAXPATHLEN)
400         sysdir = g_utf16_to_utf8 (wsysdir, -1, NULL, NULL, NULL);
401       
402       n = GetWindowsDirectoryW (wwindir, MAXPATHLEN);
403       if (n > 0 && n < MAXPATHLEN)
404         windir = g_utf16_to_utf8 (wwindir, -1, NULL, NULL, NULL);
405     }
406   else
407     {
408       int n;
409       gchar cpfilename[MAXPATHLEN], cpsysdir[MAXPATHLEN],
410         cpwindir[MAXPATHLEN];
411       
412       n = GetModuleFileNameA (NULL, cpfilename, MAXPATHLEN);
413       if (n > 0 && n < MAXPATHLEN)
414         filename = g_locale_to_utf8 (cpfilename, -1, NULL, NULL, NULL);
415       
416       n = GetSystemDirectoryA (cpsysdir, MAXPATHLEN);
417       if (n > 0 && n < MAXPATHLEN)
418         sysdir = g_locale_to_utf8 (cpsysdir, -1, NULL, NULL, NULL);
419       
420       n = GetWindowsDirectoryA (cpwindir, MAXPATHLEN);
421       if (n > 0 && n < MAXPATHLEN)
422         windir = g_locale_to_utf8 (cpwindir, -1, NULL, NULL, NULL);
423     }
424   
425   if (filename)
426     {
427       appdir = g_path_get_dirname (filename);
428       g_free (filename);
429     }
430   
431   path = g_strdup (path);
432
433   if (windir)
434     {
435       const gchar *tem = path;
436       path = g_strconcat (windir, ";", path, NULL);
437       g_free ((gchar *) tem);
438       g_free (windir);
439     }
440   
441   if (sysdir)
442     {
443       const gchar *tem = path;
444       path = g_strconcat (sysdir, ";", path, NULL);
445       g_free ((gchar *) tem);
446       g_free (sysdir);
447     }
448   
449   {
450     const gchar *tem = path;
451     path = g_strconcat (".;", path, NULL);
452     g_free ((gchar *) tem);
453   }
454   
455   if (appdir)
456     {
457       const gchar *tem = path;
458       path = g_strconcat (appdir, ";", path, NULL);
459       g_free ((gchar *) tem);
460       g_free (appdir);
461     }
462
463   path_copy = path;
464 #endif
465   
466   len = strlen (program) + 1;
467   pathlen = strlen (path);
468   freeme = name = g_malloc (pathlen + len + 1);
469   
470   /* Copy the file name at the top, including '\0'  */
471   memcpy (name + pathlen + 1, program, len);
472   name = name + pathlen;
473   /* And add the slash before the filename  */
474   *name = G_DIR_SEPARATOR;
475   
476   p = path;
477   do
478     {
479       char *startp;
480
481       path = p;
482       p = my_strchrnul (path, G_SEARCHPATH_SEPARATOR);
483
484       if (p == path)
485         /* Two adjacent colons, or a colon at the beginning or the end
486          * of `PATH' means to search the current directory.
487          */
488         startp = name + 1;
489       else
490         startp = memcpy (name - (p - path), path, p - path);
491
492       if (g_file_test (startp, G_FILE_TEST_IS_EXECUTABLE) &&
493           !g_file_test (startp, G_FILE_TEST_IS_DIR))
494         {
495           gchar *ret;
496           ret = g_strdup (startp);
497           g_free (freeme);
498 #ifdef G_OS_WIN32
499           g_free ((gchar *) path_copy);
500 #endif
501           return ret;
502         }
503     }
504   while (*p++ != '\0');
505   
506   g_free (freeme);
507 #ifdef G_OS_WIN32
508   g_free ((gchar *) path_copy);
509 #endif
510
511   return NULL;
512 }
513
514 /**
515  * g_parse_debug_string:
516  * @string: a list of debug options separated by ':' or "all" 
517  *     to set all flags.
518  * @keys: pointer to an array of #GDebugKey which associate 
519  *     strings with bit flags.
520  * @nkeys: the number of #GDebugKey<!-- -->s in the array.
521  *
522  * Parses a string containing debugging options separated 
523  * by ':' into a %guint containing bit flags. This is used 
524  * within GDK and GTK+ to parse the debug options passed on the
525  * command line or through environment variables.
526  *
527  * Returns: the combined set of bit flags.
528  */
529 guint        
530 g_parse_debug_string  (const gchar     *string, 
531                        const GDebugKey *keys, 
532                        guint            nkeys)
533 {
534   guint i;
535   guint result = 0;
536   
537   g_return_val_if_fail (string != NULL, 0);
538   
539   if (!g_ascii_strcasecmp (string, "all"))
540     {
541       for (i=0; i<nkeys; i++)
542         result |= keys[i].value;
543     }
544   else
545     {
546       const gchar *p = string;
547       const gchar *q;
548       gboolean done = FALSE;
549       
550       while (*p && !done)
551         {
552           q = strchr (p, ':');
553           if (!q)
554             {
555               q = p + strlen(p);
556               done = TRUE;
557             }
558           
559           for (i=0; i<nkeys; i++)
560             if (g_ascii_strncasecmp (keys[i].key, p, q - p) == 0 &&
561                 keys[i].key[q - p] == '\0')
562               result |= keys[i].value;
563           
564           p = q + 1;
565         }
566     }
567   
568   return result;
569 }
570
571 /**
572  * g_basename:
573  * @file_name: the name of the file.
574  * 
575  * Gets the name of the file without any leading directory components.  
576  * It returns a pointer into the given file name string.
577  * 
578  * Return value: the name of the file without any leading directory components.
579  *
580  * Deprecated: Use g_path_get_basename() instead, but notice that
581  * g_path_get_basename() allocates new memory for the returned string, unlike
582  * this function which returns a pointer into the argument.
583  **/
584 G_CONST_RETURN gchar*
585 g_basename (const gchar    *file_name)
586 {
587   register gchar *base;
588   
589   g_return_val_if_fail (file_name != NULL, NULL);
590   
591   base = strrchr (file_name, G_DIR_SEPARATOR);
592
593 #ifdef G_OS_WIN32
594   {
595     gchar *q = strrchr (file_name, '/');
596     if (base == NULL || (q != NULL && q > base))
597         base = q;
598   }
599 #endif
600
601   if (base)
602     return base + 1;
603
604 #ifdef G_OS_WIN32
605   if (g_ascii_isalpha (file_name[0]) && file_name[1] == ':')
606     return (gchar*) file_name + 2;
607 #endif /* G_OS_WIN32 */
608   
609   return (gchar*) file_name;
610 }
611
612 /**
613  * g_path_get_basename:
614  * @file_name: the name of the file.
615  *
616  * Gets the last component of the filename. If @file_name ends with a 
617  * directory separator it gets the component before the last slash. If 
618  * @file_name consists only of directory separators (and on Windows, 
619  * possibly a drive letter), a single separator is returned. If
620  * @file_name is empty, it gets ".".
621  *
622  * Return value: a newly allocated string containing the last component of 
623  *   the filename.
624  */
625 gchar*
626 g_path_get_basename (const gchar   *file_name)
627 {
628   register gssize base;             
629   register gssize last_nonslash;    
630   gsize len;    
631   gchar *retval;
632  
633   g_return_val_if_fail (file_name != NULL, NULL);
634
635   if (file_name[0] == '\0')
636     /* empty string */
637     return g_strdup (".");
638   
639   last_nonslash = strlen (file_name) - 1;
640
641   while (last_nonslash >= 0 && G_IS_DIR_SEPARATOR (file_name [last_nonslash]))
642     last_nonslash--;
643
644   if (last_nonslash == -1)
645     /* string only containing slashes */
646     return g_strdup (G_DIR_SEPARATOR_S);
647
648 #ifdef G_OS_WIN32
649   if (last_nonslash == 1 && g_ascii_isalpha (file_name[0]) && file_name[1] == ':')
650     /* string only containing slashes and a drive */
651     return g_strdup (G_DIR_SEPARATOR_S);
652 #endif /* G_OS_WIN32 */
653
654   base = last_nonslash;
655
656   while (base >=0 && !G_IS_DIR_SEPARATOR (file_name [base]))
657     base--;
658
659 #ifdef G_OS_WIN32
660   if (base == -1 && g_ascii_isalpha (file_name[0]) && file_name[1] == ':')
661     base = 1;
662 #endif /* G_OS_WIN32 */
663
664   len = last_nonslash - base;
665   retval = g_malloc (len + 1);
666   memcpy (retval, file_name + base + 1, len);
667   retval [len] = '\0';
668   return retval;
669 }
670
671 /**
672  * g_path_is_absolute:
673  * @file_name: a file name.
674  *
675  * Returns %TRUE if the given @file_name is an absolute file name,
676  * i.e. it contains a full path from the root directory such as "/usr/local"
677  * on UNIX or "C:\windows" on Windows systems.
678  *
679  * Returns: %TRUE if @file_name is an absolute path. 
680  */
681 gboolean
682 g_path_is_absolute (const gchar *file_name)
683 {
684   g_return_val_if_fail (file_name != NULL, FALSE);
685   
686   if (G_IS_DIR_SEPARATOR (file_name[0]))
687     return TRUE;
688
689 #ifdef G_OS_WIN32
690   /* Recognize drive letter on native Windows */
691   if (g_ascii_isalpha (file_name[0]) && 
692       file_name[1] == ':' && G_IS_DIR_SEPARATOR (file_name[2]))
693     return TRUE;
694 #endif /* G_OS_WIN32 */
695
696   return FALSE;
697 }
698
699 /**
700  * g_path_skip_root:
701  * @file_name: a file name.
702  *
703  * Returns a pointer into @file_name after the root component, i.e. after
704  * the "/" in UNIX or "C:\" under Windows. If @file_name is not an absolute
705  * path it returns %NULL.
706  *
707  * Returns: a pointer into @file_name after the root component.
708  */
709 G_CONST_RETURN gchar*
710 g_path_skip_root (const gchar *file_name)
711 {
712   g_return_val_if_fail (file_name != NULL, NULL);
713   
714 #ifdef G_PLATFORM_WIN32
715   /* Skip \\server\share or //server/share */
716   if (G_IS_DIR_SEPARATOR (file_name[0]) &&
717       G_IS_DIR_SEPARATOR (file_name[1]) &&
718       file_name[2] &&
719       !G_IS_DIR_SEPARATOR (file_name[2]))
720     {
721       gchar *p;
722
723       p = strchr (file_name + 2, G_DIR_SEPARATOR);
724 #ifdef G_OS_WIN32
725       {
726         gchar *q = strchr (file_name + 2, '/');
727         if (p == NULL || (q != NULL && q < p))
728           p = q;
729       }
730 #endif
731       if (p &&
732           p > file_name + 2 &&
733           p[1])
734         {
735           file_name = p + 1;
736
737           while (file_name[0] && !G_IS_DIR_SEPARATOR (file_name[0]))
738             file_name++;
739
740           /* Possibly skip a backslash after the share name */
741           if (G_IS_DIR_SEPARATOR (file_name[0]))
742             file_name++;
743
744           return (gchar *)file_name;
745         }
746     }
747 #endif
748   
749   /* Skip initial slashes */
750   if (G_IS_DIR_SEPARATOR (file_name[0]))
751     {
752       while (G_IS_DIR_SEPARATOR (file_name[0]))
753         file_name++;
754       return (gchar *)file_name;
755     }
756
757 #ifdef G_OS_WIN32
758   /* Skip X:\ */
759   if (g_ascii_isalpha (file_name[0]) && file_name[1] == ':' && G_IS_DIR_SEPARATOR (file_name[2]))
760     return (gchar *)file_name + 3;
761 #endif
762
763   return NULL;
764 }
765
766 /**
767  * g_path_get_dirname:
768  * @file_name: the name of the file.
769  *
770  * Gets the directory components of a file name.  If the file name has no
771  * directory components "." is returned.  The returned string should be
772  * freed when no longer needed.
773  * 
774  * Returns: the directory components of the file.
775  */
776 gchar*
777 g_path_get_dirname (const gchar    *file_name)
778 {
779   register gchar *base;
780   register gsize len;    
781   
782   g_return_val_if_fail (file_name != NULL, NULL);
783   
784   base = strrchr (file_name, G_DIR_SEPARATOR);
785 #ifdef G_OS_WIN32
786   {
787     gchar *q = strrchr (file_name, '/');
788     if (base == NULL || (q != NULL && q > base))
789         base = q;
790   }
791 #endif
792   if (!base)
793     {
794 #ifdef G_OS_WIN32
795       if (g_ascii_isalpha (file_name[0]) && file_name[1] == ':')
796         {
797           gchar drive_colon_dot[4];
798
799           drive_colon_dot[0] = file_name[0];
800           drive_colon_dot[1] = ':';
801           drive_colon_dot[2] = '.';
802           drive_colon_dot[3] = '\0';
803
804           return g_strdup (drive_colon_dot);
805         }
806 #endif
807     return g_strdup (".");
808     }
809
810   while (base > file_name && G_IS_DIR_SEPARATOR (*base))
811     base--;
812
813 #ifdef G_OS_WIN32
814   /* base points to the char before the last slash.
815    *
816    * In case file_name is the root of a drive (X:\) or a child of the
817    * root of a drive (X:\foo), include the slash.
818    *
819    * In case file_name is the root share of an UNC path
820    * (\\server\share), add a slash, returning \\server\share\ .
821    *
822    * In case file_name is a direct child of a share in an UNC path
823    * (\\server\share\foo), include the slash after the share name,
824    * returning \\server\share\ .
825    */
826   if (base == file_name + 1 && g_ascii_isalpha (file_name[0]) && file_name[1] == ':')
827     base++;
828   else if (G_IS_DIR_SEPARATOR (file_name[0]) &&
829            G_IS_DIR_SEPARATOR (file_name[1]) &&
830            file_name[2] &&
831            !G_IS_DIR_SEPARATOR (file_name[2]) &&
832            base >= file_name + 2)
833     {
834       const gchar *p = file_name + 2;
835       while (*p && !G_IS_DIR_SEPARATOR (*p))
836         p++;
837       if (p == base + 1)
838         {
839           len = (guint) strlen (file_name) + 1;
840           base = g_new (gchar, len + 1);
841           strcpy (base, file_name);
842           base[len-1] = G_DIR_SEPARATOR;
843           base[len] = 0;
844           return base;
845         }
846       if (G_IS_DIR_SEPARATOR (*p))
847         {
848           p++;
849           while (*p && !G_IS_DIR_SEPARATOR (*p))
850             p++;
851           if (p == base + 1)
852             base++;
853         }
854     }
855 #endif
856
857   len = (guint) 1 + base - file_name;
858   
859   base = g_new (gchar, len + 1);
860   g_memmove (base, file_name, len);
861   base[len] = 0;
862   
863   return base;
864 }
865
866 /**
867  * g_get_current_dir:
868  *
869  * Gets the current directory.
870  * The returned string should be freed when no longer needed. The encoding 
871  * of the returned string is system defined. On Windows, it is always UTF-8.
872  * 
873  * Returns: the current directory.
874  */
875 gchar*
876 g_get_current_dir (void)
877 {
878 #ifdef G_OS_WIN32
879
880   gchar *dir = NULL;
881
882   if (G_WIN32_HAVE_WIDECHAR_API ())
883     {
884       wchar_t dummy[2], *wdir;
885       int len;
886
887       len = GetCurrentDirectoryW (2, dummy);
888       wdir = g_new (wchar_t, len);
889
890       if (GetCurrentDirectoryW (len, wdir) == len - 1)
891         dir = g_utf16_to_utf8 (wdir, -1, NULL, NULL, NULL);
892
893       g_free (wdir);
894     }
895   else
896     {
897       gchar dummy[2], *cpdir;
898       int len;
899
900       len = GetCurrentDirectoryA (2, dummy);
901       cpdir = g_new (gchar, len);
902
903       if (GetCurrentDirectoryA (len, cpdir) == len - 1)
904         dir = g_locale_to_utf8 (cpdir, -1, NULL, NULL, NULL);
905
906       g_free (cpdir);
907     }
908
909   if (dir == NULL)
910     dir = g_strdup ("\\");
911
912   return dir;
913
914 #else
915
916   gchar *buffer = NULL;
917   gchar *dir = NULL;
918   static gulong max_len = 0;
919
920   if (max_len == 0) 
921     max_len = (G_PATH_LENGTH == -1) ? 2048 : G_PATH_LENGTH;
922   
923   /* We don't use getcwd(3) on SUNOS, because, it does a popen("pwd")
924    * and, if that wasn't bad enough, hangs in doing so.
925    */
926 #if     (defined (sun) && !defined (__SVR4)) || !defined(HAVE_GETCWD)
927   buffer = g_new (gchar, max_len + 1);
928   *buffer = 0;
929   dir = getwd (buffer);
930 #else   /* !sun || !HAVE_GETCWD */
931   while (max_len < G_MAXULONG / 2)
932     {
933       buffer = g_new (gchar, max_len + 1);
934       *buffer = 0;
935       dir = getcwd (buffer, max_len);
936
937       if (dir || errno != ERANGE)
938         break;
939
940       g_free (buffer);
941       max_len *= 2;
942     }
943 #endif  /* !sun || !HAVE_GETCWD */
944   
945   if (!dir || !*buffer)
946     {
947       /* hm, should we g_error() out here?
948        * this can happen if e.g. "./" has mode \0000
949        */
950       buffer[0] = G_DIR_SEPARATOR;
951       buffer[1] = 0;
952     }
953
954   dir = g_strdup (buffer);
955   g_free (buffer);
956   
957   return dir;
958 #endif /* !Win32 */
959 }
960
961 /**
962  * g_getenv:
963  * @variable: the environment variable to get, in the GLib file name encoding.
964  * 
965  * Returns the value of an environment variable. The name and value
966  * are in the GLib file name encoding. On UNIX, this means the actual
967  * bytes which might or might not be in some consistent character set
968  * and encoding. On Windows, it is in UTF-8. On Windows, in case the
969  * environment variable's value contains references to other
970  * environment variables, they are expanded.
971  * 
972  * Return value: the value of the environment variable, or %NULL if
973  * the environment variable is not found. The returned string may be
974  * overwritten by the next call to g_getenv(), g_setenv() or
975  * g_unsetenv().
976  **/
977 G_CONST_RETURN gchar*
978 g_getenv (const gchar *variable)
979 {
980 #ifndef G_OS_WIN32
981
982   g_return_val_if_fail (variable != NULL, NULL);
983
984   return getenv (variable);
985
986 #else /* G_OS_WIN32 */
987
988   GQuark quark;
989   gchar *value;
990
991   g_return_val_if_fail (variable != NULL, NULL);
992   g_return_val_if_fail (g_utf8_validate (variable, -1, NULL), NULL);
993
994   /* On Windows NT, it is relatively typical that environment
995    * variables contain references to other environment variables. If
996    * so, use ExpandEnvironmentStrings(). (In an ideal world, such
997    * environment variables would be stored in the Registry as
998    * REG_EXPAND_SZ type values, and would then get automatically
999    * expanded before a program sees them. But there is broken software
1000    * that stores environment variables as REG_SZ values even if they
1001    * contain references to other environment variables.)
1002    */
1003
1004   if (G_WIN32_HAVE_WIDECHAR_API ())
1005     {
1006       wchar_t dummy[2], *wname, *wvalue;
1007       int len;
1008       
1009       wname = g_utf8_to_utf16 (variable, -1, NULL, NULL, NULL);
1010
1011       len = GetEnvironmentVariableW (wname, dummy, 2);
1012
1013       if (len == 0)
1014         {
1015           g_free (wname);
1016           return NULL;
1017         }
1018       else if (len == 1)
1019         len = 2;
1020
1021       wvalue = g_new (wchar_t, len);
1022
1023       if (GetEnvironmentVariableW (wname, wvalue, len) != len - 1)
1024         {
1025           g_free (wname);
1026           g_free (wvalue);
1027           return NULL;
1028         }
1029
1030       if (wcschr (wvalue, L'%') != NULL)
1031         {
1032           wchar_t *tem = wvalue;
1033
1034           len = ExpandEnvironmentStringsW (wvalue, dummy, 2);
1035
1036           if (len > 0)
1037             {
1038               wvalue = g_new (wchar_t, len);
1039
1040               if (ExpandEnvironmentStringsW (tem, wvalue, len) != len)
1041                 {
1042                   g_free (wvalue);
1043                   wvalue = tem;
1044                 }
1045               else
1046                 g_free (tem);
1047             }
1048         }
1049
1050       value = g_utf16_to_utf8 (wvalue, -1, NULL, NULL, NULL);
1051
1052       g_free (wname);
1053       g_free (wvalue);
1054     }
1055   else
1056     {
1057       gchar dummy[3], *cpname, *cpvalue;
1058       int len;
1059       
1060       cpname = g_locale_from_utf8 (variable, -1, NULL, NULL, NULL);
1061
1062       g_return_val_if_fail (cpname != NULL, NULL);
1063
1064       len = GetEnvironmentVariableA (cpname, dummy, 2);
1065
1066       if (len == 0)
1067         {
1068           g_free (cpname);
1069           return NULL;
1070         }
1071       else if (len == 1)
1072         len = 2;
1073
1074       cpvalue = g_new (gchar, len);
1075
1076       if (GetEnvironmentVariableA (cpname, cpvalue, len) != len - 1)
1077         {
1078           g_free (cpname);
1079           g_free (cpvalue);
1080           return NULL;
1081         }
1082
1083       if (strchr (cpvalue, '%') != NULL)
1084         {
1085           gchar *tem = cpvalue;
1086
1087           len = ExpandEnvironmentStringsA (cpvalue, dummy, 3);
1088
1089           if (len > 0)
1090             {
1091               cpvalue = g_new (gchar, len);
1092
1093               if (ExpandEnvironmentStringsA (tem, cpvalue, len) != len)
1094                 {
1095                   g_free (cpvalue);
1096                   cpvalue = tem;
1097                 }
1098               else
1099                 g_free (tem);
1100             }
1101         }
1102
1103       value = g_locale_to_utf8 (cpvalue, -1, NULL, NULL, NULL);
1104
1105       g_free (cpname);
1106       g_free (cpvalue);
1107     }
1108
1109   quark = g_quark_from_string (value);
1110   g_free (value);
1111   
1112   return g_quark_to_string (quark);
1113
1114 #endif /* G_OS_WIN32 */
1115 }
1116
1117 /**
1118  * g_setenv:
1119  * @variable: the environment variable to set, must not contain '='.
1120  * @value: the value for to set the variable to.
1121  * @overwrite: whether to change the variable if it already exists.
1122  *
1123  * Sets an environment variable. Both the variable's name and value
1124  * should be in the GLib file name encoding. On UNIX, this means that
1125  * they can be any sequence of bytes. On Windows, they should be in
1126  * UTF-8.
1127  *
1128  * Note that on some systems, when variables are overwritten, the memory 
1129  * used for the previous variables and its value isn't reclaimed.
1130  *
1131  * Returns: %FALSE if the environment variable couldn't be set.
1132  *
1133  * Since: 2.4
1134  */
1135 gboolean
1136 g_setenv (const gchar *variable, 
1137           const gchar *value, 
1138           gboolean     overwrite)
1139 {
1140 #ifndef G_OS_WIN32
1141
1142   gint result;
1143 #ifndef HAVE_SETENV
1144   gchar *string;
1145 #endif
1146
1147   g_return_val_if_fail (variable != NULL, FALSE);
1148   g_return_val_if_fail (strchr (variable, '=') == NULL, FALSE);
1149
1150 #ifdef HAVE_SETENV
1151   result = setenv (variable, value, overwrite);
1152 #else
1153   if (!overwrite && getenv (variable) != NULL)
1154     return TRUE;
1155   
1156   /* This results in a leak when you overwrite existing
1157    * settings. It would be fairly easy to fix this by keeping
1158    * our own parallel array or hash table.
1159    */
1160   string = g_strconcat (variable, "=", value, NULL);
1161   result = putenv (string);
1162 #endif
1163   return result == 0;
1164
1165 #else /* G_OS_WIN32 */
1166
1167   gboolean retval;
1168
1169   g_return_val_if_fail (variable != NULL, FALSE);
1170   g_return_val_if_fail (strchr (variable, '=') == NULL, FALSE);
1171   g_return_val_if_fail (g_utf8_validate (variable, -1, NULL), FALSE);
1172   g_return_val_if_fail (g_utf8_validate (value, -1, NULL), FALSE);
1173
1174   if (!overwrite && g_getenv (variable) != NULL)
1175     return TRUE;
1176
1177   /* We want to (if possible) set both the environment variable copy
1178    * kept by the C runtime and the one kept by the system.
1179    *
1180    * We can't use only the C runtime's putenv or _wputenv() as that
1181    * won't work for arbitrary Unicode strings in a "non-Unicode" app
1182    * (with main() and not wmain()). In a "main()" app the C runtime
1183    * initializes the C runtime's environment table by converting the
1184    * real (wide char) environment variables to system codepage, thus
1185    * breaking those that aren't representable in the system codepage.
1186    *
1187    * As the C runtime's putenv() will also set the system copy, we do
1188    * the putenv() first, then call SetEnvironmentValueW ourselves.
1189    */
1190
1191   if (G_WIN32_HAVE_WIDECHAR_API ())
1192     {
1193       wchar_t *wname = g_utf8_to_utf16 (variable, -1, NULL, NULL, NULL);
1194       wchar_t *wvalue = g_utf8_to_utf16 (value, -1, NULL, NULL, NULL);
1195       gchar *tem = g_strconcat (variable, "=", value, NULL);
1196       wchar_t *wassignment = g_utf8_to_utf16 (tem, -1, NULL, NULL, NULL);
1197       
1198       g_free (tem);
1199       _wputenv (wassignment);
1200       g_free (wassignment);
1201
1202       retval = (SetEnvironmentVariableW (wname, wvalue) != 0);
1203
1204       g_free (wname);
1205       g_free (wvalue);
1206     }
1207   else
1208     {
1209       /* In the non-Unicode case (Win9x), just putenv() is good
1210        * enough.
1211        */
1212       gchar *tem = g_strconcat (variable, "=", value, NULL);
1213       gchar *cpassignment = g_locale_from_utf8 (tem, -1, NULL, NULL, NULL);
1214
1215       g_free (tem);
1216       
1217       retval = (putenv (cpassignment) == 0);
1218
1219       g_free (cpassignment);
1220     }
1221
1222   return retval;
1223
1224 #endif /* G_OS_WIN32 */
1225 }
1226
1227 #ifndef G_OS_WIN32
1228
1229 /* According to the Single Unix Specification, environ is not in 
1230  * any system header, although unistd.h often declares it.
1231  */
1232 extern char **environ;
1233
1234 #endif
1235            
1236 /**
1237  * g_unsetenv:
1238  * @variable: the environment variable to remove, must not contain '='.
1239  * 
1240  * Removes an environment variable from the environment.
1241  *
1242  * Note that on some systems, when variables are overwritten, the memory 
1243  * used for the previous variables and its value isn't reclaimed.
1244  * Furthermore, this function can't be guaranteed to operate in a 
1245  * threadsafe way.
1246  *
1247  * Since: 2.4 
1248  **/
1249 void
1250 g_unsetenv (const gchar *variable)
1251 {
1252 #ifndef G_OS_WIN32
1253
1254 #ifdef HAVE_UNSETENV
1255   g_return_if_fail (variable != NULL);
1256   g_return_if_fail (strchr (variable, '=') == NULL);
1257
1258   unsetenv (variable);
1259 #else /* !HAVE_UNSETENV */
1260   int len;
1261   gchar **e, **f;
1262
1263   g_return_if_fail (variable != NULL);
1264   g_return_if_fail (strchr (variable, '=') == NULL);
1265
1266   len = strlen (variable);
1267   
1268   /* Mess directly with the environ array.
1269    * This seems to be the only portable way to do this.
1270    *
1271    * Note that we remove *all* environment entries for
1272    * the variable name, not just the first.
1273    */
1274   e = f = environ;
1275   while (*e != NULL) 
1276     {
1277       if (strncmp (*e, variable, len) != 0 || (*e)[len] != '=') 
1278         {
1279           *f = *e;
1280           f++;
1281         }
1282       e++;
1283     }
1284   *f = NULL;
1285 #endif /* !HAVE_UNSETENV */
1286
1287 #else  /* G_OS_WIN32 */
1288
1289   g_return_if_fail (variable != NULL);
1290   g_return_if_fail (strchr (variable, '=') == NULL);
1291   g_return_if_fail (g_utf8_validate (variable, -1, NULL));
1292
1293   if (G_WIN32_HAVE_WIDECHAR_API ())
1294     {
1295       wchar_t *wname = g_utf8_to_utf16 (variable, -1, NULL, NULL, NULL);
1296       gchar *tem = g_strconcat (variable, "=", NULL);
1297       wchar_t *wassignment = g_utf8_to_utf16 (tem, -1, NULL, NULL, NULL);
1298       
1299       g_free (tem);
1300       _wputenv (wassignment);
1301       g_free (wassignment);
1302
1303       SetEnvironmentVariableW (wname, NULL);
1304
1305       g_free (wname);
1306     }
1307   else
1308     {
1309       /* In the non-Unicode case (Win9x), just putenv() is good
1310        * enough.
1311        */
1312       gchar *tem = g_strconcat (variable, "=", NULL);
1313       gchar *cpassignment = g_locale_from_utf8 (tem, -1, NULL, NULL, NULL);
1314
1315       g_free (tem);
1316       
1317       putenv (cpassignment);
1318
1319       g_free (cpassignment);
1320     }
1321
1322 #endif /* G_OS_WIN32 */
1323 }
1324
1325 /**
1326  * g_listenv:
1327  *
1328  * Gets the names of all variables set in the environment.
1329  * 
1330  * Return: a NUL-terminated list of strings which must be freed
1331  * with g_strfreev().
1332  *
1333  * Since: 2.8
1334  */
1335 gchar **
1336 g_listenv (void)
1337 {
1338   gchar **result, *eq;
1339   gint len, i;
1340
1341   len = g_strv_length (environ);
1342   result = g_new0 (gchar *, len + 1);
1343   
1344   for (i = 0; i < len; i++)
1345     {
1346       eq = strchr (environ[i], '=');
1347       result[i] = g_strndup (environ[i], eq - environ[i]);
1348     }
1349
1350   result[len] = NULL;
1351
1352   return result;
1353 }
1354
1355 G_LOCK_DEFINE_STATIC (g_utils_global);
1356
1357 static  gchar   *g_tmp_dir = NULL;
1358 static  gchar   *g_user_name = NULL;
1359 static  gchar   *g_real_name = NULL;
1360 static  gchar   *g_home_dir = NULL;
1361
1362 #ifdef G_OS_WIN32
1363 /* System codepage versions of the above, kept at file level so that they,
1364  * too, are produced only once.
1365  */
1366 static  gchar   *g_tmp_dir_cp = NULL;
1367 static  gchar   *g_user_name_cp = NULL;
1368 static  gchar   *g_real_name_cp = NULL;
1369 static  gchar   *g_home_dir_cp = NULL;
1370 #endif
1371
1372 static  gchar   *g_user_data_dir = NULL;
1373 static  gchar  **g_system_data_dirs = NULL;
1374 static  gchar   *g_user_cache_dir = NULL;
1375 static  gchar   *g_user_config_dir = NULL;
1376 static  gchar  **g_system_config_dirs = NULL;
1377
1378 #ifdef G_OS_WIN32
1379
1380 static gchar *
1381 get_special_folder (int csidl)
1382 {
1383   union {
1384     char c[MAX_PATH+1];
1385     wchar_t wc[MAX_PATH+1];
1386   } path;
1387   HRESULT hr;
1388   LPITEMIDLIST pidl = NULL;
1389   BOOL b;
1390   gchar *retval = NULL;
1391
1392   hr = SHGetSpecialFolderLocation (NULL, csidl, &pidl);
1393   if (hr == S_OK)
1394     {
1395       if (G_WIN32_HAVE_WIDECHAR_API ())
1396         {
1397           b = SHGetPathFromIDListW (pidl, path.wc);
1398           if (b)
1399             retval = g_utf16_to_utf8 (path.wc, -1, NULL, NULL, NULL);
1400         }
1401       else
1402         {
1403           b = SHGetPathFromIDListA (pidl, path.c);
1404           if (b)
1405             retval = g_locale_to_utf8 (path.c, -1, NULL, NULL, NULL);
1406         }
1407       CoTaskMemFree (pidl);
1408     }
1409   return retval;
1410 }
1411
1412 #endif
1413
1414 /* HOLDS: g_utils_global_lock */
1415 static void
1416 g_get_any_init (void)
1417 {
1418   if (!g_tmp_dir)
1419     {
1420       g_tmp_dir = g_strdup (g_getenv ("TMPDIR"));
1421       if (!g_tmp_dir)
1422         g_tmp_dir = g_strdup (g_getenv ("TMP"));
1423       if (!g_tmp_dir)
1424         g_tmp_dir = g_strdup (g_getenv ("TEMP"));
1425       
1426 #ifdef P_tmpdir
1427       if (!g_tmp_dir)
1428         {
1429           gsize k;    
1430           g_tmp_dir = g_strdup (P_tmpdir);
1431           k = strlen (g_tmp_dir);
1432           if (k > 1 && G_IS_DIR_SEPARATOR (g_tmp_dir[k - 1]))
1433             g_tmp_dir[k - 1] = '\0';
1434         }
1435 #endif
1436       
1437       if (!g_tmp_dir)
1438         {
1439 #ifndef G_OS_WIN32
1440           g_tmp_dir = g_strdup ("/tmp");
1441 #else /* G_OS_WIN32 */
1442           g_tmp_dir = g_strdup ("\\");
1443 #endif /* G_OS_WIN32 */
1444         }
1445       
1446 #ifdef G_OS_WIN32
1447       /* We check $HOME first for Win32, though it is a last resort for Unix
1448        * where we prefer the results of getpwuid().
1449        */
1450       g_home_dir = g_strdup (g_getenv ("HOME"));
1451
1452       /* Only believe HOME if it is an absolute path and exists */
1453       if (g_home_dir)
1454         {
1455           if (!(g_path_is_absolute (g_home_dir) &&
1456                 g_file_test (g_home_dir, G_FILE_TEST_IS_DIR)))
1457             {
1458               g_free (g_home_dir);
1459               g_home_dir = NULL;
1460             }
1461         }
1462       
1463       /* In case HOME is Unix-style (it happens), convert it to
1464        * Windows style.
1465        */
1466       if (g_home_dir)
1467         {
1468           gchar *p;
1469           while ((p = strchr (g_home_dir, '/')) != NULL)
1470             *p = '\\';
1471         }
1472
1473       if (!g_home_dir)
1474         {
1475           /* USERPROFILE is probably the closest equivalent to $HOME? */
1476           if (g_getenv ("USERPROFILE") != NULL)
1477             g_home_dir = g_strdup (g_getenv ("USERPROFILE"));
1478         }
1479
1480       if (!g_home_dir)
1481         g_home_dir = get_special_folder (CSIDL_PROFILE);
1482       
1483       if (!g_home_dir)
1484         {
1485           /* At least at some time, HOMEDRIVE and HOMEPATH were used
1486            * to point to the home directory, I think. But on Windows
1487            * 2000 HOMEDRIVE seems to be equal to SYSTEMDRIVE, and
1488            * HOMEPATH is its root "\"?
1489            */
1490           if (g_getenv ("HOMEDRIVE") != NULL && g_getenv ("HOMEPATH") != NULL)
1491             g_home_dir = g_strconcat (g_getenv ("HOMEDRIVE"),
1492                                       g_getenv ("HOMEPATH"),
1493                                       NULL);
1494         }
1495 #endif /* G_OS_WIN32 */
1496       
1497 #ifdef HAVE_PWD_H
1498       {
1499         struct passwd *pw = NULL;
1500         gpointer buffer = NULL;
1501         gint error;
1502         
1503 #  if defined (HAVE_POSIX_GETPWUID_R) || defined (HAVE_NONPOSIX_GETPWUID_R)
1504         struct passwd pwd;
1505 #    ifdef _SC_GETPW_R_SIZE_MAX  
1506         /* This reurns the maximum length */
1507         glong bufsize = sysconf (_SC_GETPW_R_SIZE_MAX);
1508         
1509         if (bufsize < 0)
1510           bufsize = 64;
1511 #    else /* _SC_GETPW_R_SIZE_MAX */
1512         glong bufsize = 64;
1513 #    endif /* _SC_GETPW_R_SIZE_MAX */
1514         
1515         do
1516           {
1517             g_free (buffer);
1518             /* we allocate 6 extra bytes to work around a bug in 
1519              * Mac OS < 10.3. See #156446
1520              */
1521             buffer = g_malloc (bufsize + 6);
1522             errno = 0;
1523             
1524 #    ifdef HAVE_POSIX_GETPWUID_R
1525             error = getpwuid_r (getuid (), &pwd, buffer, bufsize, &pw);
1526             error = error < 0 ? errno : error;
1527 #    else /* HAVE_NONPOSIX_GETPWUID_R */
1528        /* HPUX 11 falls into the HAVE_POSIX_GETPWUID_R case */
1529 #      if defined(_AIX) || defined(__hpux)
1530             error = getpwuid_r (getuid (), &pwd, buffer, bufsize);
1531             pw = error == 0 ? &pwd : NULL;
1532 #      else /* !_AIX */
1533             pw = getpwuid_r (getuid (), &pwd, buffer, bufsize);
1534             error = pw ? 0 : errno;
1535 #      endif /* !_AIX */            
1536 #    endif /* HAVE_NONPOSIX_GETPWUID_R */
1537             
1538             if (!pw)
1539               {
1540                 /* we bail out prematurely if the user id can't be found
1541                  * (should be pretty rare case actually), or if the buffer
1542                  * should be sufficiently big and lookups are still not
1543                  * successfull.
1544                  */
1545                 if (error == 0 || error == ENOENT)
1546                   {
1547                     g_warning ("getpwuid_r(): failed due to unknown user id (%lu)",
1548                                (gulong) getuid ());
1549                     break;
1550                   }
1551                 if (bufsize > 32 * 1024)
1552                   {
1553                     g_warning ("getpwuid_r(): failed due to: %s.",
1554                                g_strerror (error));
1555                     break;
1556                   }
1557                 
1558                 bufsize *= 2;
1559               }
1560           }
1561         while (!pw);
1562 #  endif /* HAVE_POSIX_GETPWUID_R || HAVE_NONPOSIX_GETPWUID_R */
1563         
1564         if (!pw)
1565           {
1566             setpwent ();
1567             pw = getpwuid (getuid ());
1568             endpwent ();
1569           }
1570         if (pw)
1571           {
1572             g_user_name = g_strdup (pw->pw_name);
1573
1574             if (pw->pw_gecos && *pw->pw_gecos != '\0') 
1575               {
1576                 gchar **gecos_fields;
1577                 gchar **name_parts;
1578
1579                 /* split the gecos field and substitute '&' */
1580                 gecos_fields = g_strsplit (pw->pw_gecos, ",", 0);
1581                 name_parts = g_strsplit (gecos_fields[0], "&", 0);
1582                 pw->pw_name[0] = g_ascii_toupper (pw->pw_name[0]);
1583                 g_real_name = g_strjoinv (pw->pw_name, name_parts);
1584                 g_strfreev (gecos_fields);
1585                 g_strfreev (name_parts);
1586               }
1587
1588             if (!g_home_dir)
1589               g_home_dir = g_strdup (pw->pw_dir);
1590           }
1591         g_free (buffer);
1592       }
1593       
1594 #else /* !HAVE_PWD_H */
1595       
1596 #ifdef G_OS_WIN32
1597       if (G_WIN32_HAVE_WIDECHAR_API ())
1598         {
1599           guint len = UNLEN+1;
1600           wchar_t buffer[UNLEN+1];
1601           
1602           if (GetUserNameW (buffer, (LPDWORD) &len))
1603             {
1604               g_user_name = g_utf16_to_utf8 (buffer, -1, NULL, NULL, NULL);
1605               g_real_name = g_strdup (g_user_name);
1606             }
1607         }
1608       else
1609         {
1610           guint len = UNLEN+1;
1611           char buffer[UNLEN+1];
1612           
1613           if (GetUserNameA (buffer, (LPDWORD) &len))
1614             {
1615               g_user_name = g_locale_to_utf8 (buffer, -1, NULL, NULL, NULL);
1616               g_real_name = g_strdup (g_user_name);
1617             }
1618         }
1619 #endif /* G_OS_WIN32 */
1620
1621 #endif /* !HAVE_PWD_H */
1622
1623 #ifndef G_OS_WIN32
1624       if (!g_home_dir)
1625         g_home_dir = g_strdup (g_getenv ("HOME"));
1626 #endif
1627
1628 #ifdef __EMX__
1629       /* change '\\' in %HOME% to '/' */
1630       g_strdelimit (g_home_dir, "\\",'/');
1631 #endif
1632       if (!g_user_name)
1633         g_user_name = g_strdup ("somebody");
1634       if (!g_real_name)
1635         g_real_name = g_strdup ("Unknown");
1636
1637 #ifdef G_OS_WIN32
1638       g_tmp_dir_cp = g_locale_from_utf8 (g_tmp_dir, -1, NULL, NULL, NULL);
1639       g_user_name_cp = g_locale_from_utf8 (g_user_name, -1, NULL, NULL, NULL);
1640       g_real_name_cp = g_locale_from_utf8 (g_real_name, -1, NULL, NULL, NULL);
1641
1642       if (!g_tmp_dir_cp)
1643         g_tmp_dir_cp = g_strdup ("\\");
1644       if (!g_user_name_cp)
1645         g_user_name_cp = g_strdup ("somebody");
1646       if (!g_real_name_cp)
1647         g_real_name_cp = g_strdup ("Unknown");
1648
1649       /* home_dir might be NULL, unlike tmp_dir, user_name and
1650        * real_name.
1651        */
1652       if (g_home_dir)
1653         g_home_dir_cp = g_locale_from_utf8 (g_home_dir, -1, NULL, NULL, NULL);
1654       else
1655         g_home_dir_cp = NULL;
1656 #endif /* G_OS_WIN32 */
1657     }
1658 }
1659
1660 /**
1661  * g_get_user_name:
1662  *
1663  * Gets the user name of the current user. The encoding of the returned
1664  * string is system-defined. On UNIX, it might be the preferred file name
1665  * encoding, or something else, and there is no guarantee that it is even
1666  * consistent on a machine. On Windows, it is always UTF-8.
1667  *
1668  * Returns: the user name of the current user.
1669  */
1670 G_CONST_RETURN gchar*
1671 g_get_user_name (void)
1672 {
1673   G_LOCK (g_utils_global);
1674   if (!g_tmp_dir)
1675     g_get_any_init ();
1676   G_UNLOCK (g_utils_global);
1677   
1678   return g_user_name;
1679 }
1680
1681 /**
1682  * g_get_real_name:
1683  *
1684  * Gets the real name of the user. This usually comes from the user's entry 
1685  * in the <filename>passwd</filename> file. The encoding of the returned 
1686  * string is system-defined. (On Windows, it is, however, always UTF-8.) 
1687  * If the real user name cannot be determined, the string "Unknown" is 
1688  * returned.
1689  *
1690  * Returns: the user's real name.
1691  */
1692 G_CONST_RETURN gchar*
1693 g_get_real_name (void)
1694 {
1695   G_LOCK (g_utils_global);
1696   if (!g_tmp_dir)
1697     g_get_any_init ();
1698   G_UNLOCK (g_utils_global);
1699  
1700   return g_real_name;
1701 }
1702
1703 /**
1704  * g_get_home_dir:
1705  *
1706  * Gets the current user's home directory. 
1707  *
1708  * Note that in contrast to traditional UNIX tools, this function 
1709  * prefers <filename>passwd</filename> entries over the <envar>HOME</envar> 
1710  * environment variable.
1711  *
1712  * Returns: the current user's home directory.
1713  */
1714 G_CONST_RETURN gchar*
1715 g_get_home_dir (void)
1716 {
1717   G_LOCK (g_utils_global);
1718   if (!g_tmp_dir)
1719     g_get_any_init ();
1720   G_UNLOCK (g_utils_global);
1721   
1722   return g_home_dir;
1723 }
1724
1725 /**
1726  * g_get_tmp_dir:
1727  *
1728  * Gets the directory to use for temporary files. This is found from 
1729  * inspecting the environment variables <envar>TMPDIR</envar>, 
1730  * <envar>TMP</envar>, and <envar>TEMP</envar> in that order. If none 
1731  * of those are defined "/tmp" is returned on UNIX and "C:\" on Windows. 
1732  * The encoding of the returned string is system-defined. On Windows, 
1733  * it is always UTF-8. The return value is never %NULL.
1734  *
1735  * Returns: the directory to use for temporary files.
1736  */
1737 G_CONST_RETURN gchar*
1738 g_get_tmp_dir (void)
1739 {
1740   G_LOCK (g_utils_global);
1741   if (!g_tmp_dir)
1742     g_get_any_init ();
1743   G_UNLOCK (g_utils_global);
1744   
1745   return g_tmp_dir;
1746 }
1747
1748 G_LOCK_DEFINE_STATIC (g_prgname);
1749 static gchar *g_prgname = NULL;
1750
1751 /**
1752  * g_get_prgname:
1753  *
1754  * Gets the name of the program. This name should <emphasis>not</emphasis> 
1755  * be localized, contrast with g_get_application_name().
1756  * (If you are using GDK or GTK+ the program name is set in gdk_init(), 
1757  * which is called by gtk_init(). The program name is found by taking 
1758  * the last component of <literal>argv[0]</literal>.)
1759  *
1760  * Returns: the name of the program. The returned string belongs 
1761  * to GLib and must not be modified or freed.
1762  */
1763 gchar*
1764 g_get_prgname (void)
1765 {
1766   gchar* retval;
1767
1768   G_LOCK (g_prgname);
1769 #ifdef G_OS_WIN32
1770   if (g_prgname == NULL)
1771     {
1772       static gboolean beenhere = FALSE;
1773
1774       if (!beenhere)
1775         {
1776           gchar *utf8_buf = NULL;
1777
1778           beenhere = TRUE;
1779           if (G_WIN32_HAVE_WIDECHAR_API ())
1780             {
1781               wchar_t buf[MAX_PATH+1];
1782               if (GetModuleFileNameW (GetModuleHandle (NULL),
1783                                       buf, G_N_ELEMENTS (buf)) > 0)
1784                 utf8_buf = g_utf16_to_utf8 (buf, -1, NULL, NULL, NULL);
1785             }
1786           else
1787             {
1788               gchar buf[MAX_PATH+1];
1789               if (GetModuleFileNameA (GetModuleHandle (NULL),
1790                                       buf, G_N_ELEMENTS (buf)) > 0)
1791                 utf8_buf = g_locale_to_utf8 (buf, -1, NULL, NULL, NULL);
1792             }
1793           if (utf8_buf)
1794             {
1795               g_prgname = g_path_get_basename (utf8_buf);
1796               g_free (utf8_buf);
1797             }
1798         }
1799     }
1800 #endif
1801   retval = g_prgname;
1802   G_UNLOCK (g_prgname);
1803
1804   return retval;
1805 }
1806
1807 /**
1808  * g_set_prgname:
1809  * @prgname: the name of the program.
1810  *
1811  * Sets the name of the program. This name should <emphasis>not</emphasis> 
1812  * be localized, contrast with g_set_application_name(). Note that for 
1813  * thread-safety reasons this function can only be called once.
1814  */
1815 void
1816 g_set_prgname (const gchar *prgname)
1817 {
1818   G_LOCK (g_prgname);
1819   g_free (g_prgname);
1820   g_prgname = g_strdup (prgname);
1821   G_UNLOCK (g_prgname);
1822 }
1823
1824 G_LOCK_DEFINE_STATIC (g_application_name);
1825 static gchar *g_application_name = NULL;
1826
1827 /**
1828  * g_get_application_name:
1829  * 
1830  * Gets a human-readable name for the application, as set by
1831  * g_set_application_name(). This name should be localized if
1832  * possible, and is intended for display to the user.  Contrast with
1833  * g_get_prgname(), which gets a non-localized name. If
1834  * g_set_application_name() has not been called, returns the result of
1835  * g_get_prgname() (which may be %NULL if g_set_prgname() has also not
1836  * been called).
1837  * 
1838  * Return value: human-readable application name. may return %NULL
1839  *
1840  * Since: 2.2
1841  **/
1842 G_CONST_RETURN gchar*
1843 g_get_application_name (void)
1844 {
1845   gchar* retval;
1846
1847   G_LOCK (g_application_name);
1848   retval = g_application_name;
1849   G_UNLOCK (g_application_name);
1850
1851   if (retval == NULL)
1852     return g_get_prgname ();
1853   
1854   return retval;
1855 }
1856
1857 /**
1858  * g_set_application_name:
1859  * @application_name: localized name of the application
1860  *
1861  * Sets a human-readable name for the application. This name should be
1862  * localized if possible, and is intended for display to the user.
1863  * Contrast with g_set_prgname(), which sets a non-localized name.
1864  * g_set_prgname() will be called automatically by gtk_init(),
1865  * but g_set_application_name() will not.
1866  *
1867  * Note that for thread safety reasons, this function can only
1868  * be called once.
1869  *
1870  * The application name will be used in contexts such as error messages,
1871  * or when displaying an application's name in the task list.
1872  * 
1873  **/
1874 void
1875 g_set_application_name (const gchar *application_name)
1876 {
1877   gboolean already_set = FALSE;
1878         
1879   G_LOCK (g_application_name);
1880   if (g_application_name)
1881     already_set = TRUE;
1882   else
1883     g_application_name = g_strdup (application_name);
1884   G_UNLOCK (g_application_name);
1885
1886   if (already_set)
1887     g_warning ("g_set_application() name called multiple times");
1888 }
1889
1890 /**
1891  * g_get_user_data_dir:
1892  * 
1893  * Returns a base directory in which to access application data such
1894  * as icons that is customized for a particular user.  
1895  *
1896  * On UNIX platforms this is determined using the mechanisms described in
1897  * the <ulink url="http://www.freedesktop.org/Standards/basedir-spec">
1898  * XDG Base Directory Specification</ulink>
1899  * 
1900  * Return value: a string owned by GLib that must not be modified 
1901  *               or freed.
1902  * Since: 2.6
1903  **/
1904 G_CONST_RETURN gchar*
1905 g_get_user_data_dir (void)
1906 {
1907   gchar *data_dir;  
1908
1909   G_LOCK (g_utils_global);
1910
1911   if (!g_user_data_dir)
1912     {
1913 #ifdef G_OS_WIN32
1914       data_dir = get_special_folder (CSIDL_PERSONAL);
1915 #else
1916       data_dir = (gchar *) g_getenv ("XDG_DATA_HOME");
1917
1918       if (data_dir && data_dir[0])
1919         data_dir = g_strdup (data_dir);
1920 #endif
1921       if (!data_dir || !data_dir[0])
1922         {
1923           if (!g_tmp_dir)
1924             g_get_any_init ();
1925
1926           if (g_home_dir)
1927             data_dir = g_build_filename (g_home_dir, ".local", 
1928                                          "share", NULL);
1929           else
1930             data_dir = g_build_filename (g_tmp_dir, g_user_name, ".local",
1931                                          "share", NULL);
1932         }
1933
1934       g_user_data_dir = data_dir;
1935     }
1936   else
1937     data_dir = g_user_data_dir;
1938
1939   G_UNLOCK (g_utils_global);
1940
1941   return data_dir;
1942 }
1943
1944 /**
1945  * g_get_user_config_dir:
1946  * 
1947  * Returns a base directory in which to store user-specific application 
1948  * configuration information such as user preferences and settings. 
1949  *
1950  * On UNIX platforms this is determined using the mechanisms described in
1951  * the <ulink url="http://www.freedesktop.org/Standards/basedir-spec">
1952  * XDG Base Directory Specification</ulink>
1953  * 
1954  * Return value: a string owned by GLib that must not be modified 
1955  *               or freed.
1956  * Since: 2.6
1957  **/
1958 G_CONST_RETURN gchar*
1959 g_get_user_config_dir (void)
1960 {
1961   gchar *config_dir;  
1962
1963   G_LOCK (g_utils_global);
1964
1965   if (!g_user_config_dir)
1966     {
1967 #ifdef G_OS_WIN32
1968       config_dir = get_special_folder (CSIDL_APPDATA);
1969 #else
1970       config_dir = (gchar *) g_getenv ("XDG_CONFIG_HOME");
1971
1972       if (config_dir && config_dir[0])
1973         config_dir = g_strdup (config_dir);
1974 #endif
1975       if (!config_dir || !config_dir[0])
1976         {
1977           if (!g_tmp_dir)
1978             g_get_any_init ();
1979           
1980           if (g_home_dir)
1981             config_dir = g_build_filename (g_home_dir, ".config", NULL);
1982           else
1983             config_dir = g_build_filename (g_tmp_dir, g_user_name, ".config", NULL);
1984         }
1985       g_user_config_dir = config_dir;
1986     }
1987   else
1988     config_dir = g_user_config_dir;
1989
1990   G_UNLOCK (g_utils_global);
1991
1992   return config_dir;
1993 }
1994
1995 /**
1996  * g_get_user_cache_dir:
1997  * 
1998  * Returns a base directory in which to store non-essential, cached
1999  * data specific to particular user.
2000  *
2001  * On UNIX platforms this is determined using the mechanisms described in
2002  * the <ulink url="http://www.freedesktop.org/Standards/basedir-spec">
2003  * XDG Base Directory Specification</ulink>
2004  * 
2005  * Return value: a string owned by GLib that must not be modified 
2006  *               or freed.
2007  * Since: 2.6
2008  **/
2009 G_CONST_RETURN gchar*
2010 g_get_user_cache_dir (void)
2011 {
2012   gchar *cache_dir;  
2013
2014   G_LOCK (g_utils_global);
2015
2016   if (!g_user_cache_dir)
2017     {
2018 #ifdef G_OS_WIN32
2019       cache_dir = get_special_folder (CSIDL_INTERNET_CACHE); /* XXX correct? */
2020 #else
2021       cache_dir = (gchar *) g_getenv ("XDG_CACHE_HOME");
2022
2023       if (cache_dir && cache_dir[0])
2024           cache_dir = g_strdup (cache_dir);
2025 #endif
2026       if (!cache_dir || !cache_dir[0])
2027         {
2028           if (!g_tmp_dir)
2029             g_get_any_init ();
2030
2031           if (g_home_dir)
2032             cache_dir = g_build_filename (g_home_dir, ".cache", NULL);
2033           else
2034             cache_dir = g_build_filename (g_tmp_dir, g_user_name, ".cache", NULL);
2035         }
2036       g_user_cache_dir = cache_dir;
2037     }
2038   else
2039     cache_dir = g_user_cache_dir;
2040
2041   G_UNLOCK (g_utils_global);
2042
2043   return cache_dir;
2044 }
2045
2046 /**
2047  * g_get_system_data_dirs:
2048  * 
2049  * Returns an ordered list of base directories in which to access 
2050  * system-wide application data.
2051  *
2052  * On UNIX platforms this is determined using the mechanisms described in
2053  * the <ulink url="http://www.freedesktop.org/Standards/basedir-spec">
2054  * XDG Base Directory Specification</ulink>
2055  * 
2056  * Return value: a %NULL-terminated array of strings owned by GLib that must 
2057  *               not be modified or freed.
2058  * Since: 2.6
2059  **/
2060 G_CONST_RETURN gchar * G_CONST_RETURN * 
2061 g_get_system_data_dirs (void)
2062 {
2063   gchar *data_dirs, **data_dir_vector;
2064
2065   G_LOCK (g_utils_global);
2066
2067   if (!g_system_data_dirs)
2068     {
2069 #ifdef G_OS_WIN32
2070       gchar *glib_top_share_dir, *exe_top_share_dir;
2071
2072       /* Documents and Settings\All Users\Application Data */
2073       char *appdata = get_special_folder (CSIDL_COMMON_APPDATA);
2074       /* Documents and Settings\All Users\Documents */
2075       char *docs = get_special_folder (CSIDL_COMMON_DOCUMENTS);
2076       
2077       if (appdata && docs)
2078         {
2079           data_dirs = g_strconcat (appdata,
2080                                    G_SEARCHPATH_SEPARATOR_S,
2081                                    docs,
2082                                    NULL);
2083           g_free (appdata);
2084           g_free (docs);
2085         }
2086       else if (appdata)
2087         data_dirs = appdata;
2088       else if (docs)
2089         data_dirs = docs;
2090       else
2091         data_dirs = g_strdup ("");
2092
2093       /* Using the above subfolders of Documents and Settings perhaps
2094        * makes sense from a Windows perspective.
2095        *
2096        * But looking at the actual use cases of this function in GTK+
2097        * and GNOME software, what we really want is the "share"
2098        * subdirectory of the installation directory for the package
2099        * our caller is a part of.
2100        *
2101        * As we don't know who calls us, punt, and use the installation
2102        * location of GLib, and of the .exe file being run. To guard
2103        * against neither of those being what we really want, callers
2104        * of this function should have Win32-specific code to look up
2105        * their installation folder themselves, and handle a subfolder
2106        * "share" of it in the same way as the folders returned from
2107        * this function.
2108        */
2109       glib_top_share_dir = g_win32_get_package_installation_subdirectory (NULL, dll_name, "share");
2110
2111       if (glib_top_share_dir)
2112         {
2113           gchar *tem = data_dirs;
2114           data_dirs = g_strconcat (data_dirs, G_SEARCHPATH_SEPARATOR_S,
2115                                    glib_top_share_dir, NULL);
2116           g_free (tem);
2117           g_free (glib_top_share_dir);
2118         }
2119
2120       exe_top_share_dir = g_win32_get_package_installation_subdirectory (NULL, NULL, "share");
2121
2122       if (exe_top_share_dir)
2123         {
2124           gchar *tem = data_dirs;
2125           data_dirs = g_strconcat (data_dirs, G_SEARCHPATH_SEPARATOR_S,
2126                                    exe_top_share_dir, NULL);
2127           g_free (tem);
2128           g_free (exe_top_share_dir);
2129         }
2130
2131       data_dir_vector = g_strsplit (data_dirs, G_SEARCHPATH_SEPARATOR_S, 0);
2132       g_free (data_dirs);
2133 #else
2134       data_dirs = (gchar *) g_getenv ("XDG_DATA_DIRS");
2135
2136       if (!data_dirs || !data_dirs[0])
2137           data_dirs = "/usr/local/share/:/usr/share/";
2138
2139       data_dir_vector = g_strsplit (data_dirs, G_SEARCHPATH_SEPARATOR_S, 0);
2140 #endif
2141
2142       g_system_data_dirs = data_dir_vector;
2143     }
2144   else
2145     data_dir_vector = g_system_data_dirs;
2146
2147   G_UNLOCK (g_utils_global);
2148
2149   return (G_CONST_RETURN gchar * G_CONST_RETURN *) data_dir_vector;
2150 }
2151
2152 /**
2153  * g_get_system_config_dirs:
2154  * 
2155  * Returns an ordered list of base directories in which to access 
2156  * system-wide configuration information.
2157  *
2158  * On UNIX platforms this is determined using the mechanisms described in
2159  * the <ulink url="http://www.freedesktop.org/Standards/basedir-spec">
2160  * XDG Base Directory Specification</ulink>
2161  * 
2162  * Return value: a %NULL-terminated array of strings owned by GLib that must 
2163  *               not be modified or freed.
2164  * Since: 2.6
2165  **/
2166 G_CONST_RETURN gchar * G_CONST_RETURN *
2167 g_get_system_config_dirs (void)
2168 {
2169   gchar *conf_dirs, **conf_dir_vector;
2170
2171   G_LOCK (g_utils_global);
2172
2173   if (!g_system_config_dirs)
2174     {
2175 #ifdef G_OS_WIN32
2176       conf_dirs = get_special_folder (CSIDL_COMMON_APPDATA);
2177       if (conf_dirs)
2178         {
2179           conf_dir_vector = g_strsplit (conf_dirs, G_SEARCHPATH_SEPARATOR_S, 0);
2180           g_free (conf_dirs);
2181         }
2182       else
2183         {
2184           /* Return empty list */
2185           conf_dir_vector = g_strsplit ("", G_SEARCHPATH_SEPARATOR_S, 0);
2186         }
2187 #else
2188       conf_dirs = (gchar *) g_getenv ("XDG_CONFIG_DIRS");
2189
2190       if (!conf_dirs || !conf_dirs[0])
2191           conf_dirs = "/etc/xdg";
2192
2193       conf_dir_vector = g_strsplit (conf_dirs, G_SEARCHPATH_SEPARATOR_S, 0);
2194 #endif
2195
2196       g_system_config_dirs = conf_dir_vector;
2197     }
2198   else
2199     conf_dir_vector = g_system_config_dirs;
2200   G_UNLOCK (g_utils_global);
2201
2202   return (G_CONST_RETURN gchar * G_CONST_RETURN *) conf_dir_vector;
2203 }
2204
2205 static GHashTable *alias_table = NULL;
2206
2207 /* read an alias file for the locales */
2208 static void
2209 read_aliases (gchar *file)
2210 {
2211   FILE *fp;
2212   char buf[256];
2213   
2214   if (!alias_table)
2215     alias_table = g_hash_table_new (g_str_hash, g_str_equal);
2216   fp = fopen (file,"r");
2217   if (!fp)
2218     return;
2219   while (fgets (buf, 256, fp))
2220     {
2221       char *p, *q;
2222
2223       g_strstrip (buf);
2224
2225       /* Line is a comment */
2226       if ((buf[0] == '#') || (buf[0] == '\0'))
2227         continue;
2228
2229       /* Reads first column */
2230       for (p = buf, q = NULL; *p; p++) {
2231         if ((*p == '\t') || (*p == ' ') || (*p == ':')) {
2232           *p = '\0';
2233           q = p+1;
2234           while ((*q == '\t') || (*q == ' ')) {
2235             q++;
2236           }
2237           break;
2238         }
2239       }
2240       /* The line only had one column */
2241       if (!q || *q == '\0')
2242         continue;
2243       
2244       /* Read second column */
2245       for (p = q; *p; p++) {
2246         if ((*p == '\t') || (*p == ' ')) {
2247           *p = '\0';
2248           break;
2249         }
2250       }
2251
2252       /* Add to alias table if necessary */
2253       if (!g_hash_table_lookup (alias_table, buf)) {
2254         g_hash_table_insert (alias_table, g_strdup (buf), g_strdup (q));
2255       }
2256     }
2257   fclose (fp);
2258 }
2259
2260 static char *
2261 unalias_lang (char *lang)
2262 {
2263   char *p;
2264   int i;
2265
2266   if (!alias_table)
2267     read_aliases ("/usr/share/locale/locale.alias");
2268
2269   i = 0;
2270   while ((p = g_hash_table_lookup (alias_table, lang)) && (strcmp (p, lang) != 0))
2271     {
2272       lang = p;
2273       if (i++ == 30)
2274         {
2275           static gboolean said_before = FALSE;
2276           if (!said_before)
2277             g_warning ("Too many alias levels for a locale, "
2278                        "may indicate a loop");
2279           said_before = TRUE;
2280           return lang;
2281         }
2282     }
2283   return lang;
2284 }
2285
2286 /* Mask for components of locale spec. The ordering here is from
2287  * least significant to most significant
2288  */
2289 enum
2290 {
2291   COMPONENT_CODESET =   1 << 0,
2292   COMPONENT_TERRITORY = 1 << 1,
2293   COMPONENT_MODIFIER =  1 << 2
2294 };
2295
2296 /* Break an X/Open style locale specification into components
2297  */
2298 static guint
2299 explode_locale (const gchar *locale,
2300                 gchar      **language, 
2301                 gchar      **territory, 
2302                 gchar      **codeset, 
2303                 gchar      **modifier)
2304 {
2305   const gchar *uscore_pos;
2306   const gchar *at_pos;
2307   const gchar *dot_pos;
2308
2309   guint mask = 0;
2310
2311   uscore_pos = strchr (locale, '_');
2312   dot_pos = strchr (uscore_pos ? uscore_pos : locale, '.');
2313   at_pos = strchr (dot_pos ? dot_pos : (uscore_pos ? uscore_pos : locale), '@');
2314
2315   if (at_pos)
2316     {
2317       mask |= COMPONENT_MODIFIER;
2318       *modifier = g_strdup (at_pos);
2319     }
2320   else
2321     at_pos = locale + strlen (locale);
2322
2323   if (dot_pos)
2324     {
2325       mask |= COMPONENT_CODESET;
2326       *codeset = g_strndup (dot_pos, at_pos - dot_pos);
2327     }
2328   else
2329     dot_pos = at_pos;
2330
2331   if (uscore_pos)
2332     {
2333       mask |= COMPONENT_TERRITORY;
2334       *territory = g_strndup (uscore_pos, dot_pos - uscore_pos);
2335     }
2336   else
2337     uscore_pos = dot_pos;
2338
2339   *language = g_strndup (locale, uscore_pos - locale);
2340
2341   return mask;
2342 }
2343
2344 /*
2345  * Compute all interesting variants for a given locale name -
2346  * by stripping off different components of the value.
2347  *
2348  * For simplicity, we assume that the locale is in
2349  * X/Open format: language[_territory][.codeset][@modifier]
2350  *
2351  * TODO: Extend this to handle the CEN format (see the GNUlibc docs)
2352  *       as well. We could just copy the code from glibc wholesale
2353  *       but it is big, ugly, and complicated, so I'm reluctant
2354  *       to do so when this should handle 99% of the time...
2355  */
2356 GSList *
2357 _g_compute_locale_variants (const gchar *locale)
2358 {
2359   GSList *retval = NULL;
2360
2361   gchar *language;
2362   gchar *territory;
2363   gchar *codeset;
2364   gchar *modifier;
2365
2366   guint mask;
2367   guint i;
2368
2369   g_return_val_if_fail (locale != NULL, NULL);
2370
2371   mask = explode_locale (locale, &language, &territory, &codeset, &modifier);
2372
2373   /* Iterate through all possible combinations, from least attractive
2374    * to most attractive.
2375    */
2376   for (i = 0; i <= mask; i++)
2377     if ((i & ~mask) == 0)
2378       {
2379         gchar *val = g_strconcat (language,
2380                                   (i & COMPONENT_TERRITORY) ? territory : "",
2381                                   (i & COMPONENT_CODESET) ? codeset : "",
2382                                   (i & COMPONENT_MODIFIER) ? modifier : "",
2383                                   NULL);
2384         retval = g_slist_prepend (retval, val);
2385       }
2386
2387   g_free (language);
2388   if (mask & COMPONENT_CODESET)
2389     g_free (codeset);
2390   if (mask & COMPONENT_TERRITORY)
2391     g_free (territory);
2392   if (mask & COMPONENT_MODIFIER)
2393     g_free (modifier);
2394
2395   return retval;
2396 }
2397
2398 /* The following is (partly) taken from the gettext package.
2399    Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.  */
2400
2401 static const gchar *
2402 guess_category_value (const gchar *category_name)
2403 {
2404   const gchar *retval;
2405
2406   /* The highest priority value is the `LANGUAGE' environment
2407      variable.  This is a GNU extension.  */
2408   retval = g_getenv ("LANGUAGE");
2409   if ((retval != NULL) && (retval[0] != '\0'))
2410     return retval;
2411
2412   /* `LANGUAGE' is not set.  So we have to proceed with the POSIX
2413      methods of looking to `LC_ALL', `LC_xxx', and `LANG'.  On some
2414      systems this can be done by the `setlocale' function itself.  */
2415
2416   /* Setting of LC_ALL overwrites all other.  */
2417   retval = g_getenv ("LC_ALL");  
2418   if ((retval != NULL) && (retval[0] != '\0'))
2419     return retval;
2420
2421   /* Next comes the name of the desired category.  */
2422   retval = g_getenv (category_name);
2423   if ((retval != NULL) && (retval[0] != '\0'))
2424     return retval;
2425
2426   /* Last possibility is the LANG environment variable.  */
2427   retval = g_getenv ("LANG");
2428   if ((retval != NULL) && (retval[0] != '\0'))
2429     return retval;
2430
2431 #ifdef G_PLATFORM_WIN32
2432   /* g_win32_getlocale() first checks for LC_ALL, LC_MESSAGES and
2433    * LANG, which we already did above. Oh well. The main point of
2434    * calling g_win32_getlocale() is to get the thread's locale as used
2435    * by Windows and the Microsoft C runtime (in the "English_United
2436    * States" format) translated into the Unixish format.
2437    */
2438   retval = g_win32_getlocale ();
2439   if ((retval != NULL) && (retval[0] != '\0'))
2440     return retval;
2441 #endif  
2442
2443   return NULL;
2444 }
2445
2446 typedef struct _GLanguageNamesCache GLanguageNamesCache;
2447
2448 struct _GLanguageNamesCache {
2449   gchar *languages;
2450   gchar **language_names;
2451 };
2452
2453 static void
2454 language_names_cache_free (gpointer data)
2455 {
2456   GLanguageNamesCache *cache = data;
2457   g_free (cache->languages);
2458   g_strfreev (cache->language_names);
2459   g_free (cache);
2460 }
2461
2462 /**
2463  * g_get_language_names:
2464  * 
2465  * Computes a list of applicable locale names, which can be used to 
2466  * e.g. construct locale-dependent filenames or search paths. The returned 
2467  * list is sorted from most desirable to least desirable and always contains 
2468  * the default locale "C".
2469  *
2470  * For example, if LANGUAGE=de:en_US, then the returned list is
2471  * "de", "en_US", "en", "C".
2472  *
2473  * This function consults the environment variables <envar>LANGUAGE</envar>, 
2474  * <envar>LC_ALL</envar>, <envar>LC_MESSAGES</envar> and <envar>LANG</envar> 
2475  * to find the list of locales specified by the user.
2476  * 
2477  * Return value: a %NULL-terminated array of strings owned by GLib 
2478  *    that must not be modified or freed.
2479  *
2480  * Since: 2.6
2481  **/
2482 G_CONST_RETURN gchar * G_CONST_RETURN * 
2483 g_get_language_names (void)
2484 {
2485   static GStaticPrivate cache_private = G_STATIC_PRIVATE_INIT;
2486   GLanguageNamesCache *cache = g_static_private_get (&cache_private);
2487   const gchar *value;
2488
2489   if (!cache)
2490     {
2491       cache = g_new0 (GLanguageNamesCache, 1);
2492       g_static_private_set (&cache_private, cache, language_names_cache_free);
2493     }
2494
2495   value = guess_category_value ("LC_MESSAGES");
2496   if (!value)
2497     value = "C";
2498
2499   if (!(cache->languages && strcmp (cache->languages, value) == 0))
2500     {
2501       gchar **languages;
2502       gchar **alist, **a;
2503       GSList *list, *l;
2504       gint i;
2505
2506       g_free (cache->languages);
2507       g_strfreev (cache->language_names);
2508       cache->languages = g_strdup (value);
2509
2510       alist = g_strsplit (value, ":", 0);
2511       list = NULL;
2512       for (a = alist; *a; a++)
2513         {
2514           gchar *b = unalias_lang (*a);
2515           list = g_slist_concat (list, _g_compute_locale_variants (b));
2516         }
2517       g_strfreev (alist);
2518       list = g_slist_append (list, g_strdup ("C"));
2519
2520       cache->language_names = languages = g_new (gchar *, g_slist_length (list) + 1);
2521       for (l = list, i = 0; l; l = l->next, i++)
2522         languages[i] = l->data;
2523       languages[i] = NULL;
2524
2525       g_slist_free (list);
2526     }
2527
2528   return (G_CONST_RETURN gchar * G_CONST_RETURN *) cache->language_names;
2529 }
2530
2531 /**
2532  * g_direct_hash:
2533  * @v: a #gpointer key
2534  *
2535  * Converts a gpointer to a hash value.
2536  * It can be passed to g_hash_table_new() as the @hash_func parameter, 
2537  * when using pointers as keys in a #GHashTable.
2538  *
2539  * Returns: a hash value corresponding to the key.
2540  */
2541 guint
2542 g_direct_hash (gconstpointer v)
2543 {
2544   return GPOINTER_TO_UINT (v);
2545 }
2546
2547 /**
2548  * g_direct_equal:
2549  * @v1: a key.
2550  * @v2: a key to compare with @v1.
2551  *
2552  * Compares two #gpointer arguments and returns %TRUE if they are equal.
2553  * It can be passed to g_hash_table_new() as the @key_equal_func
2554  * parameter, when using pointers as keys in a #GHashTable.
2555  * 
2556  * Returns: %TRUE if the two keys match.
2557  */
2558 gboolean
2559 g_direct_equal (gconstpointer v1,
2560                 gconstpointer v2)
2561 {
2562   return v1 == v2;
2563 }
2564
2565 /**
2566  * g_int_equal:
2567  * @v1: a pointer to a #gint key.
2568  * @v2: a pointer to a #gint key to compare with @v1.
2569  *
2570  * Compares the two #gint values being pointed to and returns 
2571  * %TRUE if they are equal.
2572  * It can be passed to g_hash_table_new() as the @key_equal_func
2573  * parameter, when using pointers to integers as keys in a #GHashTable.
2574  * 
2575  * Returns: %TRUE if the two keys match.
2576  */
2577 gboolean
2578 g_int_equal (gconstpointer v1,
2579              gconstpointer v2)
2580 {
2581   return *((const gint*) v1) == *((const gint*) v2);
2582 }
2583
2584 /**
2585  * g_int_hash:
2586  * @v: a pointer to a #gint key
2587  *
2588  * Converts a pointer to a #gint to a hash value.
2589  * It can be passed to g_hash_table_new() as the @hash_func parameter, 
2590  * when using pointers to integers values as keys in a #GHashTable.
2591  *
2592  * Returns: a hash value corresponding to the key.
2593  */
2594 guint
2595 g_int_hash (gconstpointer v)
2596 {
2597   return *(const gint*) v;
2598 }
2599
2600 /**
2601  * g_nullify_pointer:
2602  * @nullify_location: the memory address of the pointer.
2603  * 
2604  * Set the pointer at the specified location to %NULL.
2605  **/
2606 void
2607 g_nullify_pointer (gpointer *nullify_location)
2608 {
2609   g_return_if_fail (nullify_location != NULL);
2610
2611   *nullify_location = NULL;
2612 }
2613
2614 /**
2615  * g_get_codeset:
2616  * 
2617  * Get the codeset for the current locale.
2618  * 
2619  * Return value: a newly allocated string containing the name
2620  * of the codeset. This string must be freed with g_free().
2621  **/
2622 gchar *
2623 g_get_codeset (void)
2624 {
2625   const gchar *charset;
2626
2627   g_get_charset (&charset);
2628
2629   return g_strdup (charset);
2630 }
2631
2632 /* This is called from g_thread_init(). It's used to
2633  * initialize some static data in a threadsafe way.
2634  */
2635 void
2636 _g_utils_thread_init (void)
2637 {
2638   g_get_language_names ();
2639 }
2640
2641 #ifdef ENABLE_NLS
2642
2643 #include <libintl.h>
2644
2645 #ifdef G_PLATFORM_WIN32
2646
2647 static const gchar *
2648 _glib_get_locale_dir (void)
2649 {
2650   static const gchar *cache = NULL;
2651   if (cache == NULL)
2652     cache = g_win32_get_package_installation_subdirectory
2653       (GETTEXT_PACKAGE, dll_name, "lib\\locale");
2654
2655   return cache;
2656 }
2657
2658 #undef GLIB_LOCALE_DIR
2659 #define GLIB_LOCALE_DIR _glib_get_locale_dir ()
2660
2661 #endif /* G_PLATFORM_WIN32 */
2662
2663 G_CONST_RETURN gchar *
2664 _glib_gettext (const gchar *str)
2665 {
2666   static gboolean _glib_gettext_initialized = FALSE;
2667
2668   if (!_glib_gettext_initialized)
2669     {
2670       bindtextdomain(GETTEXT_PACKAGE, GLIB_LOCALE_DIR);
2671 #    ifdef HAVE_BIND_TEXTDOMAIN_CODESET
2672       bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
2673 #    endif
2674       _glib_gettext_initialized = TRUE;
2675     }
2676   
2677   return dgettext (GETTEXT_PACKAGE, str);
2678 }
2679
2680 #endif /* ENABLE_NLS */
2681
2682 #ifdef G_OS_WIN32
2683
2684 /* Binary compatibility versions. Not for newly compiled code. */
2685
2686 #undef g_find_program_in_path
2687
2688 gchar*
2689 g_find_program_in_path (const gchar *program)
2690 {
2691   gchar *utf8_program = g_locale_to_utf8 (program, -1, NULL, NULL, NULL);
2692   gchar *utf8_retval = g_find_program_in_path_utf8 (utf8_program);
2693   gchar *retval;
2694
2695   g_free (utf8_program);
2696   if (utf8_retval == NULL)
2697     return NULL;
2698   retval = g_locale_from_utf8 (utf8_retval, -1, NULL, NULL, NULL);
2699   g_free (utf8_retval);
2700
2701   return retval;
2702 }
2703
2704 #undef g_get_current_dir
2705
2706 gchar*
2707 g_get_current_dir (void)
2708 {
2709   gchar *utf8_dir = g_get_current_dir_utf8 ();
2710   gchar *dir = g_locale_from_utf8 (utf8_dir, -1, NULL, NULL, NULL);
2711   g_free (utf8_dir);
2712   return dir;
2713 }
2714
2715 #undef g_getenv
2716
2717 G_CONST_RETURN gchar*
2718 g_getenv (const gchar *variable)
2719 {
2720   gchar *utf8_variable = g_locale_to_utf8 (variable, -1, NULL, NULL, NULL);
2721   const gchar *utf8_value = g_getenv_utf8 (utf8_variable);
2722   gchar *value;
2723   GQuark quark;
2724
2725   g_free (utf8_variable);
2726   if (!utf8_value)
2727     return NULL;
2728   value = g_locale_from_utf8 (utf8_value, -1, NULL, NULL, NULL);
2729   quark = g_quark_from_string (value);
2730   g_free (value);
2731
2732   return g_quark_to_string (quark);
2733 }
2734
2735 #undef g_setenv
2736
2737 gboolean
2738 g_setenv (const gchar *variable, 
2739           const gchar *value, 
2740           gboolean     overwrite)
2741 {
2742   gchar *utf8_variable = g_locale_to_utf8 (variable, -1, NULL, NULL, NULL);
2743   gchar *utf8_value = g_locale_to_utf8 (value, -1, NULL, NULL, NULL);
2744   gboolean retval = g_setenv_utf8 (utf8_variable, utf8_value, overwrite);
2745
2746   g_free (utf8_variable);
2747   g_free (utf8_value);
2748
2749   return retval;
2750 }
2751
2752 #undef g_unsetenv
2753
2754 void
2755 g_unsetenv (const gchar *variable)
2756 {
2757   gchar *utf8_variable = g_locale_to_utf8 (variable, -1, NULL, NULL, NULL);
2758
2759   g_unsetenv_utf8 (utf8_variable);
2760
2761   g_free (utf8_variable);
2762 }
2763
2764 #undef g_get_user_name
2765
2766 G_CONST_RETURN gchar*
2767 g_get_user_name (void)
2768 {
2769   G_LOCK (g_utils_global);
2770   if (!g_tmp_dir)
2771     g_get_any_init ();
2772   G_UNLOCK (g_utils_global);
2773   
2774   return g_user_name_cp;
2775 }
2776
2777 #undef g_get_real_name
2778
2779 G_CONST_RETURN gchar*
2780 g_get_real_name (void)
2781 {
2782   G_LOCK (g_utils_global);
2783   if (!g_tmp_dir)
2784     g_get_any_init ();
2785   G_UNLOCK (g_utils_global);
2786  
2787   return g_real_name_cp;
2788 }
2789
2790 #undef g_get_home_dir
2791
2792 G_CONST_RETURN gchar*
2793 g_get_home_dir (void)
2794 {
2795   G_LOCK (g_utils_global);
2796   if (!g_tmp_dir)
2797     g_get_any_init ();
2798   G_UNLOCK (g_utils_global);
2799
2800   return g_home_dir_cp;
2801 }
2802
2803 #undef g_get_tmp_dir
2804
2805 G_CONST_RETURN gchar*
2806 g_get_tmp_dir (void)
2807 {
2808   G_LOCK (g_utils_global);
2809   if (!g_tmp_dir)
2810     g_get_any_init ();
2811   G_UNLOCK (g_utils_global);
2812
2813   return g_tmp_dir_cp;
2814 }
2815
2816 #endif
2817
2818 #define __G_UTILS_C__
2819 #include "galiasdef.c"