With no one coming up with a better idea, this applied patch adds PGETC
(for pg_service.conf) and PGLOCALE (for locale dir) environment variable
processing to libpq.

The patch also adds code to our client apps so we set the environment
variable directly based on our binary location, unless it is already
set. This will allow our applications to emit proper locale messages
that are generated in libpq.

---------------------------------------------------------------------------

Bruce Momjian wrote:
> Andrew Dunstan wrote:
> > 
> > 
> > Bruce Momjian wrote:
> > 
> > >Peter Eisentraut wrote:
> > >  
> > >
> > >>Andrew Dunstan wrote:
> > >>    
> > >>
> > >>>I'm confused. Can you explain the problem more clearly, please? Do we
> > >>>need to distinguish known apps with a known (relative) message
> > >>>location, from unknown libpq clients?
> > >>>      
> > >>>
> > >>The problem boils down to the fact that libpq needs to find its data 
> > >>files (in this case locale data, but it could be anything), but it 
> > >>doesn't know its own location, so it can't use a relative path 
> > >>reference as has been proposed.
> > >>    
> > >>
> > >
> > >I am wondering if we should use environment variables, and have our apps
> > >use putenv() to set it to the proper relative path.
> > >  
> > >
> > 
> > It seems a bit roundabout, but might make sense. Maybe they shouldn't 
> > override any value already present in the environment, just set it if 
> > there is nothing there? Then the library could use the environment if 
> > set, or fall back on a hardcoded path.
> 
> Yes, that is what I was thinking.  Call it PGLOCALEDIR.
> 
> -- 
>   Bruce Momjian                        |  http://candle.pha.pa.us
>   [EMAIL PROTECTED]               |  (610) 359-1001
>   +  If your life is a hard drive,     |  13 Roberts Road
>   +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073
> 
> ---------------------------(end of broadcast)---------------------------
> TIP 8: explain analyze is your friend
> 

-- 
  Bruce Momjian                        |  http://candle.pha.pa.us
  [EMAIL PROTECTED]               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073
Index: doc/src/sgml/libpq.sgml
===================================================================
RCS file: /cvsroot/pgsql-server/doc/src/sgml/libpq.sgml,v
retrieving revision 1.155
diff -c -c -r1.155 libpq.sgml
*** doc/src/sgml/libpq.sgml     14 May 2004 18:04:02 -0000      1.155
--- doc/src/sgml/libpq.sgml     2 Jun 2004 23:59:33 -0000
***************
*** 3582,3587 ****
--- 3582,3605 ----
  (Equivalent to <literal>SET geqo TO ...</literal>.)
  </para>
  </listitem>
+ <listitem>
+ <para>
+ <indexterm>
+  <primary><envar>PGETC</envar></primary>
+ </indexterm>
+ <envar>PGETC</envar>
+ sets the directory containing the <filename>pg_service.conf</> file.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <indexterm>
+  <primary><envar>PGLOCALE</envar></primary>
+ </indexterm>
+ <envar>PGLOCALE</envar>
+ sets the directory containing the <literal>locale</> files.
+ </para>
+ </listitem>
  </itemizedlist>
  
  Refer to the <acronym>SQL</acronym> command <command>SET</command>
Index: src/backend/main/main.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/main/main.c,v
retrieving revision 1.85
diff -c -c -r1.85 main.c
*** src/backend/main/main.c     29 May 2004 22:48:19 -0000      1.85
--- src/backend/main/main.c     2 Jun 2004 23:59:41 -0000
***************
*** 152,158 ****
         * allow startup error messages to be localized.
         */
  
!       set_pglocale(argv[0], "postgres");
  
  #ifdef WIN32
  
--- 152,158 ----
         * allow startup error messages to be localized.
         */
  
!       set_pglocale_pgservice(argv[0], "postgres");
  
  #ifdef WIN32
  
Index: src/bin/initdb/initdb.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/initdb/initdb.c,v
retrieving revision 1.34
diff -c -c -r1.34 initdb.c
*** src/bin/initdb/initdb.c     1 Jun 2004 02:53:59 -0000       1.34
--- src/bin/initdb/initdb.c     2 Jun 2004 23:59:53 -0000
***************
*** 1788,1794 ****
        {"global", "pg_xlog", "pg_clog", "base", "base/1"};
  
        progname = get_progname(argv[0]);
!       set_pglocale(argv[0], "initdb");
  
      if (argc > 1)
      {
--- 1788,1794 ----
        {"global", "pg_xlog", "pg_clog", "base", "base/1"};
  
        progname = get_progname(argv[0]);
!       set_pglocale_pgservice(argv[0], "initdb");
  
      if (argc > 1)
      {
Index: src/bin/pg_controldata/pg_controldata.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/pg_controldata/pg_controldata.c,v
retrieving revision 1.16
diff -c -c -r1.16 pg_controldata.c
*** src/bin/pg_controldata/pg_controldata.c     25 May 2004 01:00:23 -0000      1.16
--- src/bin/pg_controldata/pg_controldata.c     2 Jun 2004 23:59:53 -0000
***************
*** 77,83 ****
        char       *strftime_fmt = "%c";
        const char *progname;
  
!       set_pglocale(argv[0], "pg_controldata");
  
        progname = get_progname(argv[0]);
  
--- 77,83 ----
        char       *strftime_fmt = "%c";
        const char *progname;
  
!       set_pglocale_pgservice(argv[0], "pg_controldata");
  
        progname = get_progname(argv[0]);
  
Index: src/bin/pg_ctl/pg_ctl.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/pg_ctl/pg_ctl.c,v
retrieving revision 1.5
diff -c -c -r1.5 pg_ctl.c
*** src/bin/pg_ctl/pg_ctl.c     1 Jun 2004 22:03:18 -0000       1.5
--- src/bin/pg_ctl/pg_ctl.c     2 Jun 2004 23:59:54 -0000
***************
*** 824,830 ****
  #endif
  
        progname = get_progname(argv[0]);
!       set_pglocale(argv[0], "pg_ctl");
  
        /*
         * save argv[0] so do_start() can look for the postmaster if
--- 824,830 ----
  #endif
  
        progname = get_progname(argv[0]);
!       set_pglocale_pgservice(argv[0], "pg_ctl");
  
        /*
         * save argv[0] so do_start() can look for the postmaster if
Index: src/bin/pg_dump/pg_dump.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/pg_dump/pg_dump.c,v
retrieving revision 1.372
diff -c -c -r1.372 pg_dump.c
*** src/bin/pg_dump/pg_dump.c   26 May 2004 18:24:22 -0000      1.372
--- src/bin/pg_dump/pg_dump.c   3 Jun 2004 00:00:00 -0000
***************
*** 242,248 ****
        };
        int                     optindex;
  
!       set_pglocale(argv[0], "pg_dump");
  
        g_verbose = false;
  
--- 242,248 ----
        };
        int                     optindex;
  
!       set_pglocale_pgservice(argv[0], "pg_dump");
  
        g_verbose = false;
  
Index: src/bin/pg_dump/pg_dumpall.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/pg_dump/pg_dumpall.c,v
retrieving revision 1.35
diff -c -c -r1.35 pg_dumpall.c
*** src/bin/pg_dump/pg_dumpall.c        25 May 2004 01:00:24 -0000      1.35
--- src/bin/pg_dump/pg_dumpall.c        3 Jun 2004 00:00:00 -0000
***************
*** 101,107 ****
  
        int                     optindex;
  
!       set_pglocale(argv[0], "pg_dump");
  
        progname = get_progname(argv[0]);
  
--- 101,107 ----
  
        int                     optindex;
  
!       set_pglocale_pgservice(argv[0], "pg_dump");
  
        progname = get_progname(argv[0]);
  
Index: src/bin/pg_dump/pg_restore.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/pg_dump/pg_restore.c,v
retrieving revision 1.57
diff -c -c -r1.57 pg_restore.c
*** src/bin/pg_dump/pg_restore.c        25 May 2004 01:00:24 -0000      1.57
--- src/bin/pg_dump/pg_restore.c        3 Jun 2004 00:00:01 -0000
***************
*** 121,127 ****
                {NULL, 0, NULL, 0}
        };
  
!       set_pglocale(argv[0], "pg_dump");
  
        opts = NewRestoreOptions();
  
--- 121,127 ----
                {NULL, 0, NULL, 0}
        };
  
!       set_pglocale_pgservice(argv[0], "pg_dump");
  
        opts = NewRestoreOptions();
  
Index: src/bin/pg_resetxlog/pg_resetxlog.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/pg_resetxlog/pg_resetxlog.c,v
retrieving revision 1.19
diff -c -c -r1.19 pg_resetxlog.c
*** src/bin/pg_resetxlog/pg_resetxlog.c 25 May 2004 01:00:25 -0000      1.19
--- src/bin/pg_resetxlog/pg_resetxlog.c 3 Jun 2004 00:00:02 -0000
***************
*** 102,108 ****
        int                     fd;
        char            path[MAXPGPATH];
  
!       set_pglocale(argv[0], "pg_resetxlog");
  
        progname = get_progname(argv[0]);
  
--- 102,108 ----
        int                     fd;
        char            path[MAXPGPATH];
  
!       set_pglocale_pgservice(argv[0], "pg_resetxlog");
  
        progname = get_progname(argv[0]);
  
Index: src/bin/psql/startup.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/psql/startup.c,v
retrieving revision 1.94
diff -c -c -r1.94 startup.c
*** src/bin/psql/startup.c      25 May 2004 01:00:26 -0000      1.94
--- src/bin/psql/startup.c      3 Jun 2004 00:00:02 -0000
***************
*** 102,108 ****
        char       *password = NULL;
        bool            need_pass;
  
!       set_pglocale(argv[0], "psql");
  
        pset.progname = get_progname(argv[0]);
  
--- 102,108 ----
        char       *password = NULL;
        bool            need_pass;
  
!       set_pglocale_pgservice(argv[0], "psql");
  
        pset.progname = get_progname(argv[0]);
  
Index: src/bin/scripts/clusterdb.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/scripts/clusterdb.c,v
retrieving revision 1.8
diff -c -c -r1.8 clusterdb.c
*** src/bin/scripts/clusterdb.c 1 Jun 2004 02:54:09 -0000       1.8
--- src/bin/scripts/clusterdb.c 3 Jun 2004 00:00:02 -0000
***************
*** 58,64 ****
        char       *table = NULL;
  
        progname = get_progname(argv[0]);
!       set_pglocale(argv[0], "pgscripts");
  
        handle_help_version_opts(argc, argv, "clusterdb", help);
  
--- 58,64 ----
        char       *table = NULL;
  
        progname = get_progname(argv[0]);
!       set_pglocale_pgservice(argv[0], "pgscripts");
  
        handle_help_version_opts(argc, argv, "clusterdb", help);
  
Index: src/bin/scripts/createdb.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/scripts/createdb.c,v
retrieving revision 1.10
diff -c -c -r1.10 createdb.c
*** src/bin/scripts/createdb.c  1 Jun 2004 02:54:09 -0000       1.10
--- src/bin/scripts/createdb.c  3 Jun 2004 00:00:03 -0000
***************
*** 60,66 ****
        PGresult   *result;
  
        progname = get_progname(argv[0]);
!       set_pglocale(argv[0], "pgscripts");
  
        handle_help_version_opts(argc, argv, "createdb", help);
  
--- 60,66 ----
        PGresult   *result;
  
        progname = get_progname(argv[0]);
!       set_pglocale_pgservice(argv[0], "pgscripts");
  
        handle_help_version_opts(argc, argv, "createdb", help);
  
Index: src/bin/scripts/createlang.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/scripts/createlang.c,v
retrieving revision 1.11
diff -c -c -r1.11 createlang.c
*** src/bin/scripts/createlang.c        1 Jun 2004 02:54:09 -0000       1.11
--- src/bin/scripts/createlang.c        3 Jun 2004 00:00:05 -0000
***************
*** 61,67 ****
        PGresult   *result;
  
        progname = get_progname(argv[0]);
!       set_pglocale(argv[0], "pgscripts");
  
        handle_help_version_opts(argc, argv, "createlang", help);
  
--- 61,67 ----
        PGresult   *result;
  
        progname = get_progname(argv[0]);
!       set_pglocale_pgservice(argv[0], "pgscripts");
  
        handle_help_version_opts(argc, argv, "createlang", help);
  
Index: src/bin/scripts/createuser.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/scripts/createuser.c,v
retrieving revision 1.12
diff -c -c -r1.12 createuser.c
*** src/bin/scripts/createuser.c        1 Jun 2004 02:54:09 -0000       1.12
--- src/bin/scripts/createuser.c        3 Jun 2004 00:00:05 -0000
***************
*** 63,69 ****
        PGresult   *result;
  
        progname = get_progname(argv[0]);
!       set_pglocale(argv[0], "pgscripts");
  
        handle_help_version_opts(argc, argv, "createuser", help);
  
--- 63,69 ----
        PGresult   *result;
  
        progname = get_progname(argv[0]);
!       set_pglocale_pgservice(argv[0], "pgscripts");
  
        handle_help_version_opts(argc, argv, "createuser", help);
  
Index: src/bin/scripts/dropdb.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/scripts/dropdb.c,v
retrieving revision 1.11
diff -c -c -r1.11 dropdb.c
*** src/bin/scripts/dropdb.c    1 Jun 2004 02:54:09 -0000       1.11
--- src/bin/scripts/dropdb.c    3 Jun 2004 00:00:05 -0000
***************
*** 51,57 ****
        PGresult   *result;
  
        progname = get_progname(argv[0]);
!       set_pglocale(argv[0], "pgscripts");
  
        handle_help_version_opts(argc, argv, "dropdb", help);
  
--- 51,57 ----
        PGresult   *result;
  
        progname = get_progname(argv[0]);
!       set_pglocale_pgservice(argv[0], "pgscripts");
  
        handle_help_version_opts(argc, argv, "dropdb", help);
  
Index: src/bin/scripts/droplang.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/scripts/droplang.c,v
retrieving revision 1.10
diff -c -c -r1.10 droplang.c
*** src/bin/scripts/droplang.c  1 Jun 2004 02:54:09 -0000       1.10
--- src/bin/scripts/droplang.c  3 Jun 2004 00:00:05 -0000
***************
*** 61,67 ****
        PGresult   *result;
  
        progname = get_progname(argv[0]);
!       set_pglocale(argv[0], "pgscripts");
  
        handle_help_version_opts(argc, argv, "droplang", help);
  
--- 61,67 ----
        PGresult   *result;
  
        progname = get_progname(argv[0]);
!       set_pglocale_pgservice(argv[0], "pgscripts");
  
        handle_help_version_opts(argc, argv, "droplang", help);
  
Index: src/bin/scripts/dropuser.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/scripts/dropuser.c,v
retrieving revision 1.10
diff -c -c -r1.10 dropuser.c
*** src/bin/scripts/dropuser.c  1 Jun 2004 02:54:09 -0000       1.10
--- src/bin/scripts/dropuser.c  3 Jun 2004 00:00:05 -0000
***************
*** 51,57 ****
        PGresult   *result;
  
        progname = get_progname(argv[0]);
!       set_pglocale(argv[0], "pgscripts");
  
        handle_help_version_opts(argc, argv, "dropuser", help);
  
--- 51,57 ----
        PGresult   *result;
  
        progname = get_progname(argv[0]);
!       set_pglocale_pgservice(argv[0], "pgscripts");
  
        handle_help_version_opts(argc, argv, "dropuser", help);
  
Index: src/bin/scripts/vacuumdb.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/bin/scripts/vacuumdb.c,v
retrieving revision 1.8
diff -c -c -r1.8 vacuumdb.c
*** src/bin/scripts/vacuumdb.c  1 Jun 2004 02:54:09 -0000       1.8
--- src/bin/scripts/vacuumdb.c  3 Jun 2004 00:00:05 -0000
***************
*** 66,72 ****
        bool            verbose = false;
  
        progname = get_progname(argv[0]);
!       set_pglocale(argv[0], "pgscripts");
  
        handle_help_version_opts(argc, argv, "vacuumdb", help);
  
--- 66,72 ----
        bool            verbose = false;
  
        progname = get_progname(argv[0]);
!       set_pglocale_pgservice(argv[0], "pgscripts");
  
        handle_help_version_opts(argc, argv, "vacuumdb", help);
  
Index: src/include/port.h
===================================================================
RCS file: /cvsroot/pgsql-server/src/include/port.h,v
retrieving revision 1.39
diff -c -c -r1.39 port.h
*** src/include/port.h  27 May 2004 14:39:32 -0000      1.39
--- src/include/port.h  3 Jun 2004 00:00:06 -0000
***************
*** 32,38 ****
  extern void get_pkginclude_path(const char *my_exec_path, char *ret_path);
  extern void get_pkglib_path(const char *my_exec_path, char *ret_path);
  extern void get_locale_path(const char *my_exec_path, char *ret_path);
! extern void set_pglocale(const char *argv0, const char *app);
  
  /*
   *    is_absolute_path
--- 32,38 ----
  extern void get_pkginclude_path(const char *my_exec_path, char *ret_path);
  extern void get_pkglib_path(const char *my_exec_path, char *ret_path);
  extern void get_locale_path(const char *my_exec_path, char *ret_path);
! extern void set_pglocale_pgservice(const char *argv0, const char *app);
  
  /*
   *    is_absolute_path
Index: src/interfaces/libpq/fe-connect.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/interfaces/libpq/fe-connect.c,v
retrieving revision 1.271
diff -c -c -r1.271 fe-connect.c
*** src/interfaces/libpq/fe-connect.c   26 May 2004 18:35:51 -0000      1.271
--- src/interfaces/libpq/fe-connect.c   3 Jun 2004 00:00:13 -0000
***************
*** 2363,2379 ****
  
  
  
- #ifndef SYSCONFDIR
- #error "You must compile this file with SYSCONFDIR defined."
- #endif
- 
  #define MAXBUFSIZE 256
  
  static int
  parseServiceInfo(PQconninfoOption *options, PQExpBuffer errorMessage)
  {
        char       *service = conninfo_getval(options, "service");
!       char       *serviceFile = SYSCONFDIR "/pg_service.conf";
        bool            group_found = false;
        int                     linenr = 0,
                                i;
--- 2363,2375 ----
  
  
  
  #define MAXBUFSIZE 256
  
  static int
  parseServiceInfo(PQconninfoOption *options, PQExpBuffer errorMessage)
  {
        char       *service = conninfo_getval(options, "service");
!       char            serviceFile[MAXPGPATH];
        bool            group_found = false;
        int                     linenr = 0,
                                i;
***************
*** 2385,2390 ****
--- 2381,2393 ----
         */
        if (service == NULL)
                service = getenv("PGSERVICE");
+ 
+       /*
+        *      This could be used by any application so we can't use the binary
+        *      location to find our config files.
+        */     
+       snprintf(serviceFile, MAXPGPATH, "%s/pg_service.conf",
+                        getenv("PGETC") ? getenv("PGETC") : SYSCONFDIR);
  
        if (service != NULL)
        {
Index: src/interfaces/libpq/fe-misc.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/interfaces/libpq/fe-misc.c,v
retrieving revision 1.106
diff -c -c -r1.106 fe-misc.c
*** src/interfaces/libpq/fe-misc.c      25 May 2004 01:00:29 -0000      1.106
--- src/interfaces/libpq/fe-misc.c      3 Jun 2004 00:00:13 -0000
***************
*** 1132,1138 ****
        {
                already_bound = 1;
                /* No relocatable lookup here because the binary could be anywhere */
!               bindtextdomain("libpq", LOCALEDIR);
        }
  
        return dgettext("libpq", msgid);
--- 1132,1138 ----
        {
                already_bound = 1;
                /* No relocatable lookup here because the binary could be anywhere */
!               bindtextdomain("libpq", getenv("PGLOCALE") ? getenv("PGLOCALE") : 
LOCALEDIR);
        }
  
        return dgettext("libpq", msgid);
Index: src/port/path.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/port/path.c,v
retrieving revision 1.16
diff -c -c -r1.16 path.c
*** src/port/path.c     26 May 2004 19:00:31 -0000      1.16
--- src/port/path.c     3 Jun 2004 00:00:13 -0000
***************
*** 222,253 ****
  
  
  /*
!  *    set_pglocale
   *
!  *    Set application-specific locale
   *
   *    This function takes an argv[0] rather than a full path.
   */
  void
! set_pglocale(const char *argv0, const char *app)
  {
- #ifdef ENABLE_NLS
        char path[MAXPGPATH];
        char my_exec_path[MAXPGPATH];
! #endif
  
        /* don't set LC_ALL in the backend */
        if (strcmp(app, "postgres") != 0)
                setlocale(LC_ALL, "");
  
- #ifdef ENABLE_NLS
        if (find_my_exec(argv0, my_exec_path) < 0)
                return;
                
        get_locale_path(my_exec_path, path);
        bindtextdomain(app, path);
        textdomain(app);
  #endif
  }
  
  
--- 222,268 ----
  
  
  /*
!  *    set_pglocale_pgservice
   *
!  *    Set application-specific locale and service directory
   *
   *    This function takes an argv[0] rather than a full path.
   */
  void
! set_pglocale_pgservice(const char *argv0, const char *app)
  {
        char path[MAXPGPATH];
        char my_exec_path[MAXPGPATH];
!       char env_path[MAXPGPATH + strlen("PGLOCALE=")]; /* longer than PGETC */
  
        /* don't set LC_ALL in the backend */
        if (strcmp(app, "postgres") != 0)
                setlocale(LC_ALL, "");
  
        if (find_my_exec(argv0, my_exec_path) < 0)
                return;
                
+ #ifdef ENABLE_NLS
        get_locale_path(my_exec_path, path);
        bindtextdomain(app, path);
        textdomain(app);
+ 
+       if (!getenv("PGLOCALE"))
+       {
+               /* set for libpq to use */
+               sprintf(env_path, "PGLOCALE=%s", path);
+               putenv(env_path);
+       }
  #endif
+ 
+       if (!getenv("PGETC"))
+       {
+               get_etc_path(my_exec_path, path);
+       
+               /* set for libpq to use */
+               sprintf(env_path, "PGETC=%s", path);
+               putenv(env_path);
+       }
  }
  
  
---------------------------(end of broadcast)---------------------------
TIP 9: the planner will ignore your desire to choose an index scan if your
      joining column's datatypes do not match

Reply via email to