2
* xrdb - X resource manager database utility
4
* $Xorg: xrdb.c,v 1.6 2000/08/17 19:54:56 cpqbld Exp $
5
* $XdotOrg: app/xrdb/xrdb.c,v 1.5 2006/04/03 18:23:14 alanc Exp $
10
* DIGITAL EQUIPMENT CORPORATION
11
* MAYNARD, MASSACHUSETTS
12
* MASSACHUSETTS INSTITUTE OF TECHNOLOGY
13
* CAMBRIDGE, MASSACHUSETTS
14
* ALL RIGHTS RESERVED.
16
* THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE AND
17
* SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION.
18
* DIGITAL MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR
19
* ANY PURPOSE. IT IS SUPPLIED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
21
* IF THE SOFTWARE IS MODIFIED IN A MANNER CREATING DERIVATIVE COPYRIGHT RIGHTS,
22
* APPROPRIATE LEGENDS MAY BE PLACED ON THE DERIVATIVE WORK IN ADDITION TO THAT
26
* Permission to use, copy, modify, and distribute this software and its
27
* documentation for any purpose and without fee is hereby granted, provided
28
* that the above copyright notice appear in all copies and that both that
29
* copyright notice and this permission notice appear in supporting
30
* documentation, and that the name of Digital Equipment Corporation not be
31
* used in advertising or publicity pertaining to distribution of the software
32
* without specific, written prior permission.
34
/* $XFree86: xc/programs/xrdb/xrdb.c,v 3.16tsi Exp $ */
37
* this program is used to load, or dump the resource manager database
40
* Original Author: Jim Gettys, August 28, 1987
41
* Extensively Modified: Phil Karlton, January 5, 1987
42
* Modified a Bunch More: Bob Scheifler, February, 1991
50
#include <X11/Xutil.h>
51
#include <X11/Xatom.h>
53
#include <X11/Xmu/SysUtil.h>
60
#ifdef NEED_SYS_PARAM_H
61
# include <sys/param.h> /* defines MAXHOSTNAMELEN on BSD & Linux */
65
# include <netdb.h> /* defines MAXHOSTNAMELEN on Solaris */
68
#define SCREEN_RESOURCES "SCREEN_RESOURCES"
72
/* expected to be in path */
75
#define CPP "/usr/lib/cpp"
76
#endif /* __UNIXOS2__ */
79
#define INIT_BUFFER_SIZE 10000
80
#define INIT_ENTRY_SIZE 500
95
#define RESOURCE_PROPERTY_NAME "RESOURCE_MANAGER"
96
#define BACKUP_SUFFIX ".bak" /* for editting */
98
typedef struct _Entry {
103
typedef struct _Buffer {
107
typedef struct _Entries {
112
/* dynamically allocated strings */
113
#define CHUNK_SIZE 4096
114
typedef struct _String {
122
char *filename = NULL;
124
Bool need_real_defines = False;
131
char *editFile = NULL;
132
char *cpp_program = CPP;
133
char *backup_suffix = BACKUP_SUFFIX;
134
Bool dont_execute = False;
137
#define MAX_CMD_DEFINES 512
138
char *cmd_defines[MAX_CMD_DEFINES];
139
int num_cmd_defines = 0;
145
static void fatal(char *, ...);
146
static void addstring ( String *arg, const char *s );
147
static void FormatEntries ( Buffer *buffer, Entries *entries );
148
static void StoreProperty ( Display *dpy, Window root, Atom res_prop );
149
static void Process ( int scrno, Bool doScreen, Bool execute );
150
static void ShuffleEntries ( Entries *db, Entries *dbs, int num );
151
static void ReProcess ( int scrno, Bool doScreen );
154
InitBuffer(Buffer *b)
156
b->room = INIT_BUFFER_SIZE;
158
b->buff = (char *)malloc(INIT_BUFFER_SIZE*sizeof(char));
163
FreeBuffer(Buffer *b)
170
AppendToBuffer(Buffer *b, char *str, int len)
172
while (b->used + len > b->room) {
173
b->buff = (char *)realloc(b->buff, 2*b->room*(sizeof(char)));
176
strncpy(b->buff + b->used, str, len);
181
InitEntries(Entries *e)
183
e->room = INIT_ENTRY_SIZE;
185
e->entry = (Entry *)malloc(INIT_ENTRY_SIZE*sizeof(Entry));
189
FreeEntries(Entries *e)
193
for (i = 0; i < e->used; i++) {
194
if (e->entry[i].usable) {
195
free(e->entry[i].tag);
196
free(e->entry[i].value);
199
free((char *)e->entry);
203
AddEntry(Entries *e, Entry *entry)
207
for (n = 0; n < e->used; n++) {
208
if (!strcmp(e->entry[n].tag, entry->tag)) {
209
/* overwrite old entry */
210
if (e->entry[n].lineno && !quiet) {
212
"%s: \"%s\" on line %d overrides entry on line %d\n",
213
ProgramName, entry->tag, entry->lineno,
216
free(e->entry[n].tag);
217
free(e->entry[n].value);
218
entry->usable = True;
219
e->entry[n] = *entry;
220
return; /* ok to leave, now there's only one of each tag in db */
224
if (e->used == e->room) {
225
e->entry = (Entry *)realloc((char *)e->entry,
226
2*e->room*(sizeof(Entry)));
229
entry->usable = True;
230
e->entry[e->used++] = *entry;
235
CompareEntries(const void *e1, const void *e2)
237
return strcmp(((Entry *)e1)->tag, ((Entry *)e2)->tag);
241
AppendEntryToBuffer(Buffer *buffer, Entry *entry)
243
AppendToBuffer(buffer, entry->tag, strlen(entry->tag));
244
AppendToBuffer(buffer, ":\t", 2);
245
AppendToBuffer(buffer, entry->value, strlen(entry->value));
246
AppendToBuffer(buffer, "\n", 1);
250
* Return the position of the first unescaped occurrence of dest in string.
251
* If lines is non-null, return the number of newlines skipped over.
254
FindFirst(char *string, char dest, int *lines)
261
if (*string == '\\') {
262
if (*++string == '\0')
264
} else if (*string == dest)
266
if (*string == '\n' && lines)
273
GetEntries(Entries *entries, Buffer *buff, int bequiet)
275
register char *line, *colon, *temp, *str;
283
for ( ; str < buff->buff + buff->used;
284
str = line + 1, lineno += lines_skipped) {
285
line = FindFirst(str, '\n', &lines_skipped);
288
line = buff->buff + buff->used;
293
if (!bequiet && *str == '#') {
295
if (sscanf (str, "# %d", &dummy) == 1 ||
296
sscanf (str, "# line %d", &dummy) == 1)
301
*temp && *temp != '\n' && isascii(*temp) && isspace(*temp);
303
if (!*temp || *temp == '\n') continue;
305
colon = FindFirst(str, ':', NULL);
306
if (!colon || colon > line) {
307
if (!bequiet && !quiet)
309
"%s: colon missing on line %d, ignoring line\n",
310
ProgramName, lineno);
314
/* strip leading and trailing blanks from name and store result */
315
while (*str == ' ' || *str == '\t')
317
length = colon - str;
318
while (length && (str[length-1] == ' ' || str[length-1] == '\t'))
320
temp = (char *)malloc(length + 1);
321
strncpy(temp, str, length);
325
/* strip leading and trailing blanks from value and store result */
327
while (*colon == ' ' || *colon == '\t')
329
length = line - colon;
330
temp = (char *)malloc(length + 1);
331
strncpy(temp, colon, length);
334
entry.lineno = bequiet ? 0 : lineno;
336
AddEntry(entries, &entry);
341
GetEntriesString(Entries *entries, char *str)
347
buff.used = strlen(str);
348
GetEntries(entries, &buff, 1);
353
ReadFile(Buffer *buffer, FILE *input)
355
char buf[BUFSIZ + 1];
359
while (!feof(input) && (bytes = fread(buf, 1, BUFSIZ, input)) > 0) {
363
for (p = buf; p = strchr(p, '\r'); ) {
364
if (p[-1] == '\\' && p[1] == '\n') {
366
strcpy(p - 1, p + 2);
370
AppendToBuffer(buffer, buf, bytes);
372
AppendToBuffer(buffer, "", 1);
376
AddDef(String *buff, char *title, char *value)
379
if (need_real_defines) {
380
addstring(buff, "\n#define ");
381
addstring(buff, title);
382
if (value && (value[0] != '\0')) {
383
addstring(buff, " ");
384
addstring(buff, value);
390
if (oper == OPSYMBOLS)
391
addstring(buff, "\n-D");
393
addstring(buff, " -D");
395
addstring(buff, "-D");
396
addstring(buff, title);
397
if (value && (value[0] != '\0')) {
398
addstring(buff, "=");
399
addstring(buff, value);
404
AddDefQ(String *buff, char *title, char *value)
407
if (need_real_defines)
408
AddDef(buff, title, value);
411
if (value && (value[0] != '\0')) {
412
AddDef(buff, title, "\"");
413
addstring(buff, value);
414
addstring(buff, "\"");
416
AddDef(buff, title, NULL);
420
AddNum(String *buff, char *title, int value)
423
snprintf(num, sizeof(num), "%d", value);
424
AddDef(buff, title, num);
428
AddSimpleDef(String *buff, char *title)
430
AddDef(buff, title, (char *)NULL);
434
AddDefTok(String *buff, char *prefix, char *title)
440
snprintf(name, sizeof(name), "%s%s", prefix, title);
441
for (s = name; (c = *s); s++) {
442
if (!isalpha(c) && !isdigit(c) && c != '_')
445
AddSimpleDef(buff, name);
449
AddUndef(String *buff, char *title)
452
if (need_real_defines) {
453
addstring(buff, "\n#undef ");
454
addstring(buff, title);
459
if (oper == OPSYMBOLS)
460
addstring(buff, "\n-U");
462
addstring(buff, " -U");
464
addstring(buff, "-U");
465
addstring(buff, title);
469
DoCmdDefines(String *buff)
474
for (i = 0; i < num_cmd_defines; i++) {
475
arg = cmd_defines[i];
477
val = strchr(arg, '=');
480
AddDefQ(buff, arg + 2, val + 1);
483
AddSimpleDef(buff, arg + 2);
485
AddUndef(buff, arg + 2);
490
Resolution(int pixels, int mm)
492
return ((pixels * 100000 / mm) + 50) / 100;
497
DoDisplayDefines(Display *display, String *defs, char *host)
499
#ifndef MAXHOSTNAMELEN
500
#define MAXHOSTNAMELEN 255
502
char client[MAXHOSTNAMELEN], server[MAXHOSTNAMELEN], *colon;
506
XmuGetHostname(client, MAXHOSTNAMELEN);
507
strncpy(server, XDisplayName(host), sizeof(server));
508
server[sizeof(server) - 1] = '\0';
509
/* search for final colon to skip over any embedded colons in IPv6
510
numeric address forms */
511
colon = strrchr(server, ':');
514
/* remove extra colon if there are exactly two, since it indicates
515
DECnet. Three colons is an IPv6 address ending in :: though. */
516
if ((colon > server) && (*(colon-1) == ':') &&
517
( ((colon - 1) == server) || (*(colon-2) != ':') ) ) {
521
sscanf(colon, "%d", &n);
523
if (!*server || !strcmp(server, "unix") || !strcmp(server, "localhost"))
524
strcpy(server, client);
525
AddDef(defs, "HOST", server); /* R3 compatibility */
526
AddDef(defs, "SERVERHOST", server);
527
AddDefTok(defs, "SRVR_", server);
528
AddNum(defs, "DISPLAY_NUM", n);
529
AddDef(defs, "CLIENTHOST", client);
530
AddDefTok(defs, "CLNT_", client);
531
AddNum(defs, "VERSION", ProtocolVersion(display));
532
AddNum(defs, "REVISION", ProtocolRevision(display));
533
AddDefQ(defs, "VENDOR", ServerVendor(display));
534
AddDefTok(defs, "VNDR_", ServerVendor(display));
535
AddNum(defs, "RELEASE", VendorRelease(display));
536
AddNum(defs, "NUM_SCREENS", ScreenCount(display));
537
extnames = XListExtensions(display, &n);
539
AddDefTok(defs, "EXT_", extnames[n]);
540
XFreeExtensionList(extnames);
543
char *ClassNames[] = {
553
DoScreenDefines(Display *display, int scrno, String *defs)
557
XVisualInfo vinfo, *vinfos;
561
screen = ScreenOfDisplay(display, scrno);
562
visual = DefaultVisualOfScreen(screen);
563
vinfo.screen = scrno;
564
vinfos = XGetVisualInfo(display, VisualScreenMask, &vinfo, &nv);
565
AddNum(defs, "SCREEN_NUM", scrno);
566
AddNum(defs, "WIDTH", screen->width);
567
AddNum(defs, "HEIGHT", screen->height);
568
AddNum(defs, "X_RESOLUTION", Resolution(screen->width,screen->mwidth));
569
AddNum(defs, "Y_RESOLUTION", Resolution(screen->height,screen->mheight));
570
AddNum(defs, "PLANES", DisplayPlanes(display, scrno));
571
AddNum(defs, "BITS_PER_RGB", visual->bits_per_rgb);
572
AddDef(defs, "CLASS", ClassNames[visual->class]);
573
snprintf(name, sizeof(name), "CLASS_%s", ClassNames[visual->class]);
574
AddNum(defs, name, (int)visual->visualid);
575
switch(visual->class) {
580
AddSimpleDef(defs, "COLOR");
583
for (i = 0; i < nv; i++) {
584
for (j = i; --j >= 0; ) {
585
if (vinfos[j].class == vinfos[i].class &&
586
vinfos[j].depth == vinfos[i].depth)
590
snprintf(name, sizeof(name), "CLASS_%s_%d",
591
ClassNames[vinfos[i].class], vinfos[i].depth);
592
AddNum(defs, name, (int)vinfos[i].visualid);
595
XFree((char *)vinfos);
599
FindEntry(Entries *db, Buffer *b)
606
entry.usable = False;
611
phoney.entry = &entry;
612
GetEntries(&phoney, b, 1);
615
for (i = 0; i < db->used; i++) {
619
if (strcmp(e->tag, entry.tag))
622
if (strcmp(e->value, entry.value))
630
EditFile(Entries *new, FILE *in, FILE *out)
643
if (!fgets(buff, BUFSIZ, in))
645
AppendToBuffer(&b, buff, strlen(buff));
646
c = &b.buff[b.used - 1];
647
if ((*(c--) == '\n') && (b.used == 1 || *c != '\\'))
650
if ((e = FindEntry(new, &b)))
651
fprintf(out, "%s:\t%s\n", e->tag, e->value);
653
fwrite(b.buff, 1, b.used, out);
656
for (i = 0; i < new->used; i++) {
659
fprintf(out, "%s:\t%s\n", e->tag, e->value);
667
"usage: %s [-options ...] [filename]\n\n",
670
"where options include:\n");
672
" -display host:dpy display to use\n");
674
" -all do all resources [default]\n");
676
" -global do screen-independent resources\n");
678
" -screen do screen-specific resources for one screen\n");
680
" -screens do screen-specific resources for all screens\n");
682
" -n show but don't do changes\n");
684
" -cpp filename preprocessor to use [%s]\n",
687
" -nocpp do not use a preprocessor\n");
689
" -query query resources\n");
691
" -load load resources from file [default]\n");
693
" -override add in resources from file\n");
695
" -merge merge resources from file & sort\n");
697
" -edit filename edit resources into file\n");
699
" -backup string backup suffix for -edit [%s]\n",
702
" -symbols show preprocessor symbols\n");
704
" -remove remove resources\n");
706
" -retain avoid server reset (avoid using this)\n");
708
" -quiet don't warn about duplicates\n");
710
" -Dname[=value], -Uname, -Idirectory %s\n",
711
"passed to preprocessor");
715
"A - or no input filename represents stdin.\n");
720
* The following is a hack until XrmParseCommand is ready. It determines
721
* whether or not the given string is an abbreviation of the arg.
725
isabbreviation(char *arg, char *s, int minslen)
731
if (!strcmp (arg, s)) return (True);
733
arglen = strlen (arg);
736
/* too long or too short */
737
if (slen >= arglen || slen < minslen) return (False);
740
if (strncmp (arg, s, slen) == 0) return (True);
747
addstring(String *arg, const char *s)
749
if(arg->used + strlen(s) + 1 >= arg->room) {
751
arg->val = (char *)realloc(arg->val, arg->room + CHUNK_SIZE);
753
arg->val = (char *)malloc(arg->room + CHUNK_SIZE);
755
fatal("%s: Not enough memory\n", ProgramName);
756
arg->room += CHUNK_SIZE;
762
arg->used += strlen(s);
767
main(int argc, char *argv[])
770
char *displayname = NULL;
771
int whichResources = RALL;
776
ProgramName = argv[0];
778
defines.room = defines.used = includes.room = includes.used = 0;
780
/* initialize the includes String struct */
781
addstring(&includes, "");
783
/* needs to be replaced with XrmParseCommand */
785
for (i = 1; i < argc; i++) {
789
if (arg[1] == '\0') {
792
} else if (isabbreviation ("-help", arg, 2)) {
795
} else if (isabbreviation ("-display", arg, 2)) {
796
if (++i >= argc) Syntax ();
797
displayname = argv[i];
799
} else if (isabbreviation ("-geometry", arg, 3)) {
800
if (++i >= argc) Syntax ();
801
/* ignore geometry */
803
} else if (isabbreviation ("-cpp", arg, 2)) {
804
if (++i >= argc) Syntax ();
805
cpp_program = argv[i];
807
} else if (!strcmp ("-n", arg)) {
810
} else if (isabbreviation ("-nocpp", arg, 3)) {
813
} else if (isabbreviation ("-query", arg, 2)) {
816
} else if (isabbreviation ("-load", arg, 2)) {
819
} else if (isabbreviation ("-merge", arg, 2)) {
822
} else if (isabbreviation ("-override", arg, 2)) {
825
} else if (isabbreviation ("-symbols", arg, 3)) {
828
} else if (isabbreviation ("-remove", arg, 4)) {
831
} else if (isabbreviation ("-edit", arg, 2)) {
832
if (++i >= argc) Syntax ();
836
} else if (isabbreviation ("-backup", arg, 2)) {
837
if (++i >= argc) Syntax ();
838
backup_suffix = argv[i];
840
} else if (isabbreviation ("-all", arg, 2)) {
841
whichResources = RALL;
843
} else if (isabbreviation ("-global", arg, 3)) {
844
whichResources = RGLOBAL;
846
} else if (isabbreviation ("-screen", arg, 3)) {
847
whichResources = RSCREEN;
849
} else if (!strcmp ("-screens", arg)) {
850
whichResources = RSCREENS;
852
} else if (isabbreviation ("-retain", arg, 4)) {
855
} else if (isabbreviation ("-quiet", arg, 2)) {
858
} else if (arg[1] == 'I') {
859
addstring(&includes, " ");
860
addstring(&includes, arg);
862
} else if (arg[1] == 'U' || arg[1] == 'D') {
863
if (num_cmd_defines < MAX_CMD_DEFINES) {
864
cmd_defines[num_cmd_defines++] = arg;
866
fatal("%s: Too many -U/-D arguments\n", ProgramName);
871
} else if (arg[0] == '=')
878
while ((i = open("/dev/null", O_RDONLY)) < 3)
879
; /* make sure later freopen won't clobber things */
883
if (!(dpy = XOpenDisplay (displayname)))
884
fatal("%s: Can't open display '%s'\n", ProgramName,
885
XDisplayName (displayname));
887
if (whichResources == RALL && ScreenCount(dpy) == 1)
888
whichResources = RGLOBAL;
892
(oper == OPLOAD || oper == OPMERGE || oper == OPOVERRIDE)) {
893
need_real_defines = True;
895
strcpy(tmpname2, "xrdbD_XXXXXX");
896
strcpy(tmpname3, "\\temp\\xrdbD_XXXXXX");
899
{ char *tmpdir=getenv("TMP");
900
if (!tmpdir) tmpdir="/";
901
sprintf(tmpname2, "%s/xrdbD_XXXXXX",tmpdir);
904
strcpy(tmpname2, "/tmp/xrdbD_XXXXXX");
907
(void) mktemp(tmpname2);
915
(oper == OPLOAD || oper == OPMERGE || oper == OPOVERRIDE) &&
916
(whichResources == RALL || whichResources == RSCREENS)
921
strcpy(tmpname, "\\temp\\xrdb_XXXXXX");
924
{ char *tmpdir=getenv("TMP");
925
if (!tmpdir) tmpdir="/";
926
sprintf(tmpname, "%s/xrdb_XXXXXX",tmpdir);
929
strcpy(tmpname, "/tmp/xrdb_XXXXXX");
933
(void) mktemp(tmpname);
935
fp = fopen(filename, "w");
938
int fd = mkstemp(tmpname);
940
fp = fdopen(fd, "w");
944
fatal("%s: Failed to open temp file: %s\n", ProgramName,
946
while (fgets(inputbuf, sizeof(inputbuf), stdin) != NULL)
951
DoDisplayDefines(dpy, &defines, displayname);
952
defines_base = defines.used;
953
need_newline = (oper == OPQUERY || oper == OPSYMBOLS ||
954
(dont_execute && oper != OPREMOVE));
956
if (whichResources == RGLOBAL)
957
Process(DefaultScreen(dpy), False, True);
958
else if (whichResources == RSCREEN)
959
Process(DefaultScreen(dpy), True, True);
960
else if (whichResources == RSCREENS ||
961
(oper != OPLOAD && oper != OPMERGE && oper != OPOVERRIDE)) {
962
if (whichResources == RALL && oper != OPSYMBOLS) {
964
printf("! screen-independent resources\n");
965
Process(0, False, True);
969
for (i = 0; i < ScreenCount(dpy); i++) {
971
if (oper == OPSYMBOLS)
972
printf("# screen %d symbols\n", i);
974
printf("! screen %d resources\n", i);
975
printf("#if SCREEN_NUM == %d\n", i);
978
Process(i, True, True);
980
if (oper != OPSYMBOLS)
982
if (i+1 != ScreenCount(dpy))
990
dbs = (Entries *)malloc(ScreenCount(dpy) * sizeof(Entries));
991
for (i = 0; i < ScreenCount(dpy); i++) {
992
Process(i, True, False);
996
if (oper == OPMERGE || oper == OPOVERRIDE)
997
GetEntriesString(&newDB, XResourceManagerString(dpy));
998
ShuffleEntries(&newDB, dbs, ScreenCount(dpy));
1000
printf("! screen-independent resources\n");
1001
ReProcess(0, False);
1004
for (i = 0; i < ScreenCount(dpy); i++) {
1007
printf("! screen %d resources\n", i);
1008
printf("#if SCREEN_NUM == %d\n", i);
1013
if (i+1 != ScreenCount(dpy))
1022
XSetCloseDownMode(dpy, RetainPermanent);
1029
FormatEntries(Buffer *buffer, Entries *entries)
1036
if (oper == OPMERGE)
1037
qsort(entries->entry, entries->used, sizeof(Entry),
1039
for (i = 0; i < entries->used; i++) {
1040
if (entries->entry[i].usable)
1041
AppendEntryToBuffer(buffer, &entries->entry[i]);
1046
StoreProperty(Display *dpy, Window root, Atom res_prop)
1048
int len = buffer.used;
1049
int mode = PropModeReplace;
1050
unsigned char *buf = (unsigned char *)buffer.buff;
1051
int max = (XMaxRequestSize(dpy) << 2) - 28;
1056
XChangeProperty(dpy, root, res_prop, XA_STRING, 8, mode, buf, max);
1059
mode = PropModeAppend;
1060
} while (len > max);
1062
XChangeProperty(dpy, root, res_prop, XA_STRING, 8, mode, buf, len);
1063
if (mode != PropModeReplace)
1068
Process(int scrno, Bool doScreen, Bool execute)
1073
FILE *input, *output;
1076
defines.val[defines_base] = '\0';
1077
defines.used = defines_base;
1079
InitEntries(&newDB);
1080
DoScreenDefines(dpy, scrno, &defines);
1081
DoCmdDefines(&defines);
1083
xdefs = XScreenResourceString (ScreenOfDisplay(dpy, scrno));
1084
root = RootWindow(dpy, scrno);
1085
res_prop = XInternAtom(dpy, SCREEN_RESOURCES, False);
1087
xdefs = XResourceManagerString (dpy);
1088
root = RootWindow(dpy, 0);
1089
res_prop = XA_RESOURCE_MANAGER;
1091
if (oper == OPSYMBOLS) {
1092
printf ("%s\n", defines.val);
1093
} else if (oper == OPQUERY) {
1095
printf ("%s", xdefs); /* fputs broken in SunOS 4.0 */
1096
} else if (oper == OPREMOVE) {
1098
XDeleteProperty(dpy, root, res_prop);
1099
} else if (oper == OPEDIT) {
1100
char template[100], old[100];
1102
input = fopen(editFile, "r");
1103
snprintf(template, sizeof(template), "%sXXXXXX", editFile);
1105
(void) mktemp(template);
1106
output = fopen(template, "w");
1109
int fd = mkstemp(template);
1110
output = fdopen(fd, "w");
1114
fatal("%s: can't open temporary file '%s'\n", ProgramName, template);
1115
GetEntriesString(&newDB, xdefs);
1116
EditFile(&newDB, input, output);
1120
snprintf(old, sizeof(old), "%s%s", editFile, backup_suffix);
1121
if (dont_execute) { /* then write to standard out */
1125
output = fopen (template, "r");
1127
while ((n = fread (buf, 1, sizeof buf, output)) > 0) {
1128
fwrite (buf, 1, n, stdout);
1134
rename (editFile, old);
1135
if (rename (template, editFile))
1136
fatal("%s: can't rename file '%s' to '%s'\n", ProgramName,
1137
template, editFile);
1140
if (oper == OPMERGE || oper == OPOVERRIDE)
1141
GetEntriesString(&newDB, xdefs);
1143
if (need_real_defines) {
1145
if (!(input = fopen(tmpname2, "w")))
1146
fatal("%s: can't open file '%s'\n", ProgramName, tmpname2);
1147
fputs(defines.val, input);
1148
fprintf(input, "\n#include \"%s\"\n", filename);
1150
(void) mktemp(tmpname3);
1152
malloc(strlen(cpp_program) + strlen(includes.val) +
1153
1 + strlen(tmpname2) + 3 + strlen(tmpname3) + 1)) ==
1155
fatal("%s: Out of memory\n", ProgramName);
1156
sprintf(cmd, "%s%s %s > %s", cpp_program, includes.val,
1157
tmpname2, tmpname3);
1158
if (system(cmd) < 0)
1159
fatal("%s: cannot run '%s'\n", ProgramName, cmd);
1161
if (!(input = fopen(tmpname3, "r")))
1162
fatal("%s: can't open file '%s'\n", ProgramName, tmpname3);
1164
if (!freopen(tmpname2, "w+", stdin))
1165
fatal("%s: can't open file '%s'\n", ProgramName, tmpname2);
1166
fputs(defines.val, stdin);
1167
fprintf(stdin, "\n#include \"%s\"\n", filename);
1171
malloc(strlen(cpp_program) + strlen(includes.val) + 1)) ==
1173
fatal("%s: Out of memory\n", ProgramName);
1174
sprintf(cmd, "%s%s", cpp_program, includes.val);
1175
if (!(input = popen(cmd, "r")))
1176
fatal("%s: cannot run '%s'\n", ProgramName, cmd);
1182
if (!freopen (filename, "r", stdin))
1183
fatal("%s: can't open file '%s'\n", ProgramName, filename);
1187
(void) mktemp(tmpname3);
1189
malloc(strlen(cpp_program) + strlen(includes.val) +
1190
1 + strlen(defines.val) + 1 +
1191
strlen(filename ? filename : "") + 3 +
1192
strlen(tmpname3) + 1)) ==
1194
fatal("%s: Out of memory\n", ProgramName);
1195
sprintf(cmd, "%s%s %s %s > %s", cpp_program,
1196
includes.val, defines.val,
1197
filename ? filename : "", tmpname3);
1198
if (system(cmd) < 0)
1199
fatal("%s: cannot run '%s'\n", ProgramName, cmd);
1201
if (!(input = fopen(tmpname3, "r")))
1202
fatal("%s: can't open file '%s'\n", ProgramName, tmpname3);
1205
malloc(strlen(cpp_program) + strlen(includes.val) + 1 +
1206
strlen(defines.val) + 1)) ==
1208
fatal("%s: Out of memory\n", ProgramName);
1209
sprintf(cmd, "%s%s %s", cpp_program, includes.val, defines.val);
1210
if (!(input = popen(cmd, "r")))
1211
fatal("%s: cannot run '%s'\n", ProgramName, cmd);
1220
ReadFile(&buffer, input);
1229
if (need_real_defines) {
1232
if (tmpname3[strlen(tmpname3) - 1] != 'X')
1237
GetEntries(&newDB, &buffer, 0);
1239
FormatEntries(&buffer, &newDB);
1241
if (buffer.used > 0) {
1242
fwrite (buffer.buff, 1, buffer.used, stdout);
1243
if (buffer.buff[buffer.used - 1] != '\n') putchar ('\n');
1245
} else if (buffer.used > 1 || !doScreen)
1246
StoreProperty (dpy, root, res_prop);
1248
XDeleteProperty (dpy, root, res_prop);
1252
FreeEntries(&newDB);
1253
if (doScreen && xdefs)
1258
ShuffleEntries(Entries *db, Entries *dbs, int num)
1261
register int i, j, k;
1263
char *curtag, *curvalue;
1265
hits = (int *)malloc(num * sizeof(int));
1267
for (i = 0; i < cur.used; i++) {
1268
curtag = cur.entry[i].tag;
1269
curvalue = cur.entry[i].value;
1270
for (j = 1; j < num; j++) {
1272
for (k = 0; k < cmp.used; k++) {
1273
if (cmp.entry[k].usable &&
1274
!strcmp(curtag, cmp.entry[k].tag) &&
1275
!strcmp(curvalue, cmp.entry[k].value))
1285
AddEntry(db, &cur.entry[i]);
1287
for (j = 0; j < num; j++)
1288
dbs[j].entry[hits[j]].usable = False;
1295
ReProcess(int scrno, Bool doScreen)
1300
FormatEntries(&buffer, &newDB);
1302
root = RootWindow(dpy, scrno);
1303
res_prop = XInternAtom(dpy, SCREEN_RESOURCES, False);
1305
root = RootWindow(dpy, 0);
1306
res_prop = XA_RESOURCE_MANAGER;
1309
if (buffer.used > 0) {
1310
fwrite (buffer.buff, 1, buffer.used, stdout);
1311
if (buffer.buff[buffer.used - 1] != '\n') putchar ('\n');
1314
if (buffer.used > 1 || !doScreen)
1315
StoreProperty (dpy, root, res_prop);
1317
XDeleteProperty (dpy, root, res_prop);
1319
FreeEntries(&newDB);
1323
fatal(char *msg, ...)
1328
perror(ProgramName);
1329
va_start(args, msg);
1330
vfprintf(stderr, msg, args);