1 /*-------------------------------------------------------------------------
2  *
3  * pg_config.c
4  *
5  * This program reports various pieces of information about the
6  * installed version of PostgreSQL.  Packages that interface to
7  * PostgreSQL can use it to configure their build.
8  *
9  * This is a C implementation of the previous shell script written by
10  * Peter Eisentraut <peter_e@gmx.net>, with adjustments made to
11  * accommodate the possibility that the installation has been relocated from
12  * the place originally configured.
13  *
14  * author of C translation: Andrew Dunstan	   mailto:andrew@dunslane.net
15  *
16  * This code is released under the terms of the PostgreSQL License.
17  *
18  * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
19  *
20  * src/bin/pg_config/pg_config.c
21  *
22  *-------------------------------------------------------------------------
23  */
24 
25 #include "postgres_fe.h"
26 
27 #include "common/config_info.h"
28 #include "port.h"
29 
30 static const char *progname;
31 
32 /*
33  * Table of known information items
34  *
35  * Be careful to keep this in sync with the help() display.
36  */
37 typedef struct
38 {
39 	const char *switchname;
40 	const char *configname;
41 } InfoItem;
42 
43 static const InfoItem info_items[] = {
44 	{"--bindir", "BINDIR"},
45 	{"--docdir", "DOCDIR"},
46 	{"--htmldir", "HTMLDIR"},
47 	{"--includedir", "INCLUDEDIR"},
48 	{"--pkgincludedir", "PKGINCLUDEDIR"},
49 	{"--includedir-server", "INCLUDEDIR-SERVER"},
50 	{"--libdir", "LIBDIR"},
51 	{"--pkglibdir", "PKGLIBDIR"},
52 	{"--localedir", "LOCALEDIR"},
53 	{"--mandir", "MANDIR"},
54 	{"--sharedir", "SHAREDIR"},
55 	{"--sysconfdir", "SYSCONFDIR"},
56 	{"--pgxs", "PGXS"},
57 	{"--configure", "CONFIGURE"},
58 	{"--cc", "CC"},
59 	{"--cppflags", "CPPFLAGS"},
60 	{"--cflags", "CFLAGS"},
61 	{"--cflags_sl", "CFLAGS_SL"},
62 	{"--ldflags", "LDFLAGS"},
63 	{"--ldflags_ex", "LDFLAGS_EX"},
64 	{"--ldflags_sl", "LDFLAGS_SL"},
65 	{"--libs", "LIBS"},
66 	{"--version", "VERSION"},
67 	{NULL, NULL}
68 };
69 
70 
71 static void
help(void)72 help(void)
73 {
74 	printf(_("\n%s provides information about the installed version of PostgreSQL.\n\n"), progname);
75 	printf(_("Usage:\n"));
76 	printf(_("  %s [OPTION]...\n\n"), progname);
77 	printf(_("Options:\n"));
78 	printf(_("  --bindir              show location of user executables\n"));
79 	printf(_("  --docdir              show location of documentation files\n"));
80 	printf(_("  --htmldir             show location of HTML documentation files\n"));
81 	printf(_("  --includedir          show location of C header files of the client\n"
82 			 "                        interfaces\n"));
83 	printf(_("  --pkgincludedir       show location of other C header files\n"));
84 	printf(_("  --includedir-server   show location of C header files for the server\n"));
85 	printf(_("  --libdir              show location of object code libraries\n"));
86 	printf(_("  --pkglibdir           show location of dynamically loadable modules\n"));
87 	printf(_("  --localedir           show location of locale support files\n"));
88 	printf(_("  --mandir              show location of manual pages\n"));
89 	printf(_("  --sharedir            show location of architecture-independent support files\n"));
90 	printf(_("  --sysconfdir          show location of system-wide configuration files\n"));
91 	printf(_("  --pgxs                show location of extension makefile\n"));
92 	printf(_("  --configure           show options given to \"configure\" script when\n"
93 			 "                        PostgreSQL was built\n"));
94 	printf(_("  --cc                  show CC value used when PostgreSQL was built\n"));
95 	printf(_("  --cppflags            show CPPFLAGS value used when PostgreSQL was built\n"));
96 	printf(_("  --cflags              show CFLAGS value used when PostgreSQL was built\n"));
97 	printf(_("  --cflags_sl           show CFLAGS_SL value used when PostgreSQL was built\n"));
98 	printf(_("  --ldflags             show LDFLAGS value used when PostgreSQL was built\n"));
99 	printf(_("  --ldflags_ex          show LDFLAGS_EX value used when PostgreSQL was built\n"));
100 	printf(_("  --ldflags_sl          show LDFLAGS_SL value used when PostgreSQL was built\n"));
101 	printf(_("  --libs                show LIBS value used when PostgreSQL was built\n"));
102 	printf(_("  --version             show the PostgreSQL version\n"));
103 	printf(_("  -?, --help            show this help, then exit\n"));
104 	printf(_("\nWith no arguments, all known items are shown.\n\n"));
105 	printf(_("Report bugs to <%s>.\n"), PACKAGE_BUGREPORT);
106 	printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
107 }
108 
109 static void
advice(void)110 advice(void)
111 {
112 	fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
113 }
114 
115 static void
show_item(const char * configname,ConfigData * configdata,size_t configdata_len)116 show_item(const char *configname,
117 		  ConfigData *configdata,
118 		  size_t configdata_len)
119 {
120 	int			i;
121 
122 	for (i = 0; i < configdata_len; i++)
123 	{
124 		if (strcmp(configname, configdata[i].name) == 0)
125 			printf("%s\n", configdata[i].setting);
126 	}
127 }
128 
129 int
main(int argc,char ** argv)130 main(int argc, char **argv)
131 {
132 	ConfigData *configdata;
133 	size_t		configdata_len;
134 	char		my_exec_path[MAXPGPATH];
135 	int			i;
136 	int			j;
137 
138 	set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_config"));
139 
140 	progname = get_progname(argv[0]);
141 
142 	/* check for --help */
143 	for (i = 1; i < argc; i++)
144 	{
145 		if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-?") == 0)
146 		{
147 			help();
148 			exit(0);
149 		}
150 	}
151 
152 	if (find_my_exec(argv[0], my_exec_path) < 0)
153 	{
154 		fprintf(stderr, _("%s: could not find own program executable\n"), progname);
155 		exit(1);
156 	}
157 
158 	configdata = get_configdata(my_exec_path, &configdata_len);
159 	/* no arguments -> print everything */
160 	if (argc < 2)
161 	{
162 		for (i = 0; i < configdata_len; i++)
163 			printf("%s = %s\n", configdata[i].name, configdata[i].setting);
164 		exit(0);
165 	}
166 
167 	/* otherwise print requested items */
168 	for (i = 1; i < argc; i++)
169 	{
170 		for (j = 0; info_items[j].switchname != NULL; j++)
171 		{
172 			if (strcmp(argv[i], info_items[j].switchname) == 0)
173 			{
174 				show_item(info_items[j].configname,
175 						  configdata, configdata_len);
176 				break;
177 			}
178 		}
179 		if (info_items[j].switchname == NULL)
180 		{
181 			fprintf(stderr, _("%s: invalid argument: %s\n"),
182 					progname, argv[i]);
183 			advice();
184 			exit(1);
185 		}
186 	}
187 
188 	return 0;
189 }
190