diff options
Diffstat (limited to 'saveutil.c')
-rw-r--r-- | saveutil.c | 557 |
1 files changed, 557 insertions, 0 deletions
diff --git a/saveutil.c b/saveutil.c new file mode 100644 index 0000000..04ab6bf --- /dev/null +++ b/saveutil.c @@ -0,0 +1,557 @@ +/* $Xorg: saveutil.c,v 1.5 2001/02/09 02:06:01 xorgcvs Exp $ */ +/****************************************************************************** + +Copyright 1993, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. +******************************************************************************/ + +#include "xsm.h" + +char session_save_file[PATH_MAX]; +Bool getline(); + +extern Widget manualRestartCommands; + + +void +set_session_save_file_name (session_name) + +char *session_name; + +{ + char *p; + + p = (char *) getenv ("SM_SAVE_DIR"); + if (!p) + { + p = (char *) getenv ("HOME"); + if (!p) + p = "."; + } + + strcpy (session_save_file, p); + strcat (session_save_file, "/.XSM-"); + strcat (session_save_file, session_name); +} + + + +int +ReadSave(session_name, sm_id) + +char *session_name; +char **sm_id; + +{ + char *buf; + int buflen; + char *p; + PendingClient *c; + Prop *prop; + PropValue *val; + FILE *f; + int state, i; + int version_number; + + f = fopen(session_save_file, "r"); + if(!f) { + if (verbose) + printf("No session save file.\n"); + *sm_id = NULL; + return 0; + } + if (verbose) + printf("Reading session save file...\n"); + + buf = NULL; + buflen = 0; + + /* Read version # */ + getline(&buf, &buflen, f); + if((p = strchr(buf, '\n'))) *p = '\0'; + version_number = atoi (buf); + if (version_number > SAVEFILE_VERSION) + { + if (verbose) + printf("Unsupported version number of session save file.\n"); + *sm_id = NULL; + if (buf) + free (buf); + return 0; + } + + /* Read SM's id */ + getline(&buf, &buflen, f); + if((p = strchr(buf, '\n'))) *p = '\0'; + *sm_id = XtNewString(buf); + + /* Read number of clients running in the last session */ + if (version_number >= 2) + { + getline(&buf, &buflen, f); + if((p = strchr(buf, '\n'))) *p = '\0'; + num_clients_in_last_session = atoi (buf); + } + + state = 0; + while(getline(&buf, &buflen, f)) { + if((p = strchr(buf, '\n'))) *p = '\0'; + for(p = buf; *p && isspace(*p); p++) /* LOOP */; + if(*p == '#') continue; + + if(!*p) + { + if (version_number >= 3 && + ListCount (PendingList) == num_clients_in_last_session) + { + state = 5; + break; + } + else + { + state = 0; + continue; + } + } + + if(!isspace(buf[0])) { + switch(state) { + case 0: + c = (PendingClient *)XtMalloc(sizeof *c); + if(!c) nomem(); + + c->clientId = XtNewString(p); + c->clientHostname = NULL; /* set in next state */ + + c->props = ListInit(); + if(!c->props) nomem(); + + if(!ListAddLast(PendingList, (char *)c)) nomem(); + + state = 1; + break; + + case 1: + c->clientHostname = XtNewString(p); + state = 2; + break; + + case 2: + case 4: + prop = (Prop *)XtMalloc(sizeof *prop); + if(!prop) nomem(); + + prop->name = XtNewString(p); + prop->values = ListInit(); + if(!prop->values) nomem(); + + prop->type = NULL; + + if(!ListAddLast(c->props, (char *)prop)) nomem(); + + state = 3; + break; + + case 3: + prop->type = XtNewString(p); + state = 4; + break; + + default: + fprintf(stderr, "state %d\n", state); + fprintf(stderr, + "Corrupt save file line ignored:\n%s\n", buf); + continue; + } + } else { + if (state != 4) { + fprintf(stderr, "Corrupt save file line ignored:\n%s\n", buf); + continue; + } + val = (PropValue *)XtMalloc(sizeof *val); + if(!val) nomem(); + + if (strcmp (prop->type, SmCARD8) == 0) + { + val->length = 1; + val->value = (XtPointer) XtMalloc (1); + *((char *)(val->value)) = atoi (p); + } + else + { + val->length = strlen(p); + val->value = XtNewString(p); + } + + if(!ListAddLast(prop->values, (char *)val)) nomem(); + } + } + + /* Read commands for non-session aware clients */ + + if (state == 5) + { + String strbuf; + int bufsize = 0; + + getline(&buf, &buflen, f); + if((p = strchr(buf, '\n'))) *p = '\0'; + non_session_aware_count = atoi (buf); + + if (non_session_aware_count > 0) + { + non_session_aware_clients = (char **) malloc ( + non_session_aware_count * sizeof (char *)); + + for (i = 0; i < non_session_aware_count; i++) + { + getline(&buf, &buflen, f); + if((p = strchr(buf, '\n'))) *p = '\0'; + non_session_aware_clients[i] = (char *) malloc ( + strlen (buf) + 2); + strcpy (non_session_aware_clients[i], buf); + bufsize += (strlen (buf) + 1); + } + + strbuf = (String) malloc (bufsize + 1); + strbuf[0] = '\0'; + + for (i = 0; i < non_session_aware_count; i++) + { + strcat (strbuf, non_session_aware_clients[i]); + strcat (strbuf, "\n"); + } + + XtVaSetValues (manualRestartCommands, + XtNstring, strbuf, + NULL); + + free ((char *) strbuf); + } + } + + fclose(f); + + if (buf) + free (buf); + + return 1; +} + + + +static void +SaveClient (f, client) + +FILE *f; +ClientRec *client; + +{ + List *pl; + + fprintf (f, "%s\n", client->clientId); + fprintf (f, "%s\n", client->clientHostname); + + for (pl = ListFirst (client->props); pl; pl = ListNext (pl)) + { + Prop *pprop = (Prop *) pl->thing; + List *pj, *vl; + PropValue *pval; + + fprintf (f, "%s\n", pprop->name); + fprintf (f, "%s\n", pprop->type); + + if (strcmp (pprop->type, SmCARD8) == 0) + { + char *card8; + int value; + + vl = ListFirst (pprop->values); + pval = (PropValue *) vl->thing; + + card8 = pval->value; + value = *card8; + fprintf(f, "\t%d\n", value); + } + else + { + for (pj = ListFirst (pprop->values); pj; pj = ListNext (pj)) + { + pval = (PropValue *) pj->thing; + fprintf (f, "\t%s\n", pval->value); + } + } + } + + fprintf (f, "\n"); +} + + + +void +WriteSave (sm_id) + +char *sm_id; + +{ + ClientRec *client; + FILE *f; + List *cl; + String commands; + char *p, *c; + int count; + + f = fopen (session_save_file, "w"); + + if (!f) + { + char msg[256]; + + sprintf (msg, "%s: Error creating session save file %s", + Argv[0], session_save_file); + add_log_text (msg); + perror (msg); + } + else + { + fprintf (f, "%d\n", SAVEFILE_VERSION); + fprintf (f, "%s\n", sm_id); + + count = 0; + for (cl = ListFirst (RunningList); cl; cl = ListNext (cl)) + { + client = (ClientRec *) cl->thing; + + if (client->restartHint != SmRestartNever) + count++; + } + count += ListCount (RestartAnywayList); + + fprintf (f, "%d\n", count); + if (count == 0) + fprintf (f, "\n"); + + for (cl = ListFirst (RunningList); cl; cl = ListNext (cl)) + { + client = (ClientRec *) cl->thing; + + if (client->restartHint == SmRestartNever) + continue; + + SaveClient (f, client); + } + + for (cl = ListFirst (RestartAnywayList); cl; cl = ListNext (cl)) + { + client = (ClientRec *) cl->thing; + + SaveClient (f, client); + } + + + /* Save the non-session aware clients */ + + XtVaGetValues (manualRestartCommands, + XtNstring, &commands, + NULL); + + p = c = commands; + count = 0; + + while (*p) + { + if (*p == '\n') + { + if (p != c) + count++; + c = p + 1; + } + p++; + } + if (p != c) + count++; + + fprintf (f, "%d\n", count); + + p = c = commands; + + while (*p) + { + if (*p == '\n') + { + if (p != c) + { + *p = '\0'; + fprintf (f, "%s\n", c); + *p = '\n'; + } + c = p + 1; + } + p++; + } + + if (p != c) + fprintf (f, "%s\n", c); + + fclose (f); + } +} + + + +Status +DeleteSession (session_name) + +char *session_name; + +{ + char *buf; + int buflen; + char *p, *dir; + FILE *f; + int state; + int foundDiscard; + char filename[256]; + int version_number; + + dir = (char *) getenv ("SM_SAVE_DIR"); + if (!dir) + { + dir = (char *) getenv ("HOME"); + if (!dir) + dir = "."; + } + + sprintf (filename, "%s/.XSM-%s", dir, session_name); + + f = fopen(filename, "r"); + if(!f) { + return (0); + } + + buf = NULL; + buflen = 0; + + /* Read version # */ + getline(&buf, &buflen, f); + if((p = strchr(buf, '\n'))) *p = '\0'; + version_number = atoi (buf); + if (version_number > SAVEFILE_VERSION) + { + if (verbose) + printf("Can't delete session save file - incompatible version.\n"); + if (buf) + free (buf); + return (0); + } + + /* Skip SM's id */ + getline(&buf, &buflen, f); + + /* Skip number of clients running in the last session */ + if (version_number >= 2) + getline(&buf, &buflen, f); + + state = 0; + foundDiscard = 0; + while(getline(&buf, &buflen, f)) { + if((p = strchr(buf, '\n'))) *p = '\0'; + for(p = buf; *p && isspace(*p); p++) /* LOOP */; + if(*p == '#') continue; + + if(!*p) { + state = 0; + foundDiscard = 0; + continue; + } + + if(!isspace(buf[0])) { + switch(state) { + case 0: + state = 1; + break; + + case 1: + state = 2; + break; + + case 2: + case 4: + if (strcmp (p, SmDiscardCommand) == 0) + foundDiscard = 1; + state = 3; + break; + + case 3: + state = 4; + break; + + default: + continue; + } + } else { + if (state != 4) { + continue; + } + if (foundDiscard) + { + execute_system_command (p); /* Discard Command */ + foundDiscard = 0; + } + } + } + + fclose(f); + + if (buf) + free (buf); + + return ((unlink (filename) == -1) ? 0 : 1); +} + + + +Bool +getline(pbuf, plen, f) +char **pbuf; +int *plen; +FILE *f; +{ + int c; + int i; + + i = 0; + while(1) { + if(i+2 > *plen) { + if(*plen) *plen *= 2; + else *plen = BUFSIZ; + if(*pbuf) *pbuf = (char *) realloc(*pbuf, *plen + 1); + else *pbuf = (char *) malloc(*plen + 1); + } + c = getc(f); + if(c == EOF) break; + (*pbuf)[i++] = c; + if(c == '\n') break; + } + (*pbuf)[i] = '\0'; + return i; +} |