saveutil.c revision 1a650d1e
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#include "info.h" 32 33static char session_save_file[PATH_MAX]; 34 35 36void 37set_session_save_file_name(char *session_name) 38{ 39 char *p; 40 41 p = (char *) getenv ("SM_SAVE_DIR"); 42 if (!p) 43 { 44 p = (char *) getenv ("HOME"); 45 if (!p) 46 p = "."; 47 } 48 49 snprintf (session_save_file, sizeof(session_save_file), 50 "%s/.XSM-%s", p, session_name); 51} 52 53 54 55int 56ReadSave(char *session_name, char **sm_id) 57{ 58 char *buf; 59 int buflen; 60 char *p; 61 PendingClient *c = NULL; 62 Prop *prop = NULL; 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; 73 return 0; 74 } 75 if (verbose) 76 printf("Reading session save file...\n"); 77 78 buf = NULL; 79 buflen = 0; 80 81 /* Read version # */ 82 getnextline(&buf, &buflen, f); 83 if((p = strchr(buf, '\n'))) *p = '\0'; 84 version_number = atoi (buf); 85 if (version_number > SAVEFILE_VERSION) 86 { 87 if (verbose) 88 printf("Unsupported version number of session save file.\n"); 89 *sm_id = NULL; 90 if (buf) 91 free (buf); 92 return 0; 93 } 94 95 /* Read SM's id */ 96 getnextline(&buf, &buflen, f); 97 if((p = strchr(buf, '\n'))) *p = '\0'; 98 *sm_id = XtNewString(buf); 99 100 /* Read number of clients running in the last session */ 101 if (version_number >= 2) 102 { 103 getnextline(&buf, &buflen, f); 104 if((p = strchr(buf, '\n'))) *p = '\0'; 105 num_clients_in_last_session = atoi (buf); 106 } 107 108 state = 0; 109 while(getnextline(&buf, &buflen, f)) { 110 if((p = strchr(buf, '\n'))) *p = '\0'; 111 for(p = buf; *p && isspace(*p); p++) /* LOOP */; 112 if(*p == '#') continue; 113 114 if(!*p) 115 { 116 if (version_number >= 3 && 117 ListCount (PendingList) == num_clients_in_last_session) 118 { 119 state = 5; 120 break; 121 } 122 else 123 { 124 state = 0; 125 continue; 126 } 127 } 128 129 if(!isspace(buf[0])) { 130 switch(state) { 131 case 0: 132 c = (PendingClient *)XtMalloc(sizeof *c); 133 if(!c) nomem(); 134 135 c->clientId = XtNewString(p); 136 c->clientHostname = NULL; /* set in next state */ 137 138 c->props = ListInit(); 139 if(!c->props) nomem(); 140 141 if(!ListAddLast(PendingList, (char *)c)) nomem(); 142 143 state = 1; 144 break; 145 146 case 1: 147 c->clientHostname = XtNewString(p); 148 state = 2; 149 break; 150 151 case 2: 152 case 4: 153 prop = (Prop *)XtMalloc(sizeof *prop); 154 if(!prop) nomem(); 155 156 prop->name = XtNewString(p); 157 prop->values = ListInit(); 158 if(!prop->values) nomem(); 159 160 prop->type = NULL; 161 162 if(!ListAddLast(c->props, (char *)prop)) nomem(); 163 164 state = 3; 165 break; 166 167 case 3: 168 prop->type = XtNewString(p); 169 state = 4; 170 break; 171 172 default: 173 fprintf(stderr, "state %d\n", state); 174 fprintf(stderr, 175 "Corrupt save file line ignored:\n%s\n", buf); 176 continue; 177 } 178 } else { 179 if (state != 4) { 180 fprintf(stderr, "Corrupt save file line ignored:\n%s\n", buf); 181 continue; 182 } 183 val = (PropValue *)XtMalloc(sizeof *val); 184 if(!val) nomem(); 185 186 if (strcmp (prop->type, SmCARD8) == 0) 187 { 188 val->length = 1; 189 val->value = (XtPointer) XtMalloc (1); 190 *((char *)(val->value)) = atoi (p); 191 } 192 else 193 { 194 val->length = strlen(p); 195 val->value = XtNewString(p); 196 } 197 198 if(!ListAddLast(prop->values, (char *)val)) nomem(); 199 } 200 } 201 202 /* Read commands for non-session aware clients */ 203 204 if (state == 5) 205 { 206 String strbuf; 207 int bufsize = 0; 208 209 getnextline(&buf, &buflen, f); 210 if((p = strchr(buf, '\n'))) *p = '\0'; 211 non_session_aware_count = atoi (buf); 212 213 if (non_session_aware_count > 0) 214 { 215 non_session_aware_clients = (char **) malloc ( 216 non_session_aware_count * sizeof (char *)); 217 218 for (i = 0; i < non_session_aware_count; i++) 219 { 220 getnextline(&buf, &buflen, f); 221 if((p = strchr(buf, '\n'))) *p = '\0'; 222 non_session_aware_clients[i] = (char *) malloc ( 223 strlen (buf) + 2); 224 strcpy (non_session_aware_clients[i], buf); 225 bufsize += (strlen (buf) + 1); 226 } 227 228 strbuf = (String) malloc (bufsize + 1); 229 strbuf[0] = '\0'; 230 231 for (i = 0; i < non_session_aware_count; i++) 232 { 233 strcat (strbuf, non_session_aware_clients[i]); 234 strcat (strbuf, "\n"); 235 } 236 237 XtVaSetValues (manualRestartCommands, 238 XtNstring, strbuf, 239 NULL); 240 241 free ((char *) strbuf); 242 } 243 } 244 245 fclose(f); 246 247 if (buf) 248 free (buf); 249 250 return 1; 251} 252 253 254 255static void 256SaveClient(FILE *f, ClientRec *client) 257{ 258 List *pl; 259 260 fprintf (f, "%s\n", client->clientId); 261 fprintf (f, "%s\n", client->clientHostname); 262 263 for (pl = ListFirst (client->props); pl; pl = ListNext (pl)) 264 { 265 Prop *pprop = (Prop *) pl->thing; 266 List *pj, *vl; 267 PropValue *pval; 268 269 fprintf (f, "%s\n", pprop->name); 270 fprintf (f, "%s\n", pprop->type); 271 272 if (strcmp (pprop->type, SmCARD8) == 0) 273 { 274 char *card8; 275 int value; 276 277 vl = ListFirst (pprop->values); 278 pval = (PropValue *) vl->thing; 279 280 card8 = pval->value; 281 value = *card8; 282 fprintf(f, "\t%d\n", value); 283 } 284 else 285 { 286 for (pj = ListFirst (pprop->values); pj; pj = ListNext (pj)) 287 { 288 pval = (PropValue *) pj->thing; 289 fprintf (f, "\t%s\n", (char *)pval->value); 290 } 291 } 292 } 293 294 fprintf (f, "\n"); 295} 296 297 298 299void 300WriteSave(char *sm_id) 301{ 302 ClientRec *client; 303 FILE *f; 304 List *cl; 305 String commands; 306 char *p, *c; 307 int count; 308 309 f = fopen (session_save_file, "w"); 310 311 if (!f) 312 { 313 char msg[256]; 314 315 snprintf (msg, sizeof(msg), "%s: Error creating session save file %s", 316 Argv[0], session_save_file); 317 add_log_text (msg); 318 perror (msg); 319 } 320 else 321 { 322 fprintf (f, "%d\n", SAVEFILE_VERSION); 323 fprintf (f, "%s\n", sm_id); 324 325 count = 0; 326 for (cl = ListFirst (RunningList); cl; cl = ListNext (cl)) 327 { 328 client = (ClientRec *) cl->thing; 329 330 if (client->restartHint != SmRestartNever) 331 count++; 332 } 333 count += ListCount (RestartAnywayList); 334 335 fprintf (f, "%d\n", count); 336 if (count == 0) 337 fprintf (f, "\n"); 338 339 for (cl = ListFirst (RunningList); cl; cl = ListNext (cl)) 340 { 341 client = (ClientRec *) cl->thing; 342 343 if (client->restartHint == SmRestartNever) 344 continue; 345 346 SaveClient (f, client); 347 } 348 349 for (cl = ListFirst (RestartAnywayList); cl; cl = ListNext (cl)) 350 { 351 client = (ClientRec *) cl->thing; 352 353 SaveClient (f, client); 354 } 355 356 357 /* Save the non-session aware clients */ 358 359 XtVaGetValues (manualRestartCommands, 360 XtNstring, &commands, 361 NULL); 362 363 p = c = commands; 364 count = 0; 365 366 while (*p) 367 { 368 if (*p == '\n') 369 { 370 if (p != c) 371 count++; 372 c = p + 1; 373 } 374 p++; 375 } 376 if (p != c) 377 count++; 378 379 fprintf (f, "%d\n", count); 380 381 p = c = commands; 382 383 while (*p) 384 { 385 if (*p == '\n') 386 { 387 if (p != c) 388 { 389 *p = '\0'; 390 fprintf (f, "%s\n", c); 391 *p = '\n'; 392 } 393 c = p + 1; 394 } 395 p++; 396 } 397 398 if (p != c) 399 fprintf (f, "%s\n", c); 400 401 fclose (f); 402 } 403} 404 405 406 407Status 408DeleteSession(char *session_name) 409{ 410 char *buf; 411 int buflen; 412 char *p, *dir; 413 FILE *f; 414 int state; 415 int foundDiscard; 416 char filename[256]; 417 int version_number; 418 419 dir = (char *) getenv ("SM_SAVE_DIR"); 420 if (!dir) 421 { 422 dir = (char *) getenv ("HOME"); 423 if (!dir) 424 dir = "."; 425 } 426 427 snprintf (filename, sizeof(filename), "%s/.XSM-%s", dir, session_name); 428 429 f = fopen(filename, "r"); 430 if(!f) { 431 return (0); 432 } 433 434 buf = NULL; 435 buflen = 0; 436 437 /* Read version # */ 438 getnextline(&buf, &buflen, f); 439 if((p = strchr(buf, '\n'))) *p = '\0'; 440 version_number = atoi (buf); 441 if (version_number > SAVEFILE_VERSION) 442 { 443 if (verbose) 444 printf("Can't delete session save file - incompatible version.\n"); 445 if (buf) 446 free (buf); 447 return (0); 448 } 449 450 /* Skip SM's id */ 451 getnextline(&buf, &buflen, f); 452 453 /* Skip number of clients running in the last session */ 454 if (version_number >= 2) 455 getnextline(&buf, &buflen, f); 456 457 state = 0; 458 foundDiscard = 0; 459 while(getnextline(&buf, &buflen, f)) { 460 if((p = strchr(buf, '\n'))) *p = '\0'; 461 for(p = buf; *p && isspace(*p); p++) /* LOOP */; 462 if(*p == '#') continue; 463 464 if(!*p) { 465 state = 0; 466 foundDiscard = 0; 467 continue; 468 } 469 470 if(!isspace(buf[0])) { 471 switch(state) { 472 case 0: 473 state = 1; 474 break; 475 476 case 1: 477 state = 2; 478 break; 479 480 case 2: 481 case 4: 482 if (strcmp (p, SmDiscardCommand) == 0) 483 foundDiscard = 1; 484 state = 3; 485 break; 486 487 case 3: 488 state = 4; 489 break; 490 491 default: 492 continue; 493 } 494 } else { 495 if (state != 4) { 496 continue; 497 } 498 if (foundDiscard) 499 { 500 execute_system_command (p); /* Discard Command */ 501 foundDiscard = 0; 502 } 503 } 504 } 505 506 fclose(f); 507 508 if (buf) 509 free (buf); 510 511 return ((remove (filename) == -1) ? 0 : 1); 512} 513 514 515 516Bool 517getnextline(char **pbuf, int *plen, FILE *f) 518{ 519 int c; 520 int i; 521 522 i = 0; 523 while(1) { 524 if(i+2 > *plen) { 525 if(*plen) *plen *= 2; 526 else *plen = BUFSIZ; 527 if(*pbuf) *pbuf = (char *) realloc(*pbuf, *plen + 1); 528 else *pbuf = (char *) malloc(*plen + 1); 529 } 530 c = getc(f); 531 if(c == EOF) break; 532 (*pbuf)[i++] = c; 533 if(c == '\n') break; 534 } 535 (*pbuf)[i] = '\0'; 536 return i; 537} 538