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