1 /*****************************************************************************/
2 /**       Copyright 1988 by Evans & Sutherland Computer Corporation,        **/
3 /**                          Salt Lake City, Utah                           **/
4 /**  Portions Copyright 1989 by the Massachusetts Institute of Technology   **/
5 /**                        Cambridge, Massachusetts                         **/
6 /**                                                                         **/
7 /**                           All Rights Reserved                           **/
8 /**                                                                         **/
9 /**    Permission to use, copy, modify, and distribute this software and    **/
10 /**    its documentation  for  any  purpose  and  without  fee is hereby    **/
11 /**    granted, provided that the above copyright notice appear  in  all    **/
12 /**    copies and that both  that  copyright  notice  and  this  permis-    **/
13 /**    sion  notice appear in supporting  documentation,  and  that  the    **/
14 /**    names of Evans & Sutherland and M.I.T. not be used in advertising    **/
15 /**    in publicity pertaining to distribution of the  software  without    **/
16 /**    specific, written prior permission.                                  **/
17 /**                                                                         **/
18 /**    EVANS & SUTHERLAND AND M.I.T. DISCLAIM ALL WARRANTIES WITH REGARD    **/
19 /**    TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES  OF  MERCHANT-    **/
20 /**    ABILITY  AND  FITNESS,  IN  NO  EVENT SHALL EVANS & SUTHERLAND OR    **/
21 /**    M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL  DAM-    **/
22 /**    AGES OR  ANY DAMAGES WHATSOEVER  RESULTING FROM LOSS OF USE, DATA    **/
23 /**    OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER    **/
24 /**    TORTIOUS ACTION, ARISING OUT OF OR IN  CONNECTION  WITH  THE  USE    **/
25 /**    OR PERFORMANCE OF THIS SOFTWARE.                                     **/
26 /*****************************************************************************/
27 
28 
29 /***********************************************************************
30  *
31  * $XConsortium: parse.c,v 1.52 91/07/12 09:59:37 dave Exp $
32  *
33  * parse the .twmrc file
34  *
35  * 17-Nov-87 Thomas E. LaStrange		File created
36  * 10-Oct-90 David M. Sternlicht       Storing saved colors on root
37  ***********************************************************************/
38 
39 #include <stdio.h>
40 #include <ctype.h>
41 #include <errno.h>
42 #include <X11/Xos.h>
43 #include <X11/Xmu/CharSet.h>
44 #include "twm.h"
45 #include "screen.h"
46 #include "menus.h"
47 #include "util.h"
48 #include "gram.h"
49 #include "parse.h"
50 #include <X11/Xatom.h>
51 #include "vdt.h"
52 
53 /* For m4... */
54 #include <sys/param.h>
55 #include <sys/types.h>
56 #include <sys/socket.h>
57 #include <netdb.h>
58 
59 /* m4 on 386 4.4-bsd boxes doesn't wanna read from "-"... */
60 /* XXX - is this a good-enough check?  BSD4_4 should be set on all */
61 /*       net2 based systems... */
62 #ifdef BSD4_4
63 # define M4STDIN "/dev/stdin"
64 #else
65 # define M4STDIN "-"
66 #endif
67 
68 #ifndef SYSTEM_INIT_FILE
69 #define SYSTEM_INIT_FILE "/usr/local/X11R5/lib/twm/system.twmrc"
70 #endif
71 #define BUF_LEN 300
72 
73 static FILE *twmrc;
74 static FILE *menufile;
75 static int ptr = 0;
76 static int len = 0;
77 static char buff[BUF_LEN+1];
78 static char overflowbuff[20];		/* really only need one */
79 static int overflowlen;
80 static char **stringListSource, *currentString;
81 static int ParseUsePPosition();
82 static int ParseState();
83 static FILE *start_m4();
84 int m4_pid;
85 
86 /* If you're using flex (and lex on 386 bsd boxes, which *is* flex, really)
87  * then you need to run flex (/lex) with the -l argument to cause maximum
88  * compatibility with AT&T lex, including the definition of yylineno...
89  */
90 extern int yylineno;
91 extern int mods;
92 extern char *menu_name;
93 extern MenuRoot *input_menu;
94 extern char *InitFile;
95 
96 int ConstrainedMoveTime = 400;		/* milliseconds, event times */
97 
98 static int twmFileInput(), twmStringListInput(), twmMenuInput();
99 void twmUnput();
100 int (*twmInputFunc)();
101 
102 extern char *defTwmrc[];        /* default bindings */
103 
104 
105 /***********************************************************************
106  *
107  *  Procedure:
108  *  ParseTwmrc - parse the .twmrc file
109  *
110  *  Inputs:
111  *  filename  - the filename to parse.  A NULL indicates $HOME/.twmrc
112  *
113  ***********************************************************************
114  */
115 
116 static int doparse (ifunc, srctypename, srcname)
117 	int (*ifunc)();
118 	char *srctypename;
119 	char *srcname;
120 {
121 	extern FILE *yyin;
122 
123 	yyin = twmrc;
124 
125 	mods = 0;
126 	ptr = 0;
127 	len = 0;
128 	yylineno = 1;
129 	ParseError = FALSE;
130 	twmInputFunc = ifunc;
131 	overflowlen = 0;
132 
133 	yyparse();
134 
135 	if (ParseError) {
136 		fprintf(stderr, "%s: errors found in twm %s",
137 			ProgramName, srctypename);
138 		if (srcname) fprintf (stderr, " \"%s\"", srcname);
139 		fprintf (stderr, "\n");
140 	}
141 	return (ParseError ? 0 : 1);
142 }
143 
ParseMenuFile(filename,menuname)144 int ParseMenuFile(filename, menuname)
145 char *filename;
146 char *menuname;
147 {
148     int status = 1;
149 
150     if ((menufile=fopen(filename, "r")) == NULL)
151 	return 0;
152 
153     menu_name = menuname;
154     status = doparse(twmMenuInput, "menu file", filename);
155     fclose(menufile);
156     if (input_menu == NULL) {
157 	fprintf(stderr, "%s: errors found in menu file %s\n", ProgramName,
158 		filename);
159 	status = 0;
160     }
161 
162     return status;
163 }
164 
ParseTwmrc(filename)165 int ParseTwmrc (filename)
166 	char *filename;
167 {
168 	int i;
169 	char *home = NULL;
170 	int homelen = 0;
171 	char *cp = NULL;
172 	char tmpfilename[257];
173 	static FILE *raw;
174 	extern Bool RunM4;		/* Whether or not to run m4 */
175 
176 	/*
177 	 * If filename given, try it, else try ~/.twmrc.# then ~/.twmrc.  Then
178 	 *   0.  -f filename
179 	 *   1.  .tvtwmrc.#
180 	 *   2.  .tvtwmrc
181 	 *   3.  .twmrc.#
182 	 *   4.  .twmrc
183 	 *   5.  system.twmrc
184 	 */
185 	for (twmrc = NULL, i = 0; !twmrc && i < 6; i++) {
186 	switch (i) {
187 	  case 0:           /* -f filename */
188 		cp = filename;
189 		break;
190 
191 	  case 1:           /* ~/.twmrc.screennum */
192 		if (!filename) {
193 			home = getenv ("HOME");
194 			if (home) {
195 				homelen = strlen (home);
196 				cp = tmpfilename;
197 				(void) sprintf (tmpfilename, "%s/.tvtwmrc.%d",
198 					home, Scr->screen);
199 				break;
200 			}
201 		}
202 		continue;
203 
204 	  case 2:			/* ~/.tvtwmrc */
205 		if (home) {
206 			tmpfilename[homelen + 9] = '\0';
207 		}
208 		break;
209 
210 	  case 3:			/* ~/.twmrc.screennum */
211 		if (!filename) {
212 			home = getenv ("HOME");
213 			if (home) {
214 				homelen = strlen (home);
215 				cp = tmpfilename;
216 				(void) sprintf (tmpfilename, "%s/.twmrc.%d",
217 					home, Scr->screen);
218 				break;
219 			}
220 		}
221 		continue;
222 
223 	  case 4:			/* ~/.twmrc */
224 		if (home) {
225 			tmpfilename[homelen + 7] = '\0';
226 		}
227 		break;
228 
229 	  case 5:			/* system.twmrc */
230 		cp = SYSTEM_INIT_FILE;
231 		break;
232 	}
233 
234 	if (cp) {
235 		raw = fopen (cp, "r");
236 		twmrc = raw;
237 	}
238 	}
239 
240     if (raw) {
241 		int status;
242 
243 		InitFile = strcpy(malloc(strlen(cp)+1),cp);
244 
245 		if (filename && cp != filename) {
246 			fprintf (stderr,
247 				"%s:  unable to open twmrc file %s, using %s instead\n",
248 				ProgramName, filename, cp);
249 		}
250 		if (RunM4)
251 		    twmrc = start_m4(raw);
252 		else
253 		    twmrc = raw;
254 		status = doparse (twmFileInput, "file", cp);
255 		if (RunM4)
256 		    fclose (twmrc);
257 		fclose (raw);
258 		if (input_menu) {
259 		    fprintf(stderr, "%s: found menu file when expecting twmrc\n",
260 				ProgramName);
261 		    status = 1;
262 		}
263 		return status;
264 	} else {
265 	if (filename) {
266 	    fprintf (stderr,
267 	"%s:  unable to open twmrc file %s, using built-in defaults instead\n",
268 		     ProgramName, filename);
269 	}
270 	return ParseStringList (defTwmrc);
271     }
272 }
273 
ParseStringList(sl)274 int ParseStringList (sl)
275     char **sl;
276 {
277     stringListSource = sl;
278     currentString = *sl;
279     return doparse (twmStringListInput, "string list", (char *)NULL);
280 }
281 
282 
283 /***********************************************************************
284  *
285  *  Procedure:
286  *	twmFileInput - redefinition of the lex input routine for file input
287  *
288  *  Returned Value:
289  *	the next input character
290  *
291  ***********************************************************************
292  */
293 
294 #ifdef NO_M4
295 
296 /* This has Tom's include() funtionality.  This is utterly useless if you
297  * can use m4 for the same thing.		Chris P. Ross */
298 
299 #define MAX_INCLUDES 10
300 
301 static struct incl {
302      FILE *fp;
303      char *name;
304      int lineno;
305 } rc_includes[MAX_INCLUDES];
306 static int include_file = 0;
307 
twmFileInput()308 static int twmFileInput()
309 {
310     if (overflowlen) return (int) overflowbuff[--overflowlen];
311 
312     while (ptr == len)
313     {
314 	while (include_file) {
315 	     if (fgets(buff, BUF_LEN, rc_includes[include_file].fp) == NULL) {
316 		  free(rc_includes[include_file].name);
317 		  fclose(rc_includes[include_file].fp);
318 		  yylineno = rc_includes[include_file--].lineno;
319 	     } else
320 		  break;
321 	}
322 	if (!include_file)
323 	     if (fgets(buff, BUF_LEN, twmrc) == NULL)
324 		  return 0;
325 
326 	yylineno++;
327 
328 	if (strncmp(buff, "include", 7) == 0) {
329 	     /* Whoops, an include file! */
330 	     char *p = buff + 7, *q;
331 	     FILE *fp;
332 
333 	     while (isspace(*p)) p++;
334 	     for (q = p; *q && !isspace(*q); q++)
335 		  continue;
336 	     *q = 0;
337 
338 	     if ((fp = fopen(p, "r")) == NULL) {
339 		  fprintf(stderr, "%s: Unable to open included init file %s\n",
340 			  ProgramName, p);
341 		  continue;
342 	     }
343 	     if (++include_file >= MAX_INCLUDES) {
344 		  fprintf(stderr, "%s: init file includes nested too deep\n",
345 			  ProgramName);
346 		  continue;
347 	     }
348 	     rc_includes[include_file].fp = fp;
349 	     rc_includes[include_file].lineno = yylineno;
350 	     yylineno = 0;
351 	     rc_includes[include_file].name = malloc(strlen(p)+1);
352 	     strcpy(rc_includes[include_file].name, p);
353 	     continue;
354 	}
355 	ptr = 0;
356 	len = strlen(buff);
357     }
358     return ((int)buff[ptr++]);
359 }
360 #else
361 
362 /* If you're going to use m4, use this version instead.  Much simpler.
363  * m4 ism's credit to Josh Osborne (stripes) */
364 
twmFileInput()365 static int twmFileInput()
366 {
367 	if (overflowlen) return((int) overflowbuff[--overflowlen]);
368 
369 	while (ptr == len) {
370 		if (fgets(buff, BUF_LEN, twmrc) == NULL) {
371 			/* Interrupted?  Probably just the delivery of *
372 			 * a SIGCHLD.  We don't care, so keep going.   *
373 			 *             (cross@eng.umd.edu  19-Aug-93)  */
374 			if (errno == EINTR) {
375 			    if (fgets(buff, BUF_LEN, twmrc) == NULL)
376 				return(0);
377 			} else {
378 				return(0);
379 			}
380 		}
381 
382 		yylineno++;
383 
384 		ptr = 0;
385 		len = strlen(buff);
386 	}
387 	return ((int)buff[ptr++]);
388 }
389 #endif  /* NO_M4 */
390 
current_input_line()391 char *current_input_line()
392 {
393     return buff;
394 }
395 
twmStringListInput()396 static int twmStringListInput()
397 {
398     if (overflowlen) return (int) overflowbuff[--overflowlen];
399 
400     /*
401      * return the character currently pointed to
402      */
403     if (currentString) {
404 	unsigned int c = (unsigned int) *currentString++;
405 
406 	if (c) return c;		/* if non-nul char */
407 	currentString = *++stringListSource;  /* advance to next bol */
408 	return '\n';			/* but say that we hit last eol */
409     }
410     return 0;				/* eof */
411 }
412 
twmMenuInput()413 static int twmMenuInput()
414 {
415     int c;
416 
417     if (overflowlen)
418 	return (int)overflowbuff[--overflowlen];
419 
420     if ((c=getc(menufile)) == EOF)
421 	return 0;
422     else if (c == '\n')
423 	yylineno++;
424 
425     return c;
426 }
427 
428 /***********************************************************************
429  *
430  *  Procedure:
431  *	twmUnput - redefinition of the lex unput routine
432  *
433  *  Inputs:
434  *	c	- the character to push back onto the input stream
435  *
436  ***********************************************************************
437  */
438 
twmUnput(c)439 void twmUnput (c)
440     int c;
441 {
442     if (overflowlen < sizeof overflowbuff) {
443 	overflowbuff[overflowlen++] = (char) c;
444     } else {
445 	twmrc_error_prefix ();
446 	fprintf (stderr, "unable to unput character (%d)\n",
447 		 c);
448     }
449 }
450 
451 
452 /***********************************************************************
453  *
454  *  Procedure:
455  *	TwmOutput - redefinition of the lex output routine
456  *
457  *  Inputs:
458  *	c	- the character to print
459  *
460  ***********************************************************************
461  */
462 
463 void
TwmOutput(c)464 TwmOutput(c)
465 {
466     putchar(c);
467 }
468 
469 
470 /**********************************************************************
471  *
472  *  Parsing table and routines
473  *
474  ***********************************************************************/
475 
476 typedef struct _TwmKeyword {
477     char *name;
478     int value;
479     int subnum;
480 } TwmKeyword;
481 
482 #define kw0_NoDefaults			1
483 #define kw0_AutoRelativeResize		2
484 #define kw0_ForceIcons			3
485 #define kw0_NoIconManagers		4
486 #define kw0_OpaqueMove			5
487 #define kw0_InterpolateMenuColors	6
488 #define kw0_NoVersion			7
489 #define kw0_SortIconManager		8
490 #define kw0_NoGrabServer		9
491 #define kw0_NoMenuShadows		10
492 #define kw0_NoRaiseOnMove		11
493 #define kw0_NoRaiseOnResize		12
494 #define kw0_NoRaiseOnDeiconify		13
495 #define kw0_DontMoveOff			14
496 #define kw0_NoBackingStore		15
497 #define kw0_NoSaveUnders		16
498 #define kw0_RestartPreviousState	17
499 #define kw0_ClientBorderWidth		18
500 #define kw0_NoTitleFocus		19
501 #define kw0_RandomPlacement		20
502 #define kw0_DecorateTransients		21
503 #define kw0_ShowIconManager		22
504 #define kw0_NoCaseSensitive		23
505 #define kw0_NoRaiseOnWarp		24
506 #define kw0_WarpUnmapped		25
507 #define kw0_ShowVirtualNames		26
508 #define kw0_StickyAbove			27
509 #define kw0_StayUpMenus			28
510 #define kw0_PannerOpaqueScroll		29
511 #define kw0_ListRings			30
512 #define kw0_DontInterpolateTitles	31
513 #define kw0_WrapVirtual			32
514 #define kw0_NoOpaqueMoveSaveUnders	33
515 #define kw0_RememberScreenPosition	34
516 #ifdef RJC
517 # define kw0_DoDefaultMenuAction	35
518 #endif /* RJC */
519 
520 #define kws_UsePPosition		1
521 #define kws_IconFont			2
522 #define kws_ResizeFont			3
523 #define kws_MenuFont			4
524 #define kws_TitleFont			5
525 #define kws_IconManagerFont		6
526 #define kws_UnknownIcon			7
527 #define kws_IconDirectory		8
528 #define kws_MaxWindowSize		9
529 #define kws_VirtualDesktop		10
530 #define kws_PannerState			11
531 #define kws_PannerGeometry		12
532 #define kws_VirtualFont			15
533 #define kws_MenuTitleFont               16
534 #define kws_Identification		17
535 /* Use this?  Eh, I don't know... */
536 #define kws_AfterSetupRun		18
537 
538 #define kwn_ConstrainedMoveTime		1
539 #define kwn_MoveDelta			2
540 #define kwn_XorValue			3
541 #define kwn_FramePadding		4
542 #define kwn_TitlePadding		5
543 #define kwn_ButtonIndent		6
544 #define kwn_BorderWidth			7
545 #define kwn_IconBorderWidth		8
546 #define kwn_TitleButtonBorderWidth	9
547 #define kwn_PannerScale			10
548 #define kwn_ScrollDistanceX		11
549 #define kwn_ScrollDistanceY		12
550 #define kwn_MenuLineWidth               13
551 #define kwn_TitleFontPadding            14
552 #define kwn_PopupSensitivity		15
553 #define kwn_MenuShadowWidth		16
554 
555 #define kwcl_BorderColor		1
556 #define kwcl_IconManagerHighlight	2
557 #define kwcl_BorderTileForeground	3
558 #define kwcl_BorderTileBackground	4
559 #define kwcl_TitleForeground		5
560 #define kwcl_TitleBackground		6
561 #define kwcl_IconForeground		7
562 #define kwcl_IconBackground		8
563 #define kwcl_IconBorderColor		9
564 #define kwcl_IconManagerForeground	10
565 #define kwcl_IconManagerBackground	11
566 #define kwcl_VirtualForeground		12
567 #define kwcl_VirtualBackground		13
568 
569 #define kwc_DefaultForeground		1
570 #define kwc_DefaultBackground		2
571 #define kwc_MenuForeground		3
572 #define kwc_MenuBackground		4
573 #define kwc_MenuTitleForeground		5
574 #define kwc_MenuTitleBackground		6
575 #define kwc_MenuShadowColor		7
576 #define kwc_VirtualDesktopForeground	8
577 #define kwc_VirtualDesktopBackground	9
578 #define kwc_PannerForeground		10
579 #define kwc_PannerBackground		11
580 
581 #define kwp_TitleHighlight              1
582 #define kwp_TitleHighlightLeft          2
583 #define kwp_TitleHighlightRight         3
584 #define kwp_PannerBackgroundPixmap      4
585 #define kwp_VirtualDesktopBackgroundPixmap 5
586 #define kwp_IconifyPixmap		6
587 #define kwp_PullRightPixmap		7
588 #define kwp_ShadowPixmap		8
589 
590 #define kwm_Name			LTYPE_NAME
591 #define kwm_ResName			LTYPE_RES_NAME
592 #define kwm_ResClass			LTYPE_RES_CLASS
593 
594 /*
595  * The following is sorted alphabetically according to name (which must be
596  * in lowercase and only contain the letters a-z).  It is fed to a binary
597  * search to parse keywords.
598  */
599 static TwmKeyword keytable[] = {
600 /* Again, do I really want to implement AfterSetupRun? */
601     { "aftersetuprun",		SKEYWORD, kws_AfterSetupRun },
602     { "all",			ALL, 0 },
603     { "autoraise",		AUTO_RAISE, 0 },
604     { "autorelativeresize",	KEYWORD, kw0_AutoRelativeResize },
605     { "bordercolor",		CLKEYWORD, kwcl_BorderColor },
606     { "bordertilebackground",	CLKEYWORD, kwcl_BorderTileBackground },
607     { "bordertileforeground",	CLKEYWORD, kwcl_BorderTileForeground },
608     { "borderwidth",		NKEYWORD, kwn_BorderWidth },
609     { "button",			BUTTON, 0 },
610     { "buttonindent",		NKEYWORD, kwn_ButtonIndent },
611     { "c",			CONTROL, 0 },
612     { "center",			JKEYWORD, J_CENTER },
613     { "clientborderwidth",	KEYWORD, kw0_ClientBorderWidth },
614     { "color",			COLOR, 0 },
615     { "constrainedmovetime",	NKEYWORD, kwn_ConstrainedMoveTime },
616     { "control",		CONTROL, 0 },
617     { "cursors",		CURSORS, 0 },
618     { "decoratetransients",	KEYWORD, kw0_DecorateTransients },
619     { "defaultbackground",	CKEYWORD, kwc_DefaultBackground },
620     { "defaultforeground",	CKEYWORD, kwc_DefaultForeground },
621     { "defaultfunction",	DEFAULT_FUNCTION, 0 },
622     { "destroy",		KILL, 0 },
623 #ifdef RJC
624     { "dodefaultmenuaction",	KEYWORD, kw0_DoDefaultMenuAction},
625 #endif
626     { "donticonifybyunmapping",	DONT_ICONIFY_BY_UNMAPPING, 0 },
627     { "dontinterpolatetitles",	KEYWORD, kw0_DontInterpolateTitles },
628     { "dontmoveoff",		KEYWORD, kw0_DontMoveOff },
629     { "dontsqueezeicon",	DONT_SQUEEZE_ICON, 0 },
630     { "dontsqueezetitle",	DONT_SQUEEZE_TITLE, 0 },
631     { "east",			DKEYWORD, D_EAST },
632     { "f",			FRAME, 0 },
633     { "f.autoraise",		FKEYWORD, F_AUTORAISE },
634     { "f.backiconmgr",		FKEYWORD, F_BACKICONMGR },
635     { "f.beep",			FKEYWORD, F_BEEP },
636     { "f.bottomzoom",		FKEYWORD, F_BOTTOMZOOM },
637     { "f.circledown",		FKEYWORD, F_CIRCLEDOWN },
638     { "f.circleup",		FKEYWORD, F_CIRCLEUP },
639     { "f.colormap",		FSKEYWORD, F_COLORMAP },
640     { "f.constrainedmove",	FKEYWORD, F_CONSTRAINEDMOVE },
641     { "f.cut",			FSKEYWORD, F_CUT },
642     { "f.cutfile",		FKEYWORD, F_CUTFILE },
643     { "f.deiconify",		FKEYWORD, F_DEICONIFY },
644     { "f.delete",		FKEYWORD, F_DELETE },
645     { "f.deleteordestroy",	FKEYWORD, F_DELETEORDESTROY },
646     { "f.deltastop",		FKEYWORD, F_DELTASTOP },
647     { "f.destroy",		FKEYWORD, F_DESTROY },
648     { "f.downiconmgr",		FKEYWORD, F_DOWNICONMGR },
649     { "f.dumpstate",		FKEYWORD, F_DUMPSTATE },
650     { "f.exec",			FSKEYWORD, F_EXEC },
651     { "f.file",			FSKEYWORD, F_FILE },
652     { "f.focus",		FKEYWORD, F_FOCUS },
653     { "f.forcemove",		FKEYWORD, F_FORCEMOVE },
654     { "f.forwiconmgr",		FKEYWORD, F_FORWICONMGR },
655     { "f.fullzoom",		FKEYWORD, F_FULLZOOM },
656     { "f.function",		FSKEYWORD, F_FUNCTION },
657     { "f.hbzoom",		FKEYWORD, F_BOTTOMZOOM },
658     { "f.hideiconmgr",		FKEYWORD, F_HIDELIST },
659     { "f.horizoom",		FKEYWORD, F_HORIZOOM },
660     { "f.htzoom",		FKEYWORD, F_TOPZOOM },
661     { "f.hzoom",		FKEYWORD, F_HORIZOOM },
662     { "f.iconify",		FKEYWORD, F_ICONIFY },
663     { "f.identify",		FKEYWORD, F_IDENTIFY },
664     { "f.lefticonmgr",		FKEYWORD, F_LEFTICONMGR },
665     { "f.leftzoom",		FKEYWORD, F_LEFTZOOM },
666     { "f.lower",		FKEYWORD, F_LOWER },
667     { "f.menu",			FSKEYWORD, F_MENU },
668     { "f.menufunc",		FSKEYWORD, F_MENUFUNC },
669     { "f.move",			FKEYWORD, F_MOVE },
670     { "f.nexticonmgr",		FKEYWORD, F_NEXTICONMGR },
671     { "f.nop",			FKEYWORD, F_NOP },
672     { "f.opaquemove",		FKEYWORD, F_OPAQUEMOVE },
673     { "f.pandown",		FKEYWORD, F_SCROLLDOWN },
674     { "f.panleft",		FKEYWORD, F_SCROLLLEFT },
675     { "f.panner",		FKEYWORD, F_PANNER },
676     { "f.panright",		FKEYWORD, F_SCROLLRIGHT },
677     { "f.panup",		FKEYWORD, F_SCROLLUP },
678     { "f.previconmgr",		FKEYWORD, F_PREVICONMGR },
679     { "f.quit",			FKEYWORD, F_QUIT },
680     { "f.raise",		FKEYWORD, F_RAISE },
681     { "f.raiselower",		FKEYWORD, F_RAISELOWER },
682     { "f.refresh",		FKEYWORD, F_REFRESH },
683     { "f.relativemove",		FSKEYWORD, F_RELATIVEMOVE },
684     { "f.relativeresize",	FKEYWORD, F_RELATIVERESIZE },
685     { "f.resize",		FKEYWORD, F_RESIZE },
686     { "f.restart",		FKEYWORD, F_RESTART },
687     { "f.righticonmgr",		FKEYWORD, F_RIGHTICONMGR },
688     { "f.rightzoom",		FKEYWORD, F_RIGHTZOOM },
689     { "f.saveyourself",		FKEYWORD, F_SAVEYOURSELF },
690     { "f.scroll",		FSKEYWORD, F_SCROLL },
691     { "f.scrollback",		FKEYWORD, F_SCROLLBACK },
692     { "f.scrolldown",		FKEYWORD, F_SCROLLDOWN },
693     { "f.scrollhome",		FKEYWORD, F_SCROLLHOME },
694     { "f.scrollleft",		FKEYWORD, F_SCROLLLEFT },
695     { "f.scrollright",		FKEYWORD, F_SCROLLRIGHT },
696     { "f.scrollup",		FKEYWORD, F_SCROLLUP },
697     { "f.showiconmgr",		FKEYWORD, F_SHOWLIST },
698     { "f.sorticonmgr",		FKEYWORD, F_SORTICONMGR },
699     { "f.source",		FSKEYWORD, F_BEEP },  /* XXX - don't work */
700     { "f.stick",		FKEYWORD, F_STICK },
701     { "f.test",                 FKEYWORD, F_TESTEXEC },
702     { "f.title",		FKEYWORD, F_TITLE },
703     { "f.topzoom",		FKEYWORD, F_TOPZOOM },
704     { "f.twmrc",		FKEYWORD, F_RESTART },
705     { "f.unfocus",		FKEYWORD, F_UNFOCUS },
706     { "f.upiconmgr",		FKEYWORD, F_UPICONMGR },
707     { "f.version",		FKEYWORD, F_VERSION },
708     { "f.vlzoom",		FKEYWORD, F_LEFTZOOM },
709     { "f.vrzoom",		FKEYWORD, F_RIGHTZOOM },
710     { "f.warpring",		FSKEYWORD, F_WARPRING },
711     { "f.warpto",		FSKEYWORD, F_WARPTO },
712     { "f.warptoiconmgr",	FSKEYWORD, F_WARPTOICONMGR },
713     { "f.warptoscreen",		FSKEYWORD, F_WARPTOSCREEN },
714     { "f.winexec",		FSKEYWORD, F_WINEXEC },
715     { "f.winrefresh",		FKEYWORD, F_WINREFRESH },
716     { "f.wintest",		FSKEYWORD, F_TESTWINEXEC },
717     { "f.zoom",			FKEYWORD, F_ZOOM },
718     { "forceicons",		KEYWORD, kw0_ForceIcons },
719     { "frame",			FRAME, 0 },
720     { "framepadding",		NKEYWORD, kwn_FramePadding },
721     { "function",		FUNCTION, 0 },
722     { "i",			ICON, 0 },
723     { "icon",			ICON, 0 },
724     { "iconbackground",		CLKEYWORD, kwcl_IconBackground },
725     { "iconbordercolor",	CLKEYWORD, kwcl_IconBorderColor },
726     { "iconborderwidth",	NKEYWORD, kwn_IconBorderWidth },
727     { "icondirectory",		SKEYWORD, kws_IconDirectory },
728     { "iconfont",		SKEYWORD, kws_IconFont },
729     { "iconforeground",		CLKEYWORD, kwcl_IconForeground },
730     { "iconifybyunmapping",	ICONIFY_BY_UNMAPPING, 0 },
731     { "iconifypixmap",		PKEYWORD, kwp_IconifyPixmap },
732     { "iconmanagerbackground",	CLKEYWORD, kwcl_IconManagerBackground },
733     { "iconmanagerdontshow",	ICONMGR_NOSHOW, 0 },
734     { "iconmanagerfont",	SKEYWORD, kws_IconManagerFont },
735     { "iconmanagerforeground",	CLKEYWORD, kwcl_IconManagerForeground },
736     { "iconmanagergeometry",	ICONMGR_GEOMETRY, 0 },
737     { "iconmanagerhighlight",	CLKEYWORD, kwcl_IconManagerHighlight },
738     { "iconmanagers",		ICONMGRS, 0 },
739     { "iconmanagershow",	ICONMGR_SHOW, 0 },
740     { "iconmgr",		ICONMGR, 0 },
741     { "iconregion",		ICON_REGION, 0 },
742     { "icons",			ICONS, 0 },
743     { "icontitle",		ICON_TITLE, 0 },
744     { "identification",		SKEYWORD, kws_Identification },
745     { "interpolatemenucolors",	KEYWORD, kw0_InterpolateMenuColors },
746     { "l",			LOCK, 0 },
747     { "left",			JKEYWORD, J_LEFT },
748     { "lefttitlebutton",	LEFT_TITLEBUTTON, 0 },
749     { "listrings",	        KEYWORD, kw0_ListRings },
750     { "lock",			LOCK, 0 },
751     { "m",			META, 0 },
752     { "maketitle",		MAKE_TITLE, 0 },
753     { "maxwindowsize",		SKEYWORD, kws_MaxWindowSize },
754     { "menu",			MENU, 0 },
755     { "menubackground",		CKEYWORD, kwc_MenuBackground },
756     { "menufont",		SKEYWORD, kws_MenuFont },
757     { "menuforeground",		CKEYWORD, kwc_MenuForeground },
758     { "menulinewidth",		NKEYWORD, kwn_MenuLineWidth },
759     { "menushadowcolor",	CKEYWORD, kwc_MenuShadowColor },
760     { "menushadowwidth",	NKEYWORD, kwn_MenuShadowWidth },
761     { "menutitlebackground",	CKEYWORD, kwc_MenuTitleBackground },
762     { "menutitlefont",		SKEYWORD, kws_MenuTitleFont },
763     { "menutitleforeground",	CKEYWORD, kwc_MenuTitleForeground },
764     { "meta",			META, 0 },
765     { "mod",			META, 0 },  /* fake it */
766     { "monochrome",		MONOCHROME, 0 },
767     { "move",			MOVE, 0 },
768     { "movedelta",		NKEYWORD, kwn_MoveDelta },
769     { "name",			MKEYWORD, kwm_Name },
770     { "nobackingstore",		KEYWORD, kw0_NoBackingStore },
771     { "nocasesensitive",	KEYWORD, kw0_NoCaseSensitive },
772     { "nodefaults",		KEYWORD, kw0_NoDefaults },
773     { "nograbserver",		KEYWORD, kw0_NoGrabServer },
774     { "nohighlight",		NO_HILITE, 0 },
775     { "noiconmanagers",		KEYWORD, kw0_NoIconManagers },
776     { "noicontitle",		NO_ICON_TITLE, 0 },
777     { "nomenushadows",		KEYWORD, kw0_NoMenuShadows },
778     { "noopaquemovesaveunders",	KEYWORD, kw0_NoOpaqueMoveSaveUnders },
779     { "noraiseondeiconify",	KEYWORD, kw0_NoRaiseOnDeiconify },
780     { "noraiseonmove",		KEYWORD, kw0_NoRaiseOnMove },
781     { "noraiseonresize",	KEYWORD, kw0_NoRaiseOnResize },
782     { "noraiseonwarp",		KEYWORD, kw0_NoRaiseOnWarp },
783     { "north",			DKEYWORD, D_NORTH },
784     { "nosaveunders",		KEYWORD, kw0_NoSaveUnders },
785     { "nostackmode",		NO_STACKMODE, 0 },
786     { "notitle",		NO_TITLE, 0 },
787     { "notitlefocus",		KEYWORD, kw0_NoTitleFocus },
788     { "notitlehighlight",	NO_TITLE_HILITE, 0 },
789     { "noversion",		KEYWORD, kw0_NoVersion },
790     { "opaquemove",		KEYWORD, kw0_OpaqueMove },
791     { "pannerbackground",	CKEYWORD, kwc_PannerBackground },
792     { "pannerbackgroundpixmap",	PKEYWORD, kwp_PannerBackgroundPixmap },
793     { "pannerforeground",	CKEYWORD, kwc_PannerForeground },
794     { "pannergeometry",		SKEYWORD, kws_PannerGeometry },
795     { "panneropaquescroll",       KEYWORD, kw0_PannerOpaqueScroll },
796     { "pannerscale",		NKEYWORD, kwn_PannerScale },
797     { "pannerstate",		SKEYWORD, kws_PannerState },
798     { "pixmaps",		PIXMAPS, 0 },
799     { "popupsensitivity",	NKEYWORD, kwn_PopupSensitivity },
800     { "pullrightpixmap",	PKEYWORD, kwp_PullRightPixmap },
801     { "r",			ROOT, 0 },
802     { "randomplacement",	KEYWORD, kw0_RandomPlacement },
803     { "rememberscreenposition",	KEYWORD, kw0_RememberScreenPosition },
804     { "resclass",		MKEYWORD, kwm_ResClass },
805     { "resize",			RESIZE, 0 },
806     { "resizefont",		SKEYWORD, kws_ResizeFont },
807     { "resname",		MKEYWORD, kwm_ResName },
808     { "restartpreviousstate",	KEYWORD, kw0_RestartPreviousState },
809     { "right",			JKEYWORD, J_RIGHT },
810     { "righttitlebutton",	RIGHT_TITLEBUTTON, 0 },
811     { "root",			ROOT, 0 },
812     { "s",			SHIFT, 0 },
813     { "savecolor",		SAVECOLOR, 0 },
814     { "scrolldistancex",	NKEYWORD, kwn_ScrollDistanceX },
815     { "scrolldistancey",	NKEYWORD, kwn_ScrollDistanceY },
816     { "select",			SELECT, 0 },
817     { "shadowpixmap",		PKEYWORD, kwp_ShadowPixmap },
818     { "shift",			SHIFT, 0 },
819     { "showiconmanager",	KEYWORD, kw0_ShowIconManager },
820     { "showvirtualnames",	KEYWORD, kw0_ShowVirtualNames },
821     { "sorticonmanager",	KEYWORD, kw0_SortIconManager },
822     { "south",			DKEYWORD, D_SOUTH },
823     { "squeezeicon",		SQUEEZE_ICON, 0 },
824     { "squeezetitle",		SQUEEZE_TITLE, 0 },
825     { "starticonified",		START_ICONIFIED, 0 },
826     { "stayupmenus",		KEYWORD, kw0_StayUpMenus },
827     { "sticky",			STICKY, 0 },
828     { "stickyabove",		KEYWORD, kw0_StickyAbove },
829     { "t",			TITLE, 0 },
830     { "title",			TITLE, 0 },
831     { "titlebackground",	CLKEYWORD, kwcl_TitleBackground },
832     { "titlebuttonborderwidth",	NKEYWORD, kwn_TitleButtonBorderWidth },
833     { "titlefont",		SKEYWORD, kws_TitleFont },
834     { "titlefontpadding",       NKEYWORD, kwn_TitleFontPadding },
835     { "titleforeground",	CLKEYWORD, kwcl_TitleForeground },
836     { "titlehighlight",		PKEYWORD, kwp_TitleHighlight },
837     { "titlehighlightleft",	PKEYWORD, kwp_TitleHighlightLeft },
838     { "titlehighlightright",	PKEYWORD, kwp_TitleHighlightRight },
839     { "titlepadding",		NKEYWORD, kwn_TitlePadding },
840     { "unknownicon",		SKEYWORD, kws_UnknownIcon },
841     { "usepposition",		SKEYWORD, kws_UsePPosition },
842     { "virtualbackground",	CLKEYWORD, kwcl_VirtualBackground },
843     { "virtualdesktop",		SKEYWORD, kws_VirtualDesktop },
844     { "virtualdesktopbackground",CKEYWORD, kwc_VirtualDesktopBackground },
845     { "virtualdesktopbackgroundpixmap",PKEYWORD,
846 				    kwp_VirtualDesktopBackgroundPixmap },
847     { "virtualdesktopforeground",CKEYWORD, kwc_VirtualDesktopForeground },
848     { "virtualfont",		SKEYWORD, kws_VirtualFont },
849     { "virtualforeground",	CLKEYWORD, kwcl_VirtualForeground },
850     { "w",			WINDOW, 0 },
851     { "wait",			WAIT_CURS, 0 },
852     { "warpcursor",		WARP_CURSOR, 0 },
853     { "warpunmapped",		KEYWORD, kw0_WarpUnmapped },
854     { "west",			DKEYWORD, D_WEST },
855     { "window",			WINDOW, 0 },
856     { "windowfunction",		WINDOW_FUNCTION, 0 },
857     { "windowring",		WINDOW_RING, 0 },
858     { "wrapvirtual",		KEYWORD, kw0_WrapVirtual },
859     { "xorvalue",		NKEYWORD, kwn_XorValue },
860     { "zoom",			ZOOM, 0 },
861 };
862 
863 static int numkeywords = (sizeof(keytable)/sizeof(keytable[0]));
864 
parse_keyword(s,nump)865 int parse_keyword (s, nump)
866     char *s;
867     int *nump;
868 {
869     register int lower = 0, upper = numkeywords - 1;
870 
871     XmuCopyISOLatin1Lowered (s, s);
872     while (lower <= upper) {
873         int middle = (lower + upper) / 2;
874 	TwmKeyword *p = &keytable[middle];
875         int res = strcmp (p->name, s);
876 
877         if (res < 0) {
878             lower = middle + 1;
879         } else if (res == 0) {
880 	    *nump = p->subnum;
881             return p->value;
882         } else {
883             upper = middle - 1;
884         }
885     }
886     return ERRORTOKEN;
887 }
888 
889 
890 
891 /*
892  * action routines called by grammar
893  */
894 
do_single_keyword(keyword)895 int do_single_keyword (keyword)
896     int keyword;
897 {
898     switch (keyword) {
899       case kw0_NoDefaults:
900 	Scr->NoDefaults = TRUE;
901 	return 1;
902 
903       case kw0_StickyAbove:
904 	Scr->StickyAbove = TRUE;
905 	return 1;
906 
907       case kw0_PannerOpaqueScroll:
908 	Scr->PannerOpaqueScroll = TRUE;
909 	return 1;
910 
911       case kw0_AutoRelativeResize:
912 	Scr->AutoRelativeResize = TRUE;
913 	return 1;
914 
915       case kw0_ForceIcons:
916 	if (Scr->FirstTime) Scr->ForceIcon = TRUE;
917 	return 1;
918 
919       case kw0_NoIconManagers:
920 	Scr->NoIconManagers = TRUE;
921 	return 1;
922 
923       case kw0_OpaqueMove:
924 	Scr->OpaqueMove = TRUE;
925 	return 1;
926 
927       case kw0_InterpolateMenuColors:
928 	if (Scr->FirstTime) Scr->InterpolateMenuColors = TRUE;
929 	return 1;
930 
931       case kw0_NoVersion:
932 	/* obsolete */
933 	return 1;
934 
935       case kw0_SortIconManager:
936 	if (Scr->FirstTime) Scr->SortIconMgr = TRUE;
937 	return 1;
938 
939       case kw0_NoGrabServer:
940 	Scr->NoGrabServer = TRUE;
941 	return 1;
942 
943       case kw0_NoMenuShadows:
944 	if (Scr->FirstTime) Scr->Shadow = FALSE;
945 	return 1;
946 
947       case kw0_NoRaiseOnMove:
948 	if (Scr->FirstTime) Scr->NoRaiseMove = TRUE;
949 	return 1;
950 
951       case kw0_NoRaiseOnResize:
952 	if (Scr->FirstTime) Scr->NoRaiseResize = TRUE;
953 	return 1;
954 
955       case kw0_NoRaiseOnDeiconify:
956 	if (Scr->FirstTime) Scr->NoRaiseDeicon = TRUE;
957 	return 1;
958 
959       case kw0_DontMoveOff:
960 	Scr->DontMoveOff = TRUE;
961 	return 1;
962 
963       case kw0_NoBackingStore:
964 	Scr->BackingStore = FALSE;
965 	return 1;
966 
967       case kw0_NoSaveUnders:
968 	Scr->SaveUnder = FALSE;
969 	return 1;
970 
971       case kw0_RestartPreviousState:
972 	RestartPreviousState = True;
973 	return 1;
974 
975       case kw0_ClientBorderWidth:
976 	if (Scr->FirstTime) Scr->ClientBorderWidth = TRUE;
977 	return 1;
978 
979       case kw0_NoTitleFocus:
980 	Scr->TitleFocus = FALSE;
981 	return 1;
982 
983       case kw0_RandomPlacement:
984 	Scr->RandomPlacement = TRUE;
985 	return 1;
986 
987       case kw0_DecorateTransients:
988 	Scr->DecorateTransients = TRUE;
989 	return 1;
990 
991       case kw0_ShowIconManager:
992 	Scr->ShowIconManager = TRUE;
993 	return 1;
994 
995       case kw0_ShowVirtualNames:
996 	Scr->ShowVirtualNames = TRUE;
997 	return 1;
998 
999       case kw0_StayUpMenus:
1000 	if (Scr->FirstTime) Scr->StayUpMenus = TRUE;
1001 	return 1;
1002 
1003       case kw0_NoCaseSensitive:
1004 	Scr->CaseSensitive = FALSE;
1005 	return 1;
1006 
1007       case kw0_NoRaiseOnWarp:
1008 	Scr->NoRaiseWarp = TRUE;
1009 	return 1;
1010 
1011       case kw0_WarpUnmapped:
1012 	Scr->WarpUnmapped = TRUE;
1013 	return 1;
1014 
1015       case kw0_ListRings:
1016 	if (Scr->FirstTime) Scr->ListRings = TRUE;
1017 	return 1;
1018 
1019       case kw0_DontInterpolateTitles:
1020 	Scr->DontInterpolateTitles = TRUE;
1021 	return 1;
1022 
1023       case kw0_WrapVirtual:
1024 	Scr->WrapVirtual = TRUE;
1025 	return 1;
1026 
1027       case kw0_RememberScreenPosition:
1028 	Scr->RememberScreenPosition = TRUE;
1029 	return 1;
1030 
1031       case kw0_NoOpaqueMoveSaveUnders:
1032 	if (Scr->FirstTime) Scr->OpaqueMoveSaveUnders = FALSE;
1033 	return 1;
1034 
1035 #ifdef RJC
1036       case kw0_DoDefaultMenuAction:
1037 	fprintf(stderr, "%s: DoDefaultMenuAction ignored\n", ProgramName);
1038 	return 1;
1039 #endif
1040     }
1041 
1042     return 0;
1043 }
1044 
1045 
do_string_keyword(keyword,s)1046 int do_string_keyword (keyword, s)
1047     int keyword;
1048     char *s;
1049 {
1050     switch (keyword) {
1051 
1052       case kws_VirtualDesktop:
1053 	{
1054 	    int status, x, y;
1055 	    unsigned int width, height;
1056 
1057 	    status = XParseGeometry(s, &x, &y, &width, &height);
1058 	    if ((status & (WidthValue & HeightValue)) != (WidthValue & HeightValue)) {
1059 		twmrc_error_prefix();
1060 		fprintf (stderr,
1061 			 "ignoring invalid VirtualDesktop geometry \"%s\"\n", s);
1062 	    } else {
1063 	   	Scr->VirtualDesktop = True;
1064 		Scr->vdtWidth = width;
1065 		Scr->vdtHeight = height;
1066 	    }
1067 	    return 1;
1068 	}
1069 
1070       case kws_PannerState:
1071 	{
1072 	    int state = ParseState(s);
1073 	    if (state < 0) {
1074 		twmrc_error_prefix();
1075 		fprintf (stderr,
1076 			 "ignoring invalid PannerState argument \"%s\"\n", s);
1077 	    } else {
1078 		Scr->PannerState = state;
1079 	    }
1080 	    return 1;
1081 	}
1082 
1083       case kws_PannerGeometry:
1084 	{
1085 	    int status, x, y;
1086 	    unsigned int width, height;
1087 
1088 	    status = XParseGeometry(s, &x, &y, &width, &height);
1089 	    if ((status & (XValue | YValue)) != (XValue | YValue)) {
1090 		twmrc_error_prefix();
1091 		fprintf (stderr,
1092 			 "ignoring invalid PannerGeometry \"%s\"\n", s);
1093 	    } else {
1094 		Scr->PannerGeometry = s;
1095 	    }
1096 	    return 1;
1097 	}
1098 
1099       case kws_UsePPosition:
1100 	{
1101 	    int ppos = ParseUsePPosition (s);
1102 	    if (ppos < 0) {
1103 		twmrc_error_prefix();
1104 		fprintf (stderr,
1105 			 "ignoring invalid UsePPosition argument \"%s\"\n", s);
1106 	    } else {
1107 		Scr->UsePPosition = ppos;
1108 	    }
1109 	    return 1;
1110 	}
1111 
1112       case kws_VirtualFont:
1113 	if (!Scr->HaveFonts) Scr->VirtualFont.name = s;
1114 	return 1;
1115 
1116       case kws_IconFont:
1117 	if (!Scr->HaveFonts) Scr->IconFont.name = s;
1118 	return 1;
1119 
1120       case kws_ResizeFont:
1121 	if (!Scr->HaveFonts) Scr->SizeFont.name = s;
1122 	return 1;
1123 
1124       case kws_MenuFont:
1125 	if (!Scr->HaveFonts) Scr->MenuFont.name = s;
1126 	return 1;
1127 
1128       case kws_MenuTitleFont:
1129 	if (!Scr->HaveFonts) Scr->MenuTitleFont.name = s;
1130 	return 1;
1131 
1132       case kws_TitleFont:
1133 	if (!Scr->HaveFonts) Scr->TitleBarFont.name = s;
1134 	return 1;
1135 
1136       case kws_IconManagerFont:
1137 	if (!Scr->HaveFonts) Scr->IconManagerFont.name = s;
1138 	return 1;
1139 
1140       case kws_UnknownIcon:
1141 	if (Scr->FirstTime) Scr->Unknown.name = s;
1142 	return 1;
1143 
1144       case kws_IconDirectory:
1145 	if (Scr->FirstTime) Scr->IconDirectory = ExpandFilename (s);
1146 	return 1;
1147 
1148       case kws_Identification:
1149 	if (Scr->FirstTime) Scr->Identification = s;
1150 	return 1;
1151 
1152       case kws_AfterSetupRun:
1153 	if (Scr->FirstTime) Scr->AfterSetupRun = s;
1154 	return 1;
1155 
1156       case kws_MaxWindowSize:
1157 	JunkMask = XParseGeometry (s, &JunkX, &JunkY, &JunkWidth, &JunkHeight);
1158 	if ((JunkMask & (WidthValue | HeightValue)) !=
1159 	    (WidthValue | HeightValue)) {
1160 	    twmrc_error_prefix();
1161 	    fprintf (stderr, "bad MaxWindowSize \"%s\"\n", s);
1162 	    return 0;
1163 	}
1164 	if (JunkWidth <= 0 || JunkHeight <= 0) {
1165 	    twmrc_error_prefix();
1166 	    fprintf (stderr, "MaxWindowSize \"%s\" must be positive\n", s);
1167 	    return 0;
1168 	}
1169 	Scr->MaxWindowWidth = JunkWidth;
1170 	Scr->MaxWindowHeight = JunkHeight;
1171 	return 1;
1172     }
1173 
1174     return 0;
1175 }
1176 
1177 
do_number_keyword(keyword,num)1178 int do_number_keyword (keyword, num)
1179     int keyword;
1180     int num;
1181 {
1182     switch (keyword) {
1183       case kwn_PannerScale:
1184 	if (num > 0)
1185 	    Scr->PannerScale = num;
1186 	return 1;
1187 
1188       case kwn_ScrollDistanceX:
1189 	if (Scr->FirstTime)
1190 		Scr->vdtScrollDistanceX = (num * Scr->MyDisplayWidth) / 100;
1191 	return 1;
1192 
1193       case kwn_ScrollDistanceY:
1194 	if (Scr->FirstTime)
1195 		Scr->vdtScrollDistanceY = (num * Scr->MyDisplayHeight) / 100;
1196 	return 1;
1197 
1198       case kwn_ConstrainedMoveTime:
1199 	ConstrainedMoveTime = num;
1200 	return 1;
1201 
1202       case kwn_MenuLineWidth:
1203 	Scr->MenuLineWidth = num;
1204 	return 1;
1205 
1206       case kwn_TitleFontPadding:
1207 	Scr->TitleFontPadding = num;
1208 	return 1;
1209 
1210       case kwn_MoveDelta:
1211 	Scr->MoveDelta = num;
1212 	return 1;
1213 
1214       case kwn_XorValue:
1215 	if (Scr->FirstTime) Scr->XORvalue = num;
1216 	return 1;
1217 
1218       case kwn_FramePadding:
1219 	if (Scr->FirstTime) Scr->FramePadding = num;
1220 	return 1;
1221 
1222       case kwn_TitlePadding:
1223 	if (Scr->FirstTime) Scr->TitlePadding = num;
1224 	return 1;
1225 
1226       case kwn_ButtonIndent:
1227 	if (Scr->FirstTime) Scr->ButtonIndent = num;
1228 	return 1;
1229 
1230       case kwn_BorderWidth:
1231 	if (Scr->FirstTime) Scr->BorderWidth = num;
1232 	return 1;
1233 
1234       case kwn_IconBorderWidth:
1235 	if (Scr->FirstTime) Scr->IconBorderWidth = num;
1236 	return 1;
1237 
1238       case kwn_TitleButtonBorderWidth:
1239 	if (Scr->FirstTime) Scr->TBInfo.border = num;
1240 	return 1;
1241 
1242       case kwn_PopupSensitivity:
1243 	if (num > 100 || num < 5) {
1244 	    twmrc_error_prefix();
1245 	    fprintf(stderr, "PopupSensitivity %d out of range, ignoring.\n",
1246 			num);
1247 	} else if (Scr->FirstTime) Scr->PopupSensitivity = num;
1248 	return 1;
1249 
1250       case kwn_MenuShadowWidth:
1251 	Scr->ShadowWidth = num;
1252 	return 1;
1253 
1254     }
1255 
1256     return 0;
1257 }
1258 
do_colorlist_keyword(keyword,colormode,s)1259 name_list **do_colorlist_keyword (keyword, colormode, s)
1260     int keyword;
1261     int colormode;
1262     char *s;
1263 {
1264     switch (keyword) {
1265       case kwcl_BorderColor:
1266 	GetColor (colormode, &Scr->BorderColor, s);
1267 	return &Scr->BorderColorL;
1268 
1269       case kwcl_IconManagerHighlight:
1270 	GetColor (colormode, &Scr->IconManagerHighlight, s);
1271 	return &Scr->IconManagerHighlightL;
1272 
1273       case kwcl_BorderTileForeground:
1274 	GetColor (colormode, &Scr->BorderTileC.fore, s);
1275 	return &Scr->BorderTileForegroundL;
1276 
1277       case kwcl_BorderTileBackground:
1278 	GetColor (colormode, &Scr->BorderTileC.back, s);
1279 	return &Scr->BorderTileBackgroundL;
1280 
1281       case kwcl_TitleForeground:
1282 	GetColor (colormode, &Scr->TitleC.fore, s);
1283 	return &Scr->TitleForegroundL;
1284 
1285       case kwcl_TitleBackground:
1286 	GetColor (colormode, &Scr->TitleC.back, s);
1287 	return &Scr->TitleBackgroundL;
1288 
1289       case kwcl_VirtualForeground:
1290 	GetColor (colormode, &Scr->VirtualC.fore, s);
1291 	return &Scr->VirtualForegroundL;
1292 
1293       case kwcl_VirtualBackground:
1294 	GetColor (colormode, &Scr->VirtualC.back, s);
1295 	return &Scr->VirtualBackgroundL;
1296 
1297       case kwcl_IconForeground:
1298 	GetColor (colormode, &Scr->IconC.fore, s);
1299 	return &Scr->IconForegroundL;
1300 
1301       case kwcl_IconBackground:
1302 	GetColor (colormode, &Scr->IconC.back, s);
1303 	return &Scr->IconBackgroundL;
1304 
1305       case kwcl_IconBorderColor:
1306 	GetColor (colormode, &Scr->IconBorderColor, s);
1307 	return &Scr->IconBorderColorL;
1308 
1309       case kwcl_IconManagerForeground:
1310 	GetColor (colormode, &Scr->IconManagerC.fore, s);
1311 	return &Scr->IconManagerFL;
1312 
1313       case kwcl_IconManagerBackground:
1314 	GetColor (colormode, &Scr->IconManagerC.back, s);
1315 	return &Scr->IconManagerBL;
1316     }
1317     return NULL;
1318 }
1319 
do_color_keyword(keyword,colormode,s)1320 int do_color_keyword (keyword, colormode, s)
1321     int keyword;
1322     int colormode;
1323     char *s;
1324 {
1325     switch (keyword) {
1326       case kwc_PannerBackground:
1327 	GetColor (colormode, &Scr->PannerC.back, s);
1328 	Scr->PannerBackgroundSet = True;
1329 	return 1;
1330 
1331       case kwc_PannerForeground:
1332 	GetColor (colormode, &Scr->PannerC.fore, s);
1333 	return 1;
1334 
1335       case kwc_VirtualDesktopBackground:
1336 	if (GetColor (colormode, &Scr->vdtC.back, s))
1337 	    Scr->vdtBackgroundSet = True;
1338 	return 1;
1339 
1340       case kwc_VirtualDesktopForeground:
1341 	GetColor (colormode, &Scr->vdtC.fore, s);
1342 	return 1;
1343 
1344       case kwc_DefaultForeground:
1345 	GetColor (colormode, &Scr->DefaultC.fore, s);
1346 	return 1;
1347 
1348       case kwc_DefaultBackground:
1349 	GetColor (colormode, &Scr->DefaultC.back, s);
1350 	return 1;
1351 
1352       case kwc_MenuForeground:
1353 	GetColor (colormode, &Scr->MenuC.fore, s);
1354 	return 1;
1355 
1356       case kwc_MenuBackground:
1357 	GetColor (colormode, &Scr->MenuC.back, s);
1358 	return 1;
1359 
1360       case kwc_MenuTitleForeground:
1361 	GetColor (colormode, &Scr->MenuTitleC.fore, s);
1362 	return 1;
1363 
1364       case kwc_MenuTitleBackground:
1365 	GetColor (colormode, &Scr->MenuTitleC.back, s);
1366 	return 1;
1367 
1368       case kwc_MenuShadowColor:
1369 	GetColor (colormode, &Scr->MenuShadowColor, s);
1370 	return 1;
1371 
1372     }
1373 
1374     return 0;
1375 }
1376 
do_pixmap_keyword(keyword,filename)1377 int do_pixmap_keyword(keyword, filename)
1378     int keyword;
1379     char *filename;
1380 {
1381 
1382 switch(keyword)
1383     {
1384 
1385  case kwp_TitleHighlight:
1386     Scr->hilite.name = filename;
1387     return 1;
1388 
1389  case kwp_TitleHighlightLeft:
1390     Scr->hiliteLeft.name = filename;
1391     return 1;
1392 
1393  case kwp_TitleHighlightRight:
1394     Scr->hiliteRight.name = filename;
1395     return 1;
1396 
1397  case kwp_IconifyPixmap:
1398     Scr->iconifyPm.name = filename;
1399     return 1;
1400 
1401  case kwp_PullRightPixmap:
1402     Scr->pullrightPm.name = filename;
1403     return 1;
1404 
1405  case kwp_PannerBackgroundPixmap:
1406     Scr->PannerPixmap = filename;
1407     return 1;
1408 
1409  case kwp_VirtualDesktopBackgroundPixmap:
1410     Scr->vdtPixmap = filename;
1411     return 1;
1412 
1413  case kwp_ShadowPixmap:
1414     Scr->shadowPm.name = filename;
1415     return 1;
1416 
1417     }
1418     return 0;
1419 }
1420 
1421 /*
1422  * put_pixel_on_root() Save a pixel value in twm root window color property.
1423  */
put_pixel_on_root(pixel)1424 put_pixel_on_root(pixel)
1425     Pixel pixel;
1426 {
1427   int           i, addPixel = 1;
1428   Atom          pixelAtom, retAtom;
1429   int           retFormat;
1430   unsigned long nPixels, retAfter;
1431   Pixel        *retProp;
1432   pixelAtom = XInternAtom(dpy, "_MIT_PRIORITY_COLORS", True);
1433   XGetWindowProperty(dpy, Scr->Root, pixelAtom, 0, 8192,
1434 		     False, XA_CARDINAL, &retAtom,
1435 		     &retFormat, &nPixels, &retAfter,
1436 		     (unsigned char **)&retProp);
1437 
1438   for (i=0; i< nPixels; i++)
1439       if (pixel == retProp[i]) addPixel = 0;
1440 
1441   if (addPixel)
1442       XChangeProperty (dpy, Scr->Root, _XA_MIT_PRIORITY_COLORS,
1443 		       XA_CARDINAL, 32, PropModeAppend,
1444 		       (unsigned char *)&pixel, 1);
1445 }
1446 
1447 /*
1448  * do_string_savecolor() save a color from a string in the twmrc file.
1449  */
do_string_savecolor(colormode,s)1450 void do_string_savecolor(colormode, s)
1451      int colormode;
1452      char *s;
1453 {
1454   Pixel p;
1455   GetColor(colormode, &p, s);
1456   put_pixel_on_root(p);
1457 }
1458 
1459 /*
1460  * do_var_savecolor() save a color from a var in the twmrc file.
1461  */
1462 typedef struct _cnode {int i; struct _cnode *next;} Cnode, *Cptr;
1463 Cptr chead = NULL;
1464 
1465 void
do_var_savecolor(key)1466 do_var_savecolor(key)
1467 int key;
1468 {
1469   Cptr cptrav, cpnew;
1470   if (!chead) {
1471     chead = (Cptr)malloc(sizeof(Cnode));
1472     chead->i = key; chead->next = NULL;
1473   }
1474   else {
1475     cptrav = chead;
1476     while (cptrav->next != NULL) { cptrav = cptrav->next; }
1477     cpnew = (Cptr)malloc(sizeof(Cnode));
1478     cpnew->i = key; cpnew->next = NULL; cptrav->next = cpnew;
1479   }
1480 }
1481 
1482 /*
1483  * assign_var_savecolor() traverse the var save color list placeing the pixels
1484  *                        in the root window property.
1485  */
assign_var_savecolor()1486 void assign_var_savecolor()
1487 {
1488   Cptr cp = chead;
1489   while (cp != NULL) {
1490     switch (cp->i) {
1491     case kwcl_BorderColor:
1492       put_pixel_on_root(Scr->BorderColor);
1493       break;
1494     case kwcl_IconManagerHighlight:
1495       put_pixel_on_root(Scr->IconManagerHighlight);
1496       break;
1497     case kwcl_BorderTileForeground:
1498       put_pixel_on_root(Scr->BorderTileC.fore);
1499       break;
1500     case kwcl_BorderTileBackground:
1501       put_pixel_on_root(Scr->BorderTileC.back);
1502       break;
1503     case kwcl_TitleForeground:
1504       put_pixel_on_root(Scr->TitleC.fore);
1505       break;
1506     case kwcl_TitleBackground:
1507       put_pixel_on_root(Scr->TitleC.back);
1508       break;
1509     case kwcl_IconForeground:
1510       put_pixel_on_root(Scr->IconC.fore);
1511       break;
1512     case kwcl_IconBackground:
1513       put_pixel_on_root(Scr->IconC.back);
1514       break;
1515     case kwcl_IconBorderColor:
1516       put_pixel_on_root(Scr->IconBorderColor);
1517       break;
1518     case kwcl_IconManagerForeground:
1519       put_pixel_on_root(Scr->IconManagerC.fore);
1520       break;
1521     case kwcl_IconManagerBackground:
1522       put_pixel_on_root(Scr->IconManagerC.back);
1523       break;
1524     }
1525     cp = cp->next;
1526   }
1527   if (chead) {
1528     free(chead);
1529     chead = NULL;
1530   }
1531 }
1532 
ParseUsePPosition(s)1533 static int ParseUsePPosition (s)
1534     register char *s;
1535 {
1536     XmuCopyISOLatin1Lowered (s, s);
1537 
1538     if (strcmp (s, "off") == 0) {
1539 	return PPOS_OFF;
1540     } else if (strcmp (s, "on") == 0) {
1541 	return PPOS_ON;
1542     } else if (strcmp (s, "non-zero") == 0 ||
1543 	       strcmp (s, "nonzero") == 0) {
1544 	return PPOS_NON_ZERO;
1545     }
1546 
1547     return -1;
1548 }
1549 
ParseState(s)1550 static int ParseState (s)
1551     register char *s;
1552 {
1553     XmuCopyISOLatin1Lowered (s, s);
1554 
1555     if (strcmp (s, "withdrawn") == 0) {
1556 	return WithdrawnState;
1557     } else if (strcmp (s, "normal") == 0) {
1558 	return NormalState;
1559     } else if (strcmp (s, "iconic") == 0) {
1560 	return IconicState;
1561     }
1562 
1563     return -1;
1564 }
1565 
1566 
do_squeeze_entry(list,name,type,justify,num,denom)1567 do_squeeze_entry (list, name, type, justify, num, denom)
1568     name_list **list;			/* squeeze or dont-squeeze list */
1569     char *name;				/* window name */
1570     short type;				/* match type */
1571     int justify;			/* left, center, right */
1572     int num;				/* signed num */
1573     int denom;				/* 0 or indicates fraction denom */
1574 {
1575     int absnum = (num < 0 ? -num : num);
1576 
1577     if (denom < 0) {
1578 	twmrc_error_prefix();
1579 	fprintf (stderr, "negative SqueezeTitle denominator %d\n", denom);
1580 	return;
1581     }
1582     if (absnum > denom && denom != 0) {
1583 	twmrc_error_prefix();
1584 	fprintf (stderr, "SqueezeTitle fraction %d/%d outside window\n",
1585 		 num, denom);
1586 	return;
1587     }
1588     if (denom == 1) {
1589 	twmrc_error_prefix();
1590 	fprintf (stderr, "useless SqueezeTitle faction %d/%d, assuming 0/0\n",
1591 		 num, denom);
1592 	num = 0;
1593 	denom = 0;
1594     }
1595 
1596     if (HasShape) {
1597 	SqueezeInfo *sinfo;
1598 	sinfo = (SqueezeInfo *) malloc (sizeof(SqueezeInfo));
1599 
1600 	if (!sinfo) {
1601 	    twmrc_error_prefix();
1602 	    fprintf (stderr, "unable to allocate %d bytes for squeeze info\n",
1603 		     sizeof(SqueezeInfo));
1604 	    return;
1605 	}
1606 	sinfo->justify = justify;
1607 	sinfo->num = num;
1608 	sinfo->denom = denom;
1609 	AddToList (list, name, type, (char *)sinfo);
1610     }
1611 }
1612 
1613 static char *m4_defs();
1614 
start_m4(fraw)1615 static FILE *start_m4(fraw)
1616 FILE *fraw;
1617 {
1618 	int fno;
1619 	int fids[2];
1620 	int fres;		/* Fork result */
1621 
1622 	fno = fileno(fraw);
1623 	/* if (-1 == fcntl(fno, F_SETFD, 0)) perror("fcntl()"); */
1624 	pipe(fids);
1625 	fres = fork();
1626 	if (fres < 0) {
1627 		perror("Fork for m4 failed");
1628 		exit(23);
1629 	}
1630 	if (fres == 0) {
1631 		extern Display *dpy;
1632 		extern char *display_name;
1633 		char *tmp_file;
1634 
1635 		/* Child */
1636 		close(0);			/* stdin */
1637 		close(1);			/* stdout */
1638 		dup2(fno, 0);		/* stdin = fraw */
1639 		dup2(fids[1], 1);	/* stdout = pipe to parent */
1640 		/* get_defs("m4", dpy, display_name) */
1641 		tmp_file = m4_defs(dpy, display_name);
1642 		execlp("m4", "m4", tmp_file, M4STDIN, NULL);
1643 		/* If we get here we are screwed... */
1644 		perror("Can't execlp() m4");
1645 		exit(124);
1646 	}
1647 	/* Parent */
1648 	close(fids[1]);
1649 	m4_pid = fres;
1650 #if 0
1651 #define USEC 100000
1652 	{
1653 	struct timeval tv;
1654 
1655 	timerclear(&tv);
1656 	tv.tv_sec = USEC / 1000000;
1657 	tv.tv_usec = USEC % 1000000;
1658 	select(0, NULL, NULL, NULL, &tv);
1659 	}
1660 #undef USEC
1661 	kill(m4_pid, SIGSTOP);
1662 #endif /* 0 */
1663 	return(fdopen(fids[0], "r"));
1664 }
1665 
1666 /* Code taken and munged from xrdb.c */
1667 #define MAXHOSTNAME 255
1668 #define Resolution(pixels, mm)	((((pixels) * 100000 / (mm)) + 50) / 100)
1669 #define EXTRA	(15)
1670 
MkDef(name,def)1671 static char *MkDef(name, def)
1672 char *name, *def;
1673 {
1674 	static char *cp = NULL;
1675 	static int maxsize = 0;
1676 	int n, nl;
1677 
1678 	/* The char * storage only lasts for 1 call... */
1679 	if ((n = EXTRA + ((nl = strlen(name)) +  strlen(def))) > maxsize) {
1680 		if (cp) free(cp);
1681 		cp = malloc(n);
1682 		maxsize = n;
1683 	}
1684 	/* Otherwise cp is aready big 'nuf */
1685 	if (cp == NULL) {
1686 		fprintf(stderr, "%s: Can't get %d bytes for arg parm\n",
1687 			ProgramName, n);
1688 		exit(33);
1689 	}
1690 	strcpy(cp, "define(");
1691 	strcpy(cp+7, name);
1692 	*(cp + nl + 7) = ',';
1693 	*(cp + nl + 8) = ' ';
1694 	strcpy(cp + nl + 9, def);
1695 	strcat(cp + nl + 9, ")dnl\n");
1696 	return(cp);
1697 }
1698 
1699 /* Make a definition, but quote the defined string... */
1700 
MkQte(name,def)1701 static char *MkQte(name, def)
1702 char *name, *def;
1703 {
1704 	char *cp, *cp2;
1705 
1706 	cp = malloc(3 + strlen(def));
1707 	if (cp == NULL) {
1708 		fprintf(stderr, "Can't get %d bytes for arg parm\n", 3 + strlen(def));
1709 		exit(27);
1710 	}
1711 
1712 	/* Note:  We're assuming that ` and ' are still the m4 quote */
1713 	/* characters.  Nothing should be ahead of this file in m4's */
1714 	/* stdin, so it should be safe...                            */
1715 	*cp = '`';
1716 	strcpy(cp + 1, def);
1717 	strcat(cp, "\'");
1718 	cp2 = MkDef(name, cp);
1719 	free(cp);		/* Not really needed, but good habits die hard... */
1720 	return(cp2);
1721 }
1722 
MkNum(name,def)1723 static char *MkNum(name, def)
1724 char *name;
1725 int def;
1726 {
1727 	char num[20];
1728 
1729 	sprintf(num, "%d", def);
1730 	return(MkDef(name, num));
1731 }
1732 
1733 #ifdef NOSTEMP
mkstemp(str)1734 int mkstemp(str)
1735 char *str;
1736 {
1737 	int fd;
1738 
1739 	mktemp(str);
1740 	fd = creat(str, 0744);
1741 	if (fd == -1) perror("mkstemp's creat");
1742 	return(fd);
1743 }
1744 #endif
1745 
m4_defs(display,host)1746 static char *m4_defs(display, host)
1747 Display *display;
1748 char *host;
1749 {
1750 	extern int KeepTmpFile;
1751 	int i;
1752 	Screen *screen;
1753 	Visual *visual;
1754 	char client[MAXHOSTNAME], server[MAXHOSTNAME], *colon;
1755 	struct hostent *hostname;
1756 	char *vc;		/* Visual Class */
1757 	static char tmp_name[] = "/tmp/twmrcXXXXXX";
1758 	int fd;
1759 	FILE *tmpf;
1760 	char *sp;
1761 	char *getenv_res;	/* Result of a getenv() call */
1762 	Boolean tvtwm = False;
1763 
1764 	fd = mkstemp(tmp_name);		/* I *hope* mkstemp exists, because */
1765 					/* I tried to find the "portable" */
1766 					/* mktmp... */
1767 	if (fd < 0) {
1768 		perror("mkstemp failed in m4_defs");
1769 		exit(377);
1770 	}
1771 	tmpf = fdopen(fd, "w+");
1772 	XmuGetHostname(client, MAXHOSTNAME);
1773 	hostname = gethostbyname(client);
1774 	strcpy(server, XDisplayName(host));
1775 	colon = index(server, ':');
1776 	if (colon != NULL) *colon = '\0';
1777 	if ((server[0] == '\0') || (!strcmp(server, "unix")))
1778 		strcpy(server, client); /* must be connected to :0 or unix:0 */
1779 	/* The machine running the X server */
1780 	fputs(MkDef("SERVERHOST", server), tmpf);
1781 	/* The machine running the window manager process */
1782 	fputs(MkDef("CLIENTHOST", client), tmpf);
1783 	if (hostname)
1784 		fputs(MkDef("HOSTNAME", hostname->h_name), tmpf);
1785 	else
1786 		fputs(MkDef("HOSTNAME", client), tmpf);
1787 	if ((getenv_res = getenv("USER")) == NULL)
1788 	    if ((getenv_res = getenv("LOGNAME")) == NULL)
1789 		getenv_res = "nobody";
1790 	fputs(MkDef("USER", getenv_res), tmpf);
1791 	if ((getenv_res = getenv("HOME")) == NULL)
1792 	    getenv_res = ".";
1793 	fputs(MkQte("HOME", getenv_res), tmpf);
1794 	fputs(MkNum("VERSION", ProtocolVersion(display)), tmpf);
1795 	fputs(MkNum("REVISION", ProtocolRevision(display)), tmpf);
1796 	fputs(MkQte("VENDOR", ServerVendor(display)), tmpf);
1797 	fputs(MkNum("RELEASE", VendorRelease(display)), tmpf);
1798 	screen = ScreenOfDisplay(display, Scr->screen);
1799 	visual = DefaultVisualOfScreen(screen);
1800 	fputs(MkNum("WIDTH", screen->width), tmpf);
1801 	fputs(MkNum("HEIGHT", screen->height), tmpf);
1802 	fputs(MkNum("X_RESOLUTION",Resolution(screen->width,screen->mwidth)), tmpf);
1803 	fputs(MkNum("Y_RESOLUTION",Resolution(screen->height,screen->mheight)),tmpf);
1804 	fputs(MkNum("PLANES",DisplayPlanes(display, DefaultScreen(display))), tmpf);
1805 	fputs(MkNum("BITS_PER_RGB", visual->bits_per_rgb), tmpf);
1806 	for (sp=ProgramName ; sp < (ProgramName+strlen(ProgramName)-4) ; sp++)
1807 		if (!strncmp(sp, "tvtwm", 5))
1808 		    tvtwm = True;
1809 	fputs(MkDef("TWM_TYPE", tvtwm ? "tvtwm" : "twm"), tmpf);
1810 	switch(visual->class) {
1811 		case(StaticGray):	vc = "StaticGray";	break;
1812 		case(GrayScale):	vc = "GrayScale";	break;
1813 		case(StaticColor):	vc = "StaticColor";	break;
1814 		case(PseudoColor):	vc = "PseudoColor";	break;
1815 		case(TrueColor):	vc = "TrueColor";	break;
1816 		case(DirectColor):	vc = "DirectColor";	break;
1817 		default:			vc = "NonStandard";	break;
1818 	}
1819 	fputs(MkDef("CLASS", vc), tmpf);
1820 	if (visual->class != StaticGray && visual->class != GrayScale) {
1821 		fputs(MkDef("COLOR", "Yes"), tmpf);
1822 	} else {
1823 		fputs(MkDef("COLOR", "No"), tmpf);
1824 	}
1825 	fputs(MkQte("INITFILE", InitFile), tmpf);
1826 #ifdef RJC
1827 	fputs(MkDef("RJC", "Yes"), tmpf);
1828 #else
1829 	fputs(MkDef("RJC", "No"), tmpf);
1830 #endif
1831 #ifdef XPM
1832 	fputs(MkDef("XPM", "Yes"), tmpf);
1833 #else
1834 	fputs(MkDef("XPM", "No"), tmpf);
1835 #endif
1836 	/* This is prob (Eng) UMCP only... */
1837 	def_netmask(tmpf);
1838 	/* ...This is prob (Eng) UMCP only */
1839 #if 0
1840 	for(i -= 1; i >= 0; i--) {
1841 		fprintf(stderr, "%d: %s\n", i, defs[i]);
1842 	}
1843 #endif
1844 	if (KeepTmpFile) {
1845 		fprintf(stderr, "Left file: %s\n", tmp_name);
1846 	} else {
1847 		fprintf(tmpf, "syscmd(/bin/rm %s)\n", tmp_name);
1848 	}
1849 	fclose(tmpf);
1850 	return(tmp_name);
1851 }
1852 
1853 static int getmask();
1854 extern char *strtok();
1855 
1856 typedef struct {
1857 	int bitmask;
1858 	char *name;
1859 } nm;
1860 
1861 #include <grp.h>
1862 #define  NGIDS 32
1863 
1864 /* Return TRUE if in group staff... */
isstaff()1865 int isstaff()
1866 {
1867 	struct group *g;
1868 	int           i, ngids, staffg = 10;
1869 #if defined(SYSV) || defined(SVR4)
1870 	gid_t         gids[NGIDS];
1871 #else
1872 	int           gids[NGIDS];
1873 #endif
1874 
1875 	g = getgrnam("staff");
1876 	if (g) staffg = g->gr_gid;
1877 	ngids = getgroups(NGIDS, gids);
1878 	for(i = 0; i < ngids; i++) {
1879 		if (gids[i] == staffg) return(TRUE);
1880 	}
1881 	return(FALSE);
1882 }
1883 
1884 static nm names[] = {
1885 	{0x1, "EE"}, {0x2, "AE"}, {0x4, "STD"}, {0x8, "CHNU"}, {0x10, "CEME"},
1886 	{0x20, "TURB"}, {0x40, "CALCE"}, {0x80, "STAFF"}, {0x100, "ESIS"},
1887 	{0x200, "CEMESERV"}, {0x400, "EEGRAD"}, {0x800, "EMC"}, {0x1000, "ABYSS"},
1888 	{0x2000, "THORIN"}, {0x4000, "HELLAS"}, {0x8000, "FOO"}, {0x0, NULL}};
1889 
1890 /* The way this groks through the passwd file for what is a non-existant   */
1891 /* field on most systems, and the fact that the netgroups are defined as   */
1892 /* they are above, makes this code useless to other people.  It doesn't    */
1893 /* even work in engineering anymore.  Feel free to modify this segment of  */
1894 /* code, but I will be changing it in the near future so that it will work */
1895 /* here.  I might even be able to find a way to make it more usable for    */
1896 /* others.  Until then, if you should simply be able to have the name of   */
1897 /* a "staff" group setup in isstaff() and that will set all NG_* m4 defines*/
1898 /* to 'Yes'.  And, if the user is not in that group, it will set only      */
1899 /* NG_STD to 'Yes'.  Again, feel free to muck with this, but if you do,    */
1900 /* you will have to do it again.  I will get this cleaned up a bit by the  */
1901 /* next release.                                                           */
1902 /*                                      <cross@eng.umd.edu>                */
1903 
getmask()1904 static int getmask()
1905 {
1906 	int tuid;				/* target */
1907 	FILE *passwd2;
1908 	int lineno = 0;
1909 	int mask, uid, gid;
1910 #define L 150				/* Length of a line in /etc/passwd */
1911 	char line[L], bak[L];
1912 	char *uname, *pisswd, *gcos, *dir, *shell, *num, *end;
1913 	int ch;
1914 
1915 #if 0
1916     tuid = getuid();
1917     passwd2 = fopen("/usr/local/etc/passwd/passwd", "r");
1918     if (passwd2 == NULL) {
1919 #endif
1920 	if (isstaff()) return(0xffff);
1921         return(0x4);
1922 #if 0
1923     }
1924 	uid = tuid +1;
1925 	while(uid != tuid && (!feof(passwd2))) {
1926 		lineno++;
1927 		fgets(line, L, passwd2);
1928 		if (line[0] == '#') {
1929 			/* printf("%s\n", line); */
1930 			continue;
1931 		}
1932 		strcpy(bak, line);
1933 		if (NULL == (num = strtok(line, ":"))) goto err;
1934 		mask = strtol(num, &end, 16);
1935 		if (*end != '\0') goto err;
1936 		if (NULL == (uname = strtok(NULL, ":"))) goto err;
1937 		if (NULL == (pisswd = strtok(NULL, ":"))) goto err;
1938 		if (NULL == (num = strtok(NULL, ":"))) goto err;
1939 		uid = atoi(num);
1940 		if (NULL == (num = strtok(NULL, ":"))) goto err;
1941 		gid = atoi(num);
1942 #if 0
1943 /* strtok pisses me off!  Empty fields are skipped... */
1944 		if (NULL == (gcos = strtok(NULL, ":"))) goto err;
1945 		if (NULL == (dir = strtok(NULL, ":"))) goto err;
1946 		if (NULL == (shell = strtok(NULL, ""))) goto err;
1947 #endif
1948 	}
1949 	if (uid != tuid) return(0);
1950 	return(mask);
1951 err:
1952 	fprintf(stderr, "badly formed line#%d \"%s\"\n", lineno, bak);
1953 	return(0);
1954 #endif
1955 }
1956 
def_netmask(tmpf)1957 def_netmask(tmpf)
1958 FILE *tmpf;
1959 {
1960 	int mask;
1961 	char name[L];
1962 	nm *np;
1963 
1964 	mask = getmask();
1965 	for(np = names; np->bitmask != 0; np++) {
1966 		if (!(np->bitmask & mask)) continue;
1967 		sprintf(name, "NG_%s", np->name);
1968 		fputs(MkDef(name, "yes"), tmpf);
1969 	}
1970 #undef L
1971 }
1972