• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 *
_glib_get_dll_directory(void)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
g_atexit(GVoidFunc func)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*
my_strchrnul(const gchar * str,gchar c)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*
g_find_program_in_path(const gchar * program)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 *
inner_find_program_in_path(const gchar * program)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  */
gint(g_bit_nth_lsf)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  */
gint(g_bit_nth_msf)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  */
guint(g_bit_storage)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 *
get_special_folder(int csidl)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 *
get_windows_directory_root(void)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 *
g_get_user_database_entry(void)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 *
g_get_user_name(void)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 *
g_get_real_name(void)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 *
g_build_home_dir(void)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 *
g_get_home_dir(void)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 *
g_get_tmp_dir(void)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 *
g_get_host_name(void)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*
g_get_prgname(void)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
g_set_prgname(const gchar * prgname)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 *
g_get_application_name(void)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
g_set_application_name(const gchar * application_name)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 *
get_registry_str(HKEY root_key,const wchar_t * path,const wchar_t * value_name)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 *
get_windows_8_1_update(void)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 *
get_windows_version(gboolean with_windows)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 *
get_os_info_from_os_release(const gchar * key_name,const gchar * buffer)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 *
get_os_info_from_uname(const gchar * key_name)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 *
g_get_os_info(const gchar * key_name)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
set_str_if_different(gchar ** global_str,const gchar * type,const gchar * new_value)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       g_ignore_leak (*global_str);
1605       *global_str = g_strdup (new_value);
1606     }
1607 }
1608 
1609 static void
set_strv_if_different(gchar *** global_strv,const gchar * type,const gchar * const * new_value)1610 set_strv_if_different (gchar                ***global_strv,
1611                        const gchar            *type,
1612                        const gchar  * const   *new_value)
1613 {
1614   if (*global_strv == NULL ||
1615       !g_strv_equal (new_value, (const gchar * const *) *global_strv))
1616     {
1617       gchar *new_value_str = g_strjoinv (":", (gchar **) new_value);
1618       g_debug ("g_set_user_dirs: Setting %s to %s", type, new_value_str);
1619       g_free (new_value_str);
1620 
1621       /* We have to leak the old value, as user code could be retaining pointers
1622        * to it. */
1623       g_ignore_strv_leak (*global_strv);
1624       *global_strv = g_strdupv ((gchar **) new_value);
1625     }
1626 }
1627 
1628 /*
1629  * g_set_user_dirs:
1630  * @first_dir_type: Type of the first directory to set
1631  * @...: Value to set the first directory to, followed by additional type/value
1632  *    pairs, followed by %NULL
1633  *
1634  * Set one or more ‘user’ directories to custom values. This is intended to be
1635  * used by test code (particularly with the %G_TEST_OPTION_ISOLATE_DIRS option)
1636  * to override the values returned by the following functions, so that test
1637  * code can be run without touching an installed system and user data:
1638  *
1639  *  - g_get_home_dir() — use type `HOME`, pass a string
1640  *  - g_get_user_cache_dir() — use type `XDG_CACHE_HOME`, pass a string
1641  *  - g_get_system_config_dirs() — use type `XDG_CONFIG_DIRS`, pass a
1642  *    %NULL-terminated string array
1643  *  - g_get_user_config_dir() — use type `XDG_CONFIG_HOME`, pass a string
1644  *  - g_get_system_data_dirs() — use type `XDG_DATA_DIRS`, pass a
1645  *    %NULL-terminated string array
1646  *  - g_get_user_data_dir() — use type `XDG_DATA_HOME`, pass a string
1647  *  - g_get_user_runtime_dir() — use type `XDG_RUNTIME_DIR`, pass a string
1648  *
1649  * The list must be terminated with a %NULL type. All of the values must be
1650  * non-%NULL — passing %NULL as a value won’t reset a directory. If a reference
1651  * to a directory from the calling environment needs to be kept, copy it before
1652  * the first call to g_set_user_dirs(). g_set_user_dirs() can be called multiple
1653  * times.
1654  *
1655  * Since: 2.60
1656  */
1657 /*< private > */
1658 void
g_set_user_dirs(const gchar * first_dir_type,...)1659 g_set_user_dirs (const gchar *first_dir_type,
1660                  ...)
1661 {
1662   va_list args;
1663   const gchar *dir_type;
1664 
1665   G_LOCK (g_utils_global);
1666 
1667   va_start (args, first_dir_type);
1668 
1669   for (dir_type = first_dir_type; dir_type != NULL; dir_type = va_arg (args, const gchar *))
1670     {
1671       gconstpointer dir_value = va_arg (args, gconstpointer);
1672       g_assert (dir_value != NULL);
1673 
1674       if (g_str_equal (dir_type, "HOME"))
1675         set_str_if_different (&g_home_dir, dir_type, dir_value);
1676       else if (g_str_equal (dir_type, "XDG_CACHE_HOME"))
1677         set_str_if_different (&g_user_cache_dir, dir_type, dir_value);
1678       else if (g_str_equal (dir_type, "XDG_CONFIG_DIRS"))
1679         set_strv_if_different (&g_system_config_dirs, dir_type, dir_value);
1680       else if (g_str_equal (dir_type, "XDG_CONFIG_HOME"))
1681         set_str_if_different (&g_user_config_dir, dir_type, dir_value);
1682       else if (g_str_equal (dir_type, "XDG_DATA_DIRS"))
1683         set_strv_if_different (&g_system_data_dirs, dir_type, dir_value);
1684       else if (g_str_equal (dir_type, "XDG_DATA_HOME"))
1685         set_str_if_different (&g_user_data_dir, dir_type, dir_value);
1686       else if (g_str_equal (dir_type, "XDG_RUNTIME_DIR"))
1687         set_str_if_different (&g_user_runtime_dir, dir_type, dir_value);
1688       else
1689         g_assert_not_reached ();
1690     }
1691 
1692   va_end (args);
1693 
1694   G_UNLOCK (g_utils_global);
1695 }
1696 
1697 static gchar *
g_build_user_data_dir(void)1698 g_build_user_data_dir (void)
1699 {
1700   gchar *data_dir = NULL;
1701   const gchar *data_dir_env = g_getenv ("XDG_DATA_HOME");
1702 
1703   if (data_dir_env && data_dir_env[0])
1704     data_dir = g_strdup (data_dir_env);
1705 #ifdef G_OS_WIN32
1706   else
1707     data_dir = get_special_folder (CSIDL_LOCAL_APPDATA);
1708 #endif
1709   if (!data_dir || !data_dir[0])
1710     {
1711       gchar *home_dir = g_build_home_dir ();
1712       data_dir = g_build_filename (home_dir, ".local", "share", NULL);
1713       g_free (home_dir);
1714     }
1715 
1716   return g_steal_pointer (&data_dir);
1717 }
1718 
1719 /**
1720  * g_get_user_data_dir:
1721  *
1722  * Returns a base directory in which to access application data such
1723  * as icons that is customized for a particular user.
1724  *
1725  * On UNIX platforms this is determined using the mechanisms described
1726  * in the
1727  * [XDG Base Directory Specification](http://www.freedesktop.org/Standards/basedir-spec).
1728  * In this case the directory retrieved will be `XDG_DATA_HOME`.
1729  *
1730  * On Windows it follows XDG Base Directory Specification if `XDG_DATA_HOME`
1731  * is defined. If `XDG_DATA_HOME` is undefined, the folder to use for local (as
1732  * opposed to roaming) application data is used instead. See the
1733  * [documentation for `CSIDL_LOCAL_APPDATA`](https://msdn.microsoft.com/en-us/library/windows/desktop/bb762494%28v=vs.85%29.aspx#csidl_local_appdata).
1734  * Note that in this case on Windows it will be the same
1735  * as what g_get_user_config_dir() returns.
1736  *
1737  * The return value is cached and modifying it at runtime is not supported, as
1738  * it’s not thread-safe to modify environment variables at runtime.
1739  *
1740  * Returns: (type filename) (transfer none): a string owned by GLib that must
1741  *   not be modified or freed.
1742  *
1743  * Since: 2.6
1744  **/
1745 const gchar *
g_get_user_data_dir(void)1746 g_get_user_data_dir (void)
1747 {
1748   const gchar *user_data_dir;
1749 
1750   G_LOCK (g_utils_global);
1751 
1752   if (g_user_data_dir == NULL)
1753     g_user_data_dir = g_build_user_data_dir ();
1754   user_data_dir = g_user_data_dir;
1755 
1756   G_UNLOCK (g_utils_global);
1757 
1758   return user_data_dir;
1759 }
1760 
1761 static gchar *
g_build_user_config_dir(void)1762 g_build_user_config_dir (void)
1763 {
1764   gchar *config_dir = NULL;
1765   const gchar *config_dir_env = g_getenv ("XDG_CONFIG_HOME");
1766 
1767   if (config_dir_env && config_dir_env[0])
1768     config_dir = g_strdup (config_dir_env);
1769 #ifdef G_OS_WIN32
1770   else
1771     config_dir = get_special_folder (CSIDL_LOCAL_APPDATA);
1772 #endif
1773   if (!config_dir || !config_dir[0])
1774     {
1775       gchar *home_dir = g_build_home_dir ();
1776       config_dir = g_build_filename (home_dir, ".config", NULL);
1777       g_free (home_dir);
1778     }
1779 
1780   return g_steal_pointer (&config_dir);
1781 }
1782 
1783 /**
1784  * g_get_user_config_dir:
1785  *
1786  * Returns a base directory in which to store user-specific application
1787  * configuration information such as user preferences and settings.
1788  *
1789  * On UNIX platforms this is determined using the mechanisms described
1790  * in the
1791  * [XDG Base Directory Specification](http://www.freedesktop.org/Standards/basedir-spec).
1792  * In this case the directory retrieved will be `XDG_CONFIG_HOME`.
1793  *
1794  * On Windows it follows XDG Base Directory Specification if `XDG_CONFIG_HOME` is defined.
1795  * If `XDG_CONFIG_HOME` is undefined, the folder to use for local (as opposed
1796  * to roaming) application data is used instead. See the
1797  * [documentation for `CSIDL_LOCAL_APPDATA`](https://msdn.microsoft.com/en-us/library/windows/desktop/bb762494%28v=vs.85%29.aspx#csidl_local_appdata).
1798  * Note that in this case on Windows it will be  the same
1799  * as what g_get_user_data_dir() returns.
1800  *
1801  * The return value is cached and modifying it at runtime is not supported, as
1802  * it’s not thread-safe to modify environment variables at runtime.
1803  *
1804  * Returns: (type filename) (transfer none): a string owned by GLib that
1805  *   must not be modified or freed.
1806  * Since: 2.6
1807  **/
1808 const gchar *
g_get_user_config_dir(void)1809 g_get_user_config_dir (void)
1810 {
1811   const gchar *user_config_dir;
1812 
1813   G_LOCK (g_utils_global);
1814 
1815   if (g_user_config_dir == NULL)
1816     g_user_config_dir = g_build_user_config_dir ();
1817   user_config_dir = g_user_config_dir;
1818 
1819   G_UNLOCK (g_utils_global);
1820 
1821   return user_config_dir;
1822 }
1823 
1824 static gchar *
g_build_user_cache_dir(void)1825 g_build_user_cache_dir (void)
1826 {
1827   gchar *cache_dir = NULL;
1828   const gchar *cache_dir_env = g_getenv ("XDG_CACHE_HOME");
1829 
1830   if (cache_dir_env && cache_dir_env[0])
1831     cache_dir = g_strdup (cache_dir_env);
1832 #ifdef G_OS_WIN32
1833   else
1834     cache_dir = get_special_folder (CSIDL_INTERNET_CACHE);
1835 #endif
1836   if (!cache_dir || !cache_dir[0])
1837     {
1838       gchar *home_dir = g_build_home_dir ();
1839       cache_dir = g_build_filename (home_dir, ".cache", NULL);
1840       g_free (home_dir);
1841     }
1842 
1843   return g_steal_pointer (&cache_dir);
1844 }
1845 
1846 /**
1847  * g_get_user_cache_dir:
1848  *
1849  * Returns a base directory in which to store non-essential, cached
1850  * data specific to particular user.
1851  *
1852  * On UNIX platforms this is determined using the mechanisms described
1853  * in the
1854  * [XDG Base Directory Specification](http://www.freedesktop.org/Standards/basedir-spec).
1855  * In this case the directory retrieved will be `XDG_CACHE_HOME`.
1856  *
1857  * On Windows it follows XDG Base Directory Specification if `XDG_CACHE_HOME` is defined.
1858  * If `XDG_CACHE_HOME` is undefined, the directory that serves as a common
1859  * repository for temporary Internet files is used instead. A typical path is
1860  * `C:\Documents and Settings\username\Local Settings\Temporary Internet Files`.
1861  * 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).
1862  *
1863  * The return value is cached and modifying it at runtime is not supported, as
1864  * it’s not thread-safe to modify environment variables at runtime.
1865  *
1866  * Returns: (type filename) (transfer none): a string owned by GLib that
1867  *   must not be modified or freed.
1868  * Since: 2.6
1869  **/
1870 const gchar *
g_get_user_cache_dir(void)1871 g_get_user_cache_dir (void)
1872 {
1873   const gchar *user_cache_dir;
1874 
1875   G_LOCK (g_utils_global);
1876 
1877   if (g_user_cache_dir == NULL)
1878     g_user_cache_dir = g_build_user_cache_dir ();
1879   user_cache_dir = g_user_cache_dir;
1880 
1881   G_UNLOCK (g_utils_global);
1882 
1883   return user_cache_dir;
1884 }
1885 
1886 static gchar *
g_build_user_runtime_dir(void)1887 g_build_user_runtime_dir (void)
1888 {
1889   gchar *runtime_dir = NULL;
1890   const gchar *runtime_dir_env = g_getenv ("XDG_RUNTIME_DIR");
1891 
1892   if (runtime_dir_env && runtime_dir_env[0])
1893     runtime_dir = g_strdup (runtime_dir_env);
1894   else
1895     {
1896       runtime_dir = g_build_user_cache_dir ();
1897 
1898       /* The user should be able to rely on the directory existing
1899        * when the function returns.  Probably it already does, but
1900        * let's make sure.  Just do mkdir() directly since it will be
1901        * no more expensive than a stat() in the case that the
1902        * directory already exists and is a lot easier.
1903        *
1904        * $XDG_CACHE_HOME is probably ~/.cache/ so as long as $HOME
1905        * exists this will work.  If the user changed $XDG_CACHE_HOME
1906        * then they can make sure that it exists...
1907        */
1908       (void) g_mkdir (runtime_dir, 0700);
1909     }
1910 
1911   return g_steal_pointer (&runtime_dir);
1912 }
1913 
1914 /**
1915  * g_get_user_runtime_dir:
1916  *
1917  * Returns a directory that is unique to the current user on the local
1918  * system.
1919  *
1920  * This is determined using the mechanisms described
1921  * in the
1922  * [XDG Base Directory Specification](http://www.freedesktop.org/Standards/basedir-spec).
1923  * This is the directory
1924  * specified in the `XDG_RUNTIME_DIR` environment variable.
1925  * In the case that this variable is not set, we return the value of
1926  * g_get_user_cache_dir(), after verifying that it exists.
1927  *
1928  * The return value is cached and modifying it at runtime is not supported, as
1929  * it’s not thread-safe to modify environment variables at runtime.
1930  *
1931  * Returns: (type filename): a string owned by GLib that must not be
1932  *     modified or freed.
1933  *
1934  * Since: 2.28
1935  **/
1936 const gchar *
g_get_user_runtime_dir(void)1937 g_get_user_runtime_dir (void)
1938 {
1939   const gchar *user_runtime_dir;
1940 
1941   G_LOCK (g_utils_global);
1942 
1943   if (g_user_runtime_dir == NULL)
1944     g_user_runtime_dir = g_build_user_runtime_dir ();
1945   user_runtime_dir = g_user_runtime_dir;
1946 
1947   G_UNLOCK (g_utils_global);
1948 
1949   return user_runtime_dir;
1950 }
1951 
1952 #ifdef HAVE_COCOA
1953 
1954 /* Implemented in gutils-macos.m */
1955 void load_user_special_dirs_macos (gchar **table);
1956 
1957 static void
load_user_special_dirs(void)1958 load_user_special_dirs (void)
1959 {
1960   load_user_special_dirs_macos (g_user_special_dirs);
1961 }
1962 
1963 #elif defined(G_OS_WIN32)
1964 
1965 static void
load_user_special_dirs(void)1966 load_user_special_dirs (void)
1967 {
1968   typedef HRESULT (WINAPI *t_SHGetKnownFolderPath) (const GUID *rfid,
1969 						    DWORD dwFlags,
1970 						    HANDLE hToken,
1971 						    PWSTR *ppszPath);
1972   t_SHGetKnownFolderPath p_SHGetKnownFolderPath;
1973 
1974   static const GUID FOLDERID_Downloads =
1975     { 0x374de290, 0x123f, 0x4565, { 0x91, 0x64, 0x39, 0xc4, 0x92, 0x5e, 0x46, 0x7b } };
1976   static const GUID FOLDERID_Public =
1977     { 0xDFDF76A2, 0xC82A, 0x4D63, { 0x90, 0x6A, 0x56, 0x44, 0xAC, 0x45, 0x73, 0x85 } };
1978 
1979   wchar_t *wcp;
1980 
1981   p_SHGetKnownFolderPath = (t_SHGetKnownFolderPath) GetProcAddress (GetModuleHandleW (L"shell32.dll"),
1982 								    "SHGetKnownFolderPath");
1983 
1984   g_user_special_dirs[G_USER_DIRECTORY_DESKTOP] = get_special_folder (CSIDL_DESKTOPDIRECTORY);
1985   g_user_special_dirs[G_USER_DIRECTORY_DOCUMENTS] = get_special_folder (CSIDL_PERSONAL);
1986 
1987   if (p_SHGetKnownFolderPath == NULL)
1988     {
1989       g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] = get_special_folder (CSIDL_DESKTOPDIRECTORY);
1990     }
1991   else
1992     {
1993       wcp = NULL;
1994       (*p_SHGetKnownFolderPath) (&FOLDERID_Downloads, 0, NULL, &wcp);
1995       if (wcp)
1996         {
1997           g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] = g_utf16_to_utf8 (wcp, -1, NULL, NULL, NULL);
1998           if (g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] == NULL)
1999               g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] = get_special_folder (CSIDL_DESKTOPDIRECTORY);
2000           CoTaskMemFree (wcp);
2001         }
2002       else
2003           g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] = get_special_folder (CSIDL_DESKTOPDIRECTORY);
2004     }
2005 
2006   g_user_special_dirs[G_USER_DIRECTORY_MUSIC] = get_special_folder (CSIDL_MYMUSIC);
2007   g_user_special_dirs[G_USER_DIRECTORY_PICTURES] = get_special_folder (CSIDL_MYPICTURES);
2008 
2009   if (p_SHGetKnownFolderPath == NULL)
2010     {
2011       /* XXX */
2012       g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] = get_special_folder (CSIDL_COMMON_DOCUMENTS);
2013     }
2014   else
2015     {
2016       wcp = NULL;
2017       (*p_SHGetKnownFolderPath) (&FOLDERID_Public, 0, NULL, &wcp);
2018       if (wcp)
2019         {
2020           g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] = g_utf16_to_utf8 (wcp, -1, NULL, NULL, NULL);
2021           if (g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] == NULL)
2022               g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] = get_special_folder (CSIDL_COMMON_DOCUMENTS);
2023           CoTaskMemFree (wcp);
2024         }
2025       else
2026           g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] = get_special_folder (CSIDL_COMMON_DOCUMENTS);
2027     }
2028 
2029   g_user_special_dirs[G_USER_DIRECTORY_TEMPLATES] = get_special_folder (CSIDL_TEMPLATES);
2030   g_user_special_dirs[G_USER_DIRECTORY_VIDEOS] = get_special_folder (CSIDL_MYVIDEO);
2031 }
2032 
2033 #else /* default is unix */
2034 
2035 /* adapted from xdg-user-dir-lookup.c
2036  *
2037  * Copyright (C) 2007 Red Hat Inc.
2038  *
2039  * Permission is hereby granted, free of charge, to any person
2040  * obtaining a copy of this software and associated documentation files
2041  * (the "Software"), to deal in the Software without restriction,
2042  * including without limitation the rights to use, copy, modify, merge,
2043  * publish, distribute, sublicense, and/or sell copies of the Software,
2044  * and to permit persons to whom the Software is furnished to do so,
2045  * subject to the following conditions:
2046  *
2047  * The above copyright notice and this permission notice shall be
2048  * included in all copies or substantial portions of the Software.
2049  *
2050  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
2051  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2052  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
2053  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
2054  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
2055  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
2056  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2057  * SOFTWARE.
2058  */
2059 static void
load_user_special_dirs(void)2060 load_user_special_dirs (void)
2061 {
2062   gchar *config_dir = NULL;
2063   gchar *config_file;
2064   gchar *data;
2065   gchar **lines;
2066   gint n_lines, i;
2067 
2068   config_dir = g_build_user_config_dir ();
2069   config_file = g_build_filename (config_dir,
2070                                   "user-dirs.dirs",
2071                                   NULL);
2072   g_free (config_dir);
2073 
2074   if (!g_file_get_contents (config_file, &data, NULL, NULL))
2075     {
2076       g_free (config_file);
2077       return;
2078     }
2079 
2080   lines = g_strsplit (data, "\n", -1);
2081   n_lines = g_strv_length (lines);
2082   g_free (data);
2083 
2084   for (i = 0; i < n_lines; i++)
2085     {
2086       gchar *buffer = lines[i];
2087       gchar *d, *p;
2088       gint len;
2089       gboolean is_relative = FALSE;
2090       GUserDirectory directory;
2091 
2092       /* Remove newline at end */
2093       len = strlen (buffer);
2094       if (len > 0 && buffer[len - 1] == '\n')
2095 	buffer[len - 1] = 0;
2096 
2097       p = buffer;
2098       while (*p == ' ' || *p == '\t')
2099 	p++;
2100 
2101       if (strncmp (p, "XDG_DESKTOP_DIR", strlen ("XDG_DESKTOP_DIR")) == 0)
2102         {
2103           directory = G_USER_DIRECTORY_DESKTOP;
2104           p += strlen ("XDG_DESKTOP_DIR");
2105         }
2106       else if (strncmp (p, "XDG_DOCUMENTS_DIR", strlen ("XDG_DOCUMENTS_DIR")) == 0)
2107         {
2108           directory = G_USER_DIRECTORY_DOCUMENTS;
2109           p += strlen ("XDG_DOCUMENTS_DIR");
2110         }
2111       else if (strncmp (p, "XDG_DOWNLOAD_DIR", strlen ("XDG_DOWNLOAD_DIR")) == 0)
2112         {
2113           directory = G_USER_DIRECTORY_DOWNLOAD;
2114           p += strlen ("XDG_DOWNLOAD_DIR");
2115         }
2116       else if (strncmp (p, "XDG_MUSIC_DIR", strlen ("XDG_MUSIC_DIR")) == 0)
2117         {
2118           directory = G_USER_DIRECTORY_MUSIC;
2119           p += strlen ("XDG_MUSIC_DIR");
2120         }
2121       else if (strncmp (p, "XDG_PICTURES_DIR", strlen ("XDG_PICTURES_DIR")) == 0)
2122         {
2123           directory = G_USER_DIRECTORY_PICTURES;
2124           p += strlen ("XDG_PICTURES_DIR");
2125         }
2126       else if (strncmp (p, "XDG_PUBLICSHARE_DIR", strlen ("XDG_PUBLICSHARE_DIR")) == 0)
2127         {
2128           directory = G_USER_DIRECTORY_PUBLIC_SHARE;
2129           p += strlen ("XDG_PUBLICSHARE_DIR");
2130         }
2131       else if (strncmp (p, "XDG_TEMPLATES_DIR", strlen ("XDG_TEMPLATES_DIR")) == 0)
2132         {
2133           directory = G_USER_DIRECTORY_TEMPLATES;
2134           p += strlen ("XDG_TEMPLATES_DIR");
2135         }
2136       else if (strncmp (p, "XDG_VIDEOS_DIR", strlen ("XDG_VIDEOS_DIR")) == 0)
2137         {
2138           directory = G_USER_DIRECTORY_VIDEOS;
2139           p += strlen ("XDG_VIDEOS_DIR");
2140         }
2141       else
2142 	continue;
2143 
2144       while (*p == ' ' || *p == '\t')
2145 	p++;
2146 
2147       if (*p != '=')
2148 	continue;
2149       p++;
2150 
2151       while (*p == ' ' || *p == '\t')
2152 	p++;
2153 
2154       if (*p != '"')
2155 	continue;
2156       p++;
2157 
2158       if (strncmp (p, "$HOME", 5) == 0)
2159 	{
2160 	  p += 5;
2161 	  is_relative = TRUE;
2162 	}
2163       else if (*p != '/')
2164 	continue;
2165 
2166       d = strrchr (p, '"');
2167       if (!d)
2168         continue;
2169       *d = 0;
2170 
2171       d = p;
2172 
2173       /* remove trailing slashes */
2174       len = strlen (d);
2175       if (d[len - 1] == '/')
2176         d[len - 1] = 0;
2177 
2178       if (is_relative)
2179         {
2180           gchar *home_dir = g_build_home_dir ();
2181           g_user_special_dirs[directory] = g_build_filename (home_dir, d, NULL);
2182           g_free (home_dir);
2183         }
2184       else
2185 	g_user_special_dirs[directory] = g_strdup (d);
2186     }
2187 
2188   g_strfreev (lines);
2189   g_free (config_file);
2190 }
2191 
2192 #endif /* platform-specific load_user_special_dirs implementations */
2193 
2194 
2195 /**
2196  * g_reload_user_special_dirs_cache:
2197  *
2198  * Resets the cache used for g_get_user_special_dir(), so
2199  * that the latest on-disk version is used. Call this only
2200  * if you just changed the data on disk yourself.
2201  *
2202  * Due to thread safety issues this may cause leaking of strings
2203  * that were previously returned from g_get_user_special_dir()
2204  * that can't be freed. We ensure to only leak the data for
2205  * the directories that actually changed value though.
2206  *
2207  * Since: 2.22
2208  */
2209 void
g_reload_user_special_dirs_cache(void)2210 g_reload_user_special_dirs_cache (void)
2211 {
2212   int i;
2213 
2214   G_LOCK (g_utils_global);
2215 
2216   if (g_user_special_dirs != NULL)
2217     {
2218       /* save a copy of the pointer, to check if some memory can be preserved */
2219       char **old_g_user_special_dirs = g_user_special_dirs;
2220       char *old_val;
2221 
2222       /* recreate and reload our cache */
2223       g_user_special_dirs = g_new0 (gchar *, G_USER_N_DIRECTORIES);
2224       load_user_special_dirs ();
2225 
2226       /* only leak changed directories */
2227       for (i = 0; i < G_USER_N_DIRECTORIES; i++)
2228         {
2229           old_val = old_g_user_special_dirs[i];
2230           if (g_user_special_dirs[i] == NULL)
2231             {
2232               g_user_special_dirs[i] = old_val;
2233             }
2234           else if (g_strcmp0 (old_val, g_user_special_dirs[i]) == 0)
2235             {
2236               /* don't leak */
2237               g_free (g_user_special_dirs[i]);
2238               g_user_special_dirs[i] = old_val;
2239             }
2240           else
2241             g_free (old_val);
2242         }
2243 
2244       /* free the old array */
2245       g_free (old_g_user_special_dirs);
2246     }
2247 
2248   G_UNLOCK (g_utils_global);
2249 }
2250 
2251 /**
2252  * g_get_user_special_dir:
2253  * @directory: the logical id of special directory
2254  *
2255  * Returns the full path of a special directory using its logical id.
2256  *
2257  * On UNIX this is done using the XDG special user directories.
2258  * For compatibility with existing practise, %G_USER_DIRECTORY_DESKTOP
2259  * falls back to `$HOME/Desktop` when XDG special user directories have
2260  * not been set up.
2261  *
2262  * Depending on the platform, the user might be able to change the path
2263  * of the special directory without requiring the session to restart; GLib
2264  * will not reflect any change once the special directories are loaded.
2265  *
2266  * Returns: (type filename): the path to the specified special directory, or
2267  *   %NULL if the logical id was not found. The returned string is owned by
2268  *   GLib and should not be modified or freed.
2269  *
2270  * Since: 2.14
2271  */
2272 const gchar *
g_get_user_special_dir(GUserDirectory directory)2273 g_get_user_special_dir (GUserDirectory directory)
2274 {
2275   const gchar *user_special_dir;
2276 
2277   g_return_val_if_fail (directory >= G_USER_DIRECTORY_DESKTOP &&
2278                         directory < G_USER_N_DIRECTORIES, NULL);
2279 
2280   G_LOCK (g_utils_global);
2281 
2282   if (G_UNLIKELY (g_user_special_dirs == NULL))
2283     {
2284       g_user_special_dirs = g_new0 (gchar *, G_USER_N_DIRECTORIES);
2285 
2286       load_user_special_dirs ();
2287 
2288       /* Special-case desktop for historical compatibility */
2289       if (g_user_special_dirs[G_USER_DIRECTORY_DESKTOP] == NULL)
2290         {
2291           gchar *home_dir = g_build_home_dir ();
2292           g_user_special_dirs[G_USER_DIRECTORY_DESKTOP] = g_build_filename (home_dir, "Desktop", NULL);
2293           g_free (home_dir);
2294         }
2295     }
2296   user_special_dir = g_user_special_dirs[directory];
2297 
2298   G_UNLOCK (g_utils_global);
2299 
2300   return user_special_dir;
2301 }
2302 
2303 #ifdef G_OS_WIN32
2304 
2305 #undef g_get_system_data_dirs
2306 
2307 static HMODULE
get_module_for_address(gconstpointer address)2308 get_module_for_address (gconstpointer address)
2309 {
2310   /* Holds the g_utils_global lock */
2311 
2312   HMODULE hmodule = NULL;
2313 
2314   if (!address)
2315     return NULL;
2316 
2317   if (!GetModuleHandleExW (GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT |
2318 			   GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
2319 			   address, &hmodule))
2320     {
2321       MEMORY_BASIC_INFORMATION mbi;
2322       VirtualQuery (address, &mbi, sizeof (mbi));
2323       hmodule = (HMODULE) mbi.AllocationBase;
2324     }
2325 
2326   return hmodule;
2327 }
2328 
2329 static gchar *
get_module_share_dir(gconstpointer address)2330 get_module_share_dir (gconstpointer address)
2331 {
2332   HMODULE hmodule;
2333   gchar *filename;
2334   gchar *retval;
2335 
2336   hmodule = get_module_for_address (address);
2337   if (hmodule == NULL)
2338     return NULL;
2339 
2340   filename = g_win32_get_package_installation_directory_of_module (hmodule);
2341   retval = g_build_filename (filename, "share", NULL);
2342   g_free (filename);
2343 
2344   return retval;
2345 }
2346 
2347 static const gchar * const *
g_win32_get_system_data_dirs_for_module_real(void (* address_of_function)(void))2348 g_win32_get_system_data_dirs_for_module_real (void (*address_of_function)(void))
2349 {
2350   GArray *data_dirs;
2351   HMODULE hmodule;
2352   static GHashTable *per_module_data_dirs = NULL;
2353   gchar **retval;
2354   gchar *p;
2355   gchar *exe_root;
2356 
2357   hmodule = NULL;
2358   if (address_of_function)
2359     {
2360       G_LOCK (g_utils_global);
2361       hmodule = get_module_for_address (address_of_function);
2362       if (hmodule != NULL)
2363 	{
2364 	  if (per_module_data_dirs == NULL)
2365 	    per_module_data_dirs = g_hash_table_new (NULL, NULL);
2366 	  else
2367 	    {
2368 	      retval = g_hash_table_lookup (per_module_data_dirs, hmodule);
2369 
2370 	      if (retval != NULL)
2371 		{
2372 		  G_UNLOCK (g_utils_global);
2373 		  return (const gchar * const *) retval;
2374 		}
2375 	    }
2376 	}
2377     }
2378 
2379   data_dirs = g_array_new (TRUE, TRUE, sizeof (char *));
2380 
2381   /* Documents and Settings\All Users\Application Data */
2382   p = get_special_folder (CSIDL_COMMON_APPDATA);
2383   if (p)
2384     g_array_append_val (data_dirs, p);
2385 
2386   /* Documents and Settings\All Users\Documents */
2387   p = get_special_folder (CSIDL_COMMON_DOCUMENTS);
2388   if (p)
2389     g_array_append_val (data_dirs, p);
2390 
2391   /* Using the above subfolders of Documents and Settings perhaps
2392    * makes sense from a Windows perspective.
2393    *
2394    * But looking at the actual use cases of this function in GTK+
2395    * and GNOME software, what we really want is the "share"
2396    * subdirectory of the installation directory for the package
2397    * our caller is a part of.
2398    *
2399    * The address_of_function parameter, if non-NULL, points to a
2400    * function in the calling module. Use that to determine that
2401    * module's installation folder, and use its "share" subfolder.
2402    *
2403    * Additionally, also use the "share" subfolder of the installation
2404    * locations of GLib and the .exe file being run.
2405    *
2406    * To guard against none of the above being what is really wanted,
2407    * callers of this function should have Win32-specific code to look
2408    * up their installation folder themselves, and handle a subfolder
2409    * "share" of it in the same way as the folders returned from this
2410    * function.
2411    */
2412 
2413   p = get_module_share_dir (address_of_function);
2414   if (p)
2415     g_array_append_val (data_dirs, p);
2416 
2417   if (glib_dll != NULL)
2418     {
2419       gchar *glib_root = g_win32_get_package_installation_directory_of_module (glib_dll);
2420       p = g_build_filename (glib_root, "share", NULL);
2421       if (p)
2422 	g_array_append_val (data_dirs, p);
2423       g_free (glib_root);
2424     }
2425 
2426   exe_root = g_win32_get_package_installation_directory_of_module (NULL);
2427   p = g_build_filename (exe_root, "share", NULL);
2428   if (p)
2429     g_array_append_val (data_dirs, p);
2430   g_free (exe_root);
2431 
2432   retval = (gchar **) g_array_free (data_dirs, FALSE);
2433 
2434   if (address_of_function)
2435     {
2436       if (hmodule != NULL)
2437 	g_hash_table_insert (per_module_data_dirs, hmodule, retval);
2438       G_UNLOCK (g_utils_global);
2439     }
2440 
2441   return (const gchar * const *) retval;
2442 }
2443 
2444 const gchar * const *
g_win32_get_system_data_dirs_for_module(void (* address_of_function)(void))2445 g_win32_get_system_data_dirs_for_module (void (*address_of_function)(void))
2446 {
2447   gboolean should_call_g_get_system_data_dirs;
2448 
2449   should_call_g_get_system_data_dirs = TRUE;
2450   /* These checks are the same as the ones that g_build_system_data_dirs() does.
2451    * Please keep them in sync.
2452    */
2453   G_LOCK (g_utils_global);
2454 
2455   if (!g_system_data_dirs)
2456     {
2457       const gchar *data_dirs = g_getenv ("XDG_DATA_DIRS");
2458 
2459       if (!data_dirs || !data_dirs[0])
2460         should_call_g_get_system_data_dirs = FALSE;
2461     }
2462 
2463   G_UNLOCK (g_utils_global);
2464 
2465   /* There is a subtle difference between g_win32_get_system_data_dirs_for_module (NULL),
2466    * which is what GLib code can normally call,
2467    * and g_win32_get_system_data_dirs_for_module (&_g_win32_get_system_data_dirs),
2468    * which is what the inline function used by non-GLib code calls.
2469    * The former gets prefix relative to currently-running executable,
2470    * the latter - relative to the module that calls _g_win32_get_system_data_dirs()
2471    * (disguised as g_get_system_data_dirs()), which could be an executable or
2472    * a DLL that is located somewhere else.
2473    * This is why that inline function in gutils.h exists, and why we can't just
2474    * call g_get_system_data_dirs() from there - because we need to get the address
2475    * local to the non-GLib caller-module.
2476    */
2477 
2478   /*
2479    * g_get_system_data_dirs() will fall back to calling
2480    * g_win32_get_system_data_dirs_for_module_real(NULL) if XDG_DATA_DIRS is NULL
2481    * or an empty string. The checks above ensure that we do not call it in such
2482    * cases and use the address_of_function that we've been given by the inline function.
2483    * The reason we're calling g_get_system_data_dirs /at all/ is to give
2484    * XDG_DATA_DIRS precedence (if it is set).
2485    */
2486   if (should_call_g_get_system_data_dirs)
2487     return g_get_system_data_dirs ();
2488 
2489   return g_win32_get_system_data_dirs_for_module_real (address_of_function);
2490 }
2491 
2492 #endif
2493 
2494 static gchar **
g_build_system_data_dirs(void)2495 g_build_system_data_dirs (void)
2496 {
2497   gchar **data_dir_vector = NULL;
2498   gchar *data_dirs = (gchar *) g_getenv ("XDG_DATA_DIRS");
2499 
2500   /* These checks are the same as the ones that g_win32_get_system_data_dirs_for_module()
2501    * does. Please keep them in sync.
2502    */
2503 #ifndef G_OS_WIN32
2504   if (!data_dirs || !data_dirs[0])
2505     data_dirs = "/usr/local/share/:/usr/share/";
2506 
2507   data_dir_vector = g_strsplit (data_dirs, G_SEARCHPATH_SEPARATOR_S, 0);
2508 #else
2509   if (!data_dirs || !data_dirs[0])
2510     data_dir_vector = g_strdupv ((gchar **) g_win32_get_system_data_dirs_for_module_real (NULL));
2511   else
2512     data_dir_vector = g_strsplit (data_dirs, G_SEARCHPATH_SEPARATOR_S, 0);
2513 #endif
2514 
2515   return g_steal_pointer (&data_dir_vector);
2516 }
2517 
2518 /**
2519  * g_get_system_data_dirs:
2520  *
2521  * Returns an ordered list of base directories in which to access
2522  * system-wide application data.
2523  *
2524  * On UNIX platforms this is determined using the mechanisms described
2525  * in the
2526  * [XDG Base Directory Specification](http://www.freedesktop.org/Standards/basedir-spec)
2527  * In this case the list of directories retrieved will be `XDG_DATA_DIRS`.
2528  *
2529  * On Windows it follows XDG Base Directory Specification if `XDG_DATA_DIRS` is defined.
2530  * If `XDG_DATA_DIRS` is undefined,
2531  * the first elements in the list are the Application Data
2532  * and Documents folders for All Users. (These can be determined only
2533  * on Windows 2000 or later and are not present in the list on other
2534  * Windows versions.) See documentation for CSIDL_COMMON_APPDATA and
2535  * CSIDL_COMMON_DOCUMENTS.
2536  *
2537  * Then follows the "share" subfolder in the installation folder for
2538  * the package containing the DLL that calls this function, if it can
2539  * be determined.
2540  *
2541  * Finally the list contains the "share" subfolder in the installation
2542  * folder for GLib, and in the installation folder for the package the
2543  * application's .exe file belongs to.
2544  *
2545  * The installation folders above are determined by looking up the
2546  * folder where the module (DLL or EXE) in question is located. If the
2547  * folder's name is "bin", its parent is used, otherwise the folder
2548  * itself.
2549  *
2550  * Note that on Windows the returned list can vary depending on where
2551  * this function is called.
2552  *
2553  * The return value is cached and modifying it at runtime is not supported, as
2554  * it’s not thread-safe to modify environment variables at runtime.
2555  *
2556  * Returns: (array zero-terminated=1) (element-type filename) (transfer none):
2557  *     a %NULL-terminated array of strings owned by GLib that must not be
2558  *     modified or freed.
2559  *
2560  * Since: 2.6
2561  **/
2562 const gchar * const *
g_get_system_data_dirs(void)2563 g_get_system_data_dirs (void)
2564 {
2565   const gchar * const *system_data_dirs;
2566 
2567   G_LOCK (g_utils_global);
2568 
2569   if (g_system_data_dirs == NULL)
2570     g_system_data_dirs = g_build_system_data_dirs ();
2571   system_data_dirs = (const gchar * const *) g_system_data_dirs;
2572 
2573   G_UNLOCK (g_utils_global);
2574 
2575   return system_data_dirs;
2576 }
2577 
2578 static gchar **
g_build_system_config_dirs(void)2579 g_build_system_config_dirs (void)
2580 {
2581   gchar **conf_dir_vector = NULL;
2582   const gchar *conf_dirs = g_getenv ("XDG_CONFIG_DIRS");
2583 #ifdef G_OS_WIN32
2584   if (conf_dirs)
2585     {
2586       conf_dir_vector = g_strsplit (conf_dirs, G_SEARCHPATH_SEPARATOR_S, 0);
2587     }
2588   else
2589     {
2590       gchar *special_conf_dirs = get_special_folder (CSIDL_COMMON_APPDATA);
2591 
2592       if (special_conf_dirs)
2593         conf_dir_vector = g_strsplit (special_conf_dirs, G_SEARCHPATH_SEPARATOR_S, 0);
2594       else
2595         /* Return empty list */
2596         conf_dir_vector = g_strsplit ("", G_SEARCHPATH_SEPARATOR_S, 0);
2597 
2598       g_free (special_conf_dirs);
2599     }
2600 #else
2601   if (!conf_dirs || !conf_dirs[0])
2602     conf_dirs = "/etc/xdg";
2603 
2604   conf_dir_vector = g_strsplit (conf_dirs, G_SEARCHPATH_SEPARATOR_S, 0);
2605 #endif
2606 
2607   return g_steal_pointer (&conf_dir_vector);
2608 }
2609 
2610 /**
2611  * g_get_system_config_dirs:
2612  *
2613  * Returns an ordered list of base directories in which to access
2614  * system-wide configuration information.
2615  *
2616  * On UNIX platforms this is determined using the mechanisms described
2617  * in the
2618  * [XDG Base Directory Specification](http://www.freedesktop.org/Standards/basedir-spec).
2619  * In this case the list of directories retrieved will be `XDG_CONFIG_DIRS`.
2620  *
2621  * On Windows it follows XDG Base Directory Specification if `XDG_CONFIG_DIRS` is defined.
2622  * If `XDG_CONFIG_DIRS` is undefined, the directory that contains application
2623  * data for all users is used instead. A typical path is
2624  * `C:\Documents and Settings\All Users\Application Data`.
2625  * This folder is used for application data
2626  * that is not user specific. For example, an application can store
2627  * a spell-check dictionary, a database of clip art, or a log file in the
2628  * CSIDL_COMMON_APPDATA folder. This information will not roam and is available
2629  * to anyone using the computer.
2630  *
2631  * The return value is cached and modifying it at runtime is not supported, as
2632  * it’s not thread-safe to modify environment variables at runtime.
2633  *
2634  * Returns: (array zero-terminated=1) (element-type filename) (transfer none):
2635  *     a %NULL-terminated array of strings owned by GLib that must not be
2636  *     modified or freed.
2637  *
2638  * Since: 2.6
2639  **/
2640 const gchar * const *
g_get_system_config_dirs(void)2641 g_get_system_config_dirs (void)
2642 {
2643   const gchar * const *system_config_dirs;
2644 
2645   G_LOCK (g_utils_global);
2646 
2647   if (g_system_config_dirs == NULL)
2648     g_system_config_dirs = g_build_system_config_dirs ();
2649   system_config_dirs = (const gchar * const *) g_system_config_dirs;
2650 
2651   G_UNLOCK (g_utils_global);
2652 
2653   return system_config_dirs;
2654 }
2655 
2656 /**
2657  * g_nullify_pointer:
2658  * @nullify_location: (not nullable): the memory address of the pointer.
2659  *
2660  * Set the pointer at the specified location to %NULL.
2661  **/
2662 void
g_nullify_pointer(gpointer * nullify_location)2663 g_nullify_pointer (gpointer *nullify_location)
2664 {
2665   g_return_if_fail (nullify_location != NULL);
2666 
2667   *nullify_location = NULL;
2668 }
2669 
2670 #define KILOBYTE_FACTOR (G_GOFFSET_CONSTANT (1000))
2671 #define MEGABYTE_FACTOR (KILOBYTE_FACTOR * KILOBYTE_FACTOR)
2672 #define GIGABYTE_FACTOR (MEGABYTE_FACTOR * KILOBYTE_FACTOR)
2673 #define TERABYTE_FACTOR (GIGABYTE_FACTOR * KILOBYTE_FACTOR)
2674 #define PETABYTE_FACTOR (TERABYTE_FACTOR * KILOBYTE_FACTOR)
2675 #define EXABYTE_FACTOR  (PETABYTE_FACTOR * KILOBYTE_FACTOR)
2676 
2677 #define KIBIBYTE_FACTOR (G_GOFFSET_CONSTANT (1024))
2678 #define MEBIBYTE_FACTOR (KIBIBYTE_FACTOR * KIBIBYTE_FACTOR)
2679 #define GIBIBYTE_FACTOR (MEBIBYTE_FACTOR * KIBIBYTE_FACTOR)
2680 #define TEBIBYTE_FACTOR (GIBIBYTE_FACTOR * KIBIBYTE_FACTOR)
2681 #define PEBIBYTE_FACTOR (TEBIBYTE_FACTOR * KIBIBYTE_FACTOR)
2682 #define EXBIBYTE_FACTOR (PEBIBYTE_FACTOR * KIBIBYTE_FACTOR)
2683 
2684 /**
2685  * g_format_size:
2686  * @size: a size in bytes
2687  *
2688  * Formats a size (for example the size of a file) into a human readable
2689  * string.  Sizes are rounded to the nearest size prefix (kB, MB, GB)
2690  * and are displayed rounded to the nearest tenth. E.g. the file size
2691  * 3292528 bytes will be converted into the string "3.2 MB". The returned string
2692  * is UTF-8, and may use a non-breaking space to separate the number and units,
2693  * to ensure they aren’t separated when line wrapped.
2694  *
2695  * The prefix units base is 1000 (i.e. 1 kB is 1000 bytes).
2696  *
2697  * This string should be freed with g_free() when not needed any longer.
2698  *
2699  * See g_format_size_full() for more options about how the size might be
2700  * formatted.
2701  *
2702  * Returns: (transfer full): a newly-allocated formatted string containing
2703  *   a human readable file size
2704  *
2705  * Since: 2.30
2706  */
2707 gchar *
g_format_size(guint64 size)2708 g_format_size (guint64 size)
2709 {
2710   return g_format_size_full (size, G_FORMAT_SIZE_DEFAULT);
2711 }
2712 
2713 /**
2714  * GFormatSizeFlags:
2715  * @G_FORMAT_SIZE_DEFAULT: behave the same as g_format_size()
2716  * @G_FORMAT_SIZE_LONG_FORMAT: include the exact number of bytes as part
2717  *     of the returned string.  For example, "45.6 kB (45,612 bytes)".
2718  * @G_FORMAT_SIZE_IEC_UNITS: use IEC (base 1024) units with "KiB"-style
2719  *     suffixes. IEC units should only be used for reporting things with
2720  *     a strong "power of 2" basis, like RAM sizes or RAID stripe sizes.
2721  *     Network and storage sizes should be reported in the normal SI units.
2722  * @G_FORMAT_SIZE_BITS: set the size as a quantity in bits, rather than
2723  *     bytes, and return units in bits. For example, ‘Mb’ rather than ‘MB’.
2724  *
2725  * Flags to modify the format of the string returned by g_format_size_full().
2726  */
2727 
2728 #pragma GCC diagnostic push
2729 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
2730 
2731 /**
2732  * g_format_size_full:
2733  * @size: a size in bytes
2734  * @flags: #GFormatSizeFlags to modify the output
2735  *
2736  * Formats a size.
2737  *
2738  * This function is similar to g_format_size() but allows for flags
2739  * that modify the output. See #GFormatSizeFlags.
2740  *
2741  * Returns: (transfer full): a newly-allocated formatted string
2742  *   containing a human readable file size
2743  *
2744  * Since: 2.30
2745  */
2746 gchar *
g_format_size_full(guint64 size,GFormatSizeFlags flags)2747 g_format_size_full (guint64          size,
2748                     GFormatSizeFlags flags)
2749 {
2750   struct Format
2751   {
2752     guint64 factor;
2753     char string[10];
2754   };
2755 
2756   typedef enum
2757   {
2758     FORMAT_BYTES,
2759     FORMAT_BYTES_IEC,
2760     FORMAT_BITS,
2761     FORMAT_BITS_IEC
2762   } FormatIndex;
2763 
2764   const struct Format formats[4][6] = {
2765     {
2766       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2767       { KILOBYTE_FACTOR, N_("%.1f kB") },
2768       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2769       { MEGABYTE_FACTOR, N_("%.1f MB") },
2770       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2771       { GIGABYTE_FACTOR, N_("%.1f GB") },
2772       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2773       { TERABYTE_FACTOR, N_("%.1f TB") },
2774       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2775       { PETABYTE_FACTOR, N_("%.1f PB") },
2776       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2777       { EXABYTE_FACTOR,  N_("%.1f EB") }
2778     },
2779     {
2780       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2781       { KIBIBYTE_FACTOR, N_("%.1f KiB") },
2782       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2783       { MEBIBYTE_FACTOR, N_("%.1f MiB") },
2784       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2785       { GIBIBYTE_FACTOR, N_("%.1f GiB") },
2786       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2787       { TEBIBYTE_FACTOR, N_("%.1f TiB") },
2788       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2789       { PEBIBYTE_FACTOR, N_("%.1f PiB") },
2790       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2791       { EXBIBYTE_FACTOR, N_("%.1f EiB") }
2792     },
2793     {
2794       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2795       { KILOBYTE_FACTOR, N_("%.1f kb") },
2796       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2797       { MEGABYTE_FACTOR, N_("%.1f Mb") },
2798       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2799       { GIGABYTE_FACTOR, N_("%.1f Gb") },
2800       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2801       { TERABYTE_FACTOR, N_("%.1f Tb") },
2802       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2803       { PETABYTE_FACTOR, N_("%.1f Pb") },
2804       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2805       { EXABYTE_FACTOR,  N_("%.1f Eb") }
2806     },
2807     {
2808       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2809       { KIBIBYTE_FACTOR, N_("%.1f Kib") },
2810       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2811       { MEBIBYTE_FACTOR, N_("%.1f Mib") },
2812       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2813       { GIBIBYTE_FACTOR, N_("%.1f Gib") },
2814       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2815       { TEBIBYTE_FACTOR, N_("%.1f Tib") },
2816       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2817       { PEBIBYTE_FACTOR, N_("%.1f Pib") },
2818       /* Translators: Keep the no-break space between %.1f and the unit symbol */
2819       { EXBIBYTE_FACTOR, N_("%.1f Eib") }
2820     }
2821   };
2822 
2823   GString *string;
2824   FormatIndex index;
2825 
2826   string = g_string_new (NULL);
2827 
2828   switch (flags & ~G_FORMAT_SIZE_LONG_FORMAT)
2829     {
2830     case G_FORMAT_SIZE_DEFAULT:
2831       index = FORMAT_BYTES;
2832       break;
2833     case (G_FORMAT_SIZE_DEFAULT | G_FORMAT_SIZE_IEC_UNITS):
2834       index = FORMAT_BYTES_IEC;
2835       break;
2836     case G_FORMAT_SIZE_BITS:
2837       index = FORMAT_BITS;
2838       break;
2839     case (G_FORMAT_SIZE_BITS | G_FORMAT_SIZE_IEC_UNITS):
2840       index = FORMAT_BITS_IEC;
2841       break;
2842     default:
2843       g_assert_not_reached ();
2844     }
2845 
2846 
2847   if (size < formats[index][0].factor)
2848     {
2849       const char * format;
2850 
2851       if (index == FORMAT_BYTES || index == FORMAT_BYTES_IEC)
2852         {
2853           format = g_dngettext (GETTEXT_PACKAGE, "%u byte", "%u bytes", (guint) size);
2854         }
2855       else
2856         {
2857           format = g_dngettext (GETTEXT_PACKAGE, "%u bit", "%u bits", (guint) size);
2858         }
2859 
2860       g_string_printf (string, format, (guint) size);
2861 
2862       flags &= ~G_FORMAT_SIZE_LONG_FORMAT;
2863     }
2864   else
2865     {
2866       const gsize n = G_N_ELEMENTS (formats[index]);
2867       gsize i;
2868 
2869       /*
2870        * Point the last format (the highest unit) by default
2871        * and then then scan all formats, starting with the 2nd one
2872        * because the 1st is already managed by with the plural form
2873        */
2874       const struct Format * f = &formats[index][n - 1];
2875 
2876       for (i = 1; i < n; i++)
2877         {
2878           if (size < formats[index][i].factor)
2879             {
2880               f = &formats[index][i - 1];
2881               break;
2882             }
2883         }
2884 
2885       g_string_printf (string, _(f->string), (gdouble) size / (gdouble) f->factor);
2886     }
2887 
2888   if (flags & G_FORMAT_SIZE_LONG_FORMAT)
2889     {
2890       /* First problem: we need to use the number of bytes to decide on
2891        * the plural form that is used for display, but the number of
2892        * bytes potentially exceeds the size of a guint (which is what
2893        * ngettext() takes).
2894        *
2895        * From a pragmatic standpoint, it seems that all known languages
2896        * base plural forms on one or both of the following:
2897        *
2898        *   - the lowest digits of the number
2899        *
2900        *   - if the number if greater than some small value
2901        *
2902        * Here's how we fake it:  Draw an arbitrary line at one thousand.
2903        * If the number is below that, then fine.  If it is above it,
2904        * then we take the modulus of the number by one thousand (in
2905        * order to keep the lowest digits) and add one thousand to that
2906        * (in order to ensure that 1001 is not treated the same as 1).
2907        */
2908       guint plural_form = size < 1000 ? size : size % 1000 + 1000;
2909 
2910       /* Second problem: we need to translate the string "%u byte/bit" and
2911        * "%u bytes/bits" for pluralisation, but the correct number format to
2912        * use for a gsize is different depending on which architecture
2913        * we're on.
2914        *
2915        * Solution: format the number separately and use "%s bytes/bits" on
2916        * all platforms.
2917        */
2918       const gchar *translated_format;
2919       gchar *formatted_number;
2920 
2921       if (index == FORMAT_BYTES || index == FORMAT_BYTES_IEC)
2922         {
2923           /* Translators: the %s in "%s bytes" will always be replaced by a number. */
2924           translated_format = g_dngettext (GETTEXT_PACKAGE, "%s byte", "%s bytes", plural_form);
2925         }
2926       else
2927         {
2928           /* Translators: the %s in "%s bits" will always be replaced by a number. */
2929           translated_format = g_dngettext (GETTEXT_PACKAGE, "%s bit", "%s bits", plural_form);
2930         }
2931       formatted_number = g_strdup_printf ("%'"G_GUINT64_FORMAT, size);
2932 
2933       g_string_append (string, " (");
2934       g_string_append_printf (string, translated_format, formatted_number);
2935       g_free (formatted_number);
2936       g_string_append (string, ")");
2937     }
2938 
2939   return g_string_free (string, FALSE);
2940 }
2941 
2942 #pragma GCC diagnostic pop
2943 
2944 /**
2945  * g_format_size_for_display:
2946  * @size: a size in bytes
2947  *
2948  * Formats a size (for example the size of a file) into a human
2949  * readable string. Sizes are rounded to the nearest size prefix
2950  * (KB, MB, GB) and are displayed rounded to the nearest tenth.
2951  * E.g. the file size 3292528 bytes will be converted into the
2952  * string "3.1 MB".
2953  *
2954  * The prefix units base is 1024 (i.e. 1 KB is 1024 bytes).
2955  *
2956  * This string should be freed with g_free() when not needed any longer.
2957  *
2958  * Returns: (transfer full): a newly-allocated formatted string
2959  *   containing a human readable file size
2960  *
2961  * Since: 2.16
2962  *
2963  * Deprecated:2.30: This function is broken due to its use of SI
2964  *     suffixes to denote IEC units. Use g_format_size() instead.
2965  */
2966 gchar *
g_format_size_for_display(goffset size)2967 g_format_size_for_display (goffset size)
2968 {
2969   if (size < (goffset) KIBIBYTE_FACTOR)
2970     return g_strdup_printf (g_dngettext(GETTEXT_PACKAGE, "%u byte", "%u bytes",(guint) size), (guint) size);
2971   else
2972     {
2973       gdouble displayed_size;
2974 
2975       if (size < (goffset) MEBIBYTE_FACTOR)
2976         {
2977           displayed_size = (gdouble) size / (gdouble) KIBIBYTE_FACTOR;
2978           /* Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to
2979            * mean 1024 bytes.  I am aware that 'KB' is not correct, but it has been preserved for reasons of
2980            * compatibility.  Users will not see this string unless a program is using this deprecated function.
2981            * Please translate as literally as possible.
2982            */
2983           return g_strdup_printf (_("%.1f KB"), displayed_size);
2984         }
2985       else if (size < (goffset) GIBIBYTE_FACTOR)
2986         {
2987           displayed_size = (gdouble) size / (gdouble) MEBIBYTE_FACTOR;
2988           return g_strdup_printf (_("%.1f MB"), displayed_size);
2989         }
2990       else if (size < (goffset) TEBIBYTE_FACTOR)
2991         {
2992           displayed_size = (gdouble) size / (gdouble) GIBIBYTE_FACTOR;
2993           return g_strdup_printf (_("%.1f GB"), displayed_size);
2994         }
2995       else if (size < (goffset) PEBIBYTE_FACTOR)
2996         {
2997           displayed_size = (gdouble) size / (gdouble) TEBIBYTE_FACTOR;
2998           return g_strdup_printf (_("%.1f TB"), displayed_size);
2999         }
3000       else if (size < (goffset) EXBIBYTE_FACTOR)
3001         {
3002           displayed_size = (gdouble) size / (gdouble) PEBIBYTE_FACTOR;
3003           return g_strdup_printf (_("%.1f PB"), displayed_size);
3004         }
3005       else
3006         {
3007           displayed_size = (gdouble) size / (gdouble) EXBIBYTE_FACTOR;
3008           return g_strdup_printf (_("%.1f EB"), displayed_size);
3009         }
3010     }
3011 }
3012 
3013 #if defined (G_OS_WIN32) && !defined (_WIN64)
3014 
3015 /* Binary compatibility versions. Not for newly compiled code. */
3016 
3017 _GLIB_EXTERN const gchar *g_get_user_name_utf8        (void);
3018 _GLIB_EXTERN const gchar *g_get_real_name_utf8        (void);
3019 _GLIB_EXTERN const gchar *g_get_home_dir_utf8         (void);
3020 _GLIB_EXTERN const gchar *g_get_tmp_dir_utf8          (void);
3021 _GLIB_EXTERN gchar       *g_find_program_in_path_utf8 (const gchar *program);
3022 
3023 gchar *
g_find_program_in_path_utf8(const gchar * program)3024 g_find_program_in_path_utf8 (const gchar *program)
3025 {
3026   return g_find_program_in_path (program);
3027 }
3028 
g_get_user_name_utf8(void)3029 const gchar *g_get_user_name_utf8 (void) { return g_get_user_name (); }
g_get_real_name_utf8(void)3030 const gchar *g_get_real_name_utf8 (void) { return g_get_real_name (); }
g_get_home_dir_utf8(void)3031 const gchar *g_get_home_dir_utf8 (void) { return g_get_home_dir (); }
g_get_tmp_dir_utf8(void)3032 const gchar *g_get_tmp_dir_utf8 (void) { return g_get_tmp_dir (); }
3033 
3034 #endif
3035 
3036 /* Private API:
3037  *
3038  * Returns %TRUE if the current process was executed as setuid
3039  */
3040 gboolean
g_check_setuid(void)3041 g_check_setuid (void)
3042 {
3043 #if defined(HAVE_SYS_AUXV_H) && defined(HAVE_GETAUXVAL) && defined(AT_SECURE)
3044   unsigned long value;
3045   int errsv;
3046 
3047   errno = 0;
3048   value = getauxval (AT_SECURE);
3049   errsv = errno;
3050   if (errsv)
3051     g_error ("getauxval () failed: %s", g_strerror (errsv));
3052   return value;
3053 #elif defined(HAVE_ISSETUGID) && !defined(__BIONIC__)
3054   /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */
3055 
3056   /* Android had it in older versions but the new 64 bit ABI does not
3057    * have it anymore, and some versions of the 32 bit ABI neither.
3058    * https://code.google.com/p/android-developer-preview/issues/detail?id=168
3059    */
3060   return issetugid ();
3061 #elif defined(G_OS_UNIX)
3062   uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
3063   gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */
3064 
3065   static gsize check_setuid_initialised;
3066   static gboolean is_setuid;
3067 
3068   if (g_once_init_enter (&check_setuid_initialised))
3069     {
3070 #ifdef HAVE_GETRESUID
3071       /* These aren't in the header files, so we prototype them here.
3072        */
3073       int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid);
3074       int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid);
3075 
3076       if (getresuid (&ruid, &euid, &suid) != 0 ||
3077           getresgid (&rgid, &egid, &sgid) != 0)
3078 #endif /* HAVE_GETRESUID */
3079         {
3080           suid = ruid = getuid ();
3081           sgid = rgid = getgid ();
3082           euid = geteuid ();
3083           egid = getegid ();
3084         }
3085 
3086       is_setuid = (ruid != euid || ruid != suid ||
3087                    rgid != egid || rgid != sgid);
3088 
3089       g_once_init_leave (&check_setuid_initialised, 1);
3090     }
3091   return is_setuid;
3092 #else
3093   return FALSE;
3094 #endif
3095 }
3096 
3097 #ifdef G_OS_WIN32
3098 /**
3099  * g_abort:
3100  *
3101  * A wrapper for the POSIX abort() function.
3102  *
3103  * On Windows it is a function that makes extra effort (including a call
3104  * to abort()) to ensure that a debugger-catchable exception is thrown
3105  * before the program terminates.
3106  *
3107  * See your C library manual for more details about abort().
3108  *
3109  * Since: 2.50
3110  */
3111 void
g_abort(void)3112 g_abort (void)
3113 {
3114   /* One call to break the debugger */
3115   DebugBreak ();
3116   /* One call in case CRT changes its abort() behaviour */
3117   abort ();
3118   /* And one call to bind them all and terminate the program for sure */
3119   ExitProcess (127);
3120 }
3121 #endif
3122