Bug Summary

File:session.c
Location:line 499, column 10
Description:Branch condition evaluates to a garbage value

Annotated Source Code

1/******************************************************************************
2
3Copyright 1994, 1998 The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21Except as contained in this notice, the name of The Open Group shall not be
22used in advertising or otherwise to promote the sale, use or other dealings
23in this Software without prior written authorization from The Open Group.
24
25Author: Ralph Mor, X Consortium
26******************************************************************************/
27
28#ifdef HAVE_CONFIG_H1
29# include "config.h"
30#endif
31
32#include <X11/Xos.h>
33
34#ifndef X_NOT_POSIX
35#ifdef _POSIX_SOURCE
36#include <limits.h>
37#else
38#define _POSIX_SOURCE
39#include <limits.h>
40#undef _POSIX_SOURCE
41#endif
42#endif /* X_NOT_POSIX */
43#ifndef PATH_MAX1024
44#include <sys/param.h>
45#ifndef PATH_MAX1024
46#ifdef MAXPATHLEN
47#define PATH_MAX1024 MAXPATHLEN
48#else
49#define PATH_MAX1024 1024
50#endif
51#endif
52#endif /* PATH_MAX */
53#ifdef HAVE_MKSTEMP1
54#include <unistd.h>
55#endif
56
57#include <X11/Xlib.h>
58#include <X11/SM/SMlib.h>
59#include <X11/Xatom.h>
60#include <stdio.h>
61#include "twm.h"
62#include "screen.h"
63#include "session.h"
64
65SmcConn smcConn = NULL((void*)0);
66static XtInputId iceInputId;
67static char *twm_clientId;
68static TWMWinConfigEntry *winConfigHead = NULL((void*)0);
69static Boolint sent_save_done = 0;
70
71#define SAVEFILE_VERSION2 2
72
73#ifndef HAVE_MKSTEMP1
74static char *unique_filename ( const char *path, const char *prefix );
75#else
76static char *unique_filename ( const char *path, const char *prefix, int *pFd );
77#endif
78
79
80static char *
81GetClientID (Window window)
82{
83 char *client_id = NULL((void*)0);
84 Window client_leader;
85 XTextProperty tp;
86 Atom actual_type;
87 int actual_format;
88 unsigned long nitems;
89 unsigned long bytes_after;
90 unsigned char *prop = NULL((void*)0);
91
92 if (XGetWindowProperty (dpy, window, _XA_WM_CLIENT_LEADERTwmAtoms[9],
93 0L, 1L, False0, AnyPropertyType0L, &actual_type, &actual_format,
94 &nitems, &bytes_after, &prop) == Success0)
95 {
96 if (actual_type == XA_WINDOW((Atom) 33) && actual_format == 32 &&
97 nitems == 1 && bytes_after == 0)
98 {
99 client_leader = *((Window *) prop);
100
101 if (XGetTextProperty (dpy, client_leader, &tp, _XA_SM_CLIENT_IDTwmAtoms[8]))
102 {
103 if (tp.encoding == XA_STRING((Atom) 31) &&
104 tp.format == 8 && tp.nitems != 0)
105 client_id = (char *) tp.value;
106 }
107 }
108
109 if (prop)
110 XFree (prop);
111 }
112
113 return client_id;
114}
115
116
117
118static char *
119GetWindowRole (Window window)
120{
121 XTextProperty tp;
122
123 if (XGetTextProperty (dpy, window, &tp, _XA_WM_WINDOW_ROLETwmAtoms[10]))
124 {
125 if (tp.encoding == XA_STRING((Atom) 31) && tp.format == 8 && tp.nitems != 0)
126 return ((char *) tp.value);
127 }
128
129 return NULL((void*)0);
130}
131
132
133
134static int
135write_byte (FILE *file, unsigned char b)
136{
137 if (fwrite ((char *) &b, 1, 1, file) != 1)
138 return 0;
139 return 1;
140}
141
142
143static int
144write_ushort (FILE *file, unsigned short s)
145{
146 unsigned char file_short[2];
147
148 file_short[0] = (s & (unsigned)0xff00) >> 8;
149 file_short[1] = s & 0xff;
150 if (fwrite ((char *) file_short, (int) sizeof (file_short), 1, file) != 1)
151 return 0;
152 return 1;
153}
154
155
156static int
157write_short (FILE *file, short s)
158{
159 unsigned char file_short[2];
160
161 file_short[0] = (s & (unsigned)0xff00) >> 8;
162 file_short[1] = s & 0xff;
163 if (fwrite ((char *) file_short, (int) sizeof (file_short), 1, file) != 1)
164 return 0;
165 return 1;
166}
167
168
169static int
170write_counted_string (FILE *file, char *string)
171{
172 if (string)
173 {
174 unsigned char count = strlen (string);
175
176 if (write_byte (file, count) == 0)
177 return 0;
178 if (fwrite (string, (int) sizeof (char), (int) count, file) != count)
179 return 0;
180 }
181 else
182 {
183 if (write_byte (file, 0) == 0)
184 return 0;
185 }
186
187 return 1;
188}
189
190
191
192static int
193read_byte (FILE *file, unsigned char *bp)
194{
195 if (fread ((char *) bp, 1, 1, file) != 1)
196 return 0;
197 return 1;
198}
199
200
201static int
202read_ushort (FILE *file, unsigned short *shortp)
203{
204 unsigned char file_short[2];
205
206 if (fread ((char *) file_short, (int) sizeof (file_short), 1, file) != 1)
207 return 0;
208 *shortp = file_short[0] * 256 + file_short[1];
209 return 1;
210}
211
212
213static int
214read_short (FILE *file, short *shortp)
215{
216 unsigned char file_short[2];
217
218 if (fread ((char *) file_short, (int) sizeof (file_short), 1, file) != 1)
219 return 0;
220 *shortp = file_short[0] * 256 + file_short[1];
221 return 1;
222}
223
224
225static int
226read_counted_string (FILE *file, char **stringp)
227{
228 unsigned char len;
229 char *data;
230
231 if (read_byte (file, &len) == 0)
232 return 0;
233 if (len == 0) {
234 data = 0;
235 } else {
236 data = malloc ((unsigned) len + 1);
237 if (!data)
238 return 0;
239 if (fread (data, (int) sizeof (char), (int) len, file) != len) {
240 free (data);
241 return 0;
242 }
243 data[len] = '\0';
244 }
245 *stringp = data;
246 return 1;
247}
248
249
250
251/*
252 * An entry in the saved window config file looks like this:
253 *
254 * FIELD BYTES
255 * ----- ----
256 * SM_CLIENT_ID ID len 1 (may be 0)
257 * SM_CLIENT_ID LIST of bytes (may be NULL)
258 *
259 * WM_WINDOW_ROLE length 1 (may be 0)
260 * WM_WINDOW_ROLE LIST of bytes (may be NULL)
261 *
262 * if no WM_WINDOW_ROLE (length = 0)
263 *
264 * WM_CLASS "res name" length 1
265 * WM_CLASS "res name" LIST of bytes
266 * WM_CLASS "res class" length 1
267 * WM_CLASS "res class" LIST of bytes
268 * WM_NAME length 1 (0 if name changed)
269 * WM_NAME LIST of bytes
270 * WM_COMMAND arg count 1 (0 if no SM_CLIENT_ID)
271 * For each arg in WM_COMMAND
272 * arg length 1
273 * arg LIST of bytes
274 *
275 * Iconified bool 1
276 * Icon info present bool 1
277 *
278 * if icon info present
279 * icon x 2
280 * icon y 2
281 *
282 * Geom x 2
283 * Geom y 2
284 * Geom width 2
285 * Geom height 2
286 *
287 * Width ever changed by user 1
288 * Height ever changed by user 1
289 */
290
291static int
292WriteWinConfigEntry (FILE *configFile, TwmWindow *theWindow,
293 char *clientId, char *windowRole)
294{
295 char **wm_command;
296 int wm_command_count, i;
297
298 if (!write_counted_string (configFile, clientId))
299 return 0;
300
301 if (!write_counted_string (configFile, windowRole))
302 return 0;
303
304 if (!windowRole)
305 {
306 if (!write_counted_string (configFile, theWindow->class.res_name))
307 return 0;
308 if (!write_counted_string (configFile, theWindow->class.res_class))
309 return 0;
310 if (theWindow->nameChanged)
311 {
312 /*
313 * If WM_NAME changed on this window, we can't use it as
314 * a criteria for looking up window configurations. See the
315 * longer explanation in the GetWindowConfig() function below.
316 */
317
318 if (!write_counted_string (configFile, NULL((void*)0)))
319 return 0;
320 }
321 else
322 {
323 if (!write_counted_string (configFile, theWindow->name))
324 return 0;
325 }
326
327 wm_command = NULL((void*)0);
328 wm_command_count = 0;
329 XGetCommand (dpy, theWindow->w, &wm_command, &wm_command_count);
330
331 if (clientId || !wm_command || wm_command_count == 0)
332 {
333 if (!write_byte (configFile, 0))
334 return 0;
335 }
336 else
337 {
338 if (!write_byte (configFile, (char) wm_command_count))
339 return 0;
340 for (i = 0; i < wm_command_count; i++)
341 if (!write_counted_string (configFile, wm_command[i]))
342 return 0;
343 XFreeStringList (wm_command);
344 }
345 }
346
347 if (!write_byte (configFile, theWindow->icon ? 1 : 0)) /* iconified */
348 return 0;
349
350 if (!write_byte (configFile, theWindow->icon_w ? 1 : 0)) /* icon exists */
351 return 0;
352
353 if (theWindow->icon_w)
354 {
355 int icon_x, icon_y;
356
357 XGetGeometry (dpy, theWindow->icon_w, &JunkRoot, &icon_x,
358 &icon_y, &JunkWidth, &JunkHeight, &JunkBW, &JunkDepth);
359
360 if (!write_short (configFile, (short) icon_x))
361 return 0;
362 if (!write_short (configFile, (short) icon_y))
363 return 0;
364 }
365
366 if (!write_short (configFile, (short) theWindow->frame_x))
367 return 0;
368 if (!write_short (configFile, (short) theWindow->frame_y))
369 return 0;
370 if (!write_ushort (configFile, (unsigned short) theWindow->attr.width))
371 return 0;
372 if (!write_ushort (configFile, (unsigned short) theWindow->attr.height))
373 return 0;
374
375 if (!write_byte (configFile, theWindow->widthEverChangedByUser ? 1 : 0))
376 return 0;
377
378 if (!write_byte (configFile, theWindow->heightEverChangedByUser ? 1 : 0))
379 return 0;
380
381 return 1;
382}
383
384
385static int
386ReadWinConfigEntry (FILE *configFile, unsigned short version,
387 TWMWinConfigEntry **pentry)
388{
389 TWMWinConfigEntry *entry;
390 unsigned char byte;
391 int i;
392
393 *pentry = entry = malloc (sizeof (TWMWinConfigEntry));
394 if (!*pentry)
1
Taking false branch
395 return 0;
396
397 entry->tag = 0;
398 entry->client_id = NULL((void*)0);
399 entry->window_role = NULL((void*)0);
400 entry->class.res_name = NULL((void*)0);
401 entry->class.res_class = NULL((void*)0);
402 entry->wm_name = NULL((void*)0);
403 entry->wm_command = NULL((void*)0);
404 entry->wm_command_count = 0;
405
406 if (!read_counted_string (configFile, &entry->client_id))
2
Taking false branch
407 goto give_up;
408
409 if (!read_counted_string (configFile, &entry->window_role))
3
Taking false branch
410 goto give_up;
411
412 if (!entry->window_role)
4
Taking true branch
413 {
414 if (!read_counted_string (configFile, &entry->class.res_name))
5
Taking false branch
415 goto give_up;
416 if (!read_counted_string (configFile, &entry->class.res_class))
6
Taking false branch
417 goto give_up;
418 if (!read_counted_string (configFile, &entry->wm_name))
7
Taking false branch
419 goto give_up;
420
421 if (!read_byte (configFile, &byte))
8
Taking false branch
422 goto give_up;
423 entry->wm_command_count = byte;
424
425 if (entry->wm_command_count == 0)
9
Taking false branch
426 entry->wm_command = NULL((void*)0);
427 else
428 {
429 entry->wm_command = malloc (entry->wm_command_count *
430 sizeof (char *));
431
432 if (!entry->wm_command)
10
Taking false branch
433 goto give_up;
434
435 for (i = 0; i < entry->wm_command_count; i++)
11
Loop condition is true. Entering loop body
436 if (!read_counted_string (configFile, &entry->wm_command[i]))
12
Taking true branch
437 goto give_up;
13
Control jumps to line 486
438 }
439 }
440
441 if (!read_byte (configFile, &byte))
442 goto give_up;
443 entry->iconified = byte;
444
445 if (!read_byte (configFile, &byte))
446 goto give_up;
447 entry->icon_info_present = byte;
448
449 if (entry->icon_info_present)
450 {
451 if (!read_short (configFile, (short *) &entry->icon_x))
452 goto give_up;
453 if (!read_short (configFile, (short *) &entry->icon_y))
454 goto give_up;
455 }
456
457 if (!read_short (configFile, (short *) &entry->x))
458 goto give_up;
459 if (!read_short (configFile, (short *) &entry->y))
460 goto give_up;
461 if (!read_ushort (configFile, &entry->width))
462 goto give_up;
463 if (!read_ushort (configFile, &entry->height))
464 goto give_up;
465
466 if (version > 1)
467 {
468 if (!read_byte (configFile, &byte))
469 goto give_up;
470 entry->width_ever_changed_by_user = byte;
471
472 if (!read_byte (configFile, &byte))
473 goto give_up;
474 entry->height_ever_changed_by_user = byte;
475 }
476 else
477 {
478 entry->width_ever_changed_by_user = False0;
479 entry->height_ever_changed_by_user = False0;
480 }
481
482 return 1;
483
484give_up:
485
486 if (entry->client_id)
14
Taking true branch
487 free (entry->client_id);
488 if (entry->window_role)
15
Taking false branch
489 free (entry->window_role);
490 if (entry->class.res_name)
16
Taking true branch
491 free (entry->class.res_name);
492 if (entry->class.res_class)
17
Taking false branch
493 free (entry->class.res_class);
494 if (entry->wm_name)
18
Taking true branch
495 free (entry->wm_name);
496 if (entry->wm_command_count && entry->wm_command)
19
Taking true branch
497 {
498 for (i = 0; i < entry->wm_command_count; i++)
20
Loop condition is true. Entering loop body
499 if (entry->wm_command[i])
21
Branch condition evaluates to a garbage value
500 free (entry->wm_command[i]);
501 }
502 if (entry->wm_command)
503 free (entry->wm_command);
504
505 free (entry);
506 *pentry = NULL((void*)0);
507
508 return 0;
509}
510
511
512void
513ReadWinConfigFile (char *filename)
514{
515 FILE *configFile;
516 TWMWinConfigEntry *entry;
517 int done = 0;
518 unsigned short version = 0;
519
520 configFile = fopen (filename, "rb");
521 if (!configFile)
522 return;
523
524 if (!read_ushort (configFile, &version) ||
525 version > SAVEFILE_VERSION2)
526 {
527 done = 1;
528 }
529
530 while (!done)
531 {
532 if (ReadWinConfigEntry (configFile, version, &entry))
533 {
534 entry->next = winConfigHead;
535 winConfigHead = entry;
536 }
537 else
538 done = 1;
539 }
540
541 fclose (configFile);
542}
543
544
545
546int
547GetWindowConfig (
548 TwmWindow *theWindow,
549 short *x, short *y,
550 unsigned short *width, unsigned short *height,
551 Boolint *iconified,
552 Boolint *icon_info_present,
553 short *icon_x, short *icon_y,
554 Boolint *width_ever_changed_by_user,
555 Boolint *height_ever_changed_by_user)
556{
557 char *clientId, *windowRole;
558 TWMWinConfigEntry *ptr;
559 int found = 0;
560
561 ptr = winConfigHead;
562
563 if (!ptr)
564 return 0;
565
566 clientId = GetClientID (theWindow->w);
567 windowRole = GetWindowRole (theWindow->w);
568
569 while (ptr && !found)
570 {
571 int client_id_match = (!clientId && !ptr->client_id) ||
572 (clientId && ptr->client_id &&
573 strcmp (clientId, ptr->client_id) == 0);
574
575 if (!ptr->tag && client_id_match)
576 {
577 if (windowRole || ptr->window_role)
578 {
579 found = (windowRole && ptr->window_role &&
580 strcmp (windowRole, ptr->window_role) == 0);
581 }
582 else
583 {
584 /*
585 * Compare WM_CLASS + only compare WM_NAME if the
586 * WM_NAME in the saved file is non-NULL. If the
587 * WM_NAME in the saved file is NULL, this means that
588 * the client changed the value of WM_NAME during the
589 * session, and we can not use it as a criteria for
590 * our search. For example, with xmh, at save time
591 * the window name might be "xmh: folderY". However,
592 * if xmh does not properly restore state when it is
593 * restarted, the initial window name might be
594 * "xmh: folderX". This would cause the window manager
595 * to fail in finding the saved window configuration.
596 * The best we can do is ignore WM_NAME if its value
597 * changed in the previous session.
598 */
599
600 if (strcmp (theWindow->class.res_name,
601 ptr->class.res_name) == 0 &&
602 strcmp (theWindow->class.res_class,
603 ptr->class.res_class) == 0 &&
604 (ptr->wm_name == NULL((void*)0) ||
605 strcmp (theWindow->name, ptr->wm_name) == 0))
606 {
607 if (clientId)
608 {
609 /*
610 * If a client ID was present, we should not check
611 * WM_COMMAND because Xt will put a -xtsessionID arg
612 * on the command line.
613 */
614
615 found = 1;
616 }
617 else
618 {
619 /*
620 * For non-XSMP clients, also check WM_COMMAND.
621 */
622
623 char **wm_command = NULL((void*)0);
624 int wm_command_count = 0, i;
625
626 XGetCommand (dpy, theWindow->w,
627 &wm_command, &wm_command_count);
628
629 if (wm_command_count == ptr->wm_command_count)
630 {
631 for (i = 0; i < wm_command_count; i++)
632 if (strcmp (wm_command[i],
633 ptr->wm_command[i]) != 0)
634 break;
635
636 if (i == wm_command_count)
637 found = 1;
638 }
639 }
640 }
641 }
642 }
643
644 if (!found)
645 ptr = ptr->next;
646 }
647
648 if (found)
649 {
650 *x = ptr->x;
651 *y = ptr->y;
652 *width = ptr->width;
653 *height = ptr->height;
654 *iconified = ptr->iconified;
655 *icon_info_present = ptr->icon_info_present;
656 *width_ever_changed_by_user = ptr->width_ever_changed_by_user;
657 *height_ever_changed_by_user = ptr->height_ever_changed_by_user;
658
659 if (*icon_info_present)
660 {
661 *icon_x = ptr->icon_x;
662 *icon_y = ptr->icon_y;
663 }
664 ptr->tag = 1;
665 }
666 else
667 *iconified = 0;
668
669 if (clientId)
670 XFree (clientId);
671
672 if (windowRole)
673 XFree (windowRole);
674
675 return found;
676}
677
678
679
680#ifndef HAVE_MKSTEMP1
681static char *
682unique_filename (
683 const char *path,
684 const char *prefix)
685#else
686static char *
687unique_filename (
688 const char *path,
689 const char *prefix,
690 int *pFd)
691#endif
692
693{
694#ifndef HAVE_MKSTEMP1
695#ifndef X_NOT_POSIX
696 return ((char *) tempnam (path, prefix));
697#else
698 char tempFile[PATH_MAX1024];
699 char *tmp;
700
701 snprintf (tempFile, sizeof(tempFile), "%s/%sXXXXXX", path, prefix)__builtin___snprintf_chk (tempFile, sizeof(tempFile), 0, __builtin_object_size
(tempFile, 2 > 1 ? 1 : 0), "%s/%sXXXXXX", path, prefix)
;
702 tmp = (char *) mktemp (tempFile);
703 if (tmp)
704 return strdup (tmp);
705 else
706 return (NULL((void*)0));
707#endif
708#else
709 char tempFile[PATH_MAX1024];
710 char *ptr;
711
712 snprintf (tempFile, sizeof(tempFile), "%s/%sXXXXXX", path, prefix)__builtin___snprintf_chk (tempFile, sizeof(tempFile), 0, __builtin_object_size
(tempFile, 2 > 1 ? 1 : 0), "%s/%sXXXXXX", path, prefix)
;
713 ptr = strdup (tempFile);
714 if (ptr != NULL((void*)0))
715 *pFd = mkstemp (ptr);
716 return ptr;
717#endif
718}
719
720
721
722static void
723SaveYourselfPhase2CB (SmcConn smcConn, SmPointer clientData)
724{
725 int scrnum;
726 ScreenInfo *theScreen;
727 TwmWindow *theWindow;
728 char *clientId, *windowRole;
729 FILE *configFile = NULL((void*)0);
730 const char *path;
731 char *filename = NULL((void*)0);
732 Boolint success = False0;
733 SmProp prop1, prop2, prop3, *props[3];
734 SmPropValue prop1val, prop2val, prop3val;
735 char discardCommand[80];
736 int numVals, i;
737 static int first_time = 1;
738#ifdef HAVE_MKSTEMP1
739 int fd;
740#endif
741
742 if (first_time)
743 {
744 char userId[20];
745 char hint = SmRestartIfRunning0;
746
747 prop1.name = SmProgram"Program";
748 prop1.type = SmARRAY8"ARRAY8";
749 prop1.num_vals = 1;
750 prop1.vals = &prop1val;
751 prop1val.value = Argv[0];
752 prop1val.length = strlen (Argv[0]);
753
754 snprintf (userId, sizeof(userId), "%ld", (long)getuid())__builtin___snprintf_chk (userId, sizeof(userId), 0, __builtin_object_size
(userId, 2 > 1 ? 1 : 0), "%ld", (long)getuid())
;
755 prop2.name = SmUserID"UserID";
756 prop2.type = SmARRAY8"ARRAY8";
757 prop2.num_vals = 1;
758 prop2.vals = &prop2val;
759 prop2val.value = (SmPointer) userId;
760 prop2val.length = strlen (userId);
761
762 prop3.name = SmRestartStyleHint"RestartStyleHint";
763 prop3.type = SmCARD8"CARD8";
764 prop3.num_vals = 1;
765 prop3.vals = &prop3val;
766 prop3val.value = (SmPointer) &hint;
767 prop3val.length = 1;
768
769 props[0] = &prop1;
770 props[1] = &prop2;
771 props[2] = &prop3;
772
773 SmcSetProperties (smcConn, 3, props);
774
775 first_time = 0;
776 }
777
778 path = getenv ("SM_SAVE_DIR");
779 if (!path)
780 {
781 path = getenv ("HOME");
782 if (!path)
783 path = ".";
784 }
785#ifndef HAVE_MKSTEMP1
786 if ((filename = unique_filename (path, ".twm")) == NULL((void*)0))
787 goto bad;
788
789 if (!(configFile = fopen (filename, "wb")))
790 goto bad;
791#else
792 if ((filename = unique_filename (path, ".twm", &fd)) == NULL((void*)0))
793 goto bad;
794
795 if (!(configFile = fdopen(fd, "wb")))
796 goto bad;
797#endif
798
799 if (!write_ushort (configFile, SAVEFILE_VERSION2))
800 goto bad;
801
802 success = True1;
803
804 for (scrnum = 0; scrnum < NumScreens && success; scrnum++)
805 {
806 if (ScreenList[scrnum] != NULL((void*)0))
807 {
808 theScreen = ScreenList[scrnum];
809 theWindow = theScreen->TwmRoot.next;
810
811 while (theWindow && success)
812 {
813 clientId = GetClientID (theWindow->w);
814 windowRole = GetWindowRole (theWindow->w);
815
816 if (!WriteWinConfigEntry (configFile, theWindow,
817 clientId, windowRole))
818 success = False0;
819
820 if (clientId)
821 XFree (clientId);
822
823 if (windowRole)
824 XFree (windowRole);
825
826 theWindow = theWindow->next;
827 }
828 }
829 }
830
831 prop1.name = SmRestartCommand"RestartCommand";
832 prop1.type = SmLISTofARRAY8"LISTofARRAY8";
833
834 prop1.vals = malloc ((Argc + 4) * sizeof (SmPropValue));
835
836 if (!prop1.vals)
837 {
838 success = False0;
839 goto bad;
840 }
841
842 numVals = 0;
843
844 for (i = 0; i < Argc; i++)
845 {
846 if (strcmp (Argv[i], "-clientId") == 0 ||
847 strcmp (Argv[i], "-restore") == 0)
848 {
849 i++;
850 }
851 else
852 {
853 prop1.vals[numVals].value = (SmPointer) Argv[i];
854 prop1.vals[numVals++].length = strlen (Argv[i]);
855 }
856 }
857
858 prop1.vals[numVals].value = (SmPointer) "-clientId";
859 prop1.vals[numVals++].length = 9;
860
861 prop1.vals[numVals].value = (SmPointer) twm_clientId;
862 prop1.vals[numVals++].length = strlen (twm_clientId);
863
864 prop1.vals[numVals].value = (SmPointer) "-restore";
865 prop1.vals[numVals++].length = 8;
866
867 prop1.vals[numVals].value = (SmPointer) filename;
868 prop1.vals[numVals++].length = strlen (filename);
869
870 prop1.num_vals = numVals;
871
872 snprintf (discardCommand, sizeof(discardCommand), "rm %s", filename)__builtin___snprintf_chk (discardCommand, sizeof(discardCommand
), 0, __builtin_object_size (discardCommand, 2 > 1 ? 1 : 0
), "rm %s", filename)
;
873 prop2.name = SmDiscardCommand"DiscardCommand";
874 prop2.type = SmARRAY8"ARRAY8";
875 prop2.num_vals = 1;
876 prop2.vals = &prop2val;
877 prop2val.value = (SmPointer) discardCommand;
878 prop2val.length = strlen (discardCommand);
879
880 props[0] = &prop1;
881 props[1] = &prop2;
882
883 SmcSetProperties (smcConn, 2, props);
884 free (prop1.vals);
885
886 bad:
887 SmcSaveYourselfDone (smcConn, success);
888 sent_save_done = 1;
889
890 if (configFile)
891 fclose (configFile);
892
893 if (filename)
894 free (filename);
895}
896
897
898
899static void
900SaveYourselfCB (
901 SmcConn smcConn,
902 SmPointer clientData,
903 int saveType,
904 Boolint shutdown,
905 int interactStyle,
906 Boolint fast)
907{
908 if (!SmcRequestSaveYourselfPhase2 (smcConn, SaveYourselfPhase2CB, NULL((void*)0)))
909 {
910 SmcSaveYourselfDone (smcConn, False0);
911 sent_save_done = 1;
912 }
913 else
914 sent_save_done = 0;
915}
916
917
918
919static void
920DieCB (SmcConn smcConn, SmPointer clientData)
921{
922 SmcCloseConnection (smcConn, 0, NULL((void*)0));
923 XtRemoveInput (iceInputId);
924 Done(NULL((void*)0), NULL((void*)0));
925}
926
927
928
929static void
930SaveCompleteCB (SmcConn smcConnm, SmPointer clientData)
931{
932 ;
933}
934
935
936
937static void
938ShutdownCancelledCB (SmcConn smcConn, SmPointer clientData)
939{
940 if (!sent_save_done)
941 {
942 SmcSaveYourselfDone (smcConn, False0);
943 sent_save_done = 1;
944 }
945}
946
947
948
949static void
950ProcessIceMsgProc (XtPointer client_data, int *source, XtInputId *id)
951{
952 IceConn ice_conn = (IceConn) client_data;
953
954 IceProcessMessages (ice_conn, NULL((void*)0), NULL((void*)0));
955}
956
957
958
959void
960ConnectToSessionManager (char *previous_id)
961{
962 char errorMsg[256];
963 unsigned long mask;
964 SmcCallbacks callbacks;
965 IceConn iceConn;
966
967 mask = SmcSaveYourselfProcMask(1L << 0) | SmcDieProcMask(1L << 1) |
968 SmcSaveCompleteProcMask(1L << 2) | SmcShutdownCancelledProcMask(1L << 3);
969
970 callbacks.save_yourself.callback = SaveYourselfCB;
971 callbacks.save_yourself.client_data = (SmPointer) NULL((void*)0);
972
973 callbacks.die.callback = DieCB;
974 callbacks.die.client_data = (SmPointer) NULL((void*)0);
975
976 callbacks.save_complete.callback = SaveCompleteCB;
977 callbacks.save_complete.client_data = (SmPointer) NULL((void*)0);
978
979 callbacks.shutdown_cancelled.callback = ShutdownCancelledCB;
980 callbacks.shutdown_cancelled.client_data = (SmPointer) NULL((void*)0);
981
982 smcConn = SmcOpenConnection (
983 NULL((void*)0), /* use SESSION_MANAGER env */
984 (SmPointer) appContext,
985 SmProtoMajor1,
986 SmProtoMinor0,
987 mask,
988 &callbacks,
989 previous_id,
990 &twm_clientId,
991 256, errorMsg);
992
993 if (smcConn == NULL((void*)0))
994 return;
995
996 iceConn = SmcGetIceConnection (smcConn);
997
998 iceInputId = XtAppAddInput (
999 appContext,
1000 IceConnectionNumber (iceConn),
1001 (XtPointer) XtInputReadMask(1L<<0),
1002 ProcessIceMsgProc,
1003 (XtPointer) iceConn);
1004}
1005
1006
1007