saveutil.c revision 1a650d1e
18108eb18Smrg/* $Xorg: saveutil.c,v 1.5 2001/02/09 02:06:01 xorgcvs Exp $ */ 28108eb18Smrg/****************************************************************************** 38108eb18Smrg 48108eb18SmrgCopyright 1993, 1998 The Open Group 58108eb18Smrg 68108eb18SmrgPermission to use, copy, modify, distribute, and sell this software and its 78108eb18Smrgdocumentation for any purpose is hereby granted without fee, provided that 88108eb18Smrgthe above copyright notice appear in all copies and that both that 98108eb18Smrgcopyright notice and this permission notice appear in supporting 108108eb18Smrgdocumentation. 118108eb18Smrg 128108eb18SmrgThe above copyright notice and this permission notice shall be included in 138108eb18Smrgall copies or substantial portions of the Software. 148108eb18Smrg 158108eb18SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 168108eb18SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 178108eb18SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 188108eb18SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 198108eb18SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 208108eb18SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 218108eb18Smrg 228108eb18SmrgExcept as contained in this notice, the name of The Open Group shall not be 238108eb18Smrgused in advertising or otherwise to promote the sale, use or other dealings 248108eb18Smrgin this Software without prior written authorization from The Open Group. 258108eb18Smrg******************************************************************************/ 268108eb18Smrg/* $XFree86: xc/programs/xsm/saveutil.c,v 1.5 2001/01/17 23:46:31 dawes Exp $ */ 278108eb18Smrg 288108eb18Smrg#include "xsm.h" 298108eb18Smrg#include "log.h" 308108eb18Smrg#include "saveutil.h" 311a650d1eSmrg#include "info.h" 328108eb18Smrg 331a650d1eSmrgstatic char session_save_file[PATH_MAX]; 348108eb18Smrg 358108eb18Smrg 368108eb18Smrgvoid 378108eb18Smrgset_session_save_file_name(char *session_name) 388108eb18Smrg{ 398108eb18Smrg char *p; 408108eb18Smrg 418108eb18Smrg p = (char *) getenv ("SM_SAVE_DIR"); 428108eb18Smrg if (!p) 438108eb18Smrg { 448108eb18Smrg p = (char *) getenv ("HOME"); 458108eb18Smrg if (!p) 468108eb18Smrg p = "."; 478108eb18Smrg } 488108eb18Smrg 491a650d1eSmrg snprintf (session_save_file, sizeof(session_save_file), 501a650d1eSmrg "%s/.XSM-%s", p, session_name); 518108eb18Smrg} 528108eb18Smrg 538108eb18Smrg 548108eb18Smrg 558108eb18Smrgint 568108eb18SmrgReadSave(char *session_name, char **sm_id) 578108eb18Smrg{ 588108eb18Smrg char *buf; 598108eb18Smrg int buflen; 608108eb18Smrg char *p; 618108eb18Smrg PendingClient *c = NULL; 628108eb18Smrg Prop *prop = NULL; 638108eb18Smrg PropValue *val; 648108eb18Smrg FILE *f; 658108eb18Smrg int state, i; 668108eb18Smrg int version_number; 678108eb18Smrg 688108eb18Smrg f = fopen(session_save_file, "r"); 698108eb18Smrg if(!f) { 708108eb18Smrg if (verbose) 718108eb18Smrg printf("No session save file.\n"); 728108eb18Smrg *sm_id = NULL; 738108eb18Smrg return 0; 748108eb18Smrg } 758108eb18Smrg if (verbose) 768108eb18Smrg printf("Reading session save file...\n"); 778108eb18Smrg 788108eb18Smrg buf = NULL; 798108eb18Smrg buflen = 0; 808108eb18Smrg 818108eb18Smrg /* Read version # */ 828108eb18Smrg getnextline(&buf, &buflen, f); 838108eb18Smrg if((p = strchr(buf, '\n'))) *p = '\0'; 848108eb18Smrg version_number = atoi (buf); 858108eb18Smrg if (version_number > SAVEFILE_VERSION) 868108eb18Smrg { 878108eb18Smrg if (verbose) 888108eb18Smrg printf("Unsupported version number of session save file.\n"); 898108eb18Smrg *sm_id = NULL; 908108eb18Smrg if (buf) 918108eb18Smrg free (buf); 928108eb18Smrg return 0; 938108eb18Smrg } 948108eb18Smrg 958108eb18Smrg /* Read SM's id */ 968108eb18Smrg getnextline(&buf, &buflen, f); 978108eb18Smrg if((p = strchr(buf, '\n'))) *p = '\0'; 988108eb18Smrg *sm_id = XtNewString(buf); 998108eb18Smrg 1008108eb18Smrg /* Read number of clients running in the last session */ 1018108eb18Smrg if (version_number >= 2) 1028108eb18Smrg { 1038108eb18Smrg getnextline(&buf, &buflen, f); 1048108eb18Smrg if((p = strchr(buf, '\n'))) *p = '\0'; 1058108eb18Smrg num_clients_in_last_session = atoi (buf); 1068108eb18Smrg } 1078108eb18Smrg 1088108eb18Smrg state = 0; 1098108eb18Smrg while(getnextline(&buf, &buflen, f)) { 1108108eb18Smrg if((p = strchr(buf, '\n'))) *p = '\0'; 1118108eb18Smrg for(p = buf; *p && isspace(*p); p++) /* LOOP */; 1128108eb18Smrg if(*p == '#') continue; 1138108eb18Smrg 1148108eb18Smrg if(!*p) 1158108eb18Smrg { 1168108eb18Smrg if (version_number >= 3 && 1178108eb18Smrg ListCount (PendingList) == num_clients_in_last_session) 1188108eb18Smrg { 1198108eb18Smrg state = 5; 1208108eb18Smrg break; 1218108eb18Smrg } 1228108eb18Smrg else 1238108eb18Smrg { 1248108eb18Smrg state = 0; 1258108eb18Smrg continue; 1268108eb18Smrg } 1278108eb18Smrg } 1288108eb18Smrg 1298108eb18Smrg if(!isspace(buf[0])) { 1308108eb18Smrg switch(state) { 1318108eb18Smrg case 0: 1328108eb18Smrg c = (PendingClient *)XtMalloc(sizeof *c); 1338108eb18Smrg if(!c) nomem(); 1348108eb18Smrg 1358108eb18Smrg c->clientId = XtNewString(p); 1368108eb18Smrg c->clientHostname = NULL; /* set in next state */ 1378108eb18Smrg 1388108eb18Smrg c->props = ListInit(); 1398108eb18Smrg if(!c->props) nomem(); 1408108eb18Smrg 1418108eb18Smrg if(!ListAddLast(PendingList, (char *)c)) nomem(); 1428108eb18Smrg 1438108eb18Smrg state = 1; 1448108eb18Smrg break; 1458108eb18Smrg 1468108eb18Smrg case 1: 1478108eb18Smrg c->clientHostname = XtNewString(p); 1488108eb18Smrg state = 2; 1498108eb18Smrg break; 1508108eb18Smrg 1518108eb18Smrg case 2: 1528108eb18Smrg case 4: 1538108eb18Smrg prop = (Prop *)XtMalloc(sizeof *prop); 1548108eb18Smrg if(!prop) nomem(); 1558108eb18Smrg 1568108eb18Smrg prop->name = XtNewString(p); 1578108eb18Smrg prop->values = ListInit(); 1588108eb18Smrg if(!prop->values) nomem(); 1598108eb18Smrg 1608108eb18Smrg prop->type = NULL; 1618108eb18Smrg 1628108eb18Smrg if(!ListAddLast(c->props, (char *)prop)) nomem(); 1638108eb18Smrg 1648108eb18Smrg state = 3; 1658108eb18Smrg break; 1668108eb18Smrg 1678108eb18Smrg case 3: 1688108eb18Smrg prop->type = XtNewString(p); 1698108eb18Smrg state = 4; 1708108eb18Smrg break; 1718108eb18Smrg 1728108eb18Smrg default: 1738108eb18Smrg fprintf(stderr, "state %d\n", state); 1748108eb18Smrg fprintf(stderr, 1758108eb18Smrg "Corrupt save file line ignored:\n%s\n", buf); 1768108eb18Smrg continue; 1778108eb18Smrg } 1788108eb18Smrg } else { 1798108eb18Smrg if (state != 4) { 1808108eb18Smrg fprintf(stderr, "Corrupt save file line ignored:\n%s\n", buf); 1818108eb18Smrg continue; 1828108eb18Smrg } 1838108eb18Smrg val = (PropValue *)XtMalloc(sizeof *val); 1848108eb18Smrg if(!val) nomem(); 1858108eb18Smrg 1868108eb18Smrg if (strcmp (prop->type, SmCARD8) == 0) 1878108eb18Smrg { 1888108eb18Smrg val->length = 1; 1898108eb18Smrg val->value = (XtPointer) XtMalloc (1); 1908108eb18Smrg *((char *)(val->value)) = atoi (p); 1918108eb18Smrg } 1928108eb18Smrg else 1938108eb18Smrg { 1948108eb18Smrg val->length = strlen(p); 1958108eb18Smrg val->value = XtNewString(p); 1968108eb18Smrg } 1978108eb18Smrg 1988108eb18Smrg if(!ListAddLast(prop->values, (char *)val)) nomem(); 1998108eb18Smrg } 2008108eb18Smrg } 2018108eb18Smrg 2028108eb18Smrg /* Read commands for non-session aware clients */ 2038108eb18Smrg 2048108eb18Smrg if (state == 5) 2058108eb18Smrg { 2068108eb18Smrg String strbuf; 2078108eb18Smrg int bufsize = 0; 2088108eb18Smrg 2098108eb18Smrg getnextline(&buf, &buflen, f); 2108108eb18Smrg if((p = strchr(buf, '\n'))) *p = '\0'; 2118108eb18Smrg non_session_aware_count = atoi (buf); 2128108eb18Smrg 2138108eb18Smrg if (non_session_aware_count > 0) 2148108eb18Smrg { 2158108eb18Smrg non_session_aware_clients = (char **) malloc ( 2168108eb18Smrg non_session_aware_count * sizeof (char *)); 2178108eb18Smrg 2188108eb18Smrg for (i = 0; i < non_session_aware_count; i++) 2198108eb18Smrg { 2208108eb18Smrg getnextline(&buf, &buflen, f); 2218108eb18Smrg if((p = strchr(buf, '\n'))) *p = '\0'; 2228108eb18Smrg non_session_aware_clients[i] = (char *) malloc ( 2238108eb18Smrg strlen (buf) + 2); 2248108eb18Smrg strcpy (non_session_aware_clients[i], buf); 2258108eb18Smrg bufsize += (strlen (buf) + 1); 2268108eb18Smrg } 2278108eb18Smrg 2288108eb18Smrg strbuf = (String) malloc (bufsize + 1); 2298108eb18Smrg strbuf[0] = '\0'; 2308108eb18Smrg 2318108eb18Smrg for (i = 0; i < non_session_aware_count; i++) 2328108eb18Smrg { 2338108eb18Smrg strcat (strbuf, non_session_aware_clients[i]); 2348108eb18Smrg strcat (strbuf, "\n"); 2358108eb18Smrg } 2368108eb18Smrg 2378108eb18Smrg XtVaSetValues (manualRestartCommands, 2388108eb18Smrg XtNstring, strbuf, 2398108eb18Smrg NULL); 2408108eb18Smrg 2418108eb18Smrg free ((char *) strbuf); 2428108eb18Smrg } 2438108eb18Smrg } 2448108eb18Smrg 2458108eb18Smrg fclose(f); 2468108eb18Smrg 2478108eb18Smrg if (buf) 2488108eb18Smrg free (buf); 2498108eb18Smrg 2508108eb18Smrg return 1; 2518108eb18Smrg} 2528108eb18Smrg 2538108eb18Smrg 2548108eb18Smrg 2558108eb18Smrgstatic void 2568108eb18SmrgSaveClient(FILE *f, ClientRec *client) 2578108eb18Smrg{ 2588108eb18Smrg List *pl; 2598108eb18Smrg 2608108eb18Smrg fprintf (f, "%s\n", client->clientId); 2618108eb18Smrg fprintf (f, "%s\n", client->clientHostname); 2628108eb18Smrg 2638108eb18Smrg for (pl = ListFirst (client->props); pl; pl = ListNext (pl)) 2648108eb18Smrg { 2658108eb18Smrg Prop *pprop = (Prop *) pl->thing; 2668108eb18Smrg List *pj, *vl; 2678108eb18Smrg PropValue *pval; 2688108eb18Smrg 2698108eb18Smrg fprintf (f, "%s\n", pprop->name); 2708108eb18Smrg fprintf (f, "%s\n", pprop->type); 2718108eb18Smrg 2728108eb18Smrg if (strcmp (pprop->type, SmCARD8) == 0) 2738108eb18Smrg { 2748108eb18Smrg char *card8; 2758108eb18Smrg int value; 2768108eb18Smrg 2778108eb18Smrg vl = ListFirst (pprop->values); 2788108eb18Smrg pval = (PropValue *) vl->thing; 2798108eb18Smrg 2808108eb18Smrg card8 = pval->value; 2818108eb18Smrg value = *card8; 2828108eb18Smrg fprintf(f, "\t%d\n", value); 2838108eb18Smrg } 2848108eb18Smrg else 2858108eb18Smrg { 2868108eb18Smrg for (pj = ListFirst (pprop->values); pj; pj = ListNext (pj)) 2878108eb18Smrg { 2888108eb18Smrg pval = (PropValue *) pj->thing; 2898108eb18Smrg fprintf (f, "\t%s\n", (char *)pval->value); 2908108eb18Smrg } 2918108eb18Smrg } 2928108eb18Smrg } 2938108eb18Smrg 2948108eb18Smrg fprintf (f, "\n"); 2958108eb18Smrg} 2968108eb18Smrg 2978108eb18Smrg 2988108eb18Smrg 2998108eb18Smrgvoid 3008108eb18SmrgWriteSave(char *sm_id) 3018108eb18Smrg{ 3028108eb18Smrg ClientRec *client; 3038108eb18Smrg FILE *f; 3048108eb18Smrg List *cl; 3058108eb18Smrg String commands; 3068108eb18Smrg char *p, *c; 3078108eb18Smrg int count; 3088108eb18Smrg 3098108eb18Smrg f = fopen (session_save_file, "w"); 3108108eb18Smrg 3118108eb18Smrg if (!f) 3128108eb18Smrg { 3138108eb18Smrg char msg[256]; 3148108eb18Smrg 3151a650d1eSmrg snprintf (msg, sizeof(msg), "%s: Error creating session save file %s", 3161a650d1eSmrg Argv[0], session_save_file); 3178108eb18Smrg add_log_text (msg); 3188108eb18Smrg perror (msg); 3198108eb18Smrg } 3208108eb18Smrg else 3218108eb18Smrg { 3228108eb18Smrg fprintf (f, "%d\n", SAVEFILE_VERSION); 3238108eb18Smrg fprintf (f, "%s\n", sm_id); 3248108eb18Smrg 3258108eb18Smrg count = 0; 3268108eb18Smrg for (cl = ListFirst (RunningList); cl; cl = ListNext (cl)) 3278108eb18Smrg { 3288108eb18Smrg client = (ClientRec *) cl->thing; 3298108eb18Smrg 3308108eb18Smrg if (client->restartHint != SmRestartNever) 3318108eb18Smrg count++; 3328108eb18Smrg } 3338108eb18Smrg count += ListCount (RestartAnywayList); 3348108eb18Smrg 3358108eb18Smrg fprintf (f, "%d\n", count); 3368108eb18Smrg if (count == 0) 3378108eb18Smrg fprintf (f, "\n"); 3388108eb18Smrg 3398108eb18Smrg for (cl = ListFirst (RunningList); cl; cl = ListNext (cl)) 3408108eb18Smrg { 3418108eb18Smrg client = (ClientRec *) cl->thing; 3428108eb18Smrg 3438108eb18Smrg if (client->restartHint == SmRestartNever) 3448108eb18Smrg continue; 3458108eb18Smrg 3468108eb18Smrg SaveClient (f, client); 3478108eb18Smrg } 3488108eb18Smrg 3498108eb18Smrg for (cl = ListFirst (RestartAnywayList); cl; cl = ListNext (cl)) 3508108eb18Smrg { 3518108eb18Smrg client = (ClientRec *) cl->thing; 3528108eb18Smrg 3538108eb18Smrg SaveClient (f, client); 3548108eb18Smrg } 3558108eb18Smrg 3568108eb18Smrg 3578108eb18Smrg /* Save the non-session aware clients */ 3588108eb18Smrg 3598108eb18Smrg XtVaGetValues (manualRestartCommands, 3608108eb18Smrg XtNstring, &commands, 3618108eb18Smrg NULL); 3628108eb18Smrg 3638108eb18Smrg p = c = commands; 3648108eb18Smrg count = 0; 3658108eb18Smrg 3668108eb18Smrg while (*p) 3678108eb18Smrg { 3688108eb18Smrg if (*p == '\n') 3698108eb18Smrg { 3708108eb18Smrg if (p != c) 3718108eb18Smrg count++; 3728108eb18Smrg c = p + 1; 3738108eb18Smrg } 3748108eb18Smrg p++; 3758108eb18Smrg } 3768108eb18Smrg if (p != c) 3778108eb18Smrg count++; 3788108eb18Smrg 3798108eb18Smrg fprintf (f, "%d\n", count); 3808108eb18Smrg 3818108eb18Smrg p = c = commands; 3828108eb18Smrg 3838108eb18Smrg while (*p) 3848108eb18Smrg { 3858108eb18Smrg if (*p == '\n') 3868108eb18Smrg { 3878108eb18Smrg if (p != c) 3888108eb18Smrg { 3898108eb18Smrg *p = '\0'; 3908108eb18Smrg fprintf (f, "%s\n", c); 3918108eb18Smrg *p = '\n'; 3928108eb18Smrg } 3938108eb18Smrg c = p + 1; 3948108eb18Smrg } 3958108eb18Smrg p++; 3968108eb18Smrg } 3978108eb18Smrg 3988108eb18Smrg if (p != c) 3998108eb18Smrg fprintf (f, "%s\n", c); 4008108eb18Smrg 4018108eb18Smrg fclose (f); 4028108eb18Smrg } 4038108eb18Smrg} 4048108eb18Smrg 4058108eb18Smrg 4068108eb18Smrg 4078108eb18SmrgStatus 4088108eb18SmrgDeleteSession(char *session_name) 4098108eb18Smrg{ 4108108eb18Smrg char *buf; 4118108eb18Smrg int buflen; 4128108eb18Smrg char *p, *dir; 4138108eb18Smrg FILE *f; 4148108eb18Smrg int state; 4158108eb18Smrg int foundDiscard; 4168108eb18Smrg char filename[256]; 4178108eb18Smrg int version_number; 4188108eb18Smrg 4198108eb18Smrg dir = (char *) getenv ("SM_SAVE_DIR"); 4208108eb18Smrg if (!dir) 4218108eb18Smrg { 4228108eb18Smrg dir = (char *) getenv ("HOME"); 4238108eb18Smrg if (!dir) 4248108eb18Smrg dir = "."; 4258108eb18Smrg } 4268108eb18Smrg 4271a650d1eSmrg snprintf (filename, sizeof(filename), "%s/.XSM-%s", dir, session_name); 4288108eb18Smrg 4298108eb18Smrg f = fopen(filename, "r"); 4308108eb18Smrg if(!f) { 4318108eb18Smrg return (0); 4328108eb18Smrg } 4338108eb18Smrg 4348108eb18Smrg buf = NULL; 4358108eb18Smrg buflen = 0; 4368108eb18Smrg 4378108eb18Smrg /* Read version # */ 4388108eb18Smrg getnextline(&buf, &buflen, f); 4398108eb18Smrg if((p = strchr(buf, '\n'))) *p = '\0'; 4408108eb18Smrg version_number = atoi (buf); 4418108eb18Smrg if (version_number > SAVEFILE_VERSION) 4428108eb18Smrg { 4438108eb18Smrg if (verbose) 4448108eb18Smrg printf("Can't delete session save file - incompatible version.\n"); 4458108eb18Smrg if (buf) 4468108eb18Smrg free (buf); 4478108eb18Smrg return (0); 4488108eb18Smrg } 4498108eb18Smrg 4508108eb18Smrg /* Skip SM's id */ 4518108eb18Smrg getnextline(&buf, &buflen, f); 4528108eb18Smrg 4538108eb18Smrg /* Skip number of clients running in the last session */ 4548108eb18Smrg if (version_number >= 2) 4558108eb18Smrg getnextline(&buf, &buflen, f); 4568108eb18Smrg 4578108eb18Smrg state = 0; 4588108eb18Smrg foundDiscard = 0; 4598108eb18Smrg while(getnextline(&buf, &buflen, f)) { 4608108eb18Smrg if((p = strchr(buf, '\n'))) *p = '\0'; 4618108eb18Smrg for(p = buf; *p && isspace(*p); p++) /* LOOP */; 4628108eb18Smrg if(*p == '#') continue; 4638108eb18Smrg 4648108eb18Smrg if(!*p) { 4658108eb18Smrg state = 0; 4668108eb18Smrg foundDiscard = 0; 4678108eb18Smrg continue; 4688108eb18Smrg } 4698108eb18Smrg 4708108eb18Smrg if(!isspace(buf[0])) { 4718108eb18Smrg switch(state) { 4728108eb18Smrg case 0: 4738108eb18Smrg state = 1; 4748108eb18Smrg break; 4758108eb18Smrg 4768108eb18Smrg case 1: 4778108eb18Smrg state = 2; 4788108eb18Smrg break; 4798108eb18Smrg 4808108eb18Smrg case 2: 4818108eb18Smrg case 4: 4828108eb18Smrg if (strcmp (p, SmDiscardCommand) == 0) 4838108eb18Smrg foundDiscard = 1; 4848108eb18Smrg state = 3; 4858108eb18Smrg break; 4868108eb18Smrg 4878108eb18Smrg case 3: 4888108eb18Smrg state = 4; 4898108eb18Smrg break; 4908108eb18Smrg 4918108eb18Smrg default: 4928108eb18Smrg continue; 4938108eb18Smrg } 4948108eb18Smrg } else { 4958108eb18Smrg if (state != 4) { 4968108eb18Smrg continue; 4978108eb18Smrg } 4988108eb18Smrg if (foundDiscard) 4998108eb18Smrg { 5008108eb18Smrg execute_system_command (p); /* Discard Command */ 5018108eb18Smrg foundDiscard = 0; 5028108eb18Smrg } 5038108eb18Smrg } 5048108eb18Smrg } 5058108eb18Smrg 5068108eb18Smrg fclose(f); 5078108eb18Smrg 5088108eb18Smrg if (buf) 5098108eb18Smrg free (buf); 5108108eb18Smrg 5111a650d1eSmrg return ((remove (filename) == -1) ? 0 : 1); 5128108eb18Smrg} 5138108eb18Smrg 5148108eb18Smrg 5158108eb18Smrg 5168108eb18SmrgBool 5178108eb18Smrggetnextline(char **pbuf, int *plen, FILE *f) 5188108eb18Smrg{ 5198108eb18Smrg int c; 5208108eb18Smrg int i; 5218108eb18Smrg 5228108eb18Smrg i = 0; 5238108eb18Smrg while(1) { 5248108eb18Smrg if(i+2 > *plen) { 5258108eb18Smrg if(*plen) *plen *= 2; 5268108eb18Smrg else *plen = BUFSIZ; 5278108eb18Smrg if(*pbuf) *pbuf = (char *) realloc(*pbuf, *plen + 1); 5288108eb18Smrg else *pbuf = (char *) malloc(*plen + 1); 5298108eb18Smrg } 5308108eb18Smrg c = getc(f); 5318108eb18Smrg if(c == EOF) break; 5328108eb18Smrg (*pbuf)[i++] = c; 5338108eb18Smrg if(c == '\n') break; 5348108eb18Smrg } 5358108eb18Smrg (*pbuf)[i] = '\0'; 5368108eb18Smrg return i; 5378108eb18Smrg} 538