File: | xkbcomp.c |
Location: | line 1044, column 35 |
Description: | Access to field 'flags' results in a dereference of a null pointer (loaded from field 'xkb') |
1 | /************************************************************ | |||
2 | Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. | |||
3 | ||||
4 | Permission to use, copy, modify, and distribute this | |||
5 | software and its documentation for any purpose and without | |||
6 | fee is hereby granted, provided that the above copyright | |||
7 | notice appear in all copies and that both that copyright | |||
8 | notice and this permission notice appear in supporting | |||
9 | documentation, and that the name of Silicon Graphics not be | |||
10 | used in advertising or publicity pertaining to distribution | |||
11 | of the software without specific prior written permission. | |||
12 | Silicon Graphics makes no representation about the suitability | |||
13 | of this software for any purpose. It is provided "as is" | |||
14 | without any express or implied warranty. | |||
15 | ||||
16 | SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS | |||
17 | SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY | |||
18 | AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON | |||
19 | GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL | |||
20 | DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, | |||
21 | DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE | |||
22 | OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH | |||
23 | THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||
24 | ||||
25 | ********************************************************/ | |||
26 | ||||
27 | #include <stdio.h> | |||
28 | #include <ctype.h> | |||
29 | #include <X11/keysym.h> | |||
30 | ||||
31 | /* for symlink attack security fix -- Branden Robinson */ | |||
32 | #include <sys/stat.h> | |||
33 | #include <sys/types.h> | |||
34 | #include <unistd.h> | |||
35 | /* end BR */ | |||
36 | ||||
37 | #if defined(sgi) | |||
38 | #include <malloc.h> | |||
39 | #endif | |||
40 | ||||
41 | #define DEBUG_VARdebugFlags debugFlags | |||
42 | #include "xkbcomp.h" | |||
43 | #include <stdlib.h> | |||
44 | #include "xkbpath.h" | |||
45 | #include "parseutils.h" | |||
46 | #include "misc.h" | |||
47 | #include "tokens.h" | |||
48 | #include <X11/extensions/XKBgeom.h> | |||
49 | ||||
50 | ||||
51 | #ifdef WIN32 | |||
52 | #define S_IRGRP0000040 0 | |||
53 | #define S_IWGRP0000020 0 | |||
54 | #define S_IROTH0000004 0 | |||
55 | #define S_IWOTH0000002 0 | |||
56 | #endif | |||
57 | ||||
58 | #define lowbit(x)((x) & (-(x))) ((x) & (-(x))) | |||
59 | ||||
60 | /***====================================================================***/ | |||
61 | ||||
62 | #define WANT_DEFAULT0 0 | |||
63 | #define WANT_XKM_FILE1 1 | |||
64 | #define WANT_C_HDR2 2 | |||
65 | #define WANT_XKB_FILE3 3 | |||
66 | #define WANT_X_SERVER4 4 | |||
67 | #define WANT_LISTING5 5 | |||
68 | ||||
69 | #define INPUT_UNKNOWN0 0 | |||
70 | #define INPUT_XKB1 1 | |||
71 | #define INPUT_XKM2 2 | |||
72 | ||||
73 | unsigned int debugFlags; | |||
74 | ||||
75 | static const char *fileTypeExt[] = { | |||
76 | "XXX", | |||
77 | "xkm", | |||
78 | "h", | |||
79 | "xkb", | |||
80 | "dir" | |||
81 | }; | |||
82 | ||||
83 | static unsigned inputFormat, outputFormat; | |||
84 | char *rootDir; | |||
85 | static char *inputFile; | |||
86 | static char *inputMap; | |||
87 | static char *outputFile; | |||
88 | static char *inDpyName; | |||
89 | static char *outDpyName; | |||
90 | static Display *inDpy; | |||
91 | static Display *outDpy; | |||
92 | static Boolint showImplicit = False0; | |||
93 | static Boolint synch = False0; | |||
94 | static Boolint computeDflts = False0; | |||
95 | static Boolint xkblist = False0; | |||
96 | unsigned warningLevel = 5; | |||
97 | unsigned verboseLevel = 0; | |||
98 | unsigned dirsToStrip = 0; | |||
99 | unsigned optionalParts = 0; | |||
100 | static char *preErrorMsg = NULL((void*)0); | |||
101 | static char *postErrorMsg = NULL((void*)0); | |||
102 | static char *errorPrefix = NULL((void*)0); | |||
103 | static unsigned int device_id = XkbUseCoreKbd0x0100; | |||
104 | ||||
105 | /***====================================================================***/ | |||
106 | ||||
107 | #define M(m)fprintf(__stderrp,(m)) fprintf(stderr__stderrp,(m)) | |||
108 | #define M1(m,a)fprintf(__stderrp,(m),(a)) fprintf(stderr__stderrp,(m),(a)) | |||
109 | ||||
110 | static void | |||
111 | Usage(int argc, char *argv[]) | |||
112 | { | |||
113 | if (!xkblist) | |||
114 | M1("Usage: %s [options] input-file [ output-file ]\n", argv[0])fprintf(__stderrp,("Usage: %s [options] input-file [ output-file ]\n" ),(argv[0])); | |||
115 | else | |||
116 | M1("Usage: %s [options] file[(map)] ...\n", argv[0])fprintf(__stderrp,("Usage: %s [options] file[(map)] ...\n"),( argv[0])); | |||
117 | M("Legal options:\n")fprintf(__stderrp,("Legal options:\n")); | |||
118 | M("-?,-help Print this message\n")fprintf(__stderrp,("-?,-help Print this message\n" )); | |||
119 | M("-version Print the version number\n")fprintf(__stderrp,("-version Print the version number\n" )); | |||
120 | if (!xkblist) | |||
121 | { | |||
122 | M("-a Show all actions\n")fprintf(__stderrp,("-a Show all actions\n") ); | |||
123 | M("-C Create a C header file\n")fprintf(__stderrp,("-C Create a C header file\n" )); | |||
124 | } | |||
125 | #ifdef DEBUG | |||
126 | M("-d [flags] Report debugging information\n")fprintf(__stderrp,("-d [flags] Report debugging information\n" )); | |||
127 | #endif | |||
128 | M("-em1 <msg> Print <msg> before printing first error message\n")fprintf(__stderrp,("-em1 <msg> Print <msg> before printing first error message\n" )); | |||
129 | M("-emp <msg> Print <msg> at the start of each message line\n")fprintf(__stderrp,("-emp <msg> Print <msg> at the start of each message line\n" )); | |||
130 | M("-eml <msg> If there were any errors, print <msg> before exiting\n")fprintf(__stderrp,("-eml <msg> If there were any errors, print <msg> before exiting\n" )); | |||
131 | if (!xkblist) | |||
132 | { | |||
133 | M("-dflts Compute defaults for missing parts\n")fprintf(__stderrp,("-dflts Compute defaults for missing parts\n" )); | |||
134 | M("-I[<dir>] Specifies a top level directory for include\n")fprintf(__stderrp,("-I[<dir>] Specifies a top level directory for include\n" )); | |||
135 | M(" directives. Multiple directories are legal.\n")fprintf(__stderrp,(" directives. Multiple directories are legal.\n" )); | |||
136 | M("-l [flags] List matching maps in the specified files\n")fprintf(__stderrp,("-l [flags] List matching maps in the specified files\n" )); | |||
137 | M(" f: list fully specified names\n")fprintf(__stderrp,(" f: list fully specified names\n" )); | |||
138 | M(" h: also list hidden maps\n")fprintf(__stderrp,(" h: also list hidden maps\n" )); | |||
139 | M(" l: long listing (show flags)\n")fprintf(__stderrp,(" l: long listing (show flags)\n" )); | |||
140 | M(" p: also list partial maps\n")fprintf(__stderrp,(" p: also list partial maps\n" )); | |||
141 | M(" R: recursively list subdirectories\n")fprintf(__stderrp,(" R: recursively list subdirectories\n" )); | |||
142 | M(" default is all options off\n")fprintf(__stderrp,(" default is all options off\n" )); | |||
143 | } | |||
144 | M("-i <deviceid> Specifies device ID (not name) to compile for\n")fprintf(__stderrp,("-i <deviceid> Specifies device ID (not name) to compile for\n" )); | |||
145 | M("-m[ap] <map> Specifies map to compile\n")fprintf(__stderrp,("-m[ap] <map> Specifies map to compile\n" )); | |||
146 | M("-o <file> Specifies output file name\n")fprintf(__stderrp,("-o <file> Specifies output file name\n" )); | |||
147 | if (!xkblist) | |||
148 | { | |||
149 | M("-opt[ional] <parts> Specifies optional components of keymap\n")fprintf(__stderrp,("-opt[ional] <parts> Specifies optional components of keymap\n" )); | |||
150 | M(" Errors in optional parts are not fatal\n")fprintf(__stderrp,(" Errors in optional parts are not fatal\n" )); | |||
151 | M(" <parts> can be any combination of:\n")fprintf(__stderrp,(" <parts> can be any combination of:\n" )); | |||
152 | M(" c: compat map g: geometry\n")fprintf(__stderrp,(" c: compat map g: geometry\n" )); | |||
153 | M(" k: keycodes s: symbols\n")fprintf(__stderrp,(" k: keycodes s: symbols\n" )); | |||
154 | M(" t: types\n")fprintf(__stderrp,(" t: types\n")); | |||
155 | } | |||
156 | if (xkblist) | |||
157 | { | |||
158 | M("-p <count> Specifies the number of slashes to be stripped\n")fprintf(__stderrp,("-p <count> Specifies the number of slashes to be stripped\n" )); | |||
159 | M(" from the front of the map name on output\n")fprintf(__stderrp,(" from the front of the map name on output\n" )); | |||
160 | } | |||
161 | M("-R[<DIR>] Specifies the root directory for\n")fprintf(__stderrp,("-R[<DIR>] Specifies the root directory for\n" )); | |||
162 | M(" relative path names\n")fprintf(__stderrp,(" relative path names\n" )); | |||
163 | M("-synch Force synchronization\n")fprintf(__stderrp,("-synch Force synchronization\n" )); | |||
164 | if (xkblist) | |||
165 | { | |||
166 | M("-v [<flags>] Set level of detail for listing.\n")fprintf(__stderrp,("-v [<flags>] Set level of detail for listing.\n" )); | |||
167 | M(" flags are as for the -l option\n")fprintf(__stderrp,(" flags are as for the -l option\n" )); | |||
168 | } | |||
169 | M("-w [<lvl>] Set warning level (0=none, 10=all)\n")fprintf(__stderrp,("-w [<lvl>] Set warning level (0=none, 10=all)\n" )); | |||
170 | if (!xkblist) | |||
171 | { | |||
172 | M("-xkb Create an XKB source (.xkb) file\n")fprintf(__stderrp,("-xkb Create an XKB source (.xkb) file\n" )); | |||
173 | M("-xkm Create a compiled key map (.xkm) file\n")fprintf(__stderrp,("-xkm Create a compiled key map (.xkm) file\n" )); | |||
174 | } | |||
175 | return; | |||
176 | } | |||
177 | ||||
178 | /***====================================================================***/ | |||
179 | ||||
180 | static void | |||
181 | setVerboseFlags(char *str) | |||
182 | { | |||
183 | for (; *str; str++) | |||
184 | { | |||
185 | switch (*str) | |||
186 | { | |||
187 | case 'f': | |||
188 | verboseLevel |= WantFullNames(1<<3); | |||
189 | break; | |||
190 | case 'h': | |||
191 | verboseLevel |= WantHiddenMaps(1<<2); | |||
192 | break; | |||
193 | case 'l': | |||
194 | verboseLevel |= WantLongListing(1<<0); | |||
195 | break; | |||
196 | case 'p': | |||
197 | verboseLevel |= WantPartialMaps(1<<1); | |||
198 | break; | |||
199 | case 'R': | |||
200 | verboseLevel |= ListRecursive(1<<4); | |||
201 | break; | |||
202 | default: | |||
203 | if (warningLevel > 4) | |||
204 | { | |||
205 | WARN1uWarning("Unknown verbose option \"%c\"\n", (unsigned int) *str); | |||
206 | ACTIONuAction("Ignored\n"); | |||
207 | } | |||
208 | break; | |||
209 | } | |||
210 | } | |||
211 | return; | |||
212 | } | |||
213 | ||||
214 | static Boolint | |||
215 | parseArgs(int argc, char *argv[]) | |||
216 | { | |||
217 | register int i, tmp; | |||
218 | ||||
219 | i = strlen(argv[0]); | |||
220 | tmp = strlen("xkblist"); | |||
221 | if ((i >= tmp) && (strcmp(&argv[0][i - tmp], "xkblist") == 0)) | |||
222 | { | |||
223 | xkblist = True1; | |||
224 | } | |||
225 | for (i = 1; i < argc; i++) | |||
226 | { | |||
227 | int itmp; | |||
228 | if ((argv[i][0] != '-') || (uStringEqual(argv[i], "-")((((argv[i])==((char *)((void*)0))||("-")==((char *)((void*)0 )))? (argv[i])!=("-"):strcmp(argv[i],"-"))==((Comparison)0)))) | |||
229 | { | |||
230 | if (!xkblist) | |||
231 | { | |||
232 | if (inputFile == NULL((void*)0)) | |||
233 | inputFile = argv[i]; | |||
234 | else if (outputFile == NULL((void*)0)) | |||
235 | outputFile = argv[i]; | |||
236 | else if (warningLevel > 0) | |||
237 | { | |||
238 | WARNuWarning("Too many file names on command line\n"); | |||
239 | ACTION3uAction | |||
240 | ("Compiling %s, writing to %s, ignoring %s\n", | |||
241 | inputFile, outputFile, argv[i]); | |||
242 | } | |||
243 | } | |||
244 | else if (!AddMatchingFiles(argv[i])) | |||
245 | return False0; | |||
246 | } | |||
247 | else if ((strcmp(argv[i], "-?") == 0) | |||
248 | || (strcmp(argv[i], "-help") == 0)) | |||
249 | { | |||
250 | Usage(argc, argv); | |||
251 | exit(0); | |||
252 | } | |||
253 | else if (strcmp(argv[i], "-version") == 0) | |||
254 | { | |||
255 | printf("xkbcomp %s\n", PACKAGE_VERSION"1.3.1"); | |||
256 | exit(0); | |||
257 | } else if ((strcmp(argv[i], "-a") == 0) && (!xkblist)) | |||
258 | { | |||
259 | showImplicit = True1; | |||
260 | } | |||
261 | else if ((strcmp(argv[i], "-C") == 0) && (!xkblist)) | |||
262 | { | |||
263 | if ((outputFormat != WANT_DEFAULT0) | |||
264 | && (outputFormat != WANT_C_HDR2)) | |||
265 | { | |||
266 | if (warningLevel > 0) | |||
267 | { | |||
268 | WARNuWarning("Multiple output file formats specified\n"); | |||
269 | ACTION1uAction("\"%s\" flag ignored\n", argv[i]); | |||
270 | } | |||
271 | } | |||
272 | else | |||
273 | outputFormat = WANT_C_HDR2; | |||
274 | } | |||
275 | #ifdef DEBUG | |||
276 | else if (strcmp(argv[i], "-d") == 0) | |||
277 | { | |||
278 | if ((i >= (argc - 1)) || (!isdigit(argv[i + 1][0]))) | |||
279 | { | |||
280 | debugFlags = 1; | |||
281 | } | |||
282 | else | |||
283 | { | |||
284 | if (sscanf(argv[++i], "%i", &itmp) == 1) | |||
285 | debugFlags = itmp; | |||
286 | } | |||
287 | INFO1uInformation("Setting debug flags to %d\n", debugFlags); | |||
288 | } | |||
289 | #endif | |||
290 | else if ((strcmp(argv[i], "-dflts") == 0) && (!xkblist)) | |||
291 | { | |||
292 | computeDflts = True1; | |||
293 | } | |||
294 | else if (strcmp(argv[i], "-em1") == 0) | |||
295 | { | |||
296 | if (++i >= argc) | |||
297 | { | |||
298 | if (warningLevel > 0) | |||
299 | { | |||
300 | WARNuWarning("No pre-error message specified\n"); | |||
301 | ACTIONuAction("Trailing \"-em1\" option ignored\n"); | |||
302 | } | |||
303 | } | |||
304 | else if (preErrorMsg != NULL((void*)0)) | |||
305 | { | |||
306 | if (warningLevel > 0) | |||
307 | { | |||
308 | WARNuWarning("Multiple pre-error messsages specified\n"); | |||
309 | ACTION2uAction("Compiling %s, ignoring %s\n", | |||
310 | preErrorMsg, argv[i]); | |||
311 | } | |||
312 | } | |||
313 | else | |||
314 | preErrorMsg = argv[i]; | |||
315 | } | |||
316 | else if (strcmp(argv[i], "-emp") == 0) | |||
317 | { | |||
318 | if (++i >= argc) | |||
319 | { | |||
320 | if (warningLevel > 0) | |||
321 | { | |||
322 | WARNuWarning("No error prefix specified\n"); | |||
323 | ACTIONuAction("Trailing \"-emp\" option ignored\n"); | |||
324 | } | |||
325 | } | |||
326 | else if (errorPrefix != NULL((void*)0)) | |||
327 | { | |||
328 | if (warningLevel > 0) | |||
329 | { | |||
330 | WARNuWarning("Multiple error prefixes specified\n"); | |||
331 | ACTION2uAction("Compiling %s, ignoring %s\n", | |||
332 | errorPrefix, argv[i]); | |||
333 | } | |||
334 | } | |||
335 | else | |||
336 | errorPrefix = argv[i]; | |||
337 | } | |||
338 | else if (strcmp(argv[i], "-eml") == 0) | |||
339 | { | |||
340 | if (++i >= argc) | |||
341 | { | |||
342 | if (warningLevel > 0) | |||
343 | { | |||
344 | WARNuWarning("No post-error message specified\n"); | |||
345 | ACTIONuAction("Trailing \"-eml\" option ignored\n"); | |||
346 | } | |||
347 | } | |||
348 | else if (postErrorMsg != NULL((void*)0)) | |||
349 | { | |||
350 | if (warningLevel > 0) | |||
351 | { | |||
352 | WARNuWarning("Multiple post-error messages specified\n"); | |||
353 | ACTION2uAction("Compiling %s, ignoring %s\n", | |||
354 | postErrorMsg, argv[i]); | |||
355 | } | |||
356 | } | |||
357 | else | |||
358 | postErrorMsg = argv[i]; | |||
359 | } | |||
360 | else if ((strncmp(argv[i], "-I", 2) == 0) && (!xkblist)) | |||
361 | { | |||
362 | if (!XkbAddDirectoryToPath(&argv[i][2])) | |||
363 | { | |||
364 | ACTIONuAction("Exiting\n"); | |||
365 | exit(1); | |||
366 | } | |||
367 | } | |||
368 | else if ((strncmp(argv[i], "-i", 2) == 0) && (!xkblist)) | |||
369 | { | |||
370 | if (++i >= argc) | |||
371 | { | |||
372 | if (warningLevel > 0) | |||
373 | WARNuWarning("No device ID specified\n"); | |||
374 | } | |||
375 | device_id = atoi(argv[i]); | |||
376 | } | |||
377 | else if ((strncmp(argv[i], "-l", 2) == 0) && (!xkblist)) | |||
378 | { | |||
379 | if (outputFormat != WANT_DEFAULT0) | |||
380 | { | |||
381 | if (warningLevel > 0) | |||
382 | { | |||
383 | WARNuWarning("Multiple output file formats specified\n"); | |||
384 | ACTION1uAction("\"%s\" flag ignored\n", argv[i]); | |||
385 | } | |||
386 | } | |||
387 | else | |||
388 | { | |||
389 | if (argv[i][2] != '\0') | |||
390 | setVerboseFlags(&argv[i][2]); | |||
391 | xkblist = True1; | |||
392 | if ((inputFile) && (!AddMatchingFiles(inputFile))) | |||
393 | return False0; | |||
394 | else | |||
395 | inputFile = NULL((void*)0); | |||
396 | if ((outputFile) && (!AddMatchingFiles(outputFile))) | |||
397 | return False0; | |||
398 | else | |||
399 | outputFile = NULL((void*)0); | |||
400 | } | |||
401 | } | |||
402 | else if ((strcmp(argv[i], "-m") == 0) | |||
403 | || (strcmp(argv[i], "-map") == 0)) | |||
404 | { | |||
405 | if (++i >= argc) | |||
406 | { | |||
407 | if (warningLevel > 0) | |||
408 | { | |||
409 | WARNuWarning("No map name specified\n"); | |||
410 | ACTION1uAction("Trailing \"%s\" option ignored\n", argv[i - 1]); | |||
411 | } | |||
412 | } | |||
413 | else if (xkblist) | |||
414 | { | |||
415 | if (!AddMapOnly(argv[i])) | |||
416 | return False0; | |||
417 | } | |||
418 | else if (inputMap != NULL((void*)0)) | |||
419 | { | |||
420 | if (warningLevel > 0) | |||
421 | { | |||
422 | WARNuWarning("Multiple map names specified\n"); | |||
423 | ACTION2uAction("Compiling %s, ignoring %s\n", inputMap, argv[i]); | |||
424 | } | |||
425 | } | |||
426 | else | |||
427 | inputMap = argv[i]; | |||
428 | } | |||
429 | else if ((strcmp(argv[i], "-merge") == 0) && (!xkblist)) | |||
430 | { | |||
431 | /* Ignored */ | |||
432 | } | |||
433 | else if (strcmp(argv[i], "-o") == 0) | |||
434 | { | |||
435 | if (++i >= argc) | |||
436 | { | |||
437 | if (warningLevel > 0) | |||
438 | { | |||
439 | WARNuWarning("No output file specified\n"); | |||
440 | ACTIONuAction("Trailing \"-o\" option ignored\n"); | |||
441 | } | |||
442 | } | |||
443 | else if (outputFile != NULL((void*)0)) | |||
444 | { | |||
445 | if (warningLevel > 0) | |||
446 | { | |||
447 | WARNuWarning("Multiple output files specified\n"); | |||
448 | ACTION2uAction("Compiling %s, ignoring %s\n", outputFile, | |||
449 | argv[i]); | |||
450 | } | |||
451 | } | |||
452 | else | |||
453 | outputFile = argv[i]; | |||
454 | } | |||
455 | else if (((strcmp(argv[i], "-opt") == 0) | |||
456 | || (strcmp(argv[i], "optional") == 0)) && (!xkblist)) | |||
457 | { | |||
458 | if (++i >= argc) | |||
459 | { | |||
460 | if (warningLevel > 0) | |||
461 | { | |||
462 | WARNuWarning("No optional components specified\n"); | |||
463 | ACTION1uAction("Trailing \"%s\" option ignored\n", argv[i - 1]); | |||
464 | } | |||
465 | } | |||
466 | else | |||
467 | { | |||
468 | char *tmp2; | |||
469 | for (tmp2 = argv[i]; (*tmp2 != '\0'); tmp2++) | |||
470 | { | |||
471 | switch (*tmp2) | |||
472 | { | |||
473 | case 'c': | |||
474 | case 'C': | |||
475 | optionalParts |= XkmCompatMapMask(1<<1); | |||
476 | break; | |||
477 | case 'g': | |||
478 | case 'G': | |||
479 | optionalParts |= XkmGeometryMask(1<<5); | |||
480 | break; | |||
481 | case 'k': | |||
482 | case 'K': | |||
483 | optionalParts |= XkmKeyNamesMask(1<<4); | |||
484 | break; | |||
485 | case 's': | |||
486 | case 'S': | |||
487 | optionalParts |= XkmSymbolsMask(1<<2); | |||
488 | break; | |||
489 | case 't': | |||
490 | case 'T': | |||
491 | optionalParts |= XkmTypesMask(1<<0); | |||
492 | break; | |||
493 | default: | |||
494 | if (warningLevel > 0) | |||
495 | { | |||
496 | WARN1uWarning | |||
497 | ("Illegal component for %s option\n", | |||
498 | argv[i - 1]); | |||
499 | ACTION1uAction | |||
500 | ("Ignoring unknown specifier \"%c\"\n", | |||
501 | (unsigned int) *tmp2); | |||
502 | } | |||
503 | break; | |||
504 | } | |||
505 | } | |||
506 | } | |||
507 | } | |||
508 | else if (strncmp(argv[i], "-p", 2) == 0) | |||
509 | { | |||
510 | if (isdigit(argv[i][2])) | |||
511 | { | |||
512 | if (sscanf(&argv[i][2], "%i", &itmp) == 1) | |||
513 | dirsToStrip = itmp; | |||
514 | } | |||
515 | else if ((i < (argc - 1)) && (isdigit(argv[i + 1][0]))) | |||
516 | { | |||
517 | if (sscanf(argv[++i], "%i", &itmp) == 1) | |||
518 | dirsToStrip = itmp; | |||
519 | } | |||
520 | else | |||
521 | { | |||
522 | dirsToStrip = 0; | |||
523 | } | |||
524 | if (warningLevel > 5) | |||
525 | INFO1uInformation("Setting path count to %d\n", dirsToStrip); | |||
526 | } | |||
527 | else if (strncmp(argv[i], "-R", 2) == 0) | |||
528 | { | |||
529 | if (argv[i][2] == '\0') | |||
530 | { | |||
531 | if (warningLevel > 0) | |||
532 | { | |||
533 | WARNuWarning("No root directory specified\n"); | |||
534 | ACTIONuAction("Ignoring -R option\n"); | |||
535 | } | |||
536 | } | |||
537 | else if (rootDir != NULL((void*)0)) | |||
538 | { | |||
539 | if (warningLevel > 0) | |||
540 | { | |||
541 | WARNuWarning("Multiple root directories specified\n"); | |||
542 | ACTION2uAction("Using %s, ignoring %s\n", rootDir, argv[i]); | |||
543 | } | |||
544 | } | |||
545 | else | |||
546 | { | |||
547 | rootDir = &argv[i][2]; | |||
548 | if (warningLevel > 8) | |||
549 | { | |||
550 | WARN1uWarning("Changing root directory to \"%s\"\n", rootDir); | |||
551 | } | |||
552 | if ((chdir(rootDir) < 0) && (warningLevel > 0)) | |||
553 | { | |||
554 | WARN1uWarning("Couldn't change directory to \"%s\"\n", rootDir); | |||
555 | ACTIONuAction("Root directory (-R) option ignored\n"); | |||
556 | rootDir = NULL((void*)0); | |||
557 | } | |||
558 | } | |||
559 | } | |||
560 | else if ((strcmp(argv[i], "-synch") == 0) | |||
561 | || (strcmp(argv[i], "-s") == 0)) | |||
562 | { | |||
563 | synch = True1; | |||
564 | } | |||
565 | else if (strncmp(argv[i], "-v", 2) == 0) | |||
566 | { | |||
567 | char *str; | |||
568 | if (argv[i][2] != '\0') | |||
569 | str = &argv[i][2]; | |||
570 | else if ((i < (argc - 1)) && (argv[i + 1][0] != '-')) | |||
571 | str = argv[++i]; | |||
572 | else | |||
573 | str = NULL((void*)0); | |||
574 | if (str) | |||
575 | setVerboseFlags(str); | |||
576 | } | |||
577 | else if (strncmp(argv[i], "-w", 2) == 0) | |||
578 | { | |||
579 | unsigned long utmp; | |||
580 | char *tmp2; | |||
581 | /* If text is just after "-w" in the same word, then it must | |||
582 | * be a number and it is the warning level. Otherwise, if the | |||
583 | * next argument is a number, then it is the warning level, | |||
584 | * else the warning level is assumed to be 0. | |||
585 | */ | |||
586 | if (argv[i][2] == '\0') | |||
587 | { | |||
588 | warningLevel = 0; | |||
589 | if (i < argc - 1) | |||
590 | { | |||
591 | utmp = strtoul(argv[i+1], &tmp2, 10); | |||
592 | if (argv[i+1][0] != '\0' && *tmp2 == '\0') | |||
593 | { | |||
594 | warningLevel = utmp > 10 ? 10 : utmp; | |||
595 | i++; | |||
596 | } | |||
597 | } | |||
598 | } | |||
599 | else | |||
600 | { | |||
601 | utmp = strtoul(&argv[i][2], &tmp2, 10); | |||
602 | if (*tmp2 == '\0') | |||
603 | warningLevel = utmp > 10 ? 10 : utmp; | |||
604 | else | |||
605 | { | |||
606 | ERROR1uError("Unknown flag \"%s\" on command line\n", argv[i]); | |||
607 | Usage(argc, argv); | |||
608 | return False0; | |||
609 | } | |||
610 | } | |||
611 | } | |||
612 | else if ((strcmp(argv[i], "-xkb") == 0) && (!xkblist)) | |||
613 | { | |||
614 | if ((outputFormat != WANT_DEFAULT0) | |||
615 | && (outputFormat != WANT_XKB_FILE3)) | |||
616 | { | |||
617 | if (warningLevel > 0) | |||
618 | { | |||
619 | WARNuWarning("Multiple output file formats specified\n"); | |||
620 | ACTION1uAction("\"%s\" flag ignored\n", argv[i]); | |||
621 | } | |||
622 | } | |||
623 | else | |||
624 | outputFormat = WANT_XKB_FILE3; | |||
625 | } | |||
626 | else if ((strcmp(argv[i], "-xkm") == 0) && (!xkblist)) | |||
627 | { | |||
628 | if ((outputFormat != WANT_DEFAULT0) | |||
629 | && (outputFormat != WANT_XKM_FILE1)) | |||
630 | { | |||
631 | if (warningLevel > 0) | |||
632 | { | |||
633 | WARNuWarning("Multiple output file formats specified\n"); | |||
634 | ACTION1uAction("\"%s\" flag ignored\n", argv[i]); | |||
635 | } | |||
636 | } | |||
637 | else | |||
638 | outputFormat = WANT_XKM_FILE1; | |||
639 | } | |||
640 | else | |||
641 | { | |||
642 | ERROR1uError("Unknown flag \"%s\" on command line\n", argv[i]); | |||
643 | Usage(argc, argv); | |||
644 | return False0; | |||
645 | } | |||
646 | } | |||
647 | if (xkblist) | |||
648 | inputFormat = INPUT_XKB1; | |||
649 | else if (inputFile == NULL((void*)0)) | |||
650 | { | |||
651 | ERRORuError("No input file specified\n"); | |||
652 | return False0; | |||
653 | } | |||
654 | else if (uStringEqual(inputFile, "-")((((inputFile)==((char *)((void*)0))||("-")==((char *)((void* )0)))? (inputFile)!=("-"):strcmp(inputFile,"-"))==((Comparison )0))) | |||
655 | { | |||
656 | inputFormat = INPUT_XKB1; | |||
657 | } | |||
658 | #ifndef WIN32 | |||
659 | else if (strchr(inputFile, ':') == NULL((void*)0)) | |||
660 | { | |||
661 | #else | |||
662 | else if ((strchr(inputFile, ':') == NULL((void*)0)) || (strlen(inputFile) > 2 && | |||
663 | isalpha(inputFile[0]) && | |||
664 | inputFile[1] == ':' | |||
665 | && strchr(inputFile + 2, | |||
666 | ':') == NULL((void*)0))) | |||
667 | { | |||
668 | #endif | |||
669 | int len; | |||
670 | len = strlen(inputFile); | |||
671 | if (inputFile[len - 1] == ')') | |||
672 | { | |||
673 | char *tmpstr; | |||
674 | if ((tmpstr = strchr(inputFile, '(')) != NULL((void*)0)) | |||
675 | { | |||
676 | *tmpstr = '\0'; | |||
677 | inputFile[len - 1] = '\0'; | |||
678 | tmpstr++; | |||
679 | if (*tmpstr == '\0') | |||
680 | { | |||
681 | WARNuWarning("Empty map in filename\n"); | |||
682 | ACTIONuAction("Ignored\n"); | |||
683 | } | |||
684 | else if (inputMap == NULL((void*)0)) | |||
685 | { | |||
686 | inputMap = uStringDup(tmpstr)((tmpstr) ? strdup(tmpstr) : ((void*)0)); | |||
687 | } | |||
688 | else | |||
689 | { | |||
690 | WARNuWarning("Map specified in filename and with -m flag\n"); | |||
691 | ACTION1uAction("map from name (\"%s\") ignored\n", tmpstr); | |||
692 | } | |||
693 | } | |||
694 | else | |||
695 | { | |||
696 | ERROR1uError("Illegal name \"%s\" for input file\n", inputFile); | |||
697 | return False0; | |||
698 | } | |||
699 | } | |||
700 | if ((len > 4) && (strcmp(&inputFile[len - 4], ".xkm") == 0)) | |||
701 | { | |||
702 | inputFormat = INPUT_XKM2; | |||
703 | } | |||
704 | else | |||
705 | { | |||
706 | FILE *file; | |||
707 | file = fopen(inputFile, "r"); | |||
708 | if (file) | |||
709 | { | |||
710 | if (XkmProbe(file)) | |||
711 | inputFormat = INPUT_XKM2; | |||
712 | else | |||
713 | inputFormat = INPUT_XKB1; | |||
714 | fclose(file); | |||
715 | } | |||
716 | else | |||
717 | { | |||
718 | fprintf(stderr__stderrp, "Cannot open \"%s\" for reading\n", | |||
719 | inputFile); | |||
720 | return False0; | |||
721 | } | |||
722 | } | |||
723 | } | |||
724 | else | |||
725 | { | |||
726 | inDpyName = inputFile; | |||
727 | inputFile = NULL((void*)0); | |||
728 | inputFormat = INPUT_XKM2; | |||
729 | } | |||
730 | ||||
731 | if (outputFormat == WANT_DEFAULT0) | |||
732 | { | |||
733 | if (xkblist) | |||
734 | outputFormat = WANT_LISTING5; | |||
735 | else if (inputFormat == INPUT_XKB1) | |||
736 | outputFormat = WANT_XKM_FILE1; | |||
737 | else | |||
738 | outputFormat = WANT_XKB_FILE3; | |||
739 | } | |||
740 | if ((outputFormat == WANT_LISTING5) && (inputFormat != INPUT_XKB1)) | |||
741 | { | |||
742 | if (inputFile) | |||
743 | ERRORuError("Cannot generate a listing from a .xkm file (yet)\n"); | |||
744 | else | |||
745 | ERRORuError("Cannot generate a listing from an X connection (yet)\n"); | |||
746 | return False0; | |||
747 | } | |||
748 | if (xkblist) | |||
749 | { | |||
750 | if (outputFile == NULL((void*)0)) | |||
751 | outputFile = uStringDup("-")(("-") ? strdup("-") : ((void*)0)); | |||
752 | else if (strchr(outputFile, ':') != NULL((void*)0)) | |||
753 | { | |||
754 | ERRORuError("Cannot write a listing to an X connection\n"); | |||
755 | return False0; | |||
756 | } | |||
757 | } | |||
758 | else if ((!outputFile) && (inputFile) && uStringEqual(inputFile, "-")((((inputFile)==((char *)((void*)0))||("-")==((char *)((void* )0)))? (inputFile)!=("-"):strcmp(inputFile,"-"))==((Comparison )0))) | |||
759 | { | |||
760 | int len = strlen("stdin") + strlen(fileTypeExt[outputFormat]) + 2; | |||
761 | outputFile = uTypedCalloc(len, char)((char *)uCalloc((unsigned)len,(unsigned)sizeof(char))); | |||
762 | if (outputFile == NULL((void*)0)) | |||
763 | { | |||
764 | WSGOuInternalError("Cannot allocate space for output file name\n"); | |||
765 | ACTIONuAction("Exiting\n"); | |||
766 | exit(1); | |||
767 | } | |||
768 | snprintf(outputFile, len, "stdin.%s", fileTypeExt[outputFormat])__builtin___snprintf_chk (outputFile, len, 0, __builtin_object_size (outputFile, 2 > 1 ? 1 : 0), "stdin.%s", fileTypeExt[outputFormat ]); | |||
769 | } | |||
770 | else if ((outputFile == NULL((void*)0)) && (inputFile != NULL((void*)0))) | |||
771 | { | |||
772 | int len; | |||
773 | char *base, *ext; | |||
774 | ||||
775 | if (inputMap == NULL((void*)0)) | |||
776 | { | |||
777 | base = strrchr(inputFile, '/'); | |||
778 | if (base == NULL((void*)0)) | |||
779 | base = inputFile; | |||
780 | else | |||
781 | base++; | |||
782 | } | |||
783 | else | |||
784 | base = inputMap; | |||
785 | ||||
786 | len = strlen(base) + strlen(fileTypeExt[outputFormat]) + 2; | |||
787 | outputFile = uTypedCalloc(len, char)((char *)uCalloc((unsigned)len,(unsigned)sizeof(char))); | |||
788 | if (outputFile == NULL((void*)0)) | |||
789 | { | |||
790 | WSGOuInternalError("Cannot allocate space for output file name\n"); | |||
791 | ACTIONuAction("Exiting\n"); | |||
792 | exit(1); | |||
793 | } | |||
794 | ext = strrchr(base, '.'); | |||
795 | if (ext == NULL((void*)0)) | |||
796 | snprintf(outputFile, len, "%s.%s", base, fileTypeExt[outputFormat])__builtin___snprintf_chk (outputFile, len, 0, __builtin_object_size (outputFile, 2 > 1 ? 1 : 0), "%s.%s", base, fileTypeExt[outputFormat ]); | |||
797 | else | |||
798 | { | |||
799 | strcpy(outputFile, base)__builtin___strcpy_chk (outputFile, base, __builtin_object_size (outputFile, 2 > 1 ? 1 : 0)); | |||
800 | strcpy(&outputFile[ext - base + 1], fileTypeExt[outputFormat])__builtin___strcpy_chk (&outputFile[ext - base + 1], fileTypeExt [outputFormat], __builtin_object_size (&outputFile[ext - base + 1], 2 > 1 ? 1 : 0)); | |||
801 | } | |||
802 | } | |||
803 | else if (outputFile == NULL((void*)0)) | |||
804 | { | |||
805 | int len; | |||
806 | char *ch, *name, buf[128]; | |||
807 | if (inDpyName[0] == ':') | |||
808 | snprintf(name = buf, sizeof(buf), "server%s", inDpyName)__builtin___snprintf_chk (name = buf, sizeof(buf), 0, __builtin_object_size (name = buf, 2 > 1 ? 1 : 0), "server%s", inDpyName); | |||
809 | else | |||
810 | name = inDpyName; | |||
811 | ||||
812 | len = strlen(name) + strlen(fileTypeExt[outputFormat]) + 2; | |||
813 | outputFile = uTypedCalloc(len, char)((char *)uCalloc((unsigned)len,(unsigned)sizeof(char))); | |||
814 | if (outputFile == NULL((void*)0)) | |||
815 | { | |||
816 | WSGOuInternalError("Cannot allocate space for output file name\n"); | |||
817 | ACTIONuAction("Exiting\n"); | |||
818 | exit(1); | |||
819 | } | |||
820 | strcpy(outputFile, name)__builtin___strcpy_chk (outputFile, name, __builtin_object_size (outputFile, 2 > 1 ? 1 : 0)); | |||
821 | for (ch = outputFile; (*ch) != '\0'; ch++) | |||
822 | { | |||
823 | if (*ch == ':') | |||
824 | *ch = '-'; | |||
825 | else if (*ch == '.') | |||
826 | *ch = '_'; | |||
827 | } | |||
828 | *ch++ = '.'; | |||
829 | strcpy(ch, fileTypeExt[outputFormat])__builtin___strcpy_chk (ch, fileTypeExt[outputFormat], __builtin_object_size (ch, 2 > 1 ? 1 : 0)); | |||
830 | } | |||
831 | #ifdef WIN32 | |||
832 | else if (strlen(outputFile) > 2 && | |||
833 | isalpha(outputFile[0]) && | |||
834 | outputFile[1] == ':' && strchr(outputFile + 2, ':') == NULL((void*)0)) | |||
835 | { | |||
836 | } | |||
837 | #endif | |||
838 | else if (strchr(outputFile, ':') != NULL((void*)0)) | |||
839 | { | |||
840 | outDpyName = outputFile; | |||
841 | outputFile = NULL((void*)0); | |||
842 | outputFormat = WANT_X_SERVER4; | |||
843 | } | |||
844 | return True1; | |||
845 | } | |||
846 | ||||
847 | static Display * | |||
848 | GetDisplay(char *program, char *dpyName) | |||
849 | { | |||
850 | int mjr, mnr, error; | |||
851 | Display *dpy; | |||
852 | ||||
853 | mjr = XkbMajorVersion1; | |||
854 | mnr = XkbMinorVersion0; | |||
855 | dpy = XkbOpenDisplay(dpyName, NULL((void*)0), NULL((void*)0), &mjr, &mnr, &error); | |||
856 | if (dpy == NULL((void*)0)) | |||
857 | { | |||
858 | switch (error) | |||
859 | { | |||
860 | case XkbOD_BadLibraryVersion1: | |||
861 | INFO3uInformation("%s was compiled with XKB version %d.%02d\n", | |||
862 | program, XkbMajorVersion1, XkbMinorVersion0); | |||
863 | ERROR2uError("X library supports incompatible version %d.%02d\n", | |||
864 | mjr, mnr); | |||
865 | break; | |||
866 | case XkbOD_ConnectionRefused2: | |||
867 | ERROR1uError("Cannot open display \"%s\"\n", dpyName); | |||
868 | break; | |||
869 | case XkbOD_NonXkbServer3: | |||
870 | ERROR1uError("XKB extension not present on %s\n", dpyName); | |||
871 | break; | |||
872 | case XkbOD_BadServerVersion4: | |||
873 | INFO3uInformation("%s was compiled with XKB version %d.%02d\n", | |||
874 | program, XkbMajorVersion1, XkbMinorVersion0); | |||
875 | ERROR3uError("Server %s uses incompatible version %d.%02d\n", | |||
876 | dpyName, mjr, mnr); | |||
877 | break; | |||
878 | default: | |||
879 | WSGO1uInternalError("Unknown error %d from XkbOpenDisplay\n", error); | |||
880 | } | |||
881 | } | |||
882 | else if (synch) | |||
883 | XSynchronize(dpy, True1); | |||
884 | return dpy; | |||
885 | } | |||
886 | ||||
887 | /***====================================================================***/ | |||
888 | ||||
889 | #ifdef DEBUG | |||
890 | extern int yydebug; | |||
891 | #endif | |||
892 | ||||
893 | int | |||
894 | main(int argc, char *argv[]) | |||
895 | { | |||
896 | FILE *file; /* input file (or stdin) */ | |||
897 | XkbFile *rtrn; | |||
898 | XkbFile *mapToUse; | |||
899 | int ok; | |||
900 | XkbFileInfo result; | |||
901 | Statusint status; | |||
902 | ||||
903 | scan_set_file(stdin__stdinp); | |||
904 | uSetDebugFile(NullString((char *)((void*)0))); | |||
905 | uSetErrorFile(NullString((char *)((void*)0))); | |||
906 | ||||
907 | XkbInitIncludePath(); | |||
908 | if (!parseArgs(argc, argv)) | |||
| ||||
909 | exit(1); | |||
910 | #ifdef DEBUG | |||
911 | if (debugFlags & 0x2) | |||
912 | yydebug = 1; | |||
913 | #endif | |||
914 | if (preErrorMsg) | |||
915 | uSetPreErrorMessage(preErrorMsg); | |||
916 | if (errorPrefix) | |||
917 | uSetErrorPrefix(errorPrefix); | |||
918 | if (postErrorMsg) | |||
919 | uSetPostErrorMessage(postErrorMsg); | |||
920 | file = NULL((void*)0); | |||
921 | XkbInitAtoms(NULL((void*)0)); | |||
922 | XkbAddDefaultDirectoriesToPath(); | |||
923 | if (xkblist) | |||
924 | { | |||
925 | Boolint gotSome; | |||
926 | gotSome = GenerateListing(outputFile); | |||
927 | if ((warningLevel > 7) && (!gotSome)) | |||
928 | return -1; | |||
929 | return 0; | |||
930 | } | |||
931 | if (inputFile != NULL((void*)0)) | |||
932 | { | |||
933 | if (uStringEqual(inputFile, "-")((((inputFile)==((char *)((void*)0))||("-")==((char *)((void* )0)))? (inputFile)!=("-"):strcmp(inputFile,"-"))==((Comparison )0))) | |||
934 | { | |||
935 | file = stdin__stdinp; | |||
936 | inputFile = "stdin"; | |||
937 | } | |||
938 | else | |||
939 | { | |||
940 | file = fopen(inputFile, "r"); | |||
941 | } | |||
942 | } | |||
943 | else if (inDpyName != NULL((void*)0)) | |||
944 | { | |||
945 | inDpy = GetDisplay(argv[0], inDpyName); | |||
946 | if (!inDpy) | |||
947 | { | |||
948 | ACTIONuAction("Exiting\n"); | |||
949 | exit(1); | |||
950 | } | |||
951 | } | |||
952 | if (outDpyName != NULL((void*)0)) | |||
953 | { | |||
954 | outDpy = GetDisplay(argv[0], outDpyName); | |||
955 | if (!outDpy) | |||
956 | { | |||
957 | ACTIONuAction("Exiting\n"); | |||
958 | exit(1); | |||
959 | } | |||
960 | } | |||
961 | if ((inDpy == NULL((void*)0)) && (outDpy == NULL((void*)0))) | |||
962 | { | |||
963 | int mjr, mnr; | |||
964 | mjr = XkbMajorVersion1; | |||
965 | mnr = XkbMinorVersion0; | |||
966 | if (!XkbLibraryVersion(&mjr, &mnr)) | |||
967 | { | |||
968 | INFO3uInformation("%s was compiled with XKB version %d.%02d\n", | |||
969 | argv[0], XkbMajorVersion1, XkbMinorVersion0); | |||
970 | ERROR2uError("X library supports incompatible version %d.%02d\n", | |||
971 | mjr, mnr); | |||
972 | ACTIONuAction("Exiting\n"); | |||
973 | exit(1); | |||
974 | } | |||
975 | } | |||
976 | if (file) | |||
977 | { | |||
978 | ok = True1; | |||
979 | setScanState(inputFile, 1); | |||
980 | if ((inputFormat == INPUT_XKB1) /* parse .xkb file */ | |||
981 | && (XKBParseFile(file, &rtrn) && (rtrn != NULL((void*)0)))) | |||
982 | { | |||
983 | fclose(file); | |||
984 | mapToUse = rtrn; | |||
985 | if (inputMap != NULL((void*)0)) /* map specified on cmdline? */ | |||
986 | { | |||
987 | while ((mapToUse) | |||
988 | && (!uStringEqual(mapToUse->name, inputMap)((((mapToUse->name)==((char *)((void*)0))||(inputMap)==((char *)((void*)0)))? (mapToUse->name)!=(inputMap):strcmp(mapToUse ->name,inputMap))==((Comparison)0)))) | |||
989 | { | |||
990 | mapToUse = (XkbFile *) mapToUse->common.next; | |||
991 | } | |||
992 | if (!mapToUse) | |||
993 | { | |||
994 | FATAL2uFatalError("No map named \"%s\" in \"%s\"\n", | |||
995 | inputMap, inputFile); | |||
996 | /* NOTREACHED */ | |||
997 | } | |||
998 | } | |||
999 | else if (rtrn->common.next != NULL((void*)0)) | |||
1000 | { | |||
1001 | /* look for map with XkbLC_Default flag. */ | |||
1002 | mapToUse = rtrn; | |||
1003 | for (; mapToUse; mapToUse = (XkbFile *) mapToUse->common.next) | |||
1004 | { | |||
1005 | if (mapToUse->flags & XkbLC_Default(1L << 1)) | |||
1006 | break; | |||
1007 | } | |||
1008 | if (!mapToUse) | |||
1009 | { | |||
1010 | mapToUse = rtrn; | |||
1011 | if (warningLevel > 4) | |||
1012 | { | |||
1013 | WARN1uWarning | |||
1014 | ("No map specified, but \"%s\" has several\n", | |||
1015 | inputFile); | |||
1016 | ACTION1uAction | |||
1017 | ("Using the first defined map, \"%s\"\n", | |||
1018 | mapToUse->name); | |||
1019 | } | |||
1020 | } | |||
1021 | } | |||
1022 | bzero((char *) &result, sizeof(result))__builtin___memset_chk ((char *) &result, 0, sizeof(result ), __builtin_object_size ((char *) &result, 0)); | |||
1023 | result.type = mapToUse->type; | |||
1024 | if ((result.xkb = XkbAllocKeyboard()) == NULL((void*)0)) | |||
1025 | { | |||
1026 | WSGOuInternalError("Cannot allocate keyboard description\n"); | |||
1027 | /* NOTREACHED */ | |||
1028 | } | |||
1029 | switch (mapToUse->type) | |||
1030 | { | |||
1031 | case XkmSemanticsFile20: | |||
1032 | case XkmLayoutFile21: | |||
1033 | case XkmKeymapFile22: | |||
1034 | ok = CompileKeymap(mapToUse, &result, MergeReplace3); | |||
1035 | break; | |||
1036 | case XkmKeyNamesIndex4: | |||
1037 | ok = CompileKeycodes(mapToUse, &result, MergeReplace3); | |||
1038 | break; | |||
1039 | case XkmTypesIndex0: | |||
1040 | ok = CompileKeyTypes(mapToUse, &result, MergeReplace3); | |||
1041 | break; | |||
1042 | case XkmSymbolsIndex2: | |||
1043 | /* if it's just symbols, invent key names */ | |||
1044 | result.xkb->flags |= AutoKeyNames(1L << 0); | |||
| ||||
1045 | ok = False0; | |||
1046 | break; | |||
1047 | case XkmCompatMapIndex1: | |||
1048 | ok = CompileCompatMap(mapToUse, &result, MergeReplace3, NULL((void*)0)); | |||
1049 | break; | |||
1050 | case XkmGeometryFile23: | |||
1051 | case XkmGeometryIndex5: | |||
1052 | /* if it's just a geometry, invent key names */ | |||
1053 | result.xkb->flags |= AutoKeyNames(1L << 0); | |||
1054 | ok = CompileGeometry(mapToUse, &result, MergeReplace3); | |||
1055 | break; | |||
1056 | default: | |||
1057 | WSGO1uInternalError("Unknown file type %d\n", mapToUse->type); | |||
1058 | ok = False0; | |||
1059 | break; | |||
1060 | } | |||
1061 | result.xkb->device_spec = device_id; | |||
1062 | } | |||
1063 | else if (inputFormat == INPUT_XKM2) /* parse xkm file */ | |||
1064 | { | |||
1065 | unsigned tmp; | |||
1066 | bzero((char *) &result, sizeof(result))__builtin___memset_chk ((char *) &result, 0, sizeof(result ), __builtin_object_size ((char *) &result, 0)); | |||
1067 | if ((result.xkb = XkbAllocKeyboard()) == NULL((void*)0)) | |||
1068 | { | |||
1069 | WSGOuInternalError("Cannot allocate keyboard description\n"); | |||
1070 | /* NOTREACHED */ | |||
1071 | } | |||
1072 | tmp = XkmReadFile(file, 0, XkmKeymapLegal((((1<<1))|((1<<4)|(1<<2)|(1<<0)))|(( ((1<<0)|(1<<6)|(1<<3))|((1<<6)|(1<< 5)))&(~(((1<<1))|((1<<4)|(1<<2)|(1<< 0)))))), &result); | |||
1073 | if (tmp == XkmKeymapLegal((((1<<1))|((1<<4)|(1<<2)|(1<<0)))|(( ((1<<0)|(1<<6)|(1<<3))|((1<<6)|(1<< 5)))&(~(((1<<1))|((1<<4)|(1<<2)|(1<< 0))))))) | |||
1074 | { | |||
1075 | ERROR1uError("Cannot read XKM file \"%s\"\n", inputFile); | |||
1076 | ok = False0; | |||
1077 | } | |||
1078 | result.xkb->device_spec = device_id; | |||
1079 | } | |||
1080 | else | |||
1081 | { | |||
1082 | INFO1uInformation("Errors encountered in %s; not compiled.\n", inputFile); | |||
1083 | ok = False0; | |||
1084 | } | |||
1085 | } | |||
1086 | else if (inDpy != NULL((void*)0)) | |||
1087 | { | |||
1088 | bzero((char *) &result, sizeof(result))__builtin___memset_chk ((char *) &result, 0, sizeof(result ), __builtin_object_size ((char *) &result, 0)); | |||
1089 | result.type = XkmKeymapFile22; | |||
1090 | result.xkb = XkbGetMap(inDpy, XkbAllMapComponentsMask(((1<<0)|(1<<1)|(1<<2))|((1<<3)|(1<< 4)|(1<<5)|(1<<6)|(1<<7))), device_id); | |||
1091 | if (result.xkb == NULL((void*)0)) | |||
1092 | WSGOuInternalError("Cannot load keyboard description\n"); | |||
1093 | if (XkbGetIndicatorMap(inDpy, ~0, result.xkb) != Success0) | |||
1094 | WSGOuInternalError("Could not load indicator map\n"); | |||
1095 | if (XkbGetControls(inDpy, XkbAllControlsMask(0xF8001FFF), result.xkb) != Success0) | |||
1096 | WSGOuInternalError("Could not load keyboard controls\n"); | |||
1097 | if (XkbGetCompatMap(inDpy, XkbAllCompatMask(0x3), result.xkb) != Success0) | |||
1098 | WSGOuInternalError("Could not load compatibility map\n"); | |||
1099 | if (XkbGetNames(inDpy, XkbAllNamesMask(0x3fff), result.xkb) != Success0) | |||
1100 | WSGOuInternalError("Could not load names\n"); | |||
1101 | if ((status = XkbGetGeometry(inDpy, result.xkb)) != Success0) | |||
1102 | { | |||
1103 | if (warningLevel > 3) | |||
1104 | { | |||
1105 | char buf[100]; | |||
1106 | buf[0] = '\0'; | |||
1107 | XGetErrorText(inDpy, status, buf, 100); | |||
1108 | WARN1uWarning("Could not load keyboard geometry for %s\n", inDpyName); | |||
1109 | ACTION1uAction("%s\n", buf); | |||
1110 | ACTIONuAction("Resulting keymap file will not describe geometry\n"); | |||
1111 | } | |||
1112 | } | |||
1113 | if (computeDflts) | |||
1114 | ok = (ComputeKbdDefaults(result.xkb) == Success0); | |||
1115 | else | |||
1116 | ok = True1; | |||
1117 | } | |||
1118 | else | |||
1119 | { | |||
1120 | fprintf(stderr__stderrp, "Cannot open \"%s\" to compile\n", inputFile); | |||
1121 | ok = 0; | |||
1122 | } | |||
1123 | if (ok) | |||
1124 | { | |||
1125 | FILE *out = stdout__stdoutp; | |||
1126 | if ((inDpy != outDpy) && | |||
1127 | (XkbChangeKbdDisplay(outDpy, &result) != Success0)) | |||
1128 | { | |||
1129 | WSGO2uInternalError("Error converting keyboard display from %s to %s\n", | |||
1130 | inDpyName, outDpyName); | |||
1131 | exit(1); | |||
1132 | } | |||
1133 | if (outputFile != NULL((void*)0)) | |||
1134 | { | |||
1135 | if (uStringEqual(outputFile, "-")((((outputFile)==((char *)((void*)0))||("-")==((char *)((void *)0)))? (outputFile)!=("-"):strcmp(outputFile,"-"))==((Comparison )0))) | |||
1136 | outputFile = "stdout"; | |||
1137 | else | |||
1138 | { | |||
1139 | /* | |||
1140 | * fix to prevent symlink attack (e.g., | |||
1141 | * ln -s /etc/passwd /var/tmp/server-0.xkm) | |||
1142 | */ | |||
1143 | /* | |||
1144 | * this patch may have POSIX, Linux, or GNU libc bias | |||
1145 | * -- Branden Robinson | |||
1146 | */ | |||
1147 | int outputFileFd; | |||
1148 | int binMode = 0; | |||
1149 | const char *openMode = "w"; | |||
1150 | unlink(outputFile); | |||
1151 | #ifdef O_BINARY | |||
1152 | switch (outputFormat) | |||
1153 | { | |||
1154 | case WANT_XKM_FILE1: | |||
1155 | binMode = O_BINARY; | |||
1156 | openMode = "wb"; | |||
1157 | break; | |||
1158 | default: | |||
1159 | binMode = 0; | |||
1160 | break; | |||
1161 | } | |||
1162 | #endif | |||
1163 | outputFileFd = | |||
1164 | open(outputFile, O_WRONLY0x0001 | O_CREAT0x0200 | O_EXCL0x0800, | |||
1165 | S_IRUSR0000400 | S_IWUSR0000200 | S_IRGRP0000040 | S_IWGRP0000020 | S_IROTH0000004 | |||
1166 | | S_IWOTH0000002 | binMode); | |||
1167 | if (outputFileFd < 0) | |||
1168 | { | |||
1169 | ERROR1uError | |||
1170 | ("Cannot open \"%s\" to write keyboard description\n", | |||
1171 | outputFile); | |||
1172 | ACTIONuAction("Exiting\n"); | |||
1173 | exit(1); | |||
1174 | } | |||
1175 | #ifndef WIN32 | |||
1176 | out = fdopen(outputFileFd, openMode); | |||
1177 | #else | |||
1178 | close(outputFileFd); | |||
1179 | out = fopen(outputFile, "wb"); | |||
1180 | #endif | |||
1181 | /* end BR */ | |||
1182 | if (out == NULL((void*)0)) | |||
1183 | { | |||
1184 | ERROR1uError | |||
1185 | ("Cannot open \"%s\" to write keyboard description\n", | |||
1186 | outputFile); | |||
1187 | ACTIONuAction("Exiting\n"); | |||
1188 | exit(1); | |||
1189 | } | |||
1190 | } | |||
1191 | } | |||
1192 | switch (outputFormat) | |||
1193 | { | |||
1194 | case WANT_XKM_FILE1: | |||
1195 | ok = XkbWriteXKMFile(out, &result); | |||
1196 | break; | |||
1197 | case WANT_XKB_FILE3: | |||
1198 | ok = XkbWriteXKBFile(out, &result, showImplicit, NULL((void*)0), NULL((void*)0)); | |||
1199 | break; | |||
1200 | case WANT_C_HDR2: | |||
1201 | ok = XkbWriteCFile(out, outputFile, &result); | |||
1202 | break; | |||
1203 | case WANT_X_SERVER4: | |||
1204 | if (!(ok = XkbWriteToServer(&result))) | |||
1205 | { | |||
1206 | ERROR2uError("%s in %s\n", _XkbErrMessages[_XkbErrCode], | |||
1207 | _XkbErrLocation ? _XkbErrLocation : "unknown"); | |||
1208 | ACTION1uAction("Couldn't write keyboard description to %s\n", | |||
1209 | outDpyName); | |||
1210 | } | |||
1211 | break; | |||
1212 | default: | |||
1213 | WSGO1uInternalError("Unknown output format %d\n", outputFormat); | |||
1214 | ACTIONuAction("No output file created\n"); | |||
1215 | ok = False0; | |||
1216 | break; | |||
1217 | } | |||
1218 | if (outputFormat != WANT_X_SERVER4) | |||
1219 | { | |||
1220 | if (fclose(out)) | |||
1221 | { | |||
1222 | ERROR1uError("Cannot close \"%s\" properly (not enough space?)\n", | |||
1223 | outputFile); | |||
1224 | ok= False0; | |||
1225 | } | |||
1226 | else if (!ok) | |||
1227 | { | |||
1228 | ERROR2uError("%s in %s\n", _XkbErrMessages[_XkbErrCode], | |||
1229 | _XkbErrLocation ? _XkbErrLocation : "unknown"); | |||
1230 | } | |||
1231 | if (!ok) | |||
1232 | { | |||
1233 | ACTION1uAction("Output file \"%s\" removed\n", outputFile); | |||
1234 | unlink(outputFile); | |||
1235 | } | |||
1236 | } | |||
1237 | } | |||
1238 | if (inDpy) | |||
1239 | XCloseDisplay(inDpy); | |||
1240 | inDpy = NULL((void*)0); | |||
1241 | if (outDpy) | |||
1242 | XCloseDisplay(outDpy); | |||
1243 | uFinishUp(); | |||
1244 | return (ok == 0); | |||
1245 | } |