39
39
* Portions Copyright (c) 1994, Regents of the University of California
40
40
* Portions taken from FreeBSD.
41
41
*
42
- * $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.42 2004/07/12 01:54 :10momjian Exp $
42
+ * $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.43 2004/07/14 17:55 :10petere Exp $
43
43
*
44
44
*-------------------------------------------------------------------------
45
45
*/
52
52
#include <locale.h>
53
53
#include <signal.h>
54
54
#include <errno.h>
55
+ #ifdef HAVE_LANGINFO_H
56
+ # include <langinfo.h>
57
+ #endif
55
58
56
59
#include "libpq/pqsignal.h"
57
60
#include "mb/pg_wchar.h"
@@ -600,29 +603,221 @@ get_id(void)
600
603
return xstrdup (pw -> pw_name );
601
604
}
602
605
606
+ static char *
607
+ encodingid_to_string (int enc )
608
+ {
609
+ char result [20 ];
610
+
611
+ sprintf (result ,"%d" ,enc );
612
+ return xstrdup (result );
613
+ }
614
+
603
615
/*
604
616
* get the encoding id for a given encoding name
605
617
*/
606
618
static char *
607
619
get_encoding_id (char * encoding_name )
608
620
{
609
621
int enc ;
610
- char result [20 ];
611
622
612
623
if (encoding_name && * encoding_name )
613
624
{
614
625
if ((enc = pg_char_to_encoding (encoding_name )) >=0 &&
615
626
pg_valid_server_encoding (encoding_name ) >=0 )
616
627
{
617
- sprintf (result ,"%d" ,enc );
618
- return xstrdup (result );
628
+ return encodingid_to_string (enc );
619
629
}
620
630
}
621
631
fprintf (stderr ,_ ("%s: \"%s\" is not a valid server encoding name\n" ),
622
632
progname ,encoding_name ?encoding_name :"(null)" );
623
633
exit (1 );
624
634
}
625
635
636
+ #ifdef HAVE_LANGINFO_H
637
+ /*
638
+ * Checks whether the encoding selected for PostgreSQL and the
639
+ * encoding used by the system locale match.
640
+ */
641
+
642
+ struct encoding_match
643
+ {
644
+ enum pg_enc pg_enc_code ;
645
+ char * system_enc_name ;
646
+ };
647
+
648
+ struct encoding_match encoding_match_list []= {
649
+ {PG_EUC_JP ,"EUC-JP" },
650
+ {PG_EUC_JP ,"eucJP" },
651
+ {PG_EUC_JP ,"IBM-eucJP" },
652
+ {PG_EUC_JP ,"sdeckanji" },
653
+
654
+ {PG_EUC_CN ,"EUC-CN" },
655
+ {PG_EUC_CN ,"eucCN" },
656
+ {PG_EUC_CN ,"IBM-eucCN" },
657
+ {PG_EUC_CN ,"GB2312" },
658
+ {PG_EUC_CN ,"dechanzi" },
659
+
660
+ {PG_EUC_KR ,"EUC-KR" },
661
+ {PG_EUC_KR ,"eucKR" },
662
+ {PG_EUC_KR ,"IBM-eucKR" },
663
+ {PG_EUC_KR ,"deckorean" },
664
+ {PG_EUC_KR ,"5601" },
665
+
666
+ {PG_EUC_TW ,"EUC-TW" },
667
+ {PG_EUC_TW ,"eucTW" },
668
+ {PG_EUC_TW ,"IBM-eucTW" },
669
+ {PG_EUC_TW ,"cns11643" },
670
+
671
+ #ifdef NOT_VERIFIED
672
+ {PG_JOHAB ,"???" },
673
+ #endif
674
+
675
+ {PG_UTF8 ,"UTF-8" },
676
+ {PG_UTF8 ,"utf8" },
677
+
678
+ {PG_LATIN1 ,"ISO-8859-1" },
679
+ {PG_LATIN1 ,"ISO8859-1" },
680
+ {PG_LATIN1 ,"iso88591" },
681
+
682
+ {PG_LATIN2 ,"ISO-8859-2" },
683
+ {PG_LATIN2 ,"ISO8859-2" },
684
+ {PG_LATIN2 ,"iso88592" },
685
+
686
+ {PG_LATIN3 ,"ISO-8859-3" },
687
+ {PG_LATIN3 ,"ISO8859-3" },
688
+ {PG_LATIN3 ,"iso88593" },
689
+
690
+ {PG_LATIN4 ,"ISO-8859-4" },
691
+ {PG_LATIN4 ,"ISO8859-4" },
692
+ {PG_LATIN4 ,"iso88594" },
693
+
694
+ {PG_LATIN5 ,"ISO-8859-9" },
695
+ {PG_LATIN5 ,"ISO8859-9" },
696
+ {PG_LATIN5 ,"iso88599" },
697
+
698
+ {PG_LATIN6 ,"ISO-8859-10" },
699
+ {PG_LATIN6 ,"ISO8859-10" },
700
+ {PG_LATIN6 ,"iso885910" },
701
+
702
+ {PG_LATIN7 ,"ISO-8859-13" },
703
+ {PG_LATIN7 ,"ISO8859-13" },
704
+ {PG_LATIN7 ,"iso885913" },
705
+
706
+ {PG_LATIN8 ,"ISO-8859-14" },
707
+ {PG_LATIN8 ,"ISO8859-14" },
708
+ {PG_LATIN8 ,"iso885914" },
709
+
710
+ {PG_LATIN9 ,"ISO-8859-15" },
711
+ {PG_LATIN9 ,"ISO8859-15" },
712
+ {PG_LATIN9 ,"iso885915" },
713
+
714
+ {PG_LATIN10 ,"ISO-8859-16" },
715
+ {PG_LATIN10 ,"ISO8859-16" },
716
+ {PG_LATIN10 ,"iso885916" },
717
+
718
+ {PG_WIN1256 ,"CP1256" },
719
+ {PG_TCVN ,"CP1258" },
720
+ #ifdef NOT_VERIFIED
721
+ {PG_WIN874 ,"???" },
722
+ #endif
723
+ {PG_KOI8R ,"KOI8-R" },
724
+ {PG_WIN1251 ,"CP1251" },
725
+ {PG_ALT ,"CP866" },
726
+
727
+ {PG_ISO_8859_5 ,"ISO-8859-5" },
728
+ {PG_ISO_8859_5 ,"ISO8859-5" },
729
+ {PG_ISO_8859_5 ,"iso88595" },
730
+
731
+ {PG_ISO_8859_6 ,"ISO-8859-6" },
732
+ {PG_ISO_8859_6 ,"ISO8859-6" },
733
+ {PG_ISO_8859_6 ,"iso88596" },
734
+
735
+ {PG_ISO_8859_7 ,"ISO-8859-7" },
736
+ {PG_ISO_8859_7 ,"ISO8859-7" },
737
+ {PG_ISO_8859_7 ,"iso88597" },
738
+
739
+ {PG_ISO_8859_8 ,"ISO-8859-8" },
740
+ {PG_ISO_8859_8 ,"ISO8859-8" },
741
+ {PG_ISO_8859_8 ,"iso88598" },
742
+
743
+ {PG_SQL_ASCII ,NULL }/* end marker */
744
+ };
745
+
746
+ static char *
747
+ get_encoding_from_locale (const char * ctype )
748
+ {
749
+ char * save ;
750
+ char * sys ;
751
+
752
+ save = setlocale (LC_CTYPE ,NULL );
753
+ if (!save )
754
+ return NULL ;
755
+ save = xstrdup (save );
756
+
757
+ setlocale (LC_CTYPE ,ctype );
758
+ sys = nl_langinfo (CODESET );
759
+ sys = xstrdup (sys );
760
+
761
+ setlocale (LC_CTYPE ,save );
762
+ free (save );
763
+
764
+ return sys ;
765
+ }
766
+
767
+ static void
768
+ check_encodings_match (int pg_enc ,const char * ctype )
769
+ {
770
+ char * sys ;
771
+ int i ;
772
+
773
+ sys = get_encoding_from_locale (ctype );
774
+
775
+ for (i = 0 ;encoding_match_list [i ].system_enc_name ;i ++ )
776
+ {
777
+ if (pg_enc == encoding_match_list [i ].pg_enc_code
778
+ && strcasecmp (sys ,encoding_match_list [i ].system_enc_name )== 0 )
779
+ {
780
+ free (sys );
781
+ return ;
782
+ }
783
+ }
784
+
785
+ fprintf (stderr ,
786
+ _ ("%s: warning: encoding mismatch\n" ),progname );
787
+ fprintf (stderr ,
788
+ _ ("The encoding you selected (%s) and the encoding that the selected\n"
789
+ "locale uses (%s) are not known to match. This may lead to\n"
790
+ "misbehavior in various character string processing functions. To fix\n"
791
+ "this situation, rerun %s and either do not specify an encoding\n"
792
+ "explicitly, or choose a matching combination.\n" ),
793
+ pg_encoding_to_char (pg_enc ),sys ,progname );
794
+
795
+ free (sys );
796
+ return ;
797
+ }
798
+
799
+ static int
800
+ find_matching_encoding (const char * ctype )
801
+ {
802
+ char * sys ;
803
+ int i ;
804
+
805
+ sys = get_encoding_from_locale (ctype );
806
+
807
+ for (i = 0 ;encoding_match_list [i ].system_enc_name ;i ++ )
808
+ {
809
+ if (strcasecmp (sys ,encoding_match_list [i ].system_enc_name )== 0 )
810
+ {
811
+ free (sys );
812
+ return encoding_match_list [i ].pg_enc_code ;
813
+ }
814
+ }
815
+
816
+ free (sys );
817
+ return -1 ;
818
+ }
819
+ #endif /* HAVE_LANGINFO_H */
820
+
626
821
/*
627
822
* get short version of VERSION
628
823
*/
@@ -2027,13 +2222,11 @@ main(int argc, char *argv[])
2027
2222
fprintf (stderr ,
2028
2223
"VERSION=%s\n"
2029
2224
"PGDATA=%s\nshare_path=%s\nPGPATH=%s\n"
2030
- "ENCODING=%s\nENCODINGID=%s\n"
2031
2225
"POSTGRES_SUPERUSERNAME=%s\nPOSTGRES_BKI=%s\n"
2032
2226
"POSTGRES_DESCR=%s\nPOSTGRESQL_CONF_SAMPLE=%s\n"
2033
2227
"PG_HBA_SAMPLE=%s\nPG_IDENT_SAMPLE=%s\n" ,
2034
2228
PG_VERSION ,
2035
2229
pg_data ,share_path ,bin_path ,
2036
- encoding ,encodingid ,
2037
2230
effective_user ,bki_file ,
2038
2231
desc_file ,conf_file ,
2039
2232
hba_file ,ident_file );
@@ -2051,21 +2244,20 @@ main(int argc, char *argv[])
2051
2244
check_input (features_file );
2052
2245
check_input (system_views_file );
2053
2246
2247
+ setlocales ();
2248
+
2054
2249
printf (_ ("The files belonging to this database system will be owned "
2055
2250
"by user \"%s\".\n"
2056
2251
"This user must also own the server process.\n\n" ),
2057
2252
effective_user );
2058
2253
2059
- setlocales ();
2060
-
2061
2254
if (strcmp (lc_ctype ,lc_collate )== 0 &&
2062
2255
strcmp (lc_ctype ,lc_time )== 0 &&
2063
2256
strcmp (lc_ctype ,lc_numeric )== 0 &&
2064
2257
strcmp (lc_ctype ,lc_monetary )== 0 &&
2065
2258
strcmp (lc_ctype ,lc_messages )== 0 )
2066
2259
{
2067
- printf (_ ("The database cluster will be initialized with locale %s.\n\n" ),
2068
- lc_ctype );
2260
+ printf (_ ("The database cluster will be initialized with locale %s.\n" ),lc_ctype );
2069
2261
}
2070
2262
else
2071
2263
{
@@ -2075,7 +2267,7 @@ main(int argc, char *argv[])
2075
2267
" MESSAGES: %s\n"
2076
2268
" MONETARY: %s\n"
2077
2269
" NUMERIC: %s\n"
2078
- " TIME: %s\n\n " ),
2270
+ " TIME: %s\n" ),
2079
2271
lc_collate ,
2080
2272
lc_ctype ,
2081
2273
lc_messages ,
@@ -2084,6 +2276,34 @@ main(int argc, char *argv[])
2084
2276
lc_time );
2085
2277
}
2086
2278
2279
+ #ifdef HAVE_LANGINFO_H
2280
+ if (strcmp (lc_ctype ,"C" )!= 0 && strcmp (lc_ctype ,"POSIX" )!= 0 )
2281
+ {
2282
+ if (strlen (encoding )== 0 )
2283
+ {
2284
+ int tmp ;
2285
+ tmp = find_matching_encoding (lc_ctype );
2286
+ if (tmp == -1 )
2287
+ {
2288
+ fprintf (stderr ,_ ("%s: could not find suitable encoding for locale \"%s\"\n" ),progname ,lc_ctype );
2289
+ fprintf (stderr ,_ ("Rerun %s with the -E option.\n" ),progname );
2290
+ fprintf (stderr ,_ ("Try \"%s --help\" for more information.\n" ),progname );
2291
+ exit (1 );
2292
+ }
2293
+ else
2294
+ {
2295
+ encodingid = encodingid_to_string (tmp );
2296
+ printf (_ ("The default database encoding has accordingly been set to %s.\n" ),
2297
+ pg_encoding_to_char (tmp ));
2298
+ }
2299
+ }
2300
+ else
2301
+ check_encodings_match (atoi (encodingid ),lc_ctype );
2302
+ }
2303
+ #endif /* HAVE_LANGINFO_H */
2304
+
2305
+ printf ("\n" );
2306
+
2087
2307
umask (077 );
2088
2308
2089
2309
/*