CTWM
Loading...
Searching...
No Matches
/usr/src/RPM/BUILD/ctwm-4.1.0/parse_m4.c
Go to the documentation of this file.
1/*
2 * Parser -- M4 specific routines. Some additional stuff from parse.c
3 * should probably migrate here over time.
4 */
5
6#include "ctwm.h"
7
8#include <sys/types.h>
9#include <stdio.h>
10#include <stdlib.h>
11#include <unistd.h>
12#include <netdb.h>
13#include <pwd.h>
14
15#include "screen.h"
16#include "parse.h"
17#include "parse_int.h"
18#include "version.h"
19
20
21static char *m4_defs(Display *display, const char *host);
22
23
24/*
25 * Primary entry point to do m4 parsing of a startup file
26 */
27FILE *
29{
30 int fids[2];
31 int fres;
32 char *defs_file;
33
34 /* Write our our standard definitions into a temp file */
36
37 /* We'll read back m4's output over a pipe */
38 pipe(fids);
39
40 /* Fork off m4 as a child */
41 fres = fork();
42 if(fres < 0) {
43 perror("Fork for " M4CMD " failed");
46 exit(23);
47 }
48
49 /*
50 * Child: setup and spawn m4, and have it write its output into one
51 * end of our pipe.
52 */
53 if(fres == 0) {
54 /* Setup file descriptors */
55 close(0); /* stdin */
56 close(1); /* stdout */
57 dup2(fileno(fraw), 0); /* stdin = fraw */
58 dup2(fids[1], 1); /* stdout = pipe to parent */
59
60 /*
61 * Kick off m4, telling it both our file of definitions, and
62 * stdin (dup of the .[c]twmrc file descriptor above) as input.
63 * It writes to stdout (one end of our pipe).
64 */
65 execlp(M4CMD, M4CMD, "-s", defs_file, "-", NULL);
66
67 /* If we get here we are screwed... */
68 perror("Can't execlp() " M4CMD);
71 exit(124);
72 }
73
74 /*
75 * Else we're the parent; hand back our reading end of the pipe.
76 */
77 close(fids[1]);
79 return (fdopen(fids[0], "r"));
80}
81
82
83/* Technically should sysconf() this, but good enough for our purposes */
84#define MAXHOSTNAME 255
85
86/*
87 * Writes out a temp file of all the m4 defs appropriate for this run,
88 * and returns the file name
89 */
90static char *
92{
93 char client[MAXHOSTNAME];
94 char *vc, *color;
95 char *tmp_name;
96 FILE *tmpf;
97 char *user;
98
99 /* Create temp file */
100 {
101 char *td = getenv("TMPDIR");
102 if(!td || strlen(td) < 2 || *td != '/') {
103 td = "/tmp";
104 }
105 asprintf(&tmp_name, "%s/ctwmrc.XXXXXXXX", td);
106 if(!tmp_name) {
107 perror("asprintf failed in m4_defs");
108 exit(1);
109 }
110
111 int fd = mkstemp(tmp_name);
112 if(fd < 0) {
113 perror("mkstemp failed in m4_defs");
114 exit(377);
115 }
116 tmpf = fdopen(fd, "w+");
117 }
118
119
120 /*
121 * Now start writing the defs into it.
122 */
123#define WR_DEF(k, v) fprintf(tmpf, "define(`%s', `%s')\n", (k), (v))
124#define WR_NUM(k, v) fprintf(tmpf, "define(`%s', `%d')\n", (k), (v))
125
126 /*
127 * The machine running the window manager process (and, presumably,
128 * most of the other clients the user is running)
129 */
130 if(gethostname(client, MAXHOSTNAME) < 0) {
131 perror("gethostname failed in m4_defs");
132 exit(1);
133 }
134 WR_DEF("CLIENTHOST", client);
135
136 /*
137 * A guess at the machine running the X server. We take the full
138 * $DISPLAY and chop off the screen specification.
139 */
140 {
141 char *server, *colon;
142
144 if(!server) {
145 server = strdup("unknown");
146 }
147 colon = strchr(server, ':');
148 if(colon != NULL) {
149 *colon = '\0';
150 }
151
152 /* :0 or unix socket connection means it's the same as CLIENTHOST */
153 if((server[0] == '\0') || (!strcmp(server, "unix"))) {
154 free(server);
156 }
157 WR_DEF("SERVERHOST", server);
158
159 free(server);
160 }
161
162#ifdef HISTORICAL_HOSTNAME_IMPL
163 /*
164 * Historical attempt to use DNS to figure a canonical name. This is
165 * left inside this #ifdef for easy restoration if somebody finds a
166 * need; enabling it is not supported or documented. Unless somebody
167 * comes up with a good reason to revive it, it will be removed after
168 * 4.0.2.
169 */
170 {
172 if(hostname) {
173 WR_DEF("HOSTNAME", hostname->h_name);
174 }
175 else {
176 WR_DEF("HOSTNAME", client);
177 }
178 }
179#else
180 /*
181 * Just leave HOSTNAME as a copy of CLIENTHOST for backward
182 * compat.
183 */
184 WR_DEF("HOSTNAME", client);
185#endif
186
187 /*
188 * Info about the user and their environment
189 */
190 if(!(user = getenv("USER")) && !(user = getenv("LOGNAME"))) {
191 struct passwd *pwd = getpwuid(getuid());
192 if(pwd) {
193 user = pwd->pw_name;
194 }
195 }
196 if(!user) {
197 user = "unknown";
198 }
199 WR_DEF("USER", user);
200 WR_DEF("HOME", Home);
201
202 /*
203 * ctwm meta
204 */
205 WR_DEF("TWM_TYPE", "ctwm");
206 WR_DEF("TWM_VERSION", VersionNumber);
207 WR_DEF("CTWM_VERSION_MAJOR", VersionNumber_major);
208 WR_DEF("CTWM_VERSION_MINOR", VersionNumber_minor);
209 WR_DEF("CTWM_VERSION_PATCH", VersionNumber_patch);
210 WR_DEF("CTWM_VERSION_ADDL", VersionNumber_addl);
211
212 /*
213 * X server meta
214 */
215 if(display) {
216 WR_NUM("VERSION", ProtocolVersion(display));
217 WR_NUM("REVISION", ProtocolRevision(display));
218 WR_DEF("VENDOR", ServerVendor(display));
219 WR_NUM("RELEASE", VendorRelease(display));
220 }
221 else {
222 // Standin numbers
223 WR_NUM("VERSION", 11);
224 WR_NUM("REVISION", 0);
225 WR_DEF("VENDOR", "Your Friendly Local Ctwm");
226 WR_NUM("RELEASE", 123456789);
227 }
228
229 /*
230 * Information about the display
231 */
232 WR_NUM("WIDTH", Scr->rootw);
233 WR_NUM("HEIGHT", Scr->rooth);
234#define Resolution(pixels, mm) ((((pixels) * 100000 / (mm)) + 50) / 100)
235 WR_NUM("X_RESOLUTION", Resolution(Scr->rootw, Scr->mm_w));
236 WR_NUM("Y_RESOLUTION", Resolution(Scr->rooth, Scr->mm_h));
237#undef Resolution
238 WR_NUM("PLANES", Scr->d_depth);
239 WR_NUM("BITS_PER_RGB", Scr->d_visual->bits_per_rgb);
240 color = "Yes";
241 switch(Scr->d_visual->class) {
242 case(StaticGray):
243 vc = "StaticGray";
244 color = "No";
245 break;
246 case(GrayScale):
247 vc = "GrayScale";
248 color = "No";
249 break;
250 case(StaticColor):
251 vc = "StaticColor";
252 break;
253 case(PseudoColor):
254 vc = "PseudoColor";
255 break;
256 case(TrueColor):
257 vc = "TrueColor";
258 break;
259 case(DirectColor):
260 vc = "DirectColor";
261 break;
262 default:
263 vc = "NonStandard";
264 break;
265 }
266 WR_DEF("CLASS", vc);
267 WR_DEF("COLOR", color);
268
269 /*
270 * Bits of "how this ctwm invocation is being run" data
271 */
272 if(0) {
273 // Dummy
274 }
275#ifdef CAPTIVE
276 else if(CLarg.is_captive && Scr->captivename) {
277 WR_DEF("TWM_CAPTIVE", "Yes");
278 WR_DEF("TWM_CAPTIVE_NAME", Scr->captivename);
279 }
280#endif
281 else {
282 WR_DEF("TWM_CAPTIVE", "No");
283 }
284
285 /*
286 * Various compile-time options.
287 */
288#ifdef PIXMAP_DIRECTORY
289 WR_DEF("PIXMAP_DIRECTORY", PIXMAP_DIRECTORY);
290#endif
291#ifdef XPM
292 WR_DEF("XPM", "Yes");
293#endif
294#ifdef JPEG
295 WR_DEF("JPEG", "Yes");
296#endif
297#ifdef SOUNDS
298 WR_DEF("SOUNDS", "Yes");
299#endif
300#ifdef EWMH
301 WR_DEF("EWMH", "Yes");
302#endif
303#ifdef XRANDR
304 WR_DEF("XRANDR", "Yes");
305#endif
306 /* Since this is no longer an option, it should be removed in the future */
307 WR_DEF("I18N", "Yes");
308
309#undef WR_NUM
310#undef WR_DEF
311
312
313 /*
314 * We might be keeping it, in which case tell the user where it is;
315 * this is mostly a debugging option. Otherwise, delete it by
316 * telling m4 to do so when it reads it; this is fairly fugly, and I
317 * have more than half a mind to dike it out and properly clean up
318 * ourselves.
319 */
320 if(CLarg.KeepTmpFile) {
321 fprintf(stderr, "Left file: %s\n", tmp_name);
322 }
323 else {
324 fprintf(tmpf, "syscmd(/bin/rm %s)\n", tmp_name);
325 }
326
327
328 /* Close out and hand it back */
329 fclose(tmpf);
330 return(tmp_name);
331}
static int PlaceX
Definition add_window.c:82
ctwm_cl_args CLarg
Definition clargs.c:27
char * Home
Definition ctwm_main.c:128
Display * dpy
Definition ctwm_main.c:84
#define Scr
#define WR_DEF(k, v)
static char * m4_defs(Display *display, const char *host)
Definition parse_m4.c:91
FILE * start_m4(FILE *fraw)
Definition parse_m4.c:28
#define MAXHOSTNAME
Definition parse_m4.c:84
#define WR_NUM(k, v)
#define Resolution(pixels, mm)
static char hostname[200]
Definition sound.c:26
char * display_name
Definition ctwm.h:391
const char * VersionNumber_patch
const char * VersionNumber_major
const char * VersionNumber_minor
const char * VersionNumber_addl
const char * VersionNumber