File: | saveutil.c |
Location: | line 136, column 19 |
Description: | Access to field 'clientId' results in a dereference of a null pointer (loaded from variable 'c') |
1 | /* $Xorg: saveutil.c,v 1.5 2001/02/09 02:06:01 xorgcvs Exp $ */ | |||
2 | /****************************************************************************** | |||
3 | ||||
4 | Copyright 1993, 1998 The Open Group | |||
5 | ||||
6 | Permission to use, copy, modify, distribute, and sell this software and its | |||
7 | documentation for any purpose is hereby granted without fee, provided that | |||
8 | the above copyright notice appear in all copies and that both that | |||
9 | copyright notice and this permission notice appear in supporting | |||
10 | documentation. | |||
11 | ||||
12 | The above copyright notice and this permission notice shall be included in | |||
13 | all copies or substantial portions of the Software. | |||
14 | ||||
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||
18 | OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN | |||
19 | AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |||
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
21 | ||||
22 | Except as contained in this notice, the name of The Open Group shall not be | |||
23 | used in advertising or otherwise to promote the sale, use or other dealings | |||
24 | in this Software without prior written authorization from The Open Group. | |||
25 | ******************************************************************************/ | |||
26 | /* $XFree86: xc/programs/xsm/saveutil.c,v 1.5 2001/01/17 23:46:31 dawes Exp $ */ | |||
27 | ||||
28 | #include "xsm.h" | |||
29 | #include "log.h" | |||
30 | #include "saveutil.h" | |||
31 | #include "info.h" | |||
32 | ||||
33 | static char session_save_file[PATH_MAX1024]; | |||
34 | ||||
35 | ||||
36 | void | |||
37 | set_session_save_file_name(const char *session_name) | |||
38 | { | |||
39 | const char *p; | |||
40 | ||||
41 | p = getenv ("SM_SAVE_DIR"); | |||
42 | if (!p) | |||
43 | { | |||
44 | p = getenv ("HOME"); | |||
45 | if (!p) | |||
46 | p = "."; | |||
47 | } | |||
48 | ||||
49 | snprintf (session_save_file, sizeof(session_save_file),__builtin___snprintf_chk (session_save_file, sizeof(session_save_file ), 0, __builtin_object_size (session_save_file, 2 > 1 ? 1 : 0), "%s/.XSM-%s", p, session_name) | |||
50 | "%s/.XSM-%s", p, session_name)__builtin___snprintf_chk (session_save_file, sizeof(session_save_file ), 0, __builtin_object_size (session_save_file, 2 > 1 ? 1 : 0), "%s/.XSM-%s", p, session_name); | |||
51 | } | |||
52 | ||||
53 | ||||
54 | ||||
55 | int | |||
56 | ReadSave(const char *session_name, char **sm_id) | |||
57 | { | |||
58 | char *buf; | |||
59 | int buflen; | |||
60 | char *p; | |||
61 | PendingClient *c = NULL((void*)0); | |||
62 | Prop *prop = NULL((void*)0); | |||
63 | PropValue *val; | |||
64 | FILE *f; | |||
65 | int state, i; | |||
66 | int version_number; | |||
67 | ||||
68 | f = fopen(session_save_file, "r"); | |||
69 | if(!f) { | |||
| ||||
70 | if (verbose) | |||
71 | printf("No session save file.\n"); | |||
72 | *sm_id = NULL((void*)0); | |||
73 | return 0; | |||
74 | } | |||
75 | fcntl(fileno(f), F_SETFD2, FD_CLOEXEC1); | |||
76 | if (verbose) | |||
77 | printf("Reading session save file...\n"); | |||
78 | ||||
79 | buf = NULL((void*)0); | |||
80 | buflen = 0; | |||
81 | ||||
82 | /* Read version # */ | |||
83 | getnextline(&buf, &buflen, f); | |||
84 | if((p = strchr(buf, '\n'))) *p = '\0'; | |||
85 | version_number = atoi (buf); | |||
86 | if (version_number > SAVEFILE_VERSION3) | |||
87 | { | |||
88 | if (verbose) | |||
89 | printf("Unsupported version number of session save file.\n"); | |||
90 | *sm_id = NULL((void*)0); | |||
91 | if (buf) | |||
92 | free (buf); | |||
93 | return 0; | |||
94 | } | |||
95 | ||||
96 | /* Read SM's id */ | |||
97 | getnextline(&buf, &buflen, f); | |||
98 | if((p = strchr(buf, '\n'))) *p = '\0'; | |||
99 | *sm_id = XtNewString(buf)((buf) != ((void*)0) ? (__builtin___strcpy_chk (XtMalloc((unsigned )strlen(buf) + 1), buf, __builtin_object_size (XtMalloc((unsigned )strlen(buf) + 1), 2 > 1 ? 1 : 0))) : ((void*)0)); | |||
100 | ||||
101 | /* Read number of clients running in the last session */ | |||
102 | if (version_number >= 2) | |||
103 | { | |||
104 | getnextline(&buf, &buflen, f); | |||
105 | if((p = strchr(buf, '\n'))) *p = '\0'; | |||
106 | num_clients_in_last_session = atoi (buf); | |||
107 | } | |||
108 | ||||
109 | state = 0; | |||
110 | while(getnextline(&buf, &buflen, f)) { | |||
111 | if((p = strchr(buf, '\n'))) *p = '\0'; | |||
112 | for(p = buf; *p && isspace(*p); p++) /* LOOP */; | |||
113 | if(*p == '#') continue; | |||
114 | ||||
115 | if(!*p) | |||
116 | { | |||
117 | if (version_number >= 3 && | |||
118 | ListCount (PendingList) == num_clients_in_last_session) | |||
119 | { | |||
120 | state = 5; | |||
121 | break; | |||
122 | } | |||
123 | else | |||
124 | { | |||
125 | state = 0; | |||
126 | continue; | |||
127 | } | |||
128 | } | |||
129 | ||||
130 | if(!isspace(buf[0])) { | |||
131 | switch(state) { | |||
132 | case 0: | |||
133 | c = (PendingClient *)XtMalloc(sizeof *c); | |||
134 | if(!c) nomem(); | |||
135 | ||||
136 | c->clientId = XtNewString(p)((p) != ((void*)0) ? (__builtin___strcpy_chk (XtMalloc((unsigned )strlen(p) + 1), p, __builtin_object_size (XtMalloc((unsigned )strlen(p) + 1), 2 > 1 ? 1 : 0))) : ((void*)0)); | |||
| ||||
137 | c->clientHostname = NULL((void*)0); /* set in next state */ | |||
138 | ||||
139 | c->props = ListInit(); | |||
140 | if(!c->props) nomem(); | |||
141 | ||||
142 | if(!ListAddLast(PendingList, (char *)c)) nomem(); | |||
143 | ||||
144 | state = 1; | |||
145 | break; | |||
146 | ||||
147 | case 1: | |||
148 | c->clientHostname = XtNewString(p)((p) != ((void*)0) ? (__builtin___strcpy_chk (XtMalloc((unsigned )strlen(p) + 1), p, __builtin_object_size (XtMalloc((unsigned )strlen(p) + 1), 2 > 1 ? 1 : 0))) : ((void*)0)); | |||
149 | state = 2; | |||
150 | break; | |||
151 | ||||
152 | case 2: | |||
153 | case 4: | |||
154 | prop = (Prop *)XtMalloc(sizeof *prop); | |||
155 | if(!prop) nomem(); | |||
156 | ||||
157 | prop->name = XtNewString(p)((p) != ((void*)0) ? (__builtin___strcpy_chk (XtMalloc((unsigned )strlen(p) + 1), p, __builtin_object_size (XtMalloc((unsigned )strlen(p) + 1), 2 > 1 ? 1 : 0))) : ((void*)0)); | |||
158 | prop->values = ListInit(); | |||
159 | if(!prop->values) nomem(); | |||
160 | ||||
161 | prop->type = NULL((void*)0); | |||
162 | ||||
163 | if(!ListAddLast(c->props, (char *)prop)) nomem(); | |||
164 | ||||
165 | state = 3; | |||
166 | break; | |||
167 | ||||
168 | case 3: | |||
169 | prop->type = XtNewString(p)((p) != ((void*)0) ? (__builtin___strcpy_chk (XtMalloc((unsigned )strlen(p) + 1), p, __builtin_object_size (XtMalloc((unsigned )strlen(p) + 1), 2 > 1 ? 1 : 0))) : ((void*)0)); | |||
170 | state = 4; | |||
171 | break; | |||
172 | ||||
173 | default: | |||
174 | fprintf(stderr__stderrp, "state %d\n", state); | |||
175 | fprintf(stderr__stderrp, | |||
176 | "Corrupt save file line ignored:\n%s\n", buf); | |||
177 | continue; | |||
178 | } | |||
179 | } else { | |||
180 | if (state != 4) { | |||
181 | fprintf(stderr__stderrp, "Corrupt save file line ignored:\n%s\n", buf); | |||
182 | continue; | |||
183 | } | |||
184 | val = (PropValue *)XtMalloc(sizeof *val); | |||
185 | if(!val) nomem(); | |||
186 | ||||
187 | if (strcmp (prop->type, SmCARD8"CARD8") == 0) | |||
188 | { | |||
189 | val->length = 1; | |||
190 | val->value = (XtPointer) XtMalloc (1); | |||
191 | *((char *)(val->value)) = atoi (p); | |||
192 | } | |||
193 | else | |||
194 | { | |||
195 | val->length = strlen(p); | |||
196 | val->value = XtNewString(p)((p) != ((void*)0) ? (__builtin___strcpy_chk (XtMalloc((unsigned )strlen(p) + 1), p, __builtin_object_size (XtMalloc((unsigned )strlen(p) + 1), 2 > 1 ? 1 : 0))) : ((void*)0)); | |||
197 | } | |||
198 | ||||
199 | if(!ListAddLast(prop->values, (char *)val)) nomem(); | |||
200 | } | |||
201 | } | |||
202 | ||||
203 | /* Read commands for non-session aware clients */ | |||
204 | ||||
205 | if (state == 5) | |||
206 | { | |||
207 | String strbuf; | |||
208 | int bufsize = 0; | |||
209 | ||||
210 | getnextline(&buf, &buflen, f); | |||
211 | if((p = strchr(buf, '\n'))) *p = '\0'; | |||
212 | non_session_aware_count = atoi (buf); | |||
213 | ||||
214 | if (non_session_aware_count > 0) | |||
215 | { | |||
216 | non_session_aware_clients = (char **) malloc ( | |||
217 | non_session_aware_count * sizeof (char *)); | |||
218 | ||||
219 | for (i = 0; i < non_session_aware_count; i++) | |||
220 | { | |||
221 | getnextline(&buf, &buflen, f); | |||
222 | if((p = strchr(buf, '\n'))) *p = '\0'; | |||
223 | non_session_aware_clients[i] = (char *) malloc ( | |||
224 | strlen (buf) + 2); | |||
225 | strcpy (non_session_aware_clients[i], buf)__builtin___strcpy_chk (non_session_aware_clients[i], buf, __builtin_object_size (non_session_aware_clients[i], 2 > 1 ? 1 : 0)); | |||
226 | bufsize += (strlen (buf) + 1); | |||
227 | } | |||
228 | ||||
229 | strbuf = (String) malloc (bufsize + 1); | |||
230 | strbuf[0] = '\0'; | |||
231 | ||||
232 | for (i = 0; i < non_session_aware_count; i++) | |||
233 | { | |||
234 | strcat (strbuf, non_session_aware_clients[i])__builtin___strcat_chk (strbuf, non_session_aware_clients[i], __builtin_object_size (strbuf, 2 > 1 ? 1 : 0)); | |||
235 | strcat (strbuf, "\n")__builtin___strcat_chk (strbuf, "\n", __builtin_object_size ( strbuf, 2 > 1 ? 1 : 0)); | |||
236 | } | |||
237 | ||||
238 | XtVaSetValues (manualRestartCommands, | |||
239 | XtNstring((char*)&XtStrings[733]), strbuf, | |||
240 | NULL((void*)0)); | |||
241 | ||||
242 | free ((char *) strbuf); | |||
243 | } | |||
244 | } | |||
245 | ||||
246 | fclose(f); | |||
247 | ||||
248 | if (buf) | |||
249 | free (buf); | |||
250 | ||||
251 | return 1; | |||
252 | } | |||
253 | ||||
254 | ||||
255 | ||||
256 | static void | |||
257 | SaveClient(FILE *f, ClientRec *client) | |||
258 | { | |||
259 | List *pl; | |||
260 | ||||
261 | fprintf (f, "%s\n", client->clientId); | |||
262 | fprintf (f, "%s\n", client->clientHostname); | |||
263 | ||||
264 | for (pl = ListFirst (client->props); pl; pl = ListNext (pl)) | |||
265 | { | |||
266 | Prop *pprop = (Prop *) pl->thing; | |||
267 | List *pj, *vl; | |||
268 | PropValue *pval; | |||
269 | ||||
270 | fprintf (f, "%s\n", pprop->name); | |||
271 | fprintf (f, "%s\n", pprop->type); | |||
272 | ||||
273 | if (strcmp (pprop->type, SmCARD8"CARD8") == 0) | |||
274 | { | |||
275 | char *card8; | |||
276 | int value; | |||
277 | ||||
278 | vl = ListFirst (pprop->values); | |||
279 | pval = (PropValue *) vl->thing; | |||
280 | ||||
281 | card8 = pval->value; | |||
282 | value = *card8; | |||
283 | fprintf(f, "\t%d\n", value); | |||
284 | } | |||
285 | else | |||
286 | { | |||
287 | for (pj = ListFirst (pprop->values); pj; pj = ListNext (pj)) | |||
288 | { | |||
289 | pval = (PropValue *) pj->thing; | |||
290 | fprintf (f, "\t%s\n", (char *)pval->value); | |||
291 | } | |||
292 | } | |||
293 | } | |||
294 | ||||
295 | fprintf (f, "\n"); | |||
296 | } | |||
297 | ||||
298 | ||||
299 | ||||
300 | void | |||
301 | WriteSave(const char *sm_id) | |||
302 | { | |||
303 | ClientRec *client; | |||
304 | FILE *f; | |||
305 | List *cl; | |||
306 | String commands; | |||
307 | char *p, *c; | |||
308 | int count; | |||
309 | ||||
310 | f = fopen (session_save_file, "w"); | |||
311 | ||||
312 | if (!f) | |||
313 | { | |||
314 | char msg[256]; | |||
315 | ||||
316 | snprintf (msg, sizeof(msg), "%s: Error creating session save file %s",__builtin___snprintf_chk (msg, sizeof(msg), 0, __builtin_object_size (msg, 2 > 1 ? 1 : 0), "%s: Error creating session save file %s" , Argv[0], session_save_file) | |||
317 | Argv[0], session_save_file)__builtin___snprintf_chk (msg, sizeof(msg), 0, __builtin_object_size (msg, 2 > 1 ? 1 : 0), "%s: Error creating session save file %s" , Argv[0], session_save_file); | |||
318 | add_log_text (msg); | |||
319 | perror (msg); | |||
320 | } | |||
321 | else | |||
322 | { | |||
323 | fcntl(fileno(f), F_SETFD2, FD_CLOEXEC1); | |||
324 | fprintf (f, "%d\n", SAVEFILE_VERSION3); | |||
325 | fprintf (f, "%s\n", sm_id); | |||
326 | ||||
327 | count = 0; | |||
328 | for (cl = ListFirst (RunningList); cl; cl = ListNext (cl)) | |||
329 | { | |||
330 | client = (ClientRec *) cl->thing; | |||
331 | ||||
332 | if (client->restartHint != SmRestartNever3) | |||
333 | count++; | |||
334 | } | |||
335 | count += ListCount (RestartAnywayList); | |||
336 | ||||
337 | fprintf (f, "%d\n", count); | |||
338 | if (count == 0) | |||
339 | fprintf (f, "\n"); | |||
340 | ||||
341 | for (cl = ListFirst (RunningList); cl; cl = ListNext (cl)) | |||
342 | { | |||
343 | client = (ClientRec *) cl->thing; | |||
344 | ||||
345 | if (client->restartHint == SmRestartNever3) | |||
346 | continue; | |||
347 | ||||
348 | SaveClient (f, client); | |||
349 | } | |||
350 | ||||
351 | for (cl = ListFirst (RestartAnywayList); cl; cl = ListNext (cl)) | |||
352 | { | |||
353 | client = (ClientRec *) cl->thing; | |||
354 | ||||
355 | SaveClient (f, client); | |||
356 | } | |||
357 | ||||
358 | ||||
359 | /* Save the non-session aware clients */ | |||
360 | ||||
361 | XtVaGetValues (manualRestartCommands, | |||
362 | XtNstring((char*)&XtStrings[733]), &commands, | |||
363 | NULL((void*)0)); | |||
364 | ||||
365 | p = c = commands; | |||
366 | count = 0; | |||
367 | ||||
368 | while (*p) | |||
369 | { | |||
370 | if (*p == '\n') | |||
371 | { | |||
372 | if (p != c) | |||
373 | count++; | |||
374 | c = p + 1; | |||
375 | } | |||
376 | p++; | |||
377 | } | |||
378 | if (p != c) | |||
379 | count++; | |||
380 | ||||
381 | fprintf (f, "%d\n", count); | |||
382 | ||||
383 | p = c = commands; | |||
384 | ||||
385 | while (*p) | |||
386 | { | |||
387 | if (*p == '\n') | |||
388 | { | |||
389 | if (p != c) | |||
390 | { | |||
391 | *p = '\0'; | |||
392 | fprintf (f, "%s\n", c); | |||
393 | *p = '\n'; | |||
394 | } | |||
395 | c = p + 1; | |||
396 | } | |||
397 | p++; | |||
398 | } | |||
399 | ||||
400 | if (p != c) | |||
401 | fprintf (f, "%s\n", c); | |||
402 | ||||
403 | fclose (f); | |||
404 | } | |||
405 | } | |||
406 | ||||
407 | ||||
408 | ||||
409 | Statusint | |||
410 | DeleteSession(const char *session_name) | |||
411 | { | |||
412 | char *buf; | |||
413 | int buflen; | |||
414 | char *p; | |||
415 | const char *dir; | |||
416 | FILE *f; | |||
417 | int state; | |||
418 | int foundDiscard; | |||
419 | char filename[256]; | |||
420 | int version_number; | |||
421 | ||||
422 | dir = getenv ("SM_SAVE_DIR"); | |||
423 | if (!dir) | |||
424 | { | |||
425 | dir = getenv ("HOME"); | |||
426 | if (!dir) | |||
427 | dir = "."; | |||
428 | } | |||
429 | ||||
430 | snprintf (filename, sizeof(filename), "%s/.XSM-%s", dir, session_name)__builtin___snprintf_chk (filename, sizeof(filename), 0, __builtin_object_size (filename, 2 > 1 ? 1 : 0), "%s/.XSM-%s", dir, session_name ); | |||
431 | ||||
432 | f = fopen(filename, "r"); | |||
433 | if(!f) { | |||
434 | return (0); | |||
435 | } | |||
436 | fcntl(fileno(f), F_SETFD2, FD_CLOEXEC1); | |||
437 | ||||
438 | buf = NULL((void*)0); | |||
439 | buflen = 0; | |||
440 | ||||
441 | /* Read version # */ | |||
442 | getnextline(&buf, &buflen, f); | |||
443 | if((p = strchr(buf, '\n'))) *p = '\0'; | |||
444 | version_number = atoi (buf); | |||
445 | if (version_number > SAVEFILE_VERSION3) | |||
446 | { | |||
447 | if (verbose) | |||
448 | printf("Can't delete session save file - incompatible version.\n"); | |||
449 | if (buf) | |||
450 | free (buf); | |||
451 | return (0); | |||
452 | } | |||
453 | ||||
454 | /* Skip SM's id */ | |||
455 | getnextline(&buf, &buflen, f); | |||
456 | ||||
457 | /* Skip number of clients running in the last session */ | |||
458 | if (version_number >= 2) | |||
459 | getnextline(&buf, &buflen, f); | |||
460 | ||||
461 | state = 0; | |||
462 | foundDiscard = 0; | |||
463 | while(getnextline(&buf, &buflen, f)) { | |||
464 | if((p = strchr(buf, '\n'))) *p = '\0'; | |||
465 | for(p = buf; *p && isspace(*p); p++) /* LOOP */; | |||
466 | if(*p == '#') continue; | |||
467 | ||||
468 | if(!*p) { | |||
469 | state = 0; | |||
470 | foundDiscard = 0; | |||
471 | continue; | |||
472 | } | |||
473 | ||||
474 | if(!isspace(buf[0])) { | |||
475 | switch(state) { | |||
476 | case 0: | |||
477 | state = 1; | |||
478 | break; | |||
479 | ||||
480 | case 1: | |||
481 | state = 2; | |||
482 | break; | |||
483 | ||||
484 | case 2: | |||
485 | case 4: | |||
486 | if (strcmp (p, SmDiscardCommand"DiscardCommand") == 0) | |||
487 | foundDiscard = 1; | |||
488 | state = 3; | |||
489 | break; | |||
490 | ||||
491 | case 3: | |||
492 | state = 4; | |||
493 | break; | |||
494 | ||||
495 | default: | |||
496 | continue; | |||
497 | } | |||
498 | } else { | |||
499 | if (state != 4) { | |||
500 | continue; | |||
501 | } | |||
502 | if (foundDiscard) | |||
503 | { | |||
504 | execute_system_command (p); /* Discard Command */ | |||
505 | foundDiscard = 0; | |||
506 | } | |||
507 | } | |||
508 | } | |||
509 | ||||
510 | fclose(f); | |||
511 | ||||
512 | if (buf) | |||
513 | free (buf); | |||
514 | ||||
515 | return ((remove (filename) == -1) ? 0 : 1); | |||
516 | } | |||
517 | ||||
518 | ||||
519 | ||||
520 | Boolint | |||
521 | getnextline(char **pbuf, int *plen, FILE *f) | |||
522 | { | |||
523 | int c; | |||
524 | int i; | |||
525 | ||||
526 | i = 0; | |||
527 | while(1) { | |||
528 | if(i+2 > *plen) { | |||
529 | if(*plen) *plen *= 2; | |||
530 | else *plen = BUFSIZ1024; | |||
531 | if(*pbuf) *pbuf = (char *) realloc(*pbuf, *plen + 1); | |||
532 | else *pbuf = (char *) malloc(*plen + 1); | |||
533 | } | |||
534 | c = getc(f); | |||
535 | if(c == EOF(-1)) break; | |||
536 | (*pbuf)[i++] = c; | |||
537 | if(c == '\n') break; | |||
538 | } | |||
539 | (*pbuf)[i] = '\0'; | |||
540 | return i; | |||
541 | } |