~ubuntu-branches/debian/sid/glib2.0/sid

« back to all changes in this revision

Viewing changes to .pc/04_homedir_env.patch/glib/gutils.c

  • Committer: Package Import Robot
  • Author(s): Martin Pitt
  • Date: 2013-05-08 06:25:57 UTC
  • mfrom: (1.27.14) (3.1.181 experimental)
  • Revision ID: package-import@ubuntu.com-20130508062557-i7gbku66mls70gi2
Tags: 2.36.1-2
Merge experimental branch, upload to unstable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
60
60
#include "gutils.h"
61
61
 
62
62
#include "glib-init.h"
 
63
#include "glib-private.h"
63
64
#include "genviron.h"
64
65
#include "gfileutils.h"
65
66
#include "ggettext.h"
576
577
 
577
578
G_LOCK_DEFINE_STATIC (g_utils_global);
578
579
 
579
 
static  gchar   *g_tmp_dir = NULL;
580
 
static  gchar   *g_user_name = NULL;
581
 
static  gchar   *g_real_name = NULL;
582
 
static  gchar   *g_home_dir = NULL;
583
 
static  gchar   *g_host_name = NULL;
584
 
 
585
 
#ifdef G_OS_WIN32
586
 
/* System codepage versions of the above, kept at file level so that they,
587
 
 * too, are produced only once.
588
 
 */
589
 
static  gchar   *g_tmp_dir_cp = NULL;
590
 
static  gchar   *g_user_name_cp = NULL;
591
 
static  gchar   *g_real_name_cp = NULL;
592
 
static  gchar   *g_home_dir_cp = NULL;
593
 
#endif
 
580
typedef struct
 
581
{
 
582
  gchar *user_name;
 
583
  gchar *real_name;
 
584
  gchar *home_dir;
 
585
} UserDatabaseEntry;
594
586
 
595
587
static  gchar   *g_user_data_dir = NULL;
596
588
static  gchar  **g_system_data_dirs = NULL;
654
646
#endif
655
647
 
656
648
/* HOLDS: g_utils_global_lock */
657
 
static void
658
 
g_get_any_init_do (void)
 
649
static UserDatabaseEntry *
 
650
g_get_user_database_entry (void)
659
651
{
660
 
  gchar hostname[100];
661
 
 
662
 
  g_tmp_dir = g_strdup (g_getenv ("TMPDIR"));
663
 
 
664
 
  if (g_tmp_dir == NULL || *g_tmp_dir == '\0')
665
 
    {
666
 
      g_free (g_tmp_dir);
667
 
      g_tmp_dir = g_strdup (g_getenv ("TMP"));
668
 
    }
669
 
 
670
 
  if (g_tmp_dir == NULL || *g_tmp_dir == '\0')
671
 
    {
672
 
      g_free (g_tmp_dir);
673
 
      g_tmp_dir = g_strdup (g_getenv ("TEMP"));
674
 
    }
675
 
 
676
 
#ifdef G_OS_WIN32
677
 
  if (g_tmp_dir == NULL || *g_tmp_dir == '\0')
678
 
    {
679
 
      g_free (g_tmp_dir);
680
 
      g_tmp_dir = get_windows_directory_root ();
681
 
    }
682
 
#else
683
 
 
684
 
#ifdef P_tmpdir
685
 
  if (g_tmp_dir == NULL || *g_tmp_dir == '\0')
686
 
    {
687
 
      gsize k;
688
 
      g_free (g_tmp_dir);
689
 
      g_tmp_dir = g_strdup (P_tmpdir);
690
 
      k = strlen (g_tmp_dir);
691
 
      if (k > 1 && G_IS_DIR_SEPARATOR (g_tmp_dir[k - 1]))
692
 
        g_tmp_dir[k - 1] = '\0';
693
 
    }
694
 
#endif
695
 
  
696
 
  if (g_tmp_dir == NULL || *g_tmp_dir == '\0')
697
 
    {
698
 
      g_free (g_tmp_dir);
699
 
      g_tmp_dir = g_strdup (g_getenv ("/tmp"));
700
 
    }
701
 
#endif  /* !G_OS_WIN32 */
702
 
  
703
 
#ifdef G_OS_WIN32
704
 
  /* We check $HOME first for Win32, though it is a last resort for Unix
705
 
   * where we prefer the results of getpwuid().
706
 
   */
707
 
  g_home_dir = g_strdup (g_getenv ("HOME"));
708
 
 
709
 
  /* Only believe HOME if it is an absolute path and exists */
710
 
  if (g_home_dir)
711
 
    {
712
 
      if (!(g_path_is_absolute (g_home_dir) &&
713
 
            g_file_test (g_home_dir, G_FILE_TEST_IS_DIR)))
714
 
        {
715
 
          g_free (g_home_dir);
716
 
          g_home_dir = NULL;
717
 
        }
718
 
    }
719
 
  
720
 
  /* In case HOME is Unix-style (it happens), convert it to
721
 
   * Windows style.
722
 
   */
723
 
  if (g_home_dir)
724
 
    {
725
 
      gchar *p;
726
 
      while ((p = strchr (g_home_dir, '/')) != NULL)
727
 
        *p = '\\';
728
 
    }
729
 
 
730
 
  if (!g_home_dir)
731
 
    {
732
 
      /* USERPROFILE is probably the closest equivalent to $HOME? */
733
 
      if (g_getenv ("USERPROFILE") != NULL)
734
 
        g_home_dir = g_strdup (g_getenv ("USERPROFILE"));
735
 
    }
736
 
 
737
 
  if (!g_home_dir)
738
 
    g_home_dir = get_special_folder (CSIDL_PROFILE);
739
 
  
740
 
  if (!g_home_dir)
741
 
    g_home_dir = get_windows_directory_root ();
742
 
#endif /* G_OS_WIN32 */
743
 
  
 
652
  static UserDatabaseEntry *entry;
 
653
 
 
654
  if (g_once_init_enter (&entry))
 
655
    {
 
656
      static UserDatabaseEntry e;
 
657
 
744
658
#ifdef HAVE_PWD_H
745
 
  {
746
 
    struct passwd *pw = NULL;
747
 
    gpointer buffer = NULL;
748
 
    gint error;
749
 
    gchar *logname;
 
659
      {
 
660
        struct passwd *pw = NULL;
 
661
        gpointer buffer = NULL;
 
662
        gint error;
 
663
        gchar *logname;
750
664
 
751
665
#  if defined (HAVE_POSIX_GETPWUID_R) || defined (HAVE_NONPOSIX_GETPWUID_R)
752
 
    struct passwd pwd;
753
 
#    ifdef _SC_GETPW_R_SIZE_MAX  
754
 
    /* This reurns the maximum length */
755
 
    glong bufsize = sysconf (_SC_GETPW_R_SIZE_MAX);
756
 
    
757
 
    if (bufsize < 0)
758
 
      bufsize = 64;
 
666
        struct passwd pwd;
 
667
#    ifdef _SC_GETPW_R_SIZE_MAX
 
668
        /* This reurns the maximum length */
 
669
        glong bufsize = sysconf (_SC_GETPW_R_SIZE_MAX);
 
670
 
 
671
        if (bufsize < 0)
 
672
          bufsize = 64;
759
673
#    else /* _SC_GETPW_R_SIZE_MAX */
760
 
    glong bufsize = 64;
 
674
        glong bufsize = 64;
761
675
#    endif /* _SC_GETPW_R_SIZE_MAX */
762
676
 
763
 
    logname = (gchar *) g_getenv ("LOGNAME");
764
 
        
765
 
    do
766
 
      {
767
 
        g_free (buffer);
768
 
        /* we allocate 6 extra bytes to work around a bug in 
769
 
         * Mac OS < 10.3. See #156446
770
 
         */
771
 
        buffer = g_malloc (bufsize + 6);
772
 
        errno = 0;
773
 
        
 
677
        logname = (gchar *) g_getenv ("LOGNAME");
 
678
 
 
679
        do
 
680
          {
 
681
            g_free (buffer);
 
682
            /* we allocate 6 extra bytes to work around a bug in
 
683
             * Mac OS < 10.3. See #156446
 
684
             */
 
685
            buffer = g_malloc (bufsize + 6);
 
686
            errno = 0;
 
687
 
774
688
#    ifdef HAVE_POSIX_GETPWUID_R
775
 
        if (logname) {
776
 
          error = getpwnam_r (logname, &pwd, buffer, bufsize, &pw);
777
 
          if (!pw || (pw->pw_uid != getuid ())) {
778
 
            /* LOGNAME is lying, fall back to looking up the uid */
779
 
            error = getpwuid_r (getuid (), &pwd, buffer, bufsize, &pw);
780
 
          }
781
 
        } else {
782
 
          error = getpwuid_r (getuid (), &pwd, buffer, bufsize, &pw);
783
 
        }
784
 
        error = error < 0 ? errno : error;
 
689
            if (logname) {
 
690
              error = getpwnam_r (logname, &pwd, buffer, bufsize, &pw);
 
691
              if (!pw || (pw->pw_uid != getuid ())) {
 
692
                /* LOGNAME is lying, fall back to looking up the uid */
 
693
                error = getpwuid_r (getuid (), &pwd, buffer, bufsize, &pw);
 
694
              }
 
695
            } else {
 
696
              error = getpwuid_r (getuid (), &pwd, buffer, bufsize, &pw);
 
697
            }
 
698
            error = error < 0 ? errno : error;
785
699
#    else /* HAVE_NONPOSIX_GETPWUID_R */
786
 
   /* HPUX 11 falls into the HAVE_POSIX_GETPWUID_R case */
 
700
       /* HPUX 11 falls into the HAVE_POSIX_GETPWUID_R case */
787
701
#      if defined(_AIX) || defined(__hpux)
788
 
        error = getpwuid_r (getuid (), &pwd, buffer, bufsize);
789
 
        pw = error == 0 ? &pwd : NULL;
 
702
            error = getpwuid_r (getuid (), &pwd, buffer, bufsize);
 
703
            pw = error == 0 ? &pwd : NULL;
790
704
#      else /* !_AIX */
791
 
        if (logname) {
792
 
          pw = getpwnam_r (logname, &pwd, buffer, bufsize);
793
 
          if (!pw || (pw->pw_uid != getuid ())) {
794
 
            /* LOGNAME is lying, fall back to looking up the uid */
795
 
            pw = getpwuid_r (getuid (), &pwd, buffer, bufsize);
796
 
          }
797
 
        } else {
798
 
          pw = getpwuid_r (getuid (), &pwd, buffer, bufsize);
799
 
        }
800
 
        error = pw ? 0 : errno;
801
 
#      endif /* !_AIX */            
 
705
            if (logname) {
 
706
              pw = getpwnam_r (logname, &pwd, buffer, bufsize);
 
707
              if (!pw || (pw->pw_uid != getuid ())) {
 
708
                /* LOGNAME is lying, fall back to looking up the uid */
 
709
                pw = getpwuid_r (getuid (), &pwd, buffer, bufsize);
 
710
              }
 
711
            } else {
 
712
              pw = getpwuid_r (getuid (), &pwd, buffer, bufsize);
 
713
            }
 
714
            error = pw ? 0 : errno;
 
715
#      endif /* !_AIX */
802
716
#    endif /* HAVE_NONPOSIX_GETPWUID_R */
803
 
        
804
 
        if (!pw)
805
 
          {
806
 
            /* we bail out prematurely if the user id can't be found
807
 
             * (should be pretty rare case actually), or if the buffer
808
 
             * should be sufficiently big and lookups are still not
809
 
             * successful.
810
 
             */
811
 
            if (error == 0 || error == ENOENT)
812
 
              {
813
 
                g_warning ("getpwuid_r(): failed due to unknown user id (%lu)",
814
 
                           (gulong) getuid ());
815
 
                break;
816
 
              }
817
 
            if (bufsize > 32 * 1024)
818
 
              {
819
 
                g_warning ("getpwuid_r(): failed due to: %s.",
820
 
                           g_strerror (error));
821
 
                break;
822
 
              }
823
 
            
824
 
            bufsize *= 2;
825
 
          }
826
 
      }
827
 
    while (!pw);
 
717
 
 
718
            if (!pw)
 
719
              {
 
720
                /* we bail out prematurely if the user id can't be found
 
721
                 * (should be pretty rare case actually), or if the buffer
 
722
                 * should be sufficiently big and lookups are still not
 
723
                 * successful.
 
724
                 */
 
725
                if (error == 0 || error == ENOENT)
 
726
                  {
 
727
                    g_warning ("getpwuid_r(): failed due to unknown user id (%lu)",
 
728
                               (gulong) getuid ());
 
729
                    break;
 
730
                  }
 
731
                if (bufsize > 32 * 1024)
 
732
                  {
 
733
                    g_warning ("getpwuid_r(): failed due to: %s.",
 
734
                               g_strerror (error));
 
735
                    break;
 
736
                  }
 
737
 
 
738
                bufsize *= 2;
 
739
              }
 
740
          }
 
741
        while (!pw);
828
742
#  endif /* HAVE_POSIX_GETPWUID_R || HAVE_NONPOSIX_GETPWUID_R */
829
 
    
830
 
    if (!pw)
831
 
      {
832
 
        setpwent ();
833
 
        pw = getpwuid (getuid ());
834
 
        endpwent ();
835
 
      }
836
 
    if (pw)
837
 
      {
838
 
        g_user_name = g_strdup (pw->pw_name);
839
 
 
840
 
        if (pw->pw_gecos && *pw->pw_gecos != '\0') 
841
 
          {
842
 
            gchar **gecos_fields;
843
 
            gchar **name_parts;
844
 
 
845
 
            /* split the gecos field and substitute '&' */
846
 
            gecos_fields = g_strsplit (pw->pw_gecos, ",", 0);
847
 
            name_parts = g_strsplit (gecos_fields[0], "&", 0);
848
 
            pw->pw_name[0] = g_ascii_toupper (pw->pw_name[0]);
849
 
            g_real_name = g_strjoinv (pw->pw_name, name_parts);
850
 
            g_strfreev (gecos_fields);
851
 
            g_strfreev (name_parts);
852
 
          }
853
 
 
854
 
        if (!g_home_dir)
855
 
          g_home_dir = g_strdup (pw->pw_dir);
856
 
      }
857
 
    g_free (buffer);
858
 
  }
859
 
  
 
743
 
 
744
        if (!pw)
 
745
          {
 
746
            setpwent ();
 
747
            pw = getpwuid (getuid ());
 
748
            endpwent ();
 
749
          }
 
750
        if (pw)
 
751
          {
 
752
            e.user_name = g_strdup (pw->pw_name);
 
753
 
 
754
            if (pw->pw_gecos && *pw->pw_gecos != '\0')
 
755
              {
 
756
                gchar **gecos_fields;
 
757
                gchar **name_parts;
 
758
 
 
759
                /* split the gecos field and substitute '&' */
 
760
                gecos_fields = g_strsplit (pw->pw_gecos, ",", 0);
 
761
                name_parts = g_strsplit (gecos_fields[0], "&", 0);
 
762
                pw->pw_name[0] = g_ascii_toupper (pw->pw_name[0]);
 
763
                e.real_name = g_strjoinv (pw->pw_name, name_parts);
 
764
                g_strfreev (gecos_fields);
 
765
                g_strfreev (name_parts);
 
766
              }
 
767
 
 
768
            if (!e.home_dir)
 
769
              e.home_dir = g_strdup (pw->pw_dir);
 
770
          }
 
771
        g_free (buffer);
 
772
      }
 
773
 
860
774
#else /* !HAVE_PWD_H */
861
 
  
 
775
 
862
776
#ifdef G_OS_WIN32
863
 
  {
864
 
    guint len = UNLEN+1;
865
 
    wchar_t buffer[UNLEN+1];
866
 
    
867
 
    if (GetUserNameW (buffer, (LPDWORD) &len))
868
777
      {
869
 
        g_user_name = g_utf16_to_utf8 (buffer, -1, NULL, NULL, NULL);
870
 
        g_real_name = g_strdup (g_user_name);
 
778
        guint len = UNLEN+1;
 
779
        wchar_t buffer[UNLEN+1];
 
780
 
 
781
        if (GetUserNameW (buffer, (LPDWORD) &len))
 
782
          {
 
783
            e.user_name = g_utf16_to_utf8 (buffer, -1, NULL, NULL, NULL);
 
784
            e.real_name = g_strdup (e.user_name);
 
785
          }
871
786
      }
872
 
  }
873
787
#endif /* G_OS_WIN32 */
874
788
 
875
789
#endif /* !HAVE_PWD_H */
876
790
 
877
 
#ifndef G_OS_WIN32
878
 
  if (!g_home_dir)
879
 
    g_home_dir = g_strdup (g_getenv ("HOME"));
880
 
#endif
881
 
 
882
791
#ifdef __EMX__
883
 
  /* change '\\' in %HOME% to '/' */
884
 
  g_strdelimit (g_home_dir, "\\",'/');
885
 
#endif
886
 
  if (!g_user_name)
887
 
    g_user_name = g_strdup ("somebody");
888
 
  if (!g_real_name)
889
 
    g_real_name = g_strdup ("Unknown");
890
 
 
891
 
  {
892
 
#ifndef G_OS_WIN32
893
 
    gboolean hostname_fail = (gethostname (hostname, sizeof (hostname)) == -1);
894
 
#else
895
 
    DWORD size = sizeof (hostname);
896
 
    gboolean hostname_fail = (!GetComputerName (hostname, &size));
897
 
#endif
898
 
    g_host_name = g_strdup (hostname_fail ? "localhost" : hostname);
899
 
  }
900
 
 
901
 
#ifdef G_OS_WIN32
902
 
  g_tmp_dir_cp = g_locale_from_utf8 (g_tmp_dir, -1, NULL, NULL, NULL);
903
 
  g_user_name_cp = g_locale_from_utf8 (g_user_name, -1, NULL, NULL, NULL);
904
 
  g_real_name_cp = g_locale_from_utf8 (g_real_name, -1, NULL, NULL, NULL);
905
 
 
906
 
  if (!g_tmp_dir_cp)
907
 
    g_tmp_dir_cp = g_strdup ("\\");
908
 
  if (!g_user_name_cp)
909
 
    g_user_name_cp = g_strdup ("somebody");
910
 
  if (!g_real_name_cp)
911
 
    g_real_name_cp = g_strdup ("Unknown");
912
 
 
913
 
  /* home_dir might be NULL, unlike tmp_dir, user_name and
914
 
   * real_name.
915
 
   */
916
 
  if (g_home_dir)
917
 
    g_home_dir_cp = g_locale_from_utf8 (g_home_dir, -1, NULL, NULL, NULL);
918
 
  else
919
 
    g_home_dir_cp = NULL;
920
 
#endif /* G_OS_WIN32 */
921
 
}
922
 
 
923
 
static inline void
924
 
g_get_any_init (void)
925
 
{
926
 
  if (!g_tmp_dir)
927
 
    g_get_any_init_do ();
928
 
}
929
 
 
930
 
static inline void
931
 
g_get_any_init_locked (void)
932
 
{
933
 
  G_LOCK (g_utils_global);
934
 
  g_get_any_init ();
935
 
  G_UNLOCK (g_utils_global);
936
 
}
937
 
 
 
792
      /* change '\\' in %HOME% to '/' */
 
793
      g_strdelimit (e.home_dir, "\\",'/');
 
794
#endif
 
795
      if (!e.user_name)
 
796
        e.user_name = g_strdup ("somebody");
 
797
      if (!e.real_name)
 
798
        e.real_name = g_strdup ("Unknown");
 
799
 
 
800
      g_once_init_leave (&entry, &e);
 
801
    }
 
802
 
 
803
  return entry;
 
804
}
938
805
 
939
806
/**
940
807
 * g_get_user_name:
949
816
const gchar *
950
817
g_get_user_name (void)
951
818
{
952
 
  g_get_any_init_locked ();
953
 
  return g_user_name;
 
819
  UserDatabaseEntry *entry;
 
820
 
 
821
  entry = g_get_user_database_entry ();
 
822
 
 
823
  return entry->user_name;
954
824
}
955
825
 
956
826
/**
967
837
const gchar *
968
838
g_get_real_name (void)
969
839
{
970
 
  g_get_any_init_locked ();
971
 
  return g_real_name;
 
840
  UserDatabaseEntry *entry;
 
841
 
 
842
  entry = g_get_user_database_entry ();
 
843
 
 
844
  return entry->real_name;
972
845
}
973
846
 
974
847
/**
975
848
 * g_get_home_dir:
976
849
 *
977
 
 * Gets the current user's home directory as defined in the 
978
 
 * password database.
979
 
 *
980
 
 * Note that in contrast to traditional UNIX tools, this function 
981
 
 * prefers <filename>passwd</filename> entries over the <envar>HOME</envar> 
982
 
 * environment variable. 
983
 
 *
984
 
 * One of the reasons for this decision is that applications in many 
985
 
 * cases need special handling to deal with the case where 
986
 
 * <envar>HOME</envar> is
987
 
 * <simplelist>
988
 
 *   <member>Not owned by the user</member>
989
 
 *   <member>Not writeable</member>
990
 
 *   <member>Not even readable</member>
991
 
 * </simplelist>
992
 
 * Since applications are in general <emphasis>not</emphasis> written 
993
 
 * to deal with these situations it was considered better to make 
994
 
 * g_get_home_dir() not pay attention to <envar>HOME</envar> and to 
995
 
 * return the real home directory for the user. If applications
996
 
 * want to pay attention to <envar>HOME</envar>, they can do:
997
 
 * |[
998
 
 *  const char *homedir = g_getenv ("HOME");
999
 
 *   if (!homedir)
1000
 
 *      homedir = g_get_home_dir (<!-- -->);
1001
 
 * ]|
 
850
 * Gets the current user's home directory.
 
851
 *
 
852
 * As with most UNIX tools, this function will return the value of the
 
853
 * <envar>HOME</envar> environment variable if it is set to an existing
 
854
 * absolute path name, falling back to the <filename>passwd</filename>
 
855
 * file in the case that it is unset.
 
856
 *
 
857
 * If the path given in <envar>HOME</envar> is non-absolute, does not
 
858
 * exist, or is not a directory, the result is undefined.
 
859
 *
 
860
 * <note><para>
 
861
 *   Before version 2.36 this function would ignore the
 
862
 *   <envar>HOME</envar> environment variable, taking the value from the
 
863
 *   <filename>passwd</filename> database instead.  This was changed to
 
864
 *   increase the compatibility of GLib with other programs (and the XDG
 
865
 *   basedir specification) and to increase testability of programs
 
866
 *   based on GLib (by making it easier to run them from test
 
867
 *   frameworks).
 
868
 * </para><para>
 
869
 *   If your program has a strong requirement for either the new or the
 
870
 *   old behaviour (and if you don't wish to increase your GLib
 
871
 *   dependency to ensure that the new behaviour is in effect) then you
 
872
 *   should either directly check the <envar>HOME</envar> environment
 
873
 *   variable yourself or unset it before calling any functions in GLib.
 
874
 * </para></note>
1002
875
 *
1003
876
 * Returns: the current user's home directory
1004
877
 */
1005
878
const gchar *
1006
879
g_get_home_dir (void)
1007
880
{
1008
 
  g_get_any_init_locked ();
1009
 
  return g_home_dir;
 
881
  static gchar *home_dir;
 
882
 
 
883
  if (g_once_init_enter (&home_dir))
 
884
    {
 
885
      gchar *tmp;
 
886
 
 
887
      /* We first check HOME and use it if it is set */
 
888
      tmp = g_strdup (g_getenv ("HOME"));
 
889
 
 
890
#ifdef G_OS_WIN32
 
891
      /* Only believe HOME if it is an absolute path and exists.
 
892
       *
 
893
       * We only do this check on Windows for a couple of reasons.
 
894
       * Historically, we only did it there because we used to ignore $HOME
 
895
       * on UNIX.  There are concerns about enabling it now on UNIX because
 
896
       * of things like autofs.  In short, if the user has a bogus value in
 
897
       * $HOME then they get what they pay for...
 
898
       */
 
899
      if (tmp)
 
900
        {
 
901
          if (!(g_path_is_absolute (tmp) &&
 
902
                g_file_test (tmp, G_FILE_TEST_IS_DIR)))
 
903
            {
 
904
              g_free (tmp);
 
905
              tmp = NULL;
 
906
            }
 
907
        }
 
908
 
 
909
      /* In case HOME is Unix-style (it happens), convert it to
 
910
       * Windows style.
 
911
       */
 
912
      if (tmp)
 
913
        {
 
914
          gchar *p;
 
915
          while ((p = strchr (tmp, '/')) != NULL)
 
916
            *p = '\\';
 
917
        }
 
918
 
 
919
      if (!tmp)
 
920
        {
 
921
          /* USERPROFILE is probably the closest equivalent to $HOME? */
 
922
          if (g_getenv ("USERPROFILE") != NULL)
 
923
            tmp = g_strdup (g_getenv ("USERPROFILE"));
 
924
        }
 
925
 
 
926
      if (!tmp)
 
927
        tmp = get_special_folder (CSIDL_PROFILE);
 
928
 
 
929
      if (!tmp)
 
930
        tmp = get_windows_directory_root ();
 
931
#endif /* G_OS_WIN32 */
 
932
 
 
933
      if (!tmp)
 
934
        {
 
935
          /* If we didn't get it from any of those methods, we will have
 
936
           * to read the user database entry.
 
937
           */
 
938
          UserDatabaseEntry *entry;
 
939
 
 
940
          entry = g_get_user_database_entry ();
 
941
 
 
942
          /* Strictly speaking, we should copy this, but we know that
 
943
           * neither will ever be freed, so don't bother...
 
944
           */
 
945
          tmp = entry->home_dir;
 
946
        }
 
947
 
 
948
      g_once_init_leave (&home_dir, tmp);
 
949
    }
 
950
 
 
951
  return home_dir;
1010
952
}
1011
953
 
1012
954
/**
1024
966
const gchar *
1025
967
g_get_tmp_dir (void)
1026
968
{
1027
 
  g_get_any_init_locked ();
1028
 
  return g_tmp_dir;
 
969
  static gchar *tmp_dir;
 
970
 
 
971
  if (g_once_init_enter (&tmp_dir))
 
972
    {
 
973
      gchar *tmp;
 
974
 
 
975
      tmp = g_strdup (g_getenv ("TMPDIR"));
 
976
 
 
977
      if (tmp == NULL || *tmp == '\0')
 
978
        {
 
979
          g_free (tmp);
 
980
          tmp = g_strdup (g_getenv ("TMP"));
 
981
        }
 
982
 
 
983
      if (tmp == NULL || *tmp == '\0')
 
984
        {
 
985
          g_free (tmp);
 
986
          tmp = g_strdup (g_getenv ("TEMP"));
 
987
        }
 
988
 
 
989
#ifdef G_OS_WIN32
 
990
      if (tmp == NULL || *tmp == '\0')
 
991
        {
 
992
          g_free (tmp);
 
993
          tmp = get_windows_directory_root ();
 
994
        }
 
995
#else
 
996
 
 
997
#ifdef P_tmpdir
 
998
      if (tmp == NULL || *tmp == '\0')
 
999
        {
 
1000
          gsize k;
 
1001
          g_free (tmp);
 
1002
          tmp = g_strdup (P_tmpdir);
 
1003
          k = strlen (tmp);
 
1004
          if (k > 1 && G_IS_DIR_SEPARATOR (tmp[k - 1]))
 
1005
            tmp[k - 1] = '\0';
 
1006
        }
 
1007
#endif
 
1008
 
 
1009
      if (tmp == NULL || *tmp == '\0')
 
1010
        {
 
1011
          g_free (tmp);
 
1012
          tmp = g_strdup ("/tmp");
 
1013
        }
 
1014
#endif /* !G_OS_WIN32 */
 
1015
 
 
1016
      g_once_init_leave (&tmp_dir, tmp);
 
1017
    }
 
1018
 
 
1019
  return tmp_dir;
1029
1020
}
1030
1021
 
1031
1022
/**
1051
1042
const gchar *
1052
1043
g_get_host_name (void)
1053
1044
{
1054
 
  g_get_any_init_locked ();
1055
 
  return g_host_name;
 
1045
  static gchar *hostname;
 
1046
 
 
1047
  if (g_once_init_enter (&hostname))
 
1048
    {
 
1049
      gboolean failed;
 
1050
      gchar tmp[100];
 
1051
 
 
1052
#ifndef G_OS_WIN32
 
1053
      failed = (gethostname (tmp, sizeof (tmp)) == -1);
 
1054
#else
 
1055
      DWORD size = sizeof (tmp);
 
1056
      failed = (!GetComputerName (tmp, &size));
 
1057
#endif
 
1058
 
 
1059
      g_once_init_leave (&hostname, g_strdup (failed ? "localhost" : tmp));
 
1060
    }
 
1061
 
 
1062
  return hostname;
1056
1063
}
1057
1064
 
1058
1065
G_LOCK_DEFINE_STATIC (g_prgname);
1070
1077
 * Returns: the name of the program. The returned string belongs 
1071
1078
 * to GLib and must not be modified or freed.
1072
1079
 */
1073
 
gchar*
 
1080
const gchar*
1074
1081
g_get_prgname (void)
1075
1082
{
1076
1083
  gchar* retval;
1228
1235
#endif
1229
1236
      if (!data_dir || !data_dir[0])
1230
1237
        {
1231
 
          g_get_any_init ();
 
1238
          const gchar *home_dir = g_get_home_dir ();
1232
1239
 
1233
 
          if (g_home_dir)
1234
 
            data_dir = g_build_filename (g_home_dir, ".local", 
1235
 
                                         "share", NULL);
 
1240
          if (home_dir)
 
1241
            data_dir = g_build_filename (home_dir, ".local", "share", NULL);
1236
1242
          else
1237
 
            data_dir = g_build_filename (g_tmp_dir, g_user_name, ".local", 
1238
 
                                         "share", NULL);
 
1243
            data_dir = g_build_filename (g_get_tmp_dir (), g_get_user_name (), ".local", "share", NULL);
1239
1244
        }
1240
1245
 
1241
1246
      g_user_data_dir = data_dir;
1265
1270
#endif
1266
1271
      if (!config_dir || !config_dir[0])
1267
1272
        {
1268
 
          g_get_any_init ();
 
1273
          const gchar *home_dir = g_get_home_dir ();
1269
1274
 
1270
 
          if (g_home_dir)
1271
 
            config_dir = g_build_filename (g_home_dir, ".config", NULL);
 
1275
          if (home_dir)
 
1276
            config_dir = g_build_filename (home_dir, ".config", NULL);
1272
1277
          else
1273
 
            config_dir = g_build_filename (g_tmp_dir, g_user_name, ".config", NULL);
 
1278
            config_dir = g_build_filename (g_get_tmp_dir (), g_get_user_name (), ".config", NULL);
1274
1279
        }
1275
1280
 
1276
1281
      g_user_config_dir = config_dir;
1348
1353
#endif
1349
1354
      if (!cache_dir || !cache_dir[0])
1350
1355
        {
1351
 
          g_get_any_init ();
1352
 
        
1353
 
          if (g_home_dir)
1354
 
            cache_dir = g_build_filename (g_home_dir, ".cache", NULL);
 
1356
          const gchar *home_dir = g_get_home_dir ();
 
1357
 
 
1358
          if (home_dir)
 
1359
            cache_dir = g_build_filename (home_dir, ".cache", NULL);
1355
1360
          else
1356
 
            cache_dir = g_build_filename (g_tmp_dir, g_user_name, ".cache", NULL);
 
1361
            cache_dir = g_build_filename (g_get_tmp_dir (), g_get_user_name (), ".cache", NULL);
1357
1362
        }
1358
1363
      g_user_cache_dir = cache_dir;
1359
1364
    }
1683
1688
      
1684
1689
      if (is_relative)
1685
1690
        {
1686
 
          g_get_any_init ();
1687
 
          g_user_special_dirs[directory] = g_build_filename (g_home_dir, d, NULL);
 
1691
          g_user_special_dirs[directory] = g_build_filename (g_get_home_dir (), d, NULL);
1688
1692
        }
1689
1693
      else
1690
1694
        g_user_special_dirs[directory] = g_strdup (d);
1790
1794
 
1791
1795
      /* Special-case desktop for historical compatibility */
1792
1796
      if (g_user_special_dirs[G_USER_DIRECTORY_DESKTOP] == NULL)
1793
 
        {
1794
 
          g_get_any_init ();
1795
 
 
1796
 
          g_user_special_dirs[G_USER_DIRECTORY_DESKTOP] =
1797
 
            g_build_filename (g_home_dir, "Desktop", NULL);
1798
 
        }
 
1797
        g_user_special_dirs[G_USER_DIRECTORY_DESKTOP] = g_build_filename (g_get_home_dir (), "Desktop", NULL);
1799
1798
    }
1800
1799
 
1801
1800
  G_UNLOCK (g_utils_global);
1860
1859
}
1861
1860
 
1862
1861
const gchar * const *
1863
 
g_win32_get_system_data_dirs_for_module (void (*address_of_function)())
 
1862
g_win32_get_system_data_dirs_for_module (void (*address_of_function)(void))
1864
1863
{
1865
1864
  GArray *data_dirs;
1866
1865
  HMODULE hmodule;
2320
2319
      if (size < (goffset) MEBIBYTE_FACTOR)
2321
2320
        {
2322
2321
          displayed_size = (gdouble) size / (gdouble) KIBIBYTE_FACTOR;
 
2322
          /* Translators: this is from the deprecated function g_format_size_for_display() which uses 'KB' to
 
2323
           * mean 1024 bytes.  I am aware that 'KB' is not correct, but it has been preserved for reasons of
 
2324
           * compatibility.  Users will not see this string unless a program is using this deprecated function.
 
2325
           * Please translate as literally as possible.
 
2326
           */
2323
2327
          return g_strdup_printf (_("%.1f KB"), displayed_size);
2324
2328
        }
2325
2329
      else if (size < (goffset) GIBIBYTE_FACTOR)
2350
2354
    }
2351
2355
}
2352
2356
 
2353
 
#if defined (G_OS_WIN32) && !defined (_WIN64)
 
2357
#if defined (G_OS_WIN32)
2354
2358
 
2355
2359
/* Binary compatibility versions. Not for newly compiled code. */
2356
2360
 
2357
 
#undef g_find_program_in_path
2358
 
 
2359
 
gchar*
2360
 
g_find_program_in_path (const gchar *program)
2361
 
{
2362
 
  gchar *utf8_program = g_locale_to_utf8 (program, -1, NULL, NULL, NULL);
2363
 
  gchar *utf8_retval = g_find_program_in_path_utf8 (utf8_program);
2364
 
  gchar *retval;
2365
 
 
2366
 
  g_free (utf8_program);
2367
 
  if (utf8_retval == NULL)
2368
 
    return NULL;
2369
 
  retval = g_locale_from_utf8 (utf8_retval, -1, NULL, NULL, NULL);
2370
 
  g_free (utf8_retval);
2371
 
 
2372
 
  return retval;
2373
 
}
2374
 
 
2375
 
#undef g_get_user_name
2376
 
 
2377
 
const gchar *
2378
 
g_get_user_name (void)
2379
 
{
2380
 
  g_get_any_init_locked ();
2381
 
  return g_user_name_cp;
2382
 
}
2383
 
 
2384
 
#undef g_get_real_name
2385
 
 
2386
 
const gchar *
2387
 
g_get_real_name (void)
2388
 
{
2389
 
  g_get_any_init_locked ();
2390
 
  return g_real_name_cp;
2391
 
}
2392
 
 
2393
 
#undef g_get_home_dir
2394
 
 
2395
 
const gchar *
2396
 
g_get_home_dir (void)
2397
 
{
2398
 
  g_get_any_init_locked ();
2399
 
  return g_home_dir_cp;
2400
 
}
2401
 
 
2402
 
#undef g_get_tmp_dir
2403
 
 
2404
 
const gchar *
2405
 
g_get_tmp_dir (void)
2406
 
{
2407
 
  g_get_any_init_locked ();
2408
 
  return g_tmp_dir_cp;
2409
 
}
2410
 
 
2411
 
#endif
 
2361
_GLIB_EXTERN const gchar *g_get_user_name_utf8        (void);
 
2362
_GLIB_EXTERN const gchar *g_get_real_name_utf8        (void);
 
2363
_GLIB_EXTERN const gchar *g_get_home_dir_utf8         (void);
 
2364
_GLIB_EXTERN const gchar *g_get_tmp_dir_utf8          (void);
 
2365
_GLIB_EXTERN gchar       *g_find_program_in_path_utf8 (const gchar *program);
 
2366
 
 
2367
gchar *
 
2368
g_find_program_in_path_utf8 (const gchar *program)
 
2369
{
 
2370
  return g_find_program_in_path (program);
 
2371
}
 
2372
 
 
2373
const gchar *g_get_user_name_utf8 (void) { return g_get_user_name (); }
 
2374
const gchar *g_get_real_name_utf8 (void) { return g_get_real_name (); }
 
2375
const gchar *g_get_home_dir_utf8 (void) { return g_get_home_dir (); }
 
2376
const gchar *g_get_tmp_dir_utf8 (void) { return g_get_tmp_dir (); }
 
2377
 
 
2378
#endif
 
2379
 
 
2380
/* Private API:
 
2381
 *
 
2382
 * Returns %TRUE if the current process was executed as setuid (or an
 
2383
 * equivalent __libc_enable_secure is available).  See:
 
2384
 * http://osdir.com/ml/linux.lfs.hardened/2007-04/msg00032.html
 
2385
 */ 
 
2386
gboolean
 
2387
g_check_setuid (void)
 
2388
{
 
2389
  /* TODO: get __libc_enable_secure exported from glibc.
 
2390
   * See http://www.openwall.com/lists/owl-dev/2012/08/14/1
 
2391
   */
 
2392
#if 0 && defined(HAVE_LIBC_ENABLE_SECURE)
 
2393
  {
 
2394
    /* See glibc/include/unistd.h */
 
2395
    extern int __libc_enable_secure;
 
2396
    return __libc_enable_secure;
 
2397
  }
 
2398
#elif defined(HAVE_ISSETUGID)
 
2399
  /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */
 
2400
  return issetugid ();
 
2401
#elif defined(G_OS_UNIX)
 
2402
  uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
 
2403
  gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */
 
2404
 
 
2405
  static gsize check_setuid_initialised;
 
2406
  static gboolean is_setuid;
 
2407
 
 
2408
  if (g_once_init_enter (&check_setuid_initialised))
 
2409
    {
 
2410
#ifdef HAVE_GETRESUID
 
2411
      /* These aren't in the header files, so we prototype them here.
 
2412
       */
 
2413
      int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid);
 
2414
      int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid);
 
2415
      
 
2416
      if (getresuid (&ruid, &euid, &suid) != 0 ||
 
2417
          getresgid (&rgid, &egid, &sgid) != 0)
 
2418
#endif /* HAVE_GETRESUID */
 
2419
        {
 
2420
          suid = ruid = getuid ();
 
2421
          sgid = rgid = getgid ();
 
2422
          euid = geteuid ();
 
2423
          egid = getegid ();
 
2424
        }
 
2425
 
 
2426
      is_setuid = (ruid != euid || ruid != suid ||
 
2427
                   rgid != egid || rgid != sgid);
 
2428
 
 
2429
      g_once_init_leave (&check_setuid_initialised, 1);
 
2430
    }
 
2431
  return is_setuid;
 
2432
#else
 
2433
  return FALSE;
 
2434
#endif
 
2435
}