Imported Upstream version 2.67.2
[platform/upstream/glib.git] / glib / gutils.c
1 /* GLIB - Library of useful routines for C programming
2  * Copyright (C) 1995-1998  Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 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, see <http://www.gnu.org/licenses/>.
16  */
17
18 /*
19  * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
20  * file for a list of people on the GLib Team.  See the ChangeLog
21  * files for a list of changes.  These files are distributed with
22  * GLib at ftp://ftp.gtk.org/pub/gtk/. 
23  */
24
25 /* 
26  * MT safe for the unix part, FIXME: make the win32 part MT safe as well.
27  */
28
29 #include "config.h"
30
31 #include "gutils.h"
32 #include "gutilsprivate.h"
33
34 #include <stdarg.h>
35 #include <stdlib.h>
36 #include <stdio.h>
37 #include <locale.h>
38 #include <string.h>
39 #include <ctype.h>              /* For tolower() */
40 #include <errno.h>
41 #include <sys/types.h>
42 #include <sys/stat.h>
43 #ifdef G_OS_UNIX
44 #include <pwd.h>
45 #include <sys/utsname.h>
46 #include <unistd.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 #ifdef HAVE_SYS_AUXV_H
56 #include <sys/auxv.h>
57 #endif
58
59 #include "glib-init.h"
60 #include "glib-private.h"
61 #include "genviron.h"
62 #include "gfileutils.h"
63 #include "ggettext.h"
64 #include "ghash.h"
65 #include "gthread.h"
66 #include "gtestutils.h"
67 #include "gunicode.h"
68 #include "gstrfuncs.h"
69 #include "garray.h"
70 #include "glibintl.h"
71 #include "gstdio.h"
72
73 #ifdef G_PLATFORM_WIN32
74 #include "gconvert.h"
75 #include "gwin32.h"
76 #endif
77
78
79 /**
80  * SECTION:misc_utils
81  * @title: Miscellaneous Utility Functions
82  * @short_description: a selection of portable utility functions
83  *
84  * These are portable utility functions.
85  */
86
87 #ifdef G_PLATFORM_WIN32
88 #  include <windows.h>
89 #  ifndef GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
90 #    define GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT 2
91 #    define GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS 4
92 #  endif
93 #  include <lmcons.h>           /* For UNLEN */
94 #endif /* G_PLATFORM_WIN32 */
95
96 #ifdef G_OS_WIN32
97 #  include <direct.h>
98 #  include <shlobj.h>
99 #  include <process.h>
100 #endif
101
102 #ifdef HAVE_CODESET
103 #include <langinfo.h>
104 #endif
105
106 #ifdef G_PLATFORM_WIN32
107
108 gchar *
109 _glib_get_dll_directory (void)
110 {
111   gchar *retval;
112   gchar *p;
113   wchar_t wc_fn[MAX_PATH];
114
115 #ifdef DLL_EXPORT
116   if (glib_dll == NULL)
117     return NULL;
118 #endif
119
120   /* This code is different from that in
121    * g_win32_get_package_installation_directory_of_module() in that
122    * here we return the actual folder where the GLib DLL is. We don't
123    * do the check for it being in a "bin" or "lib" subfolder and then
124    * returning the parent of that.
125    *
126    * In a statically built GLib, glib_dll will be NULL and we will
127    * thus look up the application's .exe file's location.
128    */
129   if (!GetModuleFileNameW (glib_dll, wc_fn, MAX_PATH))
130     return NULL;
131
132   retval = g_utf16_to_utf8 (wc_fn, -1, NULL, NULL, NULL);
133
134   p = strrchr (retval, G_DIR_SEPARATOR);
135   if (p == NULL)
136     {
137       /* Wtf? */
138       return NULL;
139     }
140   *p = '\0';
141
142   return retval;
143 }
144
145 #endif
146
147 /**
148  * g_memmove: 
149  * @dest: the destination address to copy the bytes to.
150  * @src: the source address to copy the bytes from.
151  * @len: the number of bytes to copy.
152  *
153  * Copies a block of memory @len bytes long, from @src to @dest.
154  * The source and destination areas may overlap.
155  *
156  * Deprecated:2.40: Just use memmove().
157  */
158
159 #ifdef G_OS_WIN32
160 #undef g_atexit
161 #endif
162
163 /**
164  * g_atexit:
165  * @func: (scope async): the function to call on normal program termination.
166  * 
167  * Specifies a function to be called at normal program termination.
168  *
169  * Since GLib 2.8.2, on Windows g_atexit() actually is a preprocessor
170  * macro that maps to a call to the atexit() function in the C
171  * library. This means that in case the code that calls g_atexit(),
172  * i.e. atexit(), is in a DLL, the function will be called when the
173  * DLL is detached from the program. This typically makes more sense
174  * than that the function is called when the GLib DLL is detached,
175  * which happened earlier when g_atexit() was a function in the GLib
176  * DLL.
177  *
178  * The behaviour of atexit() in the context of dynamically loaded
179  * modules is not formally specified and varies wildly.
180  *
181  * On POSIX systems, calling g_atexit() (or atexit()) in a dynamically
182  * loaded module which is unloaded before the program terminates might
183  * well cause a crash at program exit.
184  *
185  * Some POSIX systems implement atexit() like Windows, and have each
186  * dynamically loaded module maintain an own atexit chain that is
187  * called when the module is unloaded.
188  *
189  * On other POSIX systems, before a dynamically loaded module is
190  * unloaded, the registered atexit functions (if any) residing in that
191  * module are called, regardless where the code that registered them
192  * resided. This is presumably the most robust approach.
193  *
194  * As can be seen from the above, for portability it's best to avoid
195  * calling g_atexit() (or atexit()) except in the main executable of a
196  * program.
197  *
198  * Deprecated:2.32: It is best to avoid g_atexit().
199  */
200 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
201 void
202 g_atexit (GVoidFunc func)
203 {
204   gint result;
205   int errsv;
206
207   result = atexit ((void (*)(void)) func);
208   errsv = errno;
209   if (result)
210     {
211       g_error ("Could not register atexit() function: %s",
212                g_strerror (errsv));
213     }
214 }
215 G_GNUC_END_IGNORE_DEPRECATIONS
216
217 /* Based on execvp() from GNU Libc.
218  * Some of this code is cut-and-pasted into gspawn.c
219  */
220
221 static gchar*
222 my_strchrnul (const gchar *str, 
223               gchar        c)
224 {
225   gchar *p = (gchar*)str;
226   while (*p && (*p != c))
227     ++p;
228
229   return p;
230 }
231
232 #ifdef G_OS_WIN32
233
234 static gchar *inner_find_program_in_path (const gchar *program);
235
236 gchar*
237 g_find_program_in_path (const gchar *program)
238 {
239   const gchar *last_dot = strrchr (program, '.');
240
241   if (last_dot == NULL ||
242       strchr (last_dot, '\\') != NULL ||
243       strchr (last_dot, '/') != NULL)
244     {
245       const gint program_length = strlen (program);
246       gchar *pathext = g_build_path (";",
247                                      ".exe;.cmd;.bat;.com",
248                                      g_getenv ("PATHEXT"),
249                                      NULL);
250       gchar *p;
251       gchar *decorated_program;
252       gchar *retval;
253
254       p = pathext;
255       do
256         {
257           gchar *q = my_strchrnul (p, ';');
258
259           decorated_program = g_malloc (program_length + (q-p) + 1);
260           memcpy (decorated_program, program, program_length);
261           memcpy (decorated_program+program_length, p, q-p);
262           decorated_program [program_length + (q-p)] = '\0';
263           
264           retval = inner_find_program_in_path (decorated_program);
265           g_free (decorated_program);
266
267           if (retval != NULL)
268             {
269               g_free (pathext);
270               return retval;
271             }
272           p = q;
273         } while (*p++ != '\0');
274       g_free (pathext);
275       return NULL;
276     }
277   else
278     return inner_find_program_in_path (program);
279 }
280
281 #endif
282
283 /**
284  * g_find_program_in_path:
285  * @program: (type filename): a program name in the GLib file name encoding
286  * 
287  * Locates the first executable named @program in the user's path, in the
288  * same way that execvp() would locate it. Returns an allocated string
289  * with the absolute path name, or %NULL if the program is not found in
290  * the path. If @program is already an absolute path, returns a copy of
291  * @program if @program exists and is executable, and %NULL otherwise.
292  *  
293  * On Windows, if @program does not have a file type suffix, tries
294  * with the suffixes .exe, .cmd, .bat and .com, and the suffixes in
295  * the `PATHEXT` environment variable. 
296  * 
297  * On Windows, it looks for the file in the same way as CreateProcess() 
298  * would. This means first in the directory where the executing
299  * program was loaded from, then in the current directory, then in the
300  * Windows 32-bit system directory, then in the Windows directory, and
301  * finally in the directories in the `PATH` environment variable. If
302  * the program is found, the return value contains the full name
303  * including the type suffix.
304  *
305  * Returns: (type filename) (transfer full) (nullable): a newly-allocated
306  *   string with the absolute path, or %NULL
307  **/
308 #ifdef G_OS_WIN32
309 static gchar *
310 inner_find_program_in_path (const gchar *program)
311 #else
312 gchar*
313 g_find_program_in_path (const gchar *program)
314 #endif
315 {
316   const gchar *path, *p;
317   gchar *name, *freeme;
318 #ifdef G_OS_WIN32
319   const gchar *path_copy;
320   gchar *filename = NULL, *appdir = NULL;
321   gchar *sysdir = NULL, *windir = NULL;
322   int n;
323   wchar_t wfilename[MAXPATHLEN], wsysdir[MAXPATHLEN],
324     wwindir[MAXPATHLEN];
325 #endif
326   gsize len;
327   gsize pathlen;
328
329   g_return_val_if_fail (program != NULL, NULL);
330
331   /* If it is an absolute path, or a relative path including subdirectories,
332    * don't look in PATH.
333    */
334   if (g_path_is_absolute (program)
335       || strchr (program, G_DIR_SEPARATOR) != NULL
336 #ifdef G_OS_WIN32
337       || strchr (program, '/') != NULL
338 #endif
339       )
340     {
341       if (g_file_test (program, G_FILE_TEST_IS_EXECUTABLE) &&
342           !g_file_test (program, G_FILE_TEST_IS_DIR))
343         return g_strdup (program);
344       else
345         return NULL;
346     }
347   
348   path = g_getenv ("PATH");
349 #if defined(G_OS_UNIX)
350   if (path == NULL)
351     {
352       /* There is no 'PATH' in the environment.  The default
353        * search path in GNU libc is the current directory followed by
354        * the path 'confstr' returns for '_CS_PATH'.
355        */
356       
357       /* In GLib we put . last, for security, and don't use the
358        * unportable confstr(); UNIX98 does not actually specify
359        * what to search if PATH is unset. POSIX may, dunno.
360        */
361       
362       path = "/bin:/usr/bin:.";
363     }
364 #else
365   n = GetModuleFileNameW (NULL, wfilename, MAXPATHLEN);
366   if (n > 0 && n < MAXPATHLEN)
367     filename = g_utf16_to_utf8 (wfilename, -1, NULL, NULL, NULL);
368   
369   n = GetSystemDirectoryW (wsysdir, MAXPATHLEN);
370   if (n > 0 && n < MAXPATHLEN)
371     sysdir = g_utf16_to_utf8 (wsysdir, -1, NULL, NULL, NULL);
372   
373   n = GetWindowsDirectoryW (wwindir, MAXPATHLEN);
374   if (n > 0 && n < MAXPATHLEN)
375     windir = g_utf16_to_utf8 (wwindir, -1, NULL, NULL, NULL);
376   
377   if (filename)
378     {
379       appdir = g_path_get_dirname (filename);
380       g_free (filename);
381     }
382   
383   path = g_strdup (path);
384
385   if (windir)
386     {
387       const gchar *tem = path;
388       path = g_strconcat (windir, ";", path, NULL);
389       g_free ((gchar *) tem);
390       g_free (windir);
391     }
392   
393   if (sysdir)
394     {
395       const gchar *tem = path;
396       path = g_strconcat (sysdir, ";", path, NULL);
397       g_free ((gchar *) tem);
398       g_free (sysdir);
399     }
400   
401   {
402     const gchar *tem = path;
403     path = g_strconcat (".;", path, NULL);
404     g_free ((gchar *) tem);
405   }
406   
407   if (appdir)
408     {
409       const gchar *tem = path;
410       path = g_strconcat (appdir, ";", path, NULL);
411       g_free ((gchar *) tem);
412       g_free (appdir);
413     }
414
415   path_copy = path;
416 #endif
417   
418   len = strlen (program) + 1;
419   pathlen = strlen (path);
420   freeme = name = g_malloc (pathlen + len + 1);
421   
422   /* Copy the file name at the top, including '\0'  */
423   memcpy (name + pathlen + 1, program, len);
424   name = name + pathlen;
425   /* And add the slash before the filename  */
426   *name = G_DIR_SEPARATOR;
427   
428   p = path;
429   do
430     {
431       char *startp;
432
433       path = p;
434       p = my_strchrnul (path, G_SEARCHPATH_SEPARATOR);
435
436       if (p == path)
437         /* Two adjacent colons, or a colon at the beginning or the end
438          * of 'PATH' means to search the current directory.
439          */
440         startp = name + 1;
441       else
442         startp = memcpy (name - (p - path), path, p - path);
443
444       if (g_file_test (startp, G_FILE_TEST_IS_EXECUTABLE) &&
445           !g_file_test (startp, G_FILE_TEST_IS_DIR))
446         {
447           gchar *ret;
448           ret = g_strdup (startp);
449           g_free (freeme);
450 #ifdef G_OS_WIN32
451           g_free ((gchar *) path_copy);
452 #endif
453           return ret;
454         }
455     }
456   while (*p++ != '\0');
457   
458   g_free (freeme);
459 #ifdef G_OS_WIN32
460   g_free ((gchar *) path_copy);
461 #endif
462
463   return NULL;
464 }
465
466 /* The functions below are defined this way for compatibility reasons.
467  * See the note in gutils.h.
468  */
469
470 /**
471  * g_bit_nth_lsf:
472  * @mask: a #gulong containing flags
473  * @nth_bit: the index of the bit to start the search from
474  *
475  * Find the position of the first bit set in @mask, searching
476  * from (but not including) @nth_bit upwards. Bits are numbered
477  * from 0 (least significant) to sizeof(#gulong) * 8 - 1 (31 or 63,
478  * usually). To start searching from the 0th bit, set @nth_bit to -1.
479  *
480  * Returns: the index of the first bit set which is higher than @nth_bit, or -1
481  *    if no higher bits are set
482  */
483 gint
484 (g_bit_nth_lsf) (gulong mask,
485                  gint   nth_bit)
486 {
487   return g_bit_nth_lsf_impl (mask, nth_bit);
488 }
489
490 /**
491  * g_bit_nth_msf:
492  * @mask: a #gulong containing flags
493  * @nth_bit: the index of the bit to start the search from
494  *
495  * Find the position of the first bit set in @mask, searching
496  * from (but not including) @nth_bit downwards. Bits are numbered
497  * from 0 (least significant) to sizeof(#gulong) * 8 - 1 (31 or 63,
498  * usually). To start searching from the last bit, set @nth_bit to
499  * -1 or GLIB_SIZEOF_LONG * 8.
500  *
501  * Returns: the index of the first bit set which is lower than @nth_bit, or -1
502  *    if no lower bits are set
503  */
504 gint
505 (g_bit_nth_msf) (gulong mask,
506                  gint   nth_bit)
507 {
508   return g_bit_nth_msf_impl (mask, nth_bit);
509 }
510
511
512 /**
513  * g_bit_storage:
514  * @number: a #guint
515  *
516  * Gets the number of bits used to hold @number,
517  * e.g. if @number is 4, 3 bits are needed.
518  *
519  * Returns: the number of bits used to hold @number
520  */
521 guint
522 (g_bit_storage) (gulong number)
523 {
524   return g_bit_storage_impl (number);
525 }
526
527 G_LOCK_DEFINE_STATIC (g_utils_global);
528
529 typedef struct
530 {
531   gchar *user_name;
532   gchar *real_name;
533   gchar *home_dir;
534 } UserDatabaseEntry;
535
536 /* These must all be read/written with @g_utils_global held. */
537 static  gchar   *g_user_data_dir = NULL;
538 static  gchar  **g_system_data_dirs = NULL;
539 static  gchar   *g_user_cache_dir = NULL;
540 static  gchar   *g_user_config_dir = NULL;
541 static  gchar   *g_user_runtime_dir = NULL;
542 static  gchar  **g_system_config_dirs = NULL;
543 static  gchar  **g_user_special_dirs = NULL;
544
545 /* fifteen minutes of fame for everybody */
546 #define G_USER_DIRS_EXPIRE      15 * 60
547
548 #ifdef G_OS_WIN32
549
550 static gchar *
551 get_special_folder (int csidl)
552 {
553   wchar_t path[MAX_PATH+1];
554   HRESULT hr;
555   LPITEMIDLIST pidl = NULL;
556   BOOL b;
557   gchar *retval = NULL;
558
559   hr = SHGetSpecialFolderLocation (NULL, csidl, &pidl);
560   if (hr == S_OK)
561     {
562       b = SHGetPathFromIDListW (pidl, path);
563       if (b)
564         retval = g_utf16_to_utf8 (path, -1, NULL, NULL, NULL);
565       CoTaskMemFree (pidl);
566     }
567   return retval;
568 }
569
570 static char *
571 get_windows_directory_root (void)
572 {
573   wchar_t wwindowsdir[MAX_PATH];
574
575   if (GetWindowsDirectoryW (wwindowsdir, G_N_ELEMENTS (wwindowsdir)))
576     {
577       /* Usually X:\Windows, but in terminal server environments
578        * might be an UNC path, AFAIK.
579        */
580       char *windowsdir = g_utf16_to_utf8 (wwindowsdir, -1, NULL, NULL, NULL);
581       char *p;
582
583       if (windowsdir == NULL)
584         return g_strdup ("C:\\");
585
586       p = (char *) g_path_skip_root (windowsdir);
587       if (G_IS_DIR_SEPARATOR (p[-1]) && p[-2] != ':')
588         p--;
589       *p = '\0';
590       return windowsdir;
591     }
592   else
593     return g_strdup ("C:\\");
594 }
595
596 #endif
597
598 /* HOLDS: g_utils_global_lock */
599 static UserDatabaseEntry *
600 g_get_user_database_entry (void)
601 {
602   static UserDatabaseEntry *entry;
603
604   if (g_once_init_enter (&entry))
605     {
606       static UserDatabaseEntry e;
607
608 #ifdef G_OS_UNIX
609       {
610         struct passwd *pw = NULL;
611         gpointer buffer = NULL;
612         gint error;
613         gchar *logname;
614
615 #  if defined (HAVE_GETPWUID_R)
616         struct passwd pwd;
617 #    ifdef _SC_GETPW_R_SIZE_MAX
618         /* This reurns the maximum length */
619         glong bufsize = sysconf (_SC_GETPW_R_SIZE_MAX);
620
621         if (bufsize < 0)
622           bufsize = 64;
623 #    else /* _SC_GETPW_R_SIZE_MAX */
624         glong bufsize = 64;
625 #    endif /* _SC_GETPW_R_SIZE_MAX */
626
627         logname = (gchar *) g_getenv ("LOGNAME");
628
629         do
630           {
631             g_free (buffer);
632             /* we allocate 6 extra bytes to work around a bug in
633              * Mac OS < 10.3. See #156446
634              */
635             buffer = g_malloc (bufsize + 6);
636             errno = 0;
637
638             if (logname) {
639               error = getpwnam_r (logname, &pwd, buffer, bufsize, &pw);
640               if (!pw || (pw->pw_uid != getuid ())) {
641                 /* LOGNAME is lying, fall back to looking up the uid */
642                 error = getpwuid_r (getuid (), &pwd, buffer, bufsize, &pw);
643               }
644             } else {
645               error = getpwuid_r (getuid (), &pwd, buffer, bufsize, &pw);
646             }
647             error = error < 0 ? errno : error;
648
649             if (!pw)
650               {
651                 /* we bail out prematurely if the user id can't be found
652                  * (should be pretty rare case actually), or if the buffer
653                  * should be sufficiently big and lookups are still not
654                  * successful.
655                  */
656                 if (error == 0 || error == ENOENT)
657                   {
658                     g_warning ("getpwuid_r(): failed due to unknown user id (%lu)",
659                                (gulong) getuid ());
660                     break;
661                   }
662                 if (bufsize > 32 * 1024)
663                   {
664                     g_warning ("getpwuid_r(): failed due to: %s.",
665                                g_strerror (error));
666                     break;
667                   }
668
669                 bufsize *= 2;
670               }
671           }
672         while (!pw);
673 #  endif /* HAVE_GETPWUID_R */
674
675         if (!pw)
676           {
677             pw = getpwuid (getuid ());
678           }
679         if (pw)
680           {
681             e.user_name = g_strdup (pw->pw_name);
682
683 #ifndef __BIONIC__
684             if (pw->pw_gecos && *pw->pw_gecos != '\0' && pw->pw_name)
685               {
686                 gchar **gecos_fields;
687                 gchar **name_parts;
688
689                 /* split the gecos field and substitute '&' */
690                 gecos_fields = g_strsplit (pw->pw_gecos, ",", 0);
691                 name_parts = g_strsplit (gecos_fields[0], "&", 0);
692                 pw->pw_name[0] = g_ascii_toupper (pw->pw_name[0]);
693                 e.real_name = g_strjoinv (pw->pw_name, name_parts);
694                 g_strfreev (gecos_fields);
695                 g_strfreev (name_parts);
696               }
697 #endif
698
699             if (!e.home_dir)
700               e.home_dir = g_strdup (pw->pw_dir);
701           }
702         g_free (buffer);
703       }
704
705 #endif /* G_OS_UNIX */
706
707 #ifdef G_OS_WIN32
708       {
709         guint len = UNLEN+1;
710         wchar_t buffer[UNLEN+1];
711
712         if (GetUserNameW (buffer, (LPDWORD) &len))
713           {
714             e.user_name = g_utf16_to_utf8 (buffer, -1, NULL, NULL, NULL);
715             e.real_name = g_strdup (e.user_name);
716           }
717       }
718 #endif /* G_OS_WIN32 */
719
720       if (!e.user_name)
721         e.user_name = g_strdup ("somebody");
722       if (!e.real_name)
723         e.real_name = g_strdup ("Unknown");
724
725       g_once_init_leave (&entry, &e);
726     }
727
728   return entry;
729 }
730
731 /**
732  * g_get_user_name:
733  *
734  * Gets the user name of the current user. The encoding of the returned
735  * string is system-defined. On UNIX, it might be the preferred file name
736  * encoding, or something else, and there is no guarantee that it is even
737  * consistent on a machine. On Windows, it is always UTF-8.
738  *
739  * Returns: (type filename) (transfer none): the user name of the current user.
740  */
741 const gchar *
742 g_get_user_name (void)
743 {
744   UserDatabaseEntry *entry;
745
746   entry = g_get_user_database_entry ();
747
748   return entry->user_name;
749 }
750
751 /**
752  * g_get_real_name:
753  *
754  * Gets the real name of the user. This usually comes from the user's
755  * entry in the `passwd` file. The encoding of the returned string is
756  * system-defined. (On Windows, it is, however, always UTF-8.) If the
757  * real user name cannot be determined, the string "Unknown" is 
758  * returned.
759  *
760  * Returns: (type filename) (transfer none): the user's real name.
761  */
762 const gchar *
763 g_get_real_name (void)
764 {
765   UserDatabaseEntry *entry;
766
767   entry = g_get_user_database_entry ();
768
769   return entry->real_name;
770 }
771
772 /* Protected by @g_utils_global_lock. */
773 static gchar *g_home_dir = NULL;  /* (owned) (nullable before initialised) */
774
775 static gchar *
776 g_build_home_dir (void)
777 {
778   gchar *home_dir;
779
780   /* We first check HOME and use it if it is set */
781   home_dir = g_strdup (g_getenv ("HOME"));
782
783 #ifdef G_OS_WIN32
784   /* Only believe HOME if it is an absolute path and exists.
785    *
786    * We only do this check on Windows for a couple of reasons.
787    * Historically, we only did it there because we used to ignore $HOME
788    * on UNIX.  There are concerns about enabling it now on UNIX because
789    * of things like autofs.  In short, if the user has a bogus value in
790    * $HOME then they get what they pay for...
791    */
792   if (home_dir != NULL)
793     {
794       if (!(g_path_is_absolute (home_dir) &&
795             g_file_test (home_dir, G_FILE_TEST_IS_DIR)))
796         g_clear_pointer (&home_dir, g_free);
797     }
798
799   /* In case HOME is Unix-style (it happens), convert it to
800    * Windows style.
801    */
802   if (home_dir != NULL)
803     {
804       gchar *p;
805       while ((p = strchr (home_dir, '/')) != NULL)
806         *p = '\\';
807     }
808
809   if (home_dir == NULL)
810     {
811       /* USERPROFILE is probably the closest equivalent to $HOME? */
812       if (g_getenv ("USERPROFILE") != NULL)
813         home_dir = g_strdup (g_getenv ("USERPROFILE"));
814     }
815
816   if (home_dir == NULL)
817     home_dir = get_special_folder (CSIDL_PROFILE);
818
819   if (home_dir == NULL)
820     home_dir = get_windows_directory_root ();
821 #endif /* G_OS_WIN32 */
822
823   if (home_dir == NULL)
824     {
825       /* If we didn't get it from any of those methods, we will have
826        * to read the user database entry.
827        */
828       UserDatabaseEntry *entry = g_get_user_database_entry ();
829       home_dir = g_strdup (entry->home_dir);
830     }
831
832   /* If we have been denied access to /etc/passwd (for example, by an
833    * overly-zealous LSM), make up a junk value. The return value at this
834    * point is explicitly documented as â€˜undefined’. */
835   if (home_dir == NULL)
836     {
837       g_warning ("Could not find home directory: $HOME is not set, and "
838                  "user database could not be read.");
839       home_dir = g_strdup ("/");
840     }
841
842   return g_steal_pointer (&home_dir);
843 }
844
845 /**
846  * g_get_home_dir:
847  *
848  * Gets the current user's home directory.
849  *
850  * As with most UNIX tools, this function will return the value of the
851  * `HOME` environment variable if it is set to an existing absolute path
852  * name, falling back to the `passwd` file in the case that it is unset.
853  *
854  * If the path given in `HOME` is non-absolute, does not exist, or is
855  * not a directory, the result is undefined.
856  *
857  * Before version 2.36 this function would ignore the `HOME` environment
858  * variable, taking the value from the `passwd` database instead. This was
859  * changed to increase the compatibility of GLib with other programs (and
860  * the XDG basedir specification) and to increase testability of programs
861  * based on GLib (by making it easier to run them from test frameworks).
862  *
863  * If your program has a strong requirement for either the new or the
864  * old behaviour (and if you don't wish to increase your GLib
865  * dependency to ensure that the new behaviour is in effect) then you
866  * should either directly check the `HOME` environment variable yourself
867  * or unset it before calling any functions in GLib.
868  *
869  * Returns: (type filename) (transfer none): the current user's home directory
870  */
871 const gchar *
872 g_get_home_dir (void)
873 {
874   const gchar *home_dir;
875
876   G_LOCK (g_utils_global);
877
878   if (g_home_dir == NULL)
879     g_home_dir = g_build_home_dir ();
880   home_dir = g_home_dir;
881
882   G_UNLOCK (g_utils_global);
883
884   return home_dir;
885 }
886
887 /**
888  * g_get_tmp_dir:
889  *
890  * Gets the directory to use for temporary files.
891  *
892  * On UNIX, this is taken from the `TMPDIR` environment variable.
893  * If the variable is not set, `P_tmpdir` is
894  * used, as defined by the system C library. Failing that, a
895  * hard-coded default of "/tmp" is returned.
896  *
897  * On Windows, the `TEMP` environment variable is used, with the
898  * root directory of the Windows installation (eg: "C:\") used
899  * as a default.
900  *
901  * The encoding of the returned string is system-defined. On Windows,
902  * it is always UTF-8. The return value is never %NULL or the empty
903  * string.
904  *
905  * Returns: (type filename) (transfer none): the directory to use for temporary files.
906  */
907 const gchar *
908 g_get_tmp_dir (void)
909 {
910   static gchar *tmp_dir;
911
912   if (g_once_init_enter (&tmp_dir))
913     {
914       gchar *tmp;
915
916 #ifdef G_OS_WIN32
917       tmp = g_strdup (g_getenv ("TEMP"));
918
919       if (tmp == NULL || *tmp == '\0')
920         {
921           g_free (tmp);
922           tmp = get_windows_directory_root ();
923         }
924 #else /* G_OS_WIN32 */
925       tmp = g_strdup (g_getenv ("TMPDIR"));
926
927 #ifdef P_tmpdir
928       if (tmp == NULL || *tmp == '\0')
929         {
930           gsize k;
931           g_free (tmp);
932           tmp = g_strdup (P_tmpdir);
933           k = strlen (tmp);
934           if (k > 1 && G_IS_DIR_SEPARATOR (tmp[k - 1]))
935             tmp[k - 1] = '\0';
936         }
937 #endif /* P_tmpdir */
938
939       if (tmp == NULL || *tmp == '\0')
940         {
941           g_free (tmp);
942           tmp = g_strdup ("/tmp");
943         }
944 #endif /* !G_OS_WIN32 */
945
946       g_once_init_leave (&tmp_dir, tmp);
947     }
948
949   return tmp_dir;
950 }
951
952 /**
953  * g_get_host_name:
954  *
955  * Return a name for the machine. 
956  *
957  * The returned name is not necessarily a fully-qualified domain name,
958  * or even present in DNS or some other name service at all. It need
959  * not even be unique on your local network or site, but usually it
960  * is. Callers should not rely on the return value having any specific
961  * properties like uniqueness for security purposes. Even if the name
962  * of the machine is changed while an application is running, the
963  * return value from this function does not change. The returned
964  * string is owned by GLib and should not be modified or freed. If no
965  * name can be determined, a default fixed string "localhost" is
966  * returned.
967  *
968  * The encoding of the returned string is UTF-8.
969  *
970  * Returns: (transfer none): the host name of the machine.
971  *
972  * Since: 2.8
973  */
974 const gchar *
975 g_get_host_name (void)
976 {
977   static gchar *hostname;
978
979   if (g_once_init_enter (&hostname))
980     {
981       gboolean failed;
982       gchar *utmp;
983
984 #ifndef G_OS_WIN32
985       gsize size;
986       /* The number 256 * 256 is taken from the value of _POSIX_HOST_NAME_MAX,
987        * which is 255. Since we use _POSIX_HOST_NAME_MAX + 1 (= 256) in the
988        * fallback case, we pick 256 * 256 as the size of the larger buffer here.
989        * It should be large enough. It doesn't looks reasonable to name a host
990        * with a string that is longer than 64 KiB.
991        */
992       const gsize size_large = (gsize) 256 * 256;
993       gchar *tmp;
994
995 #ifdef _SC_HOST_NAME_MAX
996       {
997         glong max;
998
999         max = sysconf (_SC_HOST_NAME_MAX);
1000         if (max > 0 && (gsize) max <= G_MAXSIZE - 1)
1001           size = (gsize) max + 1;
1002         else
1003 #ifdef HOST_NAME_MAX
1004           size = HOST_NAME_MAX + 1;
1005 #else
1006           size = _POSIX_HOST_NAME_MAX + 1;
1007 #endif /* HOST_NAME_MAX */
1008       }
1009 #else
1010       /* Fallback to some reasonable value */
1011       size = 256;
1012 #endif /* _SC_HOST_NAME_MAX */
1013       tmp = g_malloc (size);
1014       failed = (gethostname (tmp, size) == -1);
1015       if (failed && size < size_large)
1016         {
1017           /* Try again with a larger buffer if 'size' may be too small. */
1018           g_free (tmp);
1019           tmp = g_malloc (size_large);
1020           failed = (gethostname (tmp, size_large) == -1);
1021         }
1022
1023       if (failed)
1024         g_clear_pointer (&tmp, g_free);
1025       utmp = tmp;
1026 #else
1027       wchar_t tmp[MAX_COMPUTERNAME_LENGTH + 1];
1028       DWORD size = sizeof (tmp) / sizeof (tmp[0]);
1029       failed = (!GetComputerNameW (tmp, &size));
1030       if (!failed)
1031         utmp = g_utf16_to_utf8 (tmp, size, NULL, NULL, NULL);
1032       if (utmp == NULL)
1033         failed = TRUE;
1034 #endif
1035
1036       g_once_init_leave (&hostname, failed ? g_strdup ("localhost") : utmp);
1037     }
1038
1039   return hostname;
1040 }
1041
1042 G_LOCK_DEFINE_STATIC (g_prgname);
1043 static gchar *g_prgname = NULL;
1044
1045 /**
1046  * g_get_prgname:
1047  *
1048  * Gets the name of the program. This name should not be localized,
1049  * in contrast to g_get_application_name().
1050  *
1051  * If you are using #GApplication the program name is set in
1052  * g_application_run(). In case of GDK or GTK+ it is set in
1053  * gdk_init(), which is called by gtk_init() and the
1054  * #GtkApplication::startup handler. The program name is found by
1055  * taking the last component of @argv[0].
1056  *
1057  * Returns: (nullable) (transfer none): the name of the program,
1058  *   or %NULL if it has not been set yet. The returned string belongs
1059  *   to GLib and must not be modified or freed.
1060  */
1061 const gchar*
1062 g_get_prgname (void)
1063 {
1064   gchar* retval;
1065
1066   G_LOCK (g_prgname);
1067   retval = g_prgname;
1068   G_UNLOCK (g_prgname);
1069
1070   return retval;
1071 }
1072
1073 /**
1074  * g_set_prgname:
1075  * @prgname: the name of the program.
1076  *
1077  * Sets the name of the program. This name should not be localized,
1078  * in contrast to g_set_application_name().
1079  *
1080  * If you are using #GApplication the program name is set in
1081  * g_application_run(). In case of GDK or GTK+ it is set in
1082  * gdk_init(), which is called by gtk_init() and the
1083  * #GtkApplication::startup handler. The program name is found by
1084  * taking the last component of @argv[0].
1085  *
1086  * Note that for thread-safety reasons this function can only be called once.
1087  */
1088 void
1089 g_set_prgname (const gchar *prgname)
1090 {
1091   G_LOCK (g_prgname);
1092   g_free (g_prgname);
1093   g_prgname = g_strdup (prgname);
1094   G_UNLOCK (g_prgname);
1095 }
1096
1097 G_LOCK_DEFINE_STATIC (g_application_name);
1098 static gchar *g_application_name = NULL;
1099
1100 /**
1101  * g_get_application_name:
1102  * 
1103  * Gets a human-readable name for the application, as set by
1104  * g_set_application_name(). This name should be localized if
1105  * possible, and is intended for display to the user.  Contrast with
1106  * g_get_prgname(), which gets a non-localized name. If
1107  * g_set_application_name() has not been called, returns the result of
1108  * g_get_prgname() (which may be %NULL if g_set_prgname() has also not
1109  * been called).
1110  * 
1111  * Returns: (transfer none) (nullable): human-readable application
1112  *   name. May return %NULL
1113  *
1114  * Since: 2.2
1115  **/
1116 const gchar *
1117 g_get_application_name (void)
1118 {
1119   gchar* retval;
1120
1121   G_LOCK (g_application_name);
1122   retval = g_application_name;
1123   G_UNLOCK (g_application_name);
1124
1125   if (retval == NULL)
1126     return g_get_prgname ();
1127   
1128   return retval;
1129 }
1130
1131 /**
1132  * g_set_application_name:
1133  * @application_name: localized name of the application
1134  *
1135  * Sets a human-readable name for the application. This name should be
1136  * localized if possible, and is intended for display to the user.
1137  * Contrast with g_set_prgname(), which sets a non-localized name.
1138  * g_set_prgname() will be called automatically by gtk_init(),
1139  * but g_set_application_name() will not.
1140  *
1141  * Note that for thread safety reasons, this function can only
1142  * be called once.
1143  *
1144  * The application name will be used in contexts such as error messages,
1145  * or when displaying an application's name in the task list.
1146  * 
1147  * Since: 2.2
1148  **/
1149 void
1150 g_set_application_name (const gchar *application_name)
1151 {
1152   gboolean already_set = FALSE;
1153         
1154   G_LOCK (g_application_name);
1155   if (g_application_name)
1156     already_set = TRUE;
1157   else
1158     g_application_name = g_strdup (application_name);
1159   G_UNLOCK (g_application_name);
1160
1161   if (already_set)
1162     g_warning ("g_set_application_name() called multiple times");
1163 }
1164
1165 #ifdef G_OS_WIN32
1166 /* For the past versions we can just
1167  * hardcode all the names.
1168  */
1169 static const struct winver
1170 {
1171   gint major;
1172   gint minor;
1173   gint sp;
1174   const char *version;
1175   const char *spversion;
1176 } versions[] =
1177 {
1178   {6, 2, 0, "8", ""},
1179   {6, 1, 1, "7", " SP1"},
1180   {6, 1, 0, "7", ""},
1181   {6, 0, 2, "Vista", " SP2"},
1182   {6, 0, 1, "Vista", " SP1"},
1183   {6, 0, 0, "Vista", ""},
1184   {5, 1, 3, "XP", " SP3"},
1185   {5, 1, 2, "XP", " SP2"},
1186   {5, 1, 1, "XP", " SP1"},
1187   {5, 1, 0, "XP", ""},
1188   {0, 0, 0, NULL, NULL},
1189 };
1190
1191 static gchar *
1192 get_registry_str (HKEY root_key, const wchar_t *path, const wchar_t *value_name)
1193 {
1194   HKEY key_handle;
1195   DWORD req_value_data_size;
1196   DWORD req_value_data_size2;
1197   LONG status;
1198   DWORD value_type_w;
1199   DWORD value_type_w2;
1200   char *req_value_data;
1201   gchar *result;
1202
1203   status = RegOpenKeyExW (root_key, path, 0, KEY_READ, &key_handle);
1204   if (status != ERROR_SUCCESS)
1205     return NULL;
1206
1207   req_value_data_size = 0;
1208   status = RegQueryValueExW (key_handle,
1209                              value_name,
1210                              NULL,
1211                              &value_type_w,
1212                              NULL,
1213                              &req_value_data_size);
1214
1215   if (status != ERROR_MORE_DATA && status != ERROR_SUCCESS)
1216     {
1217       RegCloseKey (key_handle);
1218
1219       return NULL;
1220     }
1221
1222   req_value_data = g_malloc (req_value_data_size);
1223   req_value_data_size2 = req_value_data_size;
1224
1225   status = RegQueryValueExW (key_handle,
1226                              value_name,
1227                              NULL,
1228                              &value_type_w2,
1229                              (gpointer) req_value_data,
1230                              &req_value_data_size2);
1231
1232   result = NULL;
1233
1234   if (status == ERROR_SUCCESS && value_type_w2 == REG_SZ)
1235     result = g_utf16_to_utf8 ((gunichar2 *) req_value_data,
1236                               req_value_data_size / sizeof (gunichar2),
1237                               NULL,
1238                               NULL,
1239                               NULL);
1240
1241   g_free (req_value_data);
1242   RegCloseKey (key_handle);
1243
1244   return result;
1245 }
1246
1247 /* Windows 8.1 can be either plain or with Update 1,
1248  * depending on its build number (9200 or 9600).
1249  */
1250 static gchar *
1251 get_windows_8_1_update (void)
1252 {
1253   gchar *current_build;
1254   gchar *result = NULL;
1255
1256   current_build = get_registry_str (HKEY_LOCAL_MACHINE,
1257                                     L"SOFTWARE"
1258                                     L"\\Microsoft"
1259                                     L"\\Windows NT"
1260                                     L"\\CurrentVersion",
1261                                     L"CurrentBuild");
1262
1263   if (current_build != NULL)
1264     {
1265       wchar_t *end;
1266       long build = wcstol ((const wchar_t *) current_build, &end, 10);
1267
1268       if (build <= INT_MAX &&
1269           build >= INT_MIN &&
1270           errno == 0 &&
1271           *end == L'\0')
1272         {
1273           if (build >= 9600)
1274             result = g_strdup ("Update 1");
1275         }
1276     }
1277
1278   g_clear_pointer (&current_build, g_free);
1279
1280   return result;
1281 }
1282
1283 static gchar *
1284 get_windows_version (gboolean with_windows)
1285 {
1286   GString *version = g_string_new (NULL);
1287
1288   if (g_win32_check_windows_version (10, 0, 0, G_WIN32_OS_ANY))
1289     {
1290       gchar *win10_release;
1291
1292       g_string_append (version, "10");
1293
1294       if (!g_win32_check_windows_version (10, 0, 0, G_WIN32_OS_WORKSTATION))
1295         g_string_append (version, " Server");
1296
1297       /* Windows 10 is identified by its release number, such as
1298        * 1511, 1607, 1703, 1709, 1803, 1809 or 1903.
1299        * The first version of Windows 10 has no release number.
1300        */
1301       win10_release = get_registry_str (HKEY_LOCAL_MACHINE,
1302                                         L"SOFTWARE"
1303                                         L"\\Microsoft"
1304                                         L"\\Windows NT"
1305                                         L"\\CurrentVersion",
1306                                         L"ReleaseId");
1307
1308       if (win10_release != NULL)
1309         g_string_append_printf (version, " %s", win10_release);
1310
1311       g_free (win10_release);
1312     }
1313   else if (g_win32_check_windows_version (6, 3, 0, G_WIN32_OS_ANY))
1314     {
1315       gchar *win81_update;
1316
1317       g_string_append (version, "8.1");
1318
1319       if (!g_win32_check_windows_version (6, 3, 0, G_WIN32_OS_WORKSTATION))
1320         g_string_append (version, " Server");
1321
1322       win81_update = get_windows_8_1_update ();
1323
1324       if (win81_update != NULL)
1325         g_string_append_printf (version, " %s", win81_update);
1326
1327       g_free (win81_update);
1328     }
1329   else
1330     {
1331       gint i;
1332
1333       for (i = 0; versions[i].major > 0; i++)
1334         {
1335           if (!g_win32_check_windows_version (versions[i].major, versions[i].minor, versions[i].sp, G_WIN32_OS_ANY))
1336             continue;
1337
1338           g_string_append (version, versions[i].version);
1339
1340           if (!g_win32_check_windows_version (versions[i].major, versions[i].minor, versions[i].sp, G_WIN32_OS_WORKSTATION))
1341             g_string_append (version, " Server");
1342
1343           g_string_append (version, versions[i].spversion);
1344         }
1345     }
1346
1347   if (version->len == 0)
1348     {
1349       g_string_free (version, TRUE);
1350
1351       return NULL;
1352     }
1353
1354   if (with_windows)
1355     g_string_prepend (version, "Windows ");
1356
1357   return g_string_free (version, FALSE);
1358 }
1359 #endif
1360
1361 #ifdef G_OS_UNIX
1362 static gchar *
1363 get_os_info_from_os_release (const gchar *key_name,
1364                              const gchar *buffer)
1365 {
1366   GStrv lines;
1367   gchar *prefix;
1368   size_t i;
1369   gchar *result = NULL;
1370
1371   lines = g_strsplit (buffer, "\n", -1);
1372   prefix = g_strdup_printf ("%s=", key_name);
1373   for (i = 0; lines[i] != NULL; i++)
1374     {
1375       const gchar *line = lines[i];
1376       const gchar *value;
1377
1378       if (g_str_has_prefix (line, prefix))
1379         {
1380           value = line + strlen (prefix);
1381           result = g_shell_unquote (value, NULL);
1382           if (result == NULL)
1383             result = g_strdup (value);
1384           break;
1385         }
1386     }
1387   g_strfreev (lines);
1388   g_free (prefix);
1389
1390 #ifdef __linux__
1391   /* Default values in spec */
1392   if (result == NULL)
1393     {
1394       if (g_str_equal (key_name, G_OS_INFO_KEY_NAME))
1395         return g_strdup ("Linux");
1396       if (g_str_equal (key_name, G_OS_INFO_KEY_ID))
1397         return g_strdup ("linux");
1398       if (g_str_equal (key_name, G_OS_INFO_KEY_PRETTY_NAME))
1399         return g_strdup ("Linux");
1400     }
1401 #endif
1402
1403   return g_steal_pointer (&result);
1404 }
1405
1406 static gchar *
1407 get_os_info_from_uname (const gchar *key_name)
1408 {
1409   struct utsname info;
1410
1411   if (uname (&info) == -1)
1412     return NULL;
1413
1414   if (strcmp (key_name, G_OS_INFO_KEY_NAME) == 0)
1415     return g_strdup (info.sysname);
1416   else if (strcmp (key_name, G_OS_INFO_KEY_VERSION) == 0)
1417     return g_strdup (info.release);
1418   else if (strcmp (key_name, G_OS_INFO_KEY_PRETTY_NAME) == 0)
1419     return g_strdup_printf ("%s %s", info.sysname, info.release);
1420   else if (strcmp (key_name, G_OS_INFO_KEY_ID) == 0)
1421     {
1422       gchar *result = g_ascii_strdown (info.sysname, -1);
1423
1424       g_strcanon (result, "abcdefghijklmnopqrstuvwxyz0123456789_-.", '_');
1425       return g_steal_pointer (&result);
1426     }
1427   else if (strcmp (key_name, G_OS_INFO_KEY_VERSION_ID) == 0)
1428     {
1429       /* We attempt to convert the version string to the format returned by
1430        * config.guess, which is the script used to generate target triplets
1431        * in GNU autotools. There are a lot of rules in the script. We only
1432        * implement a few rules which are easy to understand here.
1433        *
1434        * config.guess can be found at https://savannah.gnu.org/projects/config.
1435        */
1436       gchar *result;
1437
1438       if (strcmp (info.sysname, "NetBSD") == 0)
1439         {
1440           /* sed -e 's,[-_].*,,' */
1441           gssize len = G_MAXSSIZE;
1442           const gchar *c;
1443
1444           if ((c = strchr (info.release, '-')) != NULL)
1445             len = MIN (len, c - info.release);
1446           if ((c = strchr (info.release, '_')) != NULL)
1447             len = MIN (len, c - info.release);
1448           if (len == G_MAXSSIZE)
1449             len = -1;
1450
1451           result = g_ascii_strdown (info.release, len);
1452         }
1453       else if (strcmp (info.sysname, "GNU") == 0)
1454         {
1455           /* sed -e 's,/.*$,,' */
1456           gssize len = -1;
1457           const gchar *c = strchr (info.release, '/');
1458
1459           if (c != NULL)
1460             len = c - info.release;
1461
1462           result = g_ascii_strdown (info.release, len);
1463         }
1464       else if (g_str_has_prefix (info.sysname, "GNU/") ||
1465                strcmp (info.sysname, "FreeBSD") == 0 ||
1466                strcmp (info.sysname, "DragonFly") == 0)
1467         {
1468           /* sed -e 's,[-(].*,,' */
1469           gssize len = G_MAXSSIZE;
1470           const gchar *c;
1471
1472           if ((c = strchr (info.release, '-')) != NULL)
1473             len = MIN (len, c - info.release);
1474           if ((c = strchr (info.release, '(')) != NULL)
1475             len = MIN (len, c - info.release);
1476           if (len == G_MAXSSIZE)
1477             len = -1;
1478
1479           result = g_ascii_strdown (info.release, len);
1480         }
1481       else
1482         result = g_ascii_strdown (info.release, -1);
1483
1484       g_strcanon (result, "abcdefghijklmnopqrstuvwxyz0123456789_-.", '_');
1485       return g_steal_pointer (&result);
1486     }
1487   else
1488     return NULL;
1489 }
1490 #endif
1491
1492 /**
1493  * g_get_os_info:
1494  * @key_name: a key for the OS info being requested, for example %G_OS_INFO_KEY_NAME.
1495  *
1496  * Get information about the operating system.
1497  *
1498  * On Linux this comes from the `/etc/os-release` file. On other systems, it may
1499  * come from a variety of sources. You can either use the standard key names
1500  * like %G_OS_INFO_KEY_NAME or pass any UTF-8 string key name. For example,
1501  * `/etc/os-release` provides a number of other less commonly used values that may
1502  * be useful. No key is guaranteed to be provided, so the caller should always
1503  * check if the result is %NULL.
1504  *
1505  * Returns: (nullable): The associated value for the requested key or %NULL if
1506  *   this information is not provided.
1507  *
1508  * Since: 2.64
1509  **/
1510 gchar *
1511 g_get_os_info (const gchar *key_name)
1512 {
1513 #if defined (__APPLE__)
1514   if (g_strcmp0 (key_name, G_OS_INFO_KEY_NAME) == 0)
1515     return g_strdup ("macOS");
1516   else
1517     return NULL;
1518 #elif defined (G_OS_UNIX)
1519   const gchar * const os_release_files[] = { "/etc/os-release", "/usr/lib/os-release" };
1520   gsize i;
1521   gchar *buffer = NULL;
1522   gchar *result = NULL;
1523
1524   g_return_val_if_fail (key_name != NULL, NULL);
1525
1526   for (i = 0; i < G_N_ELEMENTS (os_release_files); i++)
1527     {
1528       GError *error = NULL;
1529       gboolean file_missing;
1530
1531       if (g_file_get_contents (os_release_files[i], &buffer, NULL, &error))
1532         break;
1533
1534       file_missing = g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT);
1535       g_clear_error (&error);
1536
1537       if (!file_missing)
1538         return NULL;
1539     }
1540
1541   if (buffer != NULL)
1542     result = get_os_info_from_os_release (key_name, buffer);
1543   else
1544     result = get_os_info_from_uname (key_name);
1545
1546   g_free (buffer);
1547   return g_steal_pointer (&result);
1548 #elif defined (G_OS_WIN32)
1549   if (g_strcmp0 (key_name, G_OS_INFO_KEY_NAME) == 0)
1550     return g_strdup ("Windows");
1551   else if (g_strcmp0 (key_name, G_OS_INFO_KEY_ID) == 0)
1552     return g_strdup ("windows");
1553   else if (g_strcmp0 (key_name, G_OS_INFO_KEY_PRETTY_NAME) == 0)
1554     /* Windows XP SP2 or Windows 10 1903 or Windows 7 Server SP1 */
1555     return get_windows_version (TRUE);
1556   else if (g_strcmp0 (key_name, G_OS_INFO_KEY_VERSION) == 0)
1557     /* XP SP2 or 10 1903 or 7 Server SP1 */
1558     return get_windows_version (FALSE);
1559   else if (g_strcmp0 (key_name, G_OS_INFO_KEY_VERSION_ID) == 0)
1560     {
1561       /* xp_sp2 or 10_1903 or 7_server_sp1 */
1562       gchar *result;
1563       gchar *version = get_windows_version (FALSE);
1564
1565       if (version == NULL)
1566         return NULL;
1567
1568       result = g_ascii_strdown (version, -1);
1569       g_free (version);
1570
1571       return g_strcanon (result, "abcdefghijklmnopqrstuvwxyz0123456789_-.", '_');
1572     }
1573   else if (g_strcmp0 (key_name, G_OS_INFO_KEY_HOME_URL) == 0)
1574     return g_strdup ("https://microsoft.com/windows/");
1575   else if (g_strcmp0 (key_name, G_OS_INFO_KEY_DOCUMENTATION_URL) == 0)
1576     return g_strdup ("https://docs.microsoft.com/");
1577   else if (g_strcmp0 (key_name, G_OS_INFO_KEY_SUPPORT_URL) == 0)
1578     return g_strdup ("https://support.microsoft.com/");
1579   else if (g_strcmp0 (key_name, G_OS_INFO_KEY_BUG_REPORT_URL) == 0)
1580     return g_strdup ("https://support.microsoft.com/contactus/");
1581   else if (g_strcmp0 (key_name, G_OS_INFO_KEY_PRIVACY_POLICY_URL) == 0)
1582     return g_strdup ("https://privacy.microsoft.com/");
1583   else
1584     return NULL;
1585 #endif
1586 }
1587
1588 /* Set @global_str to a copy of @new_value if it’s currently unset or has a
1589  * different value. If its current value matches @new_value, do nothing. If
1590  * replaced, we have to leak the old value as client code could still have
1591  * pointers to it. */
1592 static void
1593 set_str_if_different (gchar       **global_str,
1594                       const gchar  *type,
1595                       const gchar  *new_value)
1596 {
1597   if (*global_str == NULL ||
1598       !g_str_equal (new_value, *global_str))
1599     {
1600       g_debug ("g_set_user_dirs: Setting %s to %s", type, new_value);
1601
1602       /* We have to leak the old value, as user code could be retaining pointers
1603        * to it. */
1604       *global_str = g_strdup (new_value);
1605     }
1606 }
1607
1608 static void
1609 set_strv_if_different (gchar                ***global_strv,
1610                        const gchar            *type,
1611                        const gchar  * const   *new_value)
1612 {
1613   if (*global_strv == NULL ||
1614       !g_strv_equal (new_value, (const gchar * const *) *global_strv))
1615     {
1616       gchar *new_value_str = g_strjoinv (":", (gchar **) new_value);
1617       g_debug ("g_set_user_dirs: Setting %s to %s", type, new_value_str);
1618       g_free (new_value_str);
1619
1620       /* We have to leak the old value, as user code could be retaining pointers
1621        * to it. */
1622       *global_strv = g_strdupv ((gchar **) new_value);
1623     }
1624 }
1625
1626 /*
1627  * g_set_user_dirs:
1628  * @first_dir_type: Type of the first directory to set
1629  * @...: Value to set the first directory to, followed by additional type/value
1630  *    pairs, followed by %NULL
1631  *
1632  * Set one or more â€˜user’ directories to custom values. This is intended to be
1633  * used by test code (particularly with the %G_TEST_OPTION_ISOLATE_DIRS option)
1634  * to override the values returned by the following functions, so that test
1635  * code can be run without touching an installed system and user data:
1636  *
1637  *  - g_get_home_dir() â€” use type `HOME`, pass a string
1638  *  - g_get_user_cache_dir() â€” use type `XDG_CACHE_HOME`, pass a string
1639  *  - g_get_system_config_dirs() â€” use type `XDG_CONFIG_DIRS`, pass a
1640  *    %NULL-terminated string array
1641  *  - g_get_user_config_dir() â€” use type `XDG_CONFIG_HOME`, pass a string
1642  *  - g_get_system_data_dirs() â€” use type `XDG_DATA_DIRS`, pass a
1643  *    %NULL-terminated string array
1644  *  - g_get_user_data_dir() â€” use type `XDG_DATA_HOME`, pass a string
1645  *  - g_get_user_runtime_dir() â€” use type `XDG_RUNTIME_DIR`, pass a string
1646  *
1647  * The list must be terminated with a %NULL type. All of the values must be
1648  * non-%NULL â€” passing %NULL as a value won’t reset a directory. If a reference
1649  * to a directory from the calling environment needs to be kept, copy it before
1650  * the first call to g_set_user_dirs(). g_set_user_dirs() can be called multiple
1651  * times.
1652  *
1653  * Since: 2.60
1654  */
1655 /*< private > */
1656 void
1657 g_set_user_dirs (const gchar *first_dir_type,
1658                  ...)
1659 {
1660   va_list args;
1661   const gchar *dir_type;
1662
1663   G_LOCK (g_utils_global);
1664
1665   va_start (args, first_dir_type);
1666
1667   for (dir_type = first_dir_type; dir_type != NULL; dir_type = va_arg (args, const gchar *))
1668     {
1669       gconstpointer dir_value = va_arg (args, gconstpointer);
1670       g_assert (dir_value != NULL);
1671
1672       if (g_str_equal (dir_type, "HOME"))
1673         set_str_if_different (&g_home_dir, dir_type, dir_value);
1674       else if (g_str_equal (dir_type, "XDG_CACHE_HOME"))
1675         set_str_if_different (&g_user_cache_dir, dir_type, dir_value);
1676       else if (g_str_equal (dir_type, "XDG_CONFIG_DIRS"))
1677         set_strv_if_different (&g_system_config_dirs, dir_type, dir_value);
1678       else if (g_str_equal (dir_type, "XDG_CONFIG_HOME"))
1679         set_str_if_different (&g_user_config_dir, dir_type, dir_value);
1680       else if (g_str_equal (dir_type, "XDG_DATA_DIRS"))
1681         set_strv_if_different (&g_system_data_dirs, dir_type, dir_value);
1682       else if (g_str_equal (dir_type, "XDG_DATA_HOME"))
1683         set_str_if_different (&g_user_data_dir, dir_type, dir_value);
1684       else if (g_str_equal (dir_type, "XDG_RUNTIME_DIR"))
1685         set_str_if_different (&g_user_runtime_dir, dir_type, dir_value);
1686       else
1687         g_assert_not_reached ();
1688     }
1689
1690   va_end (args);
1691
1692   G_UNLOCK (g_utils_global);
1693 }
1694
1695 static gchar *
1696 g_build_user_data_dir (void)
1697 {
1698   gchar *data_dir = NULL;
1699   const gchar *data_dir_env = g_getenv ("XDG_DATA_HOME");
1700
1701   if (data_dir_env && data_dir_env[0])
1702     data_dir = g_strdup (data_dir_env);
1703 #ifdef G_OS_WIN32
1704   else
1705     data_dir = get_special_folder (CSIDL_LOCAL_APPDATA);
1706 #endif
1707   if (!data_dir || !data_dir[0])
1708     {
1709       gchar *home_dir = g_build_home_dir ();
1710       data_dir = g_build_filename (home_dir, ".local", "share", NULL);
1711       g_free (home_dir);
1712     }
1713
1714   return g_steal_pointer (&data_dir);
1715 }
1716
1717 /**
1718  * g_get_user_data_dir:
1719  * 
1720  * Returns a base directory in which to access application data such
1721  * as icons that is customized for a particular user.  
1722  *
1723  * On UNIX platforms this is determined using the mechanisms described
1724  * in the
1725  * [XDG Base Directory Specification](http://www.freedesktop.org/Standards/basedir-spec).
1726  * In this case the directory retrieved will be `XDG_DATA_HOME`.
1727  *
1728  * On Windows it follows XDG Base Directory Specification if `XDG_DATA_HOME`
1729  * is defined. If `XDG_DATA_HOME` is undefined, the folder to use for local (as
1730  * opposed to roaming) application data is used instead. See the
1731  * [documentation for `CSIDL_LOCAL_APPDATA`](https://msdn.microsoft.com/en-us/library/windows/desktop/bb762494%28v=vs.85%29.aspx#csidl_local_appdata).
1732  * Note that in this case on Windows it will be the same
1733  * as what g_get_user_config_dir() returns.
1734  *
1735  * Returns: (type filename) (transfer none): a string owned by GLib that must
1736  *   not be modified or freed.
1737  *
1738  * Since: 2.6
1739  **/
1740 const gchar *
1741 g_get_user_data_dir (void)
1742 {
1743   const gchar *user_data_dir;
1744
1745   G_LOCK (g_utils_global);
1746
1747   if (g_user_data_dir == NULL)
1748     g_user_data_dir = g_build_user_data_dir ();
1749   user_data_dir = g_user_data_dir;
1750
1751   G_UNLOCK (g_utils_global);
1752
1753   return user_data_dir;
1754 }
1755
1756 static gchar *
1757 g_build_user_config_dir (void)
1758 {
1759   gchar *config_dir = NULL;
1760   const gchar *config_dir_env = g_getenv ("XDG_CONFIG_HOME");
1761
1762   if (config_dir_env && config_dir_env[0])
1763     config_dir = g_strdup (config_dir_env);
1764 #ifdef G_OS_WIN32
1765   else
1766     config_dir = get_special_folder (CSIDL_LOCAL_APPDATA);
1767 #endif
1768   if (!config_dir || !config_dir[0])
1769     {
1770       gchar *home_dir = g_build_home_dir ();
1771       config_dir = g_build_filename (home_dir, ".config", NULL);
1772       g_free (home_dir);
1773     }
1774
1775   return g_steal_pointer (&config_dir);
1776 }
1777
1778 /**
1779  * g_get_user_config_dir:
1780  * 
1781  * Returns a base directory in which to store user-specific application 
1782  * configuration information such as user preferences and settings. 
1783  *
1784  * On UNIX platforms this is determined using the mechanisms described
1785  * in the
1786  * [XDG Base Directory Specification](http://www.freedesktop.org/Standards/basedir-spec).
1787  * In this case the directory retrieved will be `XDG_CONFIG_HOME`.
1788  *
1789  * On Windows it follows XDG Base Directory Specification if `XDG_CONFIG_HOME` is defined.
1790  * If `XDG_CONFIG_HOME` is undefined, the folder to use for local (as opposed
1791  * to roaming) application data is used instead. See the
1792  * [documentation for `CSIDL_LOCAL_APPDATA`](https://msdn.microsoft.com/en-us/library/windows/desktop/bb762494%28v=vs.85%29.aspx#csidl_local_appdata).
1793  * Note that in this case on Windows it will be  the same
1794  * as what g_get_user_data_dir() returns.
1795  *
1796  * Returns: (type filename) (transfer none): a string owned by GLib that
1797  *   must not be modified or freed.
1798  * Since: 2.6
1799  **/
1800 const gchar *
1801 g_get_user_config_dir (void)
1802 {
1803   const gchar *user_config_dir;
1804
1805   G_LOCK (g_utils_global);
1806
1807   if (g_user_config_dir == NULL)
1808     g_user_config_dir = g_build_user_config_dir ();
1809   user_config_dir = g_user_config_dir;
1810
1811   G_UNLOCK (g_utils_global);
1812
1813   return user_config_dir;
1814 }
1815
1816 static gchar *
1817 g_build_user_cache_dir (void)
1818 {
1819   gchar *cache_dir = NULL;
1820   const gchar *cache_dir_env = g_getenv ("XDG_CACHE_HOME");
1821
1822   if (cache_dir_env && cache_dir_env[0])
1823     cache_dir = g_strdup (cache_dir_env);
1824 #ifdef G_OS_WIN32
1825   else
1826     cache_dir = get_special_folder (CSIDL_INTERNET_CACHE);
1827 #endif
1828   if (!cache_dir || !cache_dir[0])
1829     {
1830       gchar *home_dir = g_build_home_dir ();
1831       cache_dir = g_build_filename (home_dir, ".cache", NULL);
1832       g_free (home_dir);
1833     }
1834
1835   return g_steal_pointer (&cache_dir);
1836 }
1837
1838 /**
1839  * g_get_user_cache_dir:
1840  * 
1841  * Returns a base directory in which to store non-essential, cached
1842  * data specific to particular user.
1843  *
1844  * On UNIX platforms this is determined using the mechanisms described
1845  * in the
1846  * [XDG Base Directory Specification](http://www.freedesktop.org/Standards/basedir-spec).
1847  * In this case the directory retrieved will be `XDG_CACHE_HOME`.
1848  *
1849  * On Windows it follows XDG Base Directory Specification if `XDG_CACHE_HOME` is defined.
1850  * If `XDG_CACHE_HOME` is undefined, the directory that serves as a common
1851  * repository for temporary Internet files is used instead. A typical path is
1852  * `C:\Documents and Settings\username\Local Settings\Temporary Internet Files`.
1853  * See the [documentation for `CSIDL_INTERNET_CACHE`](https://msdn.microsoft.com/en-us/library/windows/desktop/bb762494%28v=vs.85%29.aspx#csidl_internet_cache).
1854  *
1855  * Returns: (type filename) (transfer none): a string owned by GLib that
1856  *   must not be modified or freed.
1857  * Since: 2.6
1858  **/
1859 const gchar *
1860 g_get_user_cache_dir (void)
1861 {
1862   const gchar *user_cache_dir;
1863
1864   G_LOCK (g_utils_global);
1865
1866   if (g_user_cache_dir == NULL)
1867     g_user_cache_dir = g_build_user_cache_dir ();
1868   user_cache_dir = g_user_cache_dir;
1869
1870   G_UNLOCK (g_utils_global);
1871
1872   return user_cache_dir;
1873 }
1874
1875 static gchar *
1876 g_build_user_runtime_dir (void)
1877 {
1878   gchar *runtime_dir = NULL;
1879   const gchar *runtime_dir_env = g_getenv ("XDG_RUNTIME_DIR");
1880
1881   if (runtime_dir_env && runtime_dir_env[0])
1882     runtime_dir = g_strdup (runtime_dir_env);
1883   else
1884     {
1885       runtime_dir = g_build_user_cache_dir ();
1886
1887       /* The user should be able to rely on the directory existing
1888        * when the function returns.  Probably it already does, but
1889        * let's make sure.  Just do mkdir() directly since it will be
1890        * no more expensive than a stat() in the case that the
1891        * directory already exists and is a lot easier.
1892        *
1893        * $XDG_CACHE_HOME is probably ~/.cache/ so as long as $HOME
1894        * exists this will work.  If the user changed $XDG_CACHE_HOME
1895        * then they can make sure that it exists...
1896        */
1897       (void) g_mkdir (runtime_dir, 0700);
1898     }
1899
1900   return g_steal_pointer (&runtime_dir);
1901 }
1902
1903 /**
1904  * g_get_user_runtime_dir:
1905  *
1906  * Returns a directory that is unique to the current user on the local
1907  * system.
1908  *
1909  * This is determined using the mechanisms described
1910  * in the 
1911  * [XDG Base Directory Specification](http://www.freedesktop.org/Standards/basedir-spec).
1912  * This is the directory
1913  * specified in the `XDG_RUNTIME_DIR` environment variable.
1914  * In the case that this variable is not set, we return the value of
1915  * g_get_user_cache_dir(), after verifying that it exists.
1916  *
1917  * Returns: (type filename): a string owned by GLib that must not be
1918  *     modified or freed.
1919  *
1920  * Since: 2.28
1921  **/
1922 const gchar *
1923 g_get_user_runtime_dir (void)
1924 {
1925   const gchar *user_runtime_dir;
1926
1927   G_LOCK (g_utils_global);
1928
1929   if (g_user_runtime_dir == NULL)
1930     g_user_runtime_dir = g_build_user_runtime_dir ();
1931   user_runtime_dir = g_user_runtime_dir;
1932
1933   G_UNLOCK (g_utils_global);
1934
1935   return user_runtime_dir;
1936 }
1937
1938 #ifdef HAVE_COCOA
1939
1940 /* Implemented in gutils-macos.m */
1941 void load_user_special_dirs_macos (gchar **table);
1942
1943 static void
1944 load_user_special_dirs (void)
1945 {
1946   load_user_special_dirs_macos (g_user_special_dirs);
1947 }
1948
1949 #elif defined(G_OS_WIN32)
1950
1951 static void
1952 load_user_special_dirs (void)
1953 {
1954   typedef HRESULT (WINAPI *t_SHGetKnownFolderPath) (const GUID *rfid,
1955                                                     DWORD dwFlags,
1956                                                     HANDLE hToken,
1957                                                     PWSTR *ppszPath);
1958   t_SHGetKnownFolderPath p_SHGetKnownFolderPath;
1959
1960   static const GUID FOLDERID_Downloads =
1961     { 0x374de290, 0x123f, 0x4565, { 0x91, 0x64, 0x39, 0xc4, 0x92, 0x5e, 0x46, 0x7b } };
1962   static const GUID FOLDERID_Public =
1963     { 0xDFDF76A2, 0xC82A, 0x4D63, { 0x90, 0x6A, 0x56, 0x44, 0xAC, 0x45, 0x73, 0x85 } };
1964
1965   wchar_t *wcp;
1966
1967   p_SHGetKnownFolderPath = (t_SHGetKnownFolderPath) GetProcAddress (GetModuleHandleW (L"shell32.dll"),
1968                                                                     "SHGetKnownFolderPath");
1969
1970   g_user_special_dirs[G_USER_DIRECTORY_DESKTOP] = get_special_folder (CSIDL_DESKTOPDIRECTORY);
1971   g_user_special_dirs[G_USER_DIRECTORY_DOCUMENTS] = get_special_folder (CSIDL_PERSONAL);
1972
1973   if (p_SHGetKnownFolderPath == NULL)
1974     {
1975       g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] = get_special_folder (CSIDL_DESKTOPDIRECTORY);
1976     }
1977   else
1978     {
1979       wcp = NULL;
1980       (*p_SHGetKnownFolderPath) (&FOLDERID_Downloads, 0, NULL, &wcp);
1981       if (wcp)
1982         {
1983           g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] = g_utf16_to_utf8 (wcp, -1, NULL, NULL, NULL);
1984           if (g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] == NULL)
1985               g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] = get_special_folder (CSIDL_DESKTOPDIRECTORY);
1986           CoTaskMemFree (wcp);
1987         }
1988       else
1989           g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] = get_special_folder (CSIDL_DESKTOPDIRECTORY);
1990     }
1991
1992   g_user_special_dirs[G_USER_DIRECTORY_MUSIC] = get_special_folder (CSIDL_MYMUSIC);
1993   g_user_special_dirs[G_USER_DIRECTORY_PICTURES] = get_special_folder (CSIDL_MYPICTURES);
1994
1995   if (p_SHGetKnownFolderPath == NULL)
1996     {
1997       /* XXX */
1998       g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] = get_special_folder (CSIDL_COMMON_DOCUMENTS);
1999     }
2000   else
2001     {
2002       wcp = NULL;
2003       (*p_SHGetKnownFolderPath) (&FOLDERID_Public, 0, NULL, &wcp);
2004       if (wcp)
2005         {
2006           g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] = g_utf16_to_utf8 (wcp, -1, NULL, NULL, NULL);
2007           if (g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] == NULL)
2008               g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] = get_special_folder (CSIDL_COMMON_DOCUMENTS);
2009           CoTaskMemFree (wcp);
2010         }
2011       else
2012           g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] = get_special_folder (CSIDL_COMMON_DOCUMENTS);
2013     }
2014   
2015   g_user_special_dirs[G_USER_DIRECTORY_TEMPLATES] = get_special_folder (CSIDL_TEMPLATES);
2016   g_user_special_dirs[G_USER_DIRECTORY_VIDEOS] = get_special_folder (CSIDL_MYVIDEO);
2017 }
2018
2019 #else /* default is unix */
2020
2021 /* adapted from xdg-user-dir-lookup.c
2022  *
2023  * Copyright (C) 2007 Red Hat Inc.
2024  *
2025  * Permission is hereby granted, free of charge, to any person
2026  * obtaining a copy of this software and associated documentation files
2027  * (the "Software"), to deal in the Software without restriction,
2028  * including without limitation the rights to use, copy, modify, merge,
2029  * publish, distribute, sublicense, and/or sell copies of the Software,
2030  * and to permit persons to whom the Software is furnished to do so,
2031  * subject to the following conditions: 
2032  *
2033  * The above copyright notice and this permission notice shall be
2034  * included in all copies or substantial portions of the Software. 
2035  *
2036  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
2037  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2038  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
2039  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
2040  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
2041  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
2042  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2043  * SOFTWARE.
2044  */
2045 static void
2046 load_user_special_dirs (void)
2047 {
2048   gchar *config_dir = NULL;
2049   gchar *config_file;
2050   gchar *data;
2051   gchar **lines;
2052   gint n_lines, i;
2053   
2054   config_dir = g_build_user_config_dir ();
2055   config_file = g_build_filename (config_dir,
2056                                   "user-dirs.dirs",
2057                                   NULL);
2058   g_free (config_dir);
2059
2060   if (!g_file_get_contents (config_file, &data, NULL, NULL))
2061     {
2062       g_free (config_file);
2063       return;
2064     }
2065
2066   lines = g_strsplit (data, "\n", -1);
2067   n_lines = g_strv_length (lines);
2068   g_free (data);
2069   
2070   for (i = 0; i < n_lines; i++)
2071     {
2072       gchar *buffer = lines[i];
2073       gchar *d, *p;
2074       gint len;
2075       gboolean is_relative = FALSE;
2076       GUserDirectory directory;
2077
2078       /* Remove newline at end */
2079       len = strlen (buffer);
2080       if (len > 0 && buffer[len - 1] == '\n')
2081         buffer[len - 1] = 0;
2082       
2083       p = buffer;
2084       while (*p == ' ' || *p == '\t')
2085         p++;
2086       
2087       if (strncmp (p, "XDG_DESKTOP_DIR", strlen ("XDG_DESKTOP_DIR")) == 0)
2088         {
2089           directory = G_USER_DIRECTORY_DESKTOP;
2090           p += strlen ("XDG_DESKTOP_DIR");
2091         }
2092       else if (strncmp (p, "XDG_DOCUMENTS_DIR", strlen ("XDG_DOCUMENTS_DIR")) == 0)
2093         {
2094           directory = G_USER_DIRECTORY_DOCUMENTS;
2095           p += strlen ("XDG_DOCUMENTS_DIR");
2096         }
2097       else if (strncmp (p, "XDG_DOWNLOAD_DIR", strlen ("XDG_DOWNLOAD_DIR")) == 0)
2098         {
2099           directory = G_USER_DIRECTORY_DOWNLOAD;
2100           p += strlen ("XDG_DOWNLOAD_DIR");
2101         }
2102       else if (strncmp (p, "XDG_MUSIC_DIR", strlen ("XDG_MUSIC_DIR")) == 0)
2103         {
2104           directory = G_USER_DIRECTORY_MUSIC;
2105           p += strlen ("XDG_MUSIC_DIR");
2106         }
2107       else if (strncmp (p, "XDG_PICTURES_DIR", strlen ("XDG_PICTURES_DIR")) == 0)
2108         {
2109           directory = G_USER_DIRECTORY_PICTURES;
2110           p += strlen ("XDG_PICTURES_DIR");
2111         }
2112       else if (strncmp (p, "XDG_PUBLICSHARE_DIR", strlen ("XDG_PUBLICSHARE_DIR")) == 0)
2113         {
2114           directory = G_USER_DIRECTORY_PUBLIC_SHARE;
2115           p += strlen ("XDG_PUBLICSHARE_DIR");
2116         }
2117       else if (strncmp (p, "XDG_TEMPLATES_DIR", strlen ("XDG_TEMPLATES_DIR")) == 0)
2118         {
2119           directory = G_USER_DIRECTORY_TEMPLATES;
2120           p += strlen ("XDG_TEMPLATES_DIR");
2121         }
2122       else if (strncmp (p, "XDG_VIDEOS_DIR", strlen ("XDG_VIDEOS_DIR")) == 0)
2123         {
2124           directory = G_USER_DIRECTORY_VIDEOS;
2125           p += strlen ("XDG_VIDEOS_DIR");
2126         }
2127       else
2128         continue;
2129
2130       while (*p == ' ' || *p == '\t')
2131         p++;
2132
2133       if (*p != '=')
2134         continue;
2135       p++;
2136
2137       while (*p == ' ' || *p == '\t')
2138         p++;
2139
2140       if (*p != '"')
2141         continue;
2142       p++;
2143
2144       if (strncmp (p, "$HOME", 5) == 0)
2145         {
2146           p += 5;
2147           is_relative = TRUE;
2148         }
2149       else if (*p != '/')
2150         continue;
2151
2152       d = strrchr (p, '"');
2153       if (!d)
2154         continue;
2155       *d = 0;
2156
2157       d = p;
2158       
2159       /* remove trailing slashes */
2160       len = strlen (d);
2161       if (d[len - 1] == '/')
2162         d[len - 1] = 0;
2163       
2164       if (is_relative)
2165         {
2166           gchar *home_dir = g_build_home_dir ();
2167           g_user_special_dirs[directory] = g_build_filename (home_dir, d, NULL);
2168           g_free (home_dir);
2169         }
2170       else
2171         g_user_special_dirs[directory] = g_strdup (d);
2172     }
2173
2174   g_strfreev (lines);
2175   g_free (config_file);
2176 }
2177
2178 #endif /* platform-specific load_user_special_dirs implementations */
2179
2180
2181 /**
2182  * g_reload_user_special_dirs_cache:
2183  *
2184  * Resets the cache used for g_get_user_special_dir(), so
2185  * that the latest on-disk version is used. Call this only
2186  * if you just changed the data on disk yourself.
2187  *
2188  * Due to thread safety issues this may cause leaking of strings
2189  * that were previously returned from g_get_user_special_dir()
2190  * that can't be freed. We ensure to only leak the data for
2191  * the directories that actually changed value though.
2192  *
2193  * Since: 2.22
2194  */
2195 void
2196 g_reload_user_special_dirs_cache (void)
2197 {
2198   int i;
2199
2200   G_LOCK (g_utils_global);
2201
2202   if (g_user_special_dirs != NULL)
2203     {
2204       /* save a copy of the pointer, to check if some memory can be preserved */
2205       char **old_g_user_special_dirs = g_user_special_dirs;
2206       char *old_val;
2207
2208       /* recreate and reload our cache */
2209       g_user_special_dirs = g_new0 (gchar *, G_USER_N_DIRECTORIES);
2210       load_user_special_dirs ();
2211
2212       /* only leak changed directories */
2213       for (i = 0; i < G_USER_N_DIRECTORIES; i++)
2214         {
2215           old_val = old_g_user_special_dirs[i];
2216           if (g_user_special_dirs[i] == NULL)
2217             {
2218               g_user_special_dirs[i] = old_val;
2219             }
2220           else if (g_strcmp0 (old_val, g_user_special_dirs[i]) == 0)
2221             {
2222               /* don't leak */
2223               g_free (g_user_special_dirs[i]);
2224               g_user_special_dirs[i] = old_val;
2225             }
2226           else
2227             g_free (old_val);
2228         }
2229
2230       /* free the old array */
2231       g_free (old_g_user_special_dirs);
2232     }
2233
2234   G_UNLOCK (g_utils_global);
2235 }
2236
2237 /**
2238  * g_get_user_special_dir:
2239  * @directory: the logical id of special directory
2240  *
2241  * Returns the full path of a special directory using its logical id.
2242  *
2243  * On UNIX this is done using the XDG special user directories.
2244  * For compatibility with existing practise, %G_USER_DIRECTORY_DESKTOP
2245  * falls back to `$HOME/Desktop` when XDG special user directories have
2246  * not been set up. 
2247  *
2248  * Depending on the platform, the user might be able to change the path
2249  * of the special directory without requiring the session to restart; GLib
2250  * will not reflect any change once the special directories are loaded.
2251  *
2252  * Returns: (type filename): the path to the specified special directory, or
2253  *   %NULL if the logical id was not found. The returned string is owned by
2254  *   GLib and should not be modified or freed.
2255  *
2256  * Since: 2.14
2257  */
2258 const gchar *
2259 g_get_user_special_dir (GUserDirectory directory)
2260 {
2261   const gchar *user_special_dir;
2262
2263   g_return_val_if_fail (directory >= G_USER_DIRECTORY_DESKTOP &&
2264                         directory < G_USER_N_DIRECTORIES, NULL);
2265
2266   G_LOCK (g_utils_global);
2267
2268   if (G_UNLIKELY (g_user_special_dirs == NULL))
2269     {
2270       g_user_special_dirs = g_new0 (gchar *, G_USER_N_DIRECTORIES);
2271
2272       load_user_special_dirs ();
2273
2274       /* Special-case desktop for historical compatibility */
2275       if (g_user_special_dirs[G_USER_DIRECTORY_DESKTOP] == NULL)
2276         {
2277           gchar *home_dir = g_build_home_dir ();
2278           g_user_special_dirs[G_USER_DIRECTORY_DESKTOP] = g_build_filename (home_dir, "Desktop", NULL);
2279           g_free (home_dir);
2280         }
2281     }
2282   user_special_dir = g_user_special_dirs[directory];
2283
2284   G_UNLOCK (g_utils_global);
2285
2286   return user_special_dir;
2287 }
2288
2289 #ifdef G_OS_WIN32
2290
2291 #undef g_get_system_data_dirs
2292
2293 static HMODULE
2294 get_module_for_address (gconstpointer address)
2295 {
2296   /* Holds the g_utils_global lock */
2297
2298   HMODULE hmodule = NULL;
2299
2300   if (!address)
2301     return NULL;
2302
2303   if (!GetModuleHandleExW (GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT |
2304                            GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
2305                            address, &hmodule))
2306     {
2307       MEMORY_BASIC_INFORMATION mbi;
2308       VirtualQuery (address, &mbi, sizeof (mbi));
2309       hmodule = (HMODULE) mbi.AllocationBase;
2310     }
2311
2312   return hmodule;
2313 }
2314
2315 static gchar *
2316 get_module_share_dir (gconstpointer address)
2317 {
2318   HMODULE hmodule;
2319   gchar *filename;
2320   gchar *retval;
2321
2322   hmodule = get_module_for_address (address);
2323   if (hmodule == NULL)
2324     return NULL;
2325
2326   filename = g_win32_get_package_installation_directory_of_module (hmodule);
2327   retval = g_build_filename (filename, "share", NULL);
2328   g_free (filename);
2329
2330   return retval;
2331 }
2332
2333 static const gchar * const *
2334 g_win32_get_system_data_dirs_for_module_real (void (*address_of_function)(void))
2335 {
2336   GArray *data_dirs;
2337   HMODULE hmodule;
2338   static GHashTable *per_module_data_dirs = NULL;
2339   gchar **retval;
2340   gchar *p;
2341   gchar *exe_root;
2342
2343   hmodule = NULL;
2344   if (address_of_function)
2345     {
2346       G_LOCK (g_utils_global);
2347       hmodule = get_module_for_address (address_of_function);
2348       if (hmodule != NULL)
2349         {
2350           if (per_module_data_dirs == NULL)
2351             per_module_data_dirs = g_hash_table_new (NULL, NULL);
2352           else
2353             {
2354               retval = g_hash_table_lookup (per_module_data_dirs, hmodule);
2355               
2356               if (retval != NULL)
2357                 {
2358                   G_UNLOCK (g_utils_global);
2359                   return (const gchar * const *) retval;
2360                 }
2361             }
2362         }
2363     }
2364
2365   data_dirs = g_array_new (TRUE, TRUE, sizeof (char *));
2366
2367   /* Documents and Settings\All Users\Application Data */
2368   p = get_special_folder (CSIDL_COMMON_APPDATA);
2369   if (p)
2370     g_array_append_val (data_dirs, p);
2371   
2372   /* Documents and Settings\All Users\Documents */
2373   p = get_special_folder (CSIDL_COMMON_DOCUMENTS);
2374   if (p)
2375     g_array_append_val (data_dirs, p);
2376         
2377   /* Using the above subfolders of Documents and Settings perhaps
2378    * makes sense from a Windows perspective.
2379    *
2380    * But looking at the actual use cases of this function in GTK+
2381    * and GNOME software, what we really want is the "share"
2382    * subdirectory of the installation directory for the package
2383    * our caller is a part of.
2384    *
2385    * The address_of_function parameter, if non-NULL, points to a
2386    * function in the calling module. Use that to determine that
2387    * module's installation folder, and use its "share" subfolder.
2388    *
2389    * Additionally, also use the "share" subfolder of the installation
2390    * locations of GLib and the .exe file being run.
2391    *
2392    * To guard against none of the above being what is really wanted,
2393    * callers of this function should have Win32-specific code to look
2394    * up their installation folder themselves, and handle a subfolder
2395    * "share" of it in the same way as the folders returned from this
2396    * function.
2397    */
2398
2399   p = get_module_share_dir (address_of_function);
2400   if (p)
2401     g_array_append_val (data_dirs, p);
2402     
2403   if (glib_dll != NULL)
2404     {
2405       gchar *glib_root = g_win32_get_package_installation_directory_of_module (glib_dll);
2406       p = g_build_filename (glib_root, "share", NULL);
2407       if (p)
2408         g_array_append_val (data_dirs, p);
2409       g_free (glib_root);
2410     }
2411   
2412   exe_root = g_win32_get_package_installation_directory_of_module (NULL);
2413   p = g_build_filename (exe_root, "share", NULL);
2414   if (p)
2415     g_array_append_val (data_dirs, p);
2416   g_free (exe_root);
2417
2418   retval = (gchar **) g_array_free (data_dirs, FALSE);
2419
2420   if (address_of_function)
2421     {
2422       if (hmodule != NULL)
2423         g_hash_table_insert (per_module_data_dirs, hmodule, retval);
2424       G_UNLOCK (g_utils_global);
2425     }
2426
2427   return (const gchar * const *) retval;
2428 }
2429
2430 const gchar * const *
2431 g_win32_get_system_data_dirs_for_module (void (*address_of_function)(void))
2432 {
2433   gboolean should_call_g_get_system_data_dirs;
2434
2435   should_call_g_get_system_data_dirs = TRUE;
2436   /* These checks are the same as the ones that g_build_system_data_dirs() does.
2437    * Please keep them in sync.
2438    */
2439   G_LOCK (g_utils_global);
2440
2441   if (!g_system_data_dirs)
2442     {
2443       const gchar *data_dirs = g_getenv ("XDG_DATA_DIRS");
2444
2445       if (!data_dirs || !data_dirs[0])
2446         should_call_g_get_system_data_dirs = FALSE;
2447     }
2448
2449   G_UNLOCK (g_utils_global);
2450
2451   /* There is a subtle difference between g_win32_get_system_data_dirs_for_module (NULL),
2452    * which is what GLib code can normally call,
2453    * and g_win32_get_system_data_dirs_for_module (&_g_win32_get_system_data_dirs),
2454    * which is what the inline function used by non-GLib code calls.
2455    * The former gets prefix relative to currently-running executable,
2456    * the latter - relative to the module that calls _g_win32_get_system_data_dirs()
2457    * (disguised as g_get_system_data_dirs()), which could be an executable or
2458    * a DLL that is located somewhere else.
2459    * This is why that inline function in gutils.h exists, and why we can't just
2460    * call g_get_system_data_dirs() from there - because we need to get the address
2461    * local to the non-GLib caller-module.
2462    */
2463
2464   /*
2465    * g_get_system_data_dirs() will fall back to calling
2466    * g_win32_get_system_data_dirs_for_module_real(NULL) if XDG_DATA_DIRS is NULL
2467    * or an empty string. The checks above ensure that we do not call it in such
2468    * cases and use the address_of_function that we've been given by the inline function.
2469    * The reason we're calling g_get_system_data_dirs /at all/ is to give
2470    * XDG_DATA_DIRS precedence (if it is set).
2471    */
2472   if (should_call_g_get_system_data_dirs)
2473     return g_get_system_data_dirs ();
2474
2475   return g_win32_get_system_data_dirs_for_module_real (address_of_function);
2476 }
2477
2478 #endif
2479
2480 static gchar **
2481 g_build_system_data_dirs (void)
2482 {
2483   gchar **data_dir_vector = NULL;
2484   gchar *data_dirs = (gchar *) g_getenv ("XDG_DATA_DIRS");
2485
2486   /* These checks are the same as the ones that g_win32_get_system_data_dirs_for_module()
2487    * does. Please keep them in sync.
2488    */
2489 #ifndef G_OS_WIN32
2490   if (!data_dirs || !data_dirs[0])
2491     data_dirs = "/usr/local/share/:/usr/share/";
2492
2493   data_dir_vector = g_strsplit (data_dirs, G_SEARCHPATH_SEPARATOR_S, 0);
2494 #else
2495   if (!data_dirs || !data_dirs[0])
2496     data_dir_vector = g_strdupv ((gchar **) g_win32_get_system_data_dirs_for_module_real (NULL));
2497   else
2498     data_dir_vector = g_strsplit (data_dirs, G_SEARCHPATH_SEPARATOR_S, 0);
2499 #endif
2500
2501   return g_steal_pointer (&data_dir_vector);
2502 }
2503
2504 /**
2505  * g_get_system_data_dirs:
2506  * 
2507  * Returns an ordered list of base directories in which to access 
2508  * system-wide application data.
2509  *
2510  * On UNIX platforms this is determined using the mechanisms described
2511  * in the
2512  * [XDG Base Directory Specification](http://www.freedesktop.org/Standards/basedir-spec)
2513  * In this case the list of directories retrieved will be `XDG_DATA_DIRS`.
2514  *
2515  * On Windows it follows XDG Base Directory Specification if `XDG_DATA_DIRS` is defined.
2516  * If `XDG_DATA_DIRS` is undefined,
2517  * the first elements in the list are the Application Data
2518  * and Documents folders for All Users. (These can be determined only
2519  * on Windows 2000 or later and are not present in the list on other
2520  * Windows versions.) See documentation for CSIDL_COMMON_APPDATA and
2521  * CSIDL_COMMON_DOCUMENTS.
2522  *
2523  * Then follows the "share" subfolder in the installation folder for
2524  * the package containing the DLL that calls this function, if it can
2525  * be determined.
2526  * 
2527  * Finally the list contains the "share" subfolder in the installation
2528  * folder for GLib, and in the installation folder for the package the
2529  * application's .exe file belongs to.
2530  *
2531  * The installation folders above are determined by looking up the
2532  * folder where the module (DLL or EXE) in question is located. If the
2533  * folder's name is "bin", its parent is used, otherwise the folder
2534  * itself.
2535  *
2536  * Note that on Windows the returned list can vary depending on where
2537  * this function is called.
2538  *
2539  * Returns: (array zero-terminated=1) (element-type filename) (transfer none):
2540  *     a %NULL-terminated array of strings owned by GLib that must not be
2541  *     modified or freed.
2542  * 
2543  * Since: 2.6
2544  **/
2545 const gchar * const * 
2546 g_get_system_data_dirs (void)
2547 {
2548   const gchar * const *system_data_dirs;
2549
2550   G_LOCK (g_utils_global);
2551
2552   if (g_system_data_dirs == NULL)
2553     g_system_data_dirs = g_build_system_data_dirs ();
2554   system_data_dirs = (const gchar * const *) g_system_data_dirs;
2555
2556   G_UNLOCK (g_utils_global);
2557
2558   return system_data_dirs;
2559 }
2560
2561 static gchar **
2562 g_build_system_config_dirs (void)
2563 {
2564   gchar **conf_dir_vector = NULL;
2565   const gchar *conf_dirs = g_getenv ("XDG_CONFIG_DIRS");
2566 #ifdef G_OS_WIN32
2567   if (conf_dirs)
2568     {
2569       conf_dir_vector = g_strsplit (conf_dirs, G_SEARCHPATH_SEPARATOR_S, 0);
2570     }
2571   else
2572     {
2573       gchar *special_conf_dirs = get_special_folder (CSIDL_COMMON_APPDATA);
2574
2575       if (special_conf_dirs)
2576         conf_dir_vector = g_strsplit (special_conf_dirs, G_SEARCHPATH_SEPARATOR_S, 0);
2577       else
2578         /* Return empty list */
2579         conf_dir_vector = g_strsplit ("", G_SEARCHPATH_SEPARATOR_S, 0);
2580
2581       g_free (special_conf_dirs);
2582     }
2583 #else
2584   if (!conf_dirs || !conf_dirs[0])
2585     conf_dirs = "/etc/xdg";
2586
2587   conf_dir_vector = g_strsplit (conf_dirs, G_SEARCHPATH_SEPARATOR_S, 0);
2588 #endif
2589
2590   return g_steal_pointer (&conf_dir_vector);
2591 }
2592
2593 /**
2594  * g_get_system_config_dirs:
2595  * 
2596  * Returns an ordered list of base directories in which to access 
2597  * system-wide configuration information.
2598  *
2599  * On UNIX platforms this is determined using the mechanisms described
2600  * in the
2601  * [XDG Base Directory Specification](http://www.freedesktop.org/Standards/basedir-spec).
2602  * In this case the list of directories retrieved will be `XDG_CONFIG_DIRS`.
2603  *
2604  * On Windows it follows XDG Base Directory Specification if `XDG_CONFIG_DIRS` is defined.
2605  * If `XDG_CONFIG_DIRS` is undefined, the directory that contains application
2606  * data for all users is used instead. A typical path is
2607  * `C:\Documents and Settings\All Users\Application Data`.
2608  * This folder is used for application data
2609  * that is not user specific. For example, an application can store
2610  * a spell-check dictionary, a database of clip art, or a log file in the
2611  * CSIDL_COMMON_APPDATA folder. This information will not roam and is available
2612  * to anyone using the computer.
2613  *
2614  * Returns: (array zero-terminated=1) (element-type filename) (transfer none):
2615  *     a %NULL-terminated array of strings owned by GLib that must not be
2616  *     modified or freed.
2617  * 
2618  * Since: 2.6
2619  **/
2620 const gchar * const *
2621 g_get_system_config_dirs (void)
2622 {
2623   const gchar * const *system_config_dirs;
2624
2625   G_LOCK (g_utils_global);
2626
2627   if (g_system_config_dirs == NULL)
2628     g_system_config_dirs = g_build_system_config_dirs ();
2629   system_config_dirs = (const gchar * const *) g_system_config_dirs;
2630
2631   G_UNLOCK (g_utils_global);
2632
2633   return system_config_dirs;
2634 }
2635
2636 /**
2637  * g_nullify_pointer:
2638  * @nullify_location: (not nullable): the memory address of the pointer.
2639  *
2640  * Set the pointer at the specified location to %NULL.
2641  **/
2642 void
2643 g_nullify_pointer (gpointer *nullify_location)
2644 {
2645   g_return_if_fail (nullify_location != NULL);
2646
2647   *nullify_location = NULL;
2648 }
2649
2650 #define KILOBYTE_FACTOR (G_GOFFSET_CONSTANT (1000))
2651 #define MEGABYTE_FACTOR (KILOBYTE_FACTOR * KILOBYTE_FACTOR)
2652 #define GIGABYTE_FACTOR (MEGABYTE_FACTOR * KILOBYTE_FACTOR)
2653 #define TERABYTE_FACTOR (GIGABYTE_FACTOR * KILOBYTE_FACTOR)
2654 #define PETABYTE_FACTOR (TERABYTE_FACTOR * KILOBYTE_FACTOR)
2655 #define EXABYTE_FACTOR  (PETABYTE_FACTOR * KILOBYTE_FACTOR)
2656
2657 #define KIBIBYTE_FACTOR (G_GOFFSET_CONSTANT (1024))
2658 #define MEBIBYTE_FACTOR (KIBIBYTE_FACTOR * KIBIBYTE_FACTOR)
2659 #define GIBIBYTE_FACTOR (MEBIBYTE_FACTOR * KIBIBYTE_FACTOR)
2660 #define TEBIBYTE_FACTOR (GIBIBYTE_FACTOR * KIBIBYTE_FACTOR)
2661 #define PEBIBYTE_FACTOR (TEBIBYTE_FACTOR * KIBIBYTE_FACTOR)
2662 #define EXBIBYTE_FACTOR (PEBIBYTE_FACTOR * KIBIBYTE_FACTOR)
2663
2664 /**
2665  * g_format_size:
2666  * @size: a size in bytes
2667  *
2668  * Formats a size (for example the size of a file) into a human readable
2669  * string.  Sizes are rounded to the nearest size prefix (kB, MB, GB)
2670  * and are displayed rounded to the nearest tenth. E.g. the file size
2671  * 3292528 bytes will be converted into the string "3.2 MB". The returned string
2672  * is UTF-8, and may use a non-breaking space to separate the number and units,
2673  * to ensure they aren’t separated when line wrapped.
2674  *
2675  * The prefix units base is 1000 (i.e. 1 kB is 1000 bytes).
2676  *
2677  * This string should be freed with g_free() when not needed any longer.
2678  *
2679  * See g_format_size_full() for more options about how the size might be
2680  * formatted.
2681  *
2682  * Returns: (transfer full): a newly-allocated formatted string containing
2683  *   a human readable file size
2684  *
2685  * Since: 2.30
2686  */
2687 gchar *
2688 g_format_size (guint64 size)
2689 {
2690   return g_format_size_full (size, G_FORMAT_SIZE_DEFAULT);
2691 }
2692
2693 /**
2694  * GFormatSizeFlags:
2695  * @G_FORMAT_SIZE_DEFAULT: behave the same as g_format_size()
2696  * @G_FORMAT_SIZE_LONG_FORMAT: include the exact number of bytes as part
2697  *     of the returned string.  For example, "45.6 kB (45,612 bytes)".
2698  * @G_FORMAT_SIZE_IEC_UNITS: use IEC (base 1024) units with "KiB"-style
2699  *     suffixes. IEC units should only be used for reporting things with
2700  *     a strong "power of 2" basis, like RAM sizes or RAID stripe sizes.
2701  *     Network and storage sizes should be reported in the normal SI units.
2702  * @G_FORMAT_SIZE_BITS: set the size as a quantity in bits, rather than
2703  *     bytes, and return units in bits. For example, â€˜Mb’ rather than â€˜MB’.
2704  *
2705  * Flags to modify the format of the string returned by g_format_size_full().
2706  */
2707
2708 #pragma GCC diagnostic push
2709 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
2710
2711 /**
2712  * g_format_size_full:
2713  * @size: a size in bytes
2714  * @flags: #GFormatSizeFlags to modify the output
2715  *
2716  * Formats a size.
2717  *
2718  * This function is similar to g_format_size() but allows for flags
2719  * that modify the output. See #GFormatSizeFlags.
2720  *
2721  * Returns: (transfer full): a newly-allocated formatted string
2722  *   containing a human readable file size
2723  *
2724  * Since: 2.30
2725  */
2726 gchar *
2727 g_format_size_full (guint64          size,
2728                     GFormatSizeFlags flags)
2729 {
2730   struct Format
2731   {
2732     guint64 factor;
2733     char string[10];
2734   };
2735
2736   typedef enum
2737   {
2738     FORMAT_BYTES,
2739     FORMAT_BYTES_IEC,
2740     FORMAT_BITS,
2741     FORMAT_BITS_IEC
2742   } FormatIndex;
2743
2744   const struct Format formats[4][6] = {
2745     {
2746       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2747       { KILOBYTE_FACTOR, N_("%.1f kB") },
2748       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2749       { MEGABYTE_FACTOR, N_("%.1f MB") },
2750       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2751       { GIGABYTE_FACTOR, N_("%.1f GB") },
2752       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2753       { TERABYTE_FACTOR, N_("%.1f TB") },
2754       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2755       { PETABYTE_FACTOR, N_("%.1f PB") },
2756       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2757       { EXABYTE_FACTOR,  N_("%.1f EB") }
2758     },
2759     {
2760       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2761       { KIBIBYTE_FACTOR, N_("%.1f KiB") },
2762       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2763       { MEBIBYTE_FACTOR, N_("%.1f MiB") },
2764       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2765       { GIBIBYTE_FACTOR, N_("%.1f GiB") },
2766       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2767       { TEBIBYTE_FACTOR, N_("%.1f TiB") },
2768       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2769       { PEBIBYTE_FACTOR, N_("%.1f PiB") },
2770       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2771       { EXBIBYTE_FACTOR, N_("%.1f EiB") }
2772     },
2773     {
2774       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2775       { KILOBYTE_FACTOR, N_("%.1f kb") },
2776       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2777       { MEGABYTE_FACTOR, N_("%.1f Mb") },
2778       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2779       { GIGABYTE_FACTOR, N_("%.1f Gb") },
2780       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2781       { TERABYTE_FACTOR, N_("%.1f Tb") },
2782       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2783       { PETABYTE_FACTOR, N_("%.1f Pb") },
2784       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2785       { EXABYTE_FACTOR,  N_("%.1f Eb") }
2786     },
2787     {
2788       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2789       { KIBIBYTE_FACTOR, N_("%.1f Kib") },
2790       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2791       { MEBIBYTE_FACTOR, N_("%.1f Mib") },
2792       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2793       { GIBIBYTE_FACTOR, N_("%.1f Gib") },
2794       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2795       { TEBIBYTE_FACTOR, N_("%.1f Tib") },
2796       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2797       { PEBIBYTE_FACTOR, N_("%.1f Pib") },
2798       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2799       { EXBIBYTE_FACTOR, N_("%.1f Eib") }
2800     }
2801   };
2802
2803   GString *string;
2804   FormatIndex index;
2805
2806   string = g_string_new (NULL);
2807
2808   switch (flags & ~G_FORMAT_SIZE_LONG_FORMAT)
2809     {
2810     case G_FORMAT_SIZE_DEFAULT:
2811       index = FORMAT_BYTES;
2812       break;
2813     case (G_FORMAT_SIZE_DEFAULT | G_FORMAT_SIZE_IEC_UNITS):
2814       index = FORMAT_BYTES_IEC;
2815       break;
2816     case G_FORMAT_SIZE_BITS:
2817       index = FORMAT_BITS;
2818       break;
2819     case (G_FORMAT_SIZE_BITS | G_FORMAT_SIZE_IEC_UNITS):
2820       index = FORMAT_BITS_IEC;
2821       break;
2822     default:
2823       g_assert_not_reached ();
2824     }
2825
2826
2827   if (size < formats[index][0].factor)
2828     {
2829       const char * format;
2830
2831       if (index == FORMAT_BYTES || index == FORMAT_BYTES_IEC)
2832         {
2833           format = g_dngettext (GETTEXT_PACKAGE, "%u byte", "%u bytes", (guint) size);
2834         }
2835       else
2836         {
2837           format = g_dngettext (GETTEXT_PACKAGE, "%u bit", "%u bits", (guint) size);
2838         }
2839
2840       g_string_printf (string, format, (guint) size);
2841
2842       flags &= ~G_FORMAT_SIZE_LONG_FORMAT;
2843     }
2844   else
2845     {
2846       const gsize n = G_N_ELEMENTS (formats[index]);
2847       gsize i;
2848
2849       /*
2850        * Point the last format (the highest unit) by default
2851        * and then then scan all formats, starting with the 2nd one
2852        * because the 1st is already managed by with the plural form
2853        */
2854       const struct Format * f = &formats[index][n - 1];
2855
2856       for (i = 1; i < n; i++)
2857         {
2858           if (size < formats[index][i].factor)
2859             {
2860               f = &formats[index][i - 1];
2861               break;
2862             }
2863         }
2864
2865       g_string_printf (string, _(f->string), (gdouble) size / (gdouble) f->factor);
2866     }
2867
2868   if (flags & G_FORMAT_SIZE_LONG_FORMAT)
2869     {
2870       /* First problem: we need to use the number of bytes to decide on
2871        * the plural form that is used for display, but the number of
2872        * bytes potentially exceeds the size of a guint (which is what
2873        * ngettext() takes).
2874        *
2875        * From a pragmatic standpoint, it seems that all known languages
2876        * base plural forms on one or both of the following:
2877        *
2878        *   - the lowest digits of the number
2879        *
2880        *   - if the number if greater than some small value
2881        *
2882        * Here's how we fake it:  Draw an arbitrary line at one thousand.
2883        * If the number is below that, then fine.  If it is above it,
2884        * then we take the modulus of the number by one thousand (in
2885        * order to keep the lowest digits) and add one thousand to that
2886        * (in order to ensure that 1001 is not treated the same as 1).
2887        */
2888       guint plural_form = size < 1000 ? size : size % 1000 + 1000;
2889
2890       /* Second problem: we need to translate the string "%u byte/bit" and
2891        * "%u bytes/bits" for pluralisation, but the correct number format to
2892        * use for a gsize is different depending on which architecture
2893        * we're on.
2894        *
2895        * Solution: format the number separately and use "%s bytes/bits" on
2896        * all platforms.
2897        */
2898       const gchar *translated_format;
2899       gchar *formatted_number;
2900
2901       if (index == FORMAT_BYTES || index == FORMAT_BYTES_IEC)
2902         {
2903           /* Translators: the %s in "%s bytes" will always be replaced by a number. */
2904           translated_format = g_dngettext (GETTEXT_PACKAGE, "%s byte", "%s bytes", plural_form);
2905         }
2906       else
2907         {
2908           /* Translators: the %s in "%s bits" will always be replaced by a number. */
2909           translated_format = g_dngettext (GETTEXT_PACKAGE, "%s bit", "%s bits", plural_form);
2910         }
2911       formatted_number = g_strdup_printf ("%'"G_GUINT64_FORMAT, size);
2912
2913       g_string_append (string, " (");
2914       g_string_append_printf (string, translated_format, formatted_number);
2915       g_free (formatted_number);
2916       g_string_append (string, ")");
2917     }
2918
2919   return g_string_free (string, FALSE);
2920 }
2921
2922 #pragma GCC diagnostic pop
2923
2924 /**
2925  * g_format_size_for_display:
2926  * @size: a size in bytes
2927  *
2928  * Formats a size (for example the size of a file) into a human
2929  * readable string. Sizes are rounded to the nearest size prefix
2930  * (KB, MB, GB) and are displayed rounded to the nearest tenth.
2931  * E.g. the file size 3292528 bytes will be converted into the
2932  * string "3.1 MB".
2933  *
2934  * The prefix units base is 1024 (i.e. 1 KB is 1024 bytes).
2935  *
2936  * This string should be freed with g_free() when not needed any longer.
2937  *
2938  * Returns: (transfer full): a newly-allocated formatted string
2939  *   containing a human readable file size
2940  *
2941  * Since: 2.16
2942  *
2943  * Deprecated:2.30: This function is broken due to its use of SI
2944  *     suffixes to denote IEC units. Use g_format_size() instead.
2945  */
2946 gchar *
2947 g_format_size_for_display (goffset size)
2948 {
2949   if (size < (goffset) KIBIBYTE_FACTOR)
2950     return g_strdup_printf (g_dngettext(GETTEXT_PACKAGE, "%u byte", "%u bytes",(guint) size), (guint) size);
2951   else
2952     {
2953       gdouble displayed_size;
2954
2955       if (size < (goffset) MEBIBYTE_FACTOR)
2956         {
2957           displayed_size = (gdouble) size / (gdouble) KIBIBYTE_FACTOR;
2958           /* Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to
2959            * mean 1024 bytes.  I am aware that 'KB' is not correct, but it has been preserved for reasons of
2960            * compatibility.  Users will not see this string unless a program is using this deprecated function.
2961            * Please translate as literally as possible.
2962            */
2963           return g_strdup_printf (_("%.1f KB"), displayed_size);
2964         }
2965       else if (size < (goffset) GIBIBYTE_FACTOR)
2966         {
2967           displayed_size = (gdouble) size / (gdouble) MEBIBYTE_FACTOR;
2968           return g_strdup_printf (_("%.1f MB"), displayed_size);
2969         }
2970       else if (size < (goffset) TEBIBYTE_FACTOR)
2971         {
2972           displayed_size = (gdouble) size / (gdouble) GIBIBYTE_FACTOR;
2973           return g_strdup_printf (_("%.1f GB"), displayed_size);
2974         }
2975       else if (size < (goffset) PEBIBYTE_FACTOR)
2976         {
2977           displayed_size = (gdouble) size / (gdouble) TEBIBYTE_FACTOR;
2978           return g_strdup_printf (_("%.1f TB"), displayed_size);
2979         }
2980       else if (size < (goffset) EXBIBYTE_FACTOR)
2981         {
2982           displayed_size = (gdouble) size / (gdouble) PEBIBYTE_FACTOR;
2983           return g_strdup_printf (_("%.1f PB"), displayed_size);
2984         }
2985       else
2986         {
2987           displayed_size = (gdouble) size / (gdouble) EXBIBYTE_FACTOR;
2988           return g_strdup_printf (_("%.1f EB"), displayed_size);
2989         }
2990     }
2991 }
2992
2993 #if defined (G_OS_WIN32) && !defined (_WIN64)
2994
2995 /* Binary compatibility versions. Not for newly compiled code. */
2996
2997 _GLIB_EXTERN const gchar *g_get_user_name_utf8        (void);
2998 _GLIB_EXTERN const gchar *g_get_real_name_utf8        (void);
2999 _GLIB_EXTERN const gchar *g_get_home_dir_utf8         (void);
3000 _GLIB_EXTERN const gchar *g_get_tmp_dir_utf8          (void);
3001 _GLIB_EXTERN gchar       *g_find_program_in_path_utf8 (const gchar *program);
3002
3003 gchar *
3004 g_find_program_in_path_utf8 (const gchar *program)
3005 {
3006   return g_find_program_in_path (program);
3007 }
3008
3009 const gchar *g_get_user_name_utf8 (void) { return g_get_user_name (); }
3010 const gchar *g_get_real_name_utf8 (void) { return g_get_real_name (); }
3011 const gchar *g_get_home_dir_utf8 (void) { return g_get_home_dir (); }
3012 const gchar *g_get_tmp_dir_utf8 (void) { return g_get_tmp_dir (); }
3013
3014 #endif
3015
3016 /* Private API:
3017  *
3018  * Returns %TRUE if the current process was executed as setuid
3019  */ 
3020 gboolean
3021 g_check_setuid (void)
3022 {
3023 #if defined(HAVE_SYS_AUXV_H) && defined(HAVE_GETAUXVAL) && defined(AT_SECURE)
3024   unsigned long value;
3025   int errsv;
3026
3027   errno = 0;
3028   value = getauxval (AT_SECURE);
3029   errsv = errno;
3030   if (errsv)
3031     g_error ("getauxval () failed: %s", g_strerror (errsv));
3032   return value;
3033 #elif defined(HAVE_ISSETUGID) && !defined(__BIONIC__)
3034   /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */
3035
3036   /* Android had it in older versions but the new 64 bit ABI does not
3037    * have it anymore, and some versions of the 32 bit ABI neither.
3038    * https://code.google.com/p/android-developer-preview/issues/detail?id=168
3039    */
3040   return issetugid ();
3041 #elif defined(G_OS_UNIX)
3042   uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
3043   gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */
3044
3045   static gsize check_setuid_initialised;
3046   static gboolean is_setuid;
3047
3048   if (g_once_init_enter (&check_setuid_initialised))
3049     {
3050 #ifdef HAVE_GETRESUID
3051       /* These aren't in the header files, so we prototype them here.
3052        */
3053       int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid);
3054       int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid);
3055       
3056       if (getresuid (&ruid, &euid, &suid) != 0 ||
3057           getresgid (&rgid, &egid, &sgid) != 0)
3058 #endif /* HAVE_GETRESUID */
3059         {
3060           suid = ruid = getuid ();
3061           sgid = rgid = getgid ();
3062           euid = geteuid ();
3063           egid = getegid ();
3064         }
3065
3066       is_setuid = (ruid != euid || ruid != suid ||
3067                    rgid != egid || rgid != sgid);
3068
3069       g_once_init_leave (&check_setuid_initialised, 1);
3070     }
3071   return is_setuid;
3072 #else
3073   return FALSE;
3074 #endif
3075 }
3076
3077 #ifdef G_OS_WIN32
3078 /**
3079  * g_abort:
3080  *
3081  * A wrapper for the POSIX abort() function.
3082  *
3083  * On Windows it is a function that makes extra effort (including a call
3084  * to abort()) to ensure that a debugger-catchable exception is thrown
3085  * before the program terminates.
3086  *
3087  * See your C library manual for more details about abort().
3088  *
3089  * Since: 2.50
3090  */
3091 void
3092 g_abort (void)
3093 {
3094   /* One call to break the debugger */
3095   DebugBreak ();
3096   /* One call in case CRT changes its abort() behaviour */
3097   abort ();
3098   /* And one call to bind them all and terminate the program for sure */
3099   ExitProcess (127);
3100 }
3101 #endif