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