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