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