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
375977a007Smrgset_session_save_file_name(const char *session_name)
388108eb18Smrg{
395977a007Smrg    const char *p;
408108eb18Smrg
415977a007Smrg    p = getenv ("SM_SAVE_DIR");
428108eb18Smrg    if (!p)
438108eb18Smrg    {
445977a007Smrg	p = 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
565977a007SmrgReadSave(const 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
682bc08f26Swiz    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    }
752bc08f26Swiz    fcntl(fileno(f), F_SETFD, FD_CLOEXEC);
768108eb18Smrg    if (verbose)
778108eb18Smrg	printf("Reading session save file...\n");
788108eb18Smrg
798108eb18Smrg    buf = NULL;
808108eb18Smrg    buflen = 0;
818108eb18Smrg
828108eb18Smrg    /* Read version # */
838108eb18Smrg    getnextline(&buf, &buflen, f);
848108eb18Smrg    if((p = strchr(buf, '\n'))) *p = '\0';
858108eb18Smrg    version_number = atoi (buf);
868108eb18Smrg    if (version_number > SAVEFILE_VERSION)
878108eb18Smrg    {
888108eb18Smrg	if (verbose)
898108eb18Smrg	    printf("Unsupported version number of session save file.\n");
908108eb18Smrg	*sm_id = NULL;
918108eb18Smrg	if (buf)
928108eb18Smrg	    free (buf);
938108eb18Smrg	return 0;
948108eb18Smrg    }
958108eb18Smrg
968108eb18Smrg    /* Read SM's id */
978108eb18Smrg    getnextline(&buf, &buflen, f);
988108eb18Smrg    if((p = strchr(buf, '\n'))) *p = '\0';
998108eb18Smrg    *sm_id = XtNewString(buf);
1008108eb18Smrg
1018108eb18Smrg    /* Read number of clients running in the last session */
1028108eb18Smrg    if (version_number >= 2)
1038108eb18Smrg    {
1048108eb18Smrg	getnextline(&buf, &buflen, f);
1058108eb18Smrg	if((p = strchr(buf, '\n'))) *p = '\0';
1068108eb18Smrg	num_clients_in_last_session = atoi (buf);
1078108eb18Smrg    }
1088108eb18Smrg
1098108eb18Smrg    state = 0;
1108108eb18Smrg    while(getnextline(&buf, &buflen, f)) {
1118108eb18Smrg	if((p = strchr(buf, '\n'))) *p = '\0';
1128108eb18Smrg	for(p = buf; *p && isspace(*p); p++) /* LOOP */;
1138108eb18Smrg	if(*p == '#') continue;
1148108eb18Smrg
1158108eb18Smrg	if(!*p)
1168108eb18Smrg	{
1178108eb18Smrg	    if (version_number >= 3 &&
1188108eb18Smrg		ListCount (PendingList) == num_clients_in_last_session)
1198108eb18Smrg	    {
1208108eb18Smrg		state = 5;
1218108eb18Smrg		break;
1228108eb18Smrg	    }
1238108eb18Smrg	    else
1248108eb18Smrg	    {
1258108eb18Smrg		state = 0;
1268108eb18Smrg		continue;
1278108eb18Smrg	    }
1288108eb18Smrg	}
1298108eb18Smrg
1308108eb18Smrg	if(!isspace(buf[0])) {
1318108eb18Smrg	    switch(state) {
1328108eb18Smrg		case 0:
1338108eb18Smrg		    c = (PendingClient *)XtMalloc(sizeof *c);
1348108eb18Smrg		    if(!c) nomem();
1358108eb18Smrg
1368108eb18Smrg		    c->clientId = XtNewString(p);
1378108eb18Smrg		    c->clientHostname = NULL;  /* set in next state */
1388108eb18Smrg
1398108eb18Smrg		    c->props = ListInit();
1408108eb18Smrg		    if(!c->props) nomem();
1418108eb18Smrg
1428108eb18Smrg		    if(!ListAddLast(PendingList, (char *)c)) nomem();
1438108eb18Smrg
1448108eb18Smrg		    state = 1;
1458108eb18Smrg		    break;
1468108eb18Smrg
1478108eb18Smrg		case 1:
1488108eb18Smrg		    c->clientHostname = XtNewString(p);
1498108eb18Smrg                    state = 2;
1508108eb18Smrg                    break;
1518108eb18Smrg
1528108eb18Smrg		case 2:
1538108eb18Smrg		case 4:
1548108eb18Smrg		    prop = (Prop *)XtMalloc(sizeof *prop);
1558108eb18Smrg		    if(!prop) nomem();
1568108eb18Smrg
1578108eb18Smrg		    prop->name = XtNewString(p);
1588108eb18Smrg		    prop->values = ListInit();
1598108eb18Smrg		    if(!prop->values) nomem();
1608108eb18Smrg
1618108eb18Smrg		    prop->type = NULL;
1628108eb18Smrg
1638108eb18Smrg		    if(!ListAddLast(c->props, (char *)prop)) nomem();
1648108eb18Smrg
1658108eb18Smrg		    state = 3;
1668108eb18Smrg		    break;
1678108eb18Smrg
1688108eb18Smrg		case 3:
1698108eb18Smrg		    prop->type = XtNewString(p);
1708108eb18Smrg		    state = 4;
1718108eb18Smrg		    break;
1728108eb18Smrg
1738108eb18Smrg		default:
1748108eb18Smrg		    fprintf(stderr, "state %d\n", state);
1758108eb18Smrg		    fprintf(stderr,
1768108eb18Smrg			    "Corrupt save file line ignored:\n%s\n", buf);
1778108eb18Smrg		    continue;
1788108eb18Smrg	    }
1798108eb18Smrg	} else {
1808108eb18Smrg	    if (state != 4) {
1818108eb18Smrg		fprintf(stderr, "Corrupt save file line ignored:\n%s\n", buf);
1828108eb18Smrg		continue;
1838108eb18Smrg	    }
1848108eb18Smrg	    val = (PropValue *)XtMalloc(sizeof *val);
1858108eb18Smrg	    if(!val) nomem();
1868108eb18Smrg
1878108eb18Smrg	    if (strcmp (prop->type, SmCARD8) == 0)
1888108eb18Smrg	    {
1898108eb18Smrg		val->length = 1;
1908108eb18Smrg		val->value = (XtPointer) XtMalloc (1);
1918108eb18Smrg		*((char *)(val->value)) = atoi (p);
1928108eb18Smrg	    }
1938108eb18Smrg	    else
1948108eb18Smrg	    {
1958108eb18Smrg		val->length = strlen(p);
1968108eb18Smrg		val->value = XtNewString(p);
1978108eb18Smrg	    }
1988108eb18Smrg
1998108eb18Smrg	    if(!ListAddLast(prop->values, (char *)val)) nomem();
2008108eb18Smrg	}
2018108eb18Smrg    }
2028108eb18Smrg
2038108eb18Smrg    /* Read commands for non-session aware clients */
2048108eb18Smrg
2058108eb18Smrg    if (state == 5)
2068108eb18Smrg    {
20787fb7d39Smrg	char *strbuf;
2088108eb18Smrg	int bufsize = 0;
2098108eb18Smrg
2108108eb18Smrg	getnextline(&buf, &buflen, f);
2118108eb18Smrg	if((p = strchr(buf, '\n'))) *p = '\0';
2128108eb18Smrg	non_session_aware_count = atoi (buf);
2138108eb18Smrg
2148108eb18Smrg	if (non_session_aware_count > 0)
2158108eb18Smrg	{
2168108eb18Smrg	    non_session_aware_clients = (char **) malloc (
2178108eb18Smrg	        non_session_aware_count * sizeof (char *));
2188108eb18Smrg
2198108eb18Smrg	    for (i = 0; i < non_session_aware_count; i++)
2208108eb18Smrg	    {
2218108eb18Smrg		getnextline(&buf, &buflen, f);
2228108eb18Smrg		if((p = strchr(buf, '\n'))) *p = '\0';
22387fb7d39Smrg		non_session_aware_clients[i] = malloc (strlen (buf) + 2);
2248108eb18Smrg		strcpy (non_session_aware_clients[i], buf);
2258108eb18Smrg		bufsize += (strlen (buf) + 1);
2268108eb18Smrg	    }
2278108eb18Smrg
22887fb7d39Smrg	    strbuf = 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
3005977a007SmrgWriteSave(const char *sm_id)
3018108eb18Smrg{
3028108eb18Smrg    ClientRec *client;
3038108eb18Smrg    FILE *f;
3048108eb18Smrg    List *cl;
30587fb7d39Smrg    char *commands;
3068108eb18Smrg    char *p, *c;
3078108eb18Smrg    int count;
3088108eb18Smrg
3092bc08f26Swiz    f = fopen (session_save_file, "w");
3108108eb18Smrg
3118108eb18Smrg    if (!f)
3128108eb18Smrg    {
31387fb7d39Smrg	char msg[36 + sizeof(session_save_file)];
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    {
3222bc08f26Swiz	fcntl(fileno(f), F_SETFD, FD_CLOEXEC);
3238108eb18Smrg	fprintf (f, "%d\n", SAVEFILE_VERSION);
3248108eb18Smrg	fprintf (f, "%s\n", sm_id);
3258108eb18Smrg
3268108eb18Smrg	count = 0;
3278108eb18Smrg	for (cl = ListFirst (RunningList); cl; cl = ListNext (cl))
3288108eb18Smrg	{
3298108eb18Smrg	    client = (ClientRec *) cl->thing;
3308108eb18Smrg
3318108eb18Smrg	    if (client->restartHint != SmRestartNever)
3328108eb18Smrg		count++;
3338108eb18Smrg	}
3348108eb18Smrg	count += ListCount (RestartAnywayList);
3358108eb18Smrg
3368108eb18Smrg	fprintf (f, "%d\n", count);
3378108eb18Smrg	if (count == 0)
3388108eb18Smrg	    fprintf (f, "\n");
3398108eb18Smrg
3408108eb18Smrg	for (cl = ListFirst (RunningList); cl; cl = ListNext (cl))
3418108eb18Smrg	{
3428108eb18Smrg	    client = (ClientRec *) cl->thing;
3438108eb18Smrg
3448108eb18Smrg	    if (client->restartHint == SmRestartNever)
3458108eb18Smrg		continue;
3468108eb18Smrg
3478108eb18Smrg	    SaveClient (f, client);
3488108eb18Smrg	}
3498108eb18Smrg
3508108eb18Smrg	for (cl = ListFirst (RestartAnywayList); cl; cl = ListNext (cl))
3518108eb18Smrg	{
3528108eb18Smrg	    client = (ClientRec *) cl->thing;
3538108eb18Smrg
3548108eb18Smrg	    SaveClient (f, client);
3558108eb18Smrg	}
3568108eb18Smrg
3578108eb18Smrg
3588108eb18Smrg	/* Save the non-session aware clients */
3598108eb18Smrg
3608108eb18Smrg	XtVaGetValues (manualRestartCommands,
3618108eb18Smrg	    XtNstring, &commands,
3628108eb18Smrg	    NULL);
3638108eb18Smrg
3648108eb18Smrg	p = c = commands;
3658108eb18Smrg	count = 0;
3668108eb18Smrg
3678108eb18Smrg	while (*p)
3688108eb18Smrg	{
3698108eb18Smrg	    if (*p == '\n')
3708108eb18Smrg	    {
3718108eb18Smrg		if (p != c)
3728108eb18Smrg		    count++;
3738108eb18Smrg		c = p + 1;
3748108eb18Smrg	    }
3758108eb18Smrg	    p++;
3768108eb18Smrg	}
3778108eb18Smrg	if (p != c)
3788108eb18Smrg	    count++;
3798108eb18Smrg
3808108eb18Smrg	fprintf (f, "%d\n", count);
3818108eb18Smrg
3828108eb18Smrg	p = c = commands;
3838108eb18Smrg
3848108eb18Smrg	while (*p)
3858108eb18Smrg	{
3868108eb18Smrg	    if (*p == '\n')
3878108eb18Smrg	    {
3888108eb18Smrg		if (p != c)
3898108eb18Smrg		{
3908108eb18Smrg		    *p = '\0';
3918108eb18Smrg		    fprintf (f, "%s\n", c);
3928108eb18Smrg		    *p = '\n';
3938108eb18Smrg		}
3948108eb18Smrg		c = p + 1;
3958108eb18Smrg	    }
3968108eb18Smrg	    p++;
3978108eb18Smrg	}
3988108eb18Smrg
3998108eb18Smrg	if (p != c)
4008108eb18Smrg	    fprintf (f, "%s\n", c);
4018108eb18Smrg
4028108eb18Smrg	fclose (f);
4038108eb18Smrg    }
4048108eb18Smrg}
4058108eb18Smrg
4068108eb18Smrg
4078108eb18Smrg
4088108eb18SmrgStatus
4095977a007SmrgDeleteSession(const char *session_name)
4108108eb18Smrg{
4118108eb18Smrg    char	*buf;
4128108eb18Smrg    int		buflen;
4135977a007Smrg    char	*p;
4145977a007Smrg    const char	*dir;
4158108eb18Smrg    FILE	*f;
4168108eb18Smrg    int		state;
4178108eb18Smrg    int		foundDiscard;
4188108eb18Smrg    char	filename[256];
4198108eb18Smrg    int		version_number;
4208108eb18Smrg
4215977a007Smrg    dir = getenv ("SM_SAVE_DIR");
4228108eb18Smrg    if (!dir)
4238108eb18Smrg    {
4245977a007Smrg	dir = getenv ("HOME");
4258108eb18Smrg	if (!dir)
4268108eb18Smrg	    dir = ".";
4278108eb18Smrg    }
4288108eb18Smrg
4291a650d1eSmrg    snprintf (filename, sizeof(filename), "%s/.XSM-%s", dir, session_name);
4308108eb18Smrg
4312bc08f26Swiz    f = fopen(filename, "r");
4328108eb18Smrg    if(!f) {
4338108eb18Smrg	return (0);
4348108eb18Smrg    }
4352bc08f26Swiz    fcntl(fileno(f), F_SETFD, FD_CLOEXEC);
4368108eb18Smrg
4378108eb18Smrg    buf = NULL;
4388108eb18Smrg    buflen = 0;
4398108eb18Smrg
4408108eb18Smrg    /* Read version # */
4418108eb18Smrg    getnextline(&buf, &buflen, f);
4428108eb18Smrg    if((p = strchr(buf, '\n'))) *p = '\0';
4438108eb18Smrg    version_number = atoi (buf);
4448108eb18Smrg    if (version_number > SAVEFILE_VERSION)
4458108eb18Smrg    {
4468108eb18Smrg	if (verbose)
4478108eb18Smrg	    printf("Can't delete session save file - incompatible version.\n");
4488108eb18Smrg	if (buf)
4498108eb18Smrg	    free (buf);
4508108eb18Smrg	return (0);
4518108eb18Smrg    }
4528108eb18Smrg
4538108eb18Smrg    /* Skip SM's id */
4548108eb18Smrg    getnextline(&buf, &buflen, f);
4558108eb18Smrg
4568108eb18Smrg    /* Skip number of clients running in the last session */
4578108eb18Smrg    if (version_number >= 2)
4588108eb18Smrg	getnextline(&buf, &buflen, f);
4598108eb18Smrg
4608108eb18Smrg    state = 0;
4618108eb18Smrg    foundDiscard = 0;
4628108eb18Smrg    while(getnextline(&buf, &buflen, f)) {
4638108eb18Smrg	if((p = strchr(buf, '\n'))) *p = '\0';
4648108eb18Smrg	for(p = buf; *p && isspace(*p); p++) /* LOOP */;
4658108eb18Smrg	if(*p == '#') continue;
4668108eb18Smrg
4678108eb18Smrg	if(!*p) {
4688108eb18Smrg	    state = 0;
4698108eb18Smrg	    foundDiscard = 0;
4708108eb18Smrg	    continue;
4718108eb18Smrg	}
4728108eb18Smrg
4738108eb18Smrg	if(!isspace(buf[0])) {
4748108eb18Smrg	    switch(state) {
4758108eb18Smrg		case 0:
4768108eb18Smrg		    state = 1;
4778108eb18Smrg		    break;
4788108eb18Smrg
4798108eb18Smrg		case 1:
4808108eb18Smrg                    state = 2;
4818108eb18Smrg                    break;
4828108eb18Smrg
4838108eb18Smrg		case 2:
4848108eb18Smrg		case 4:
4858108eb18Smrg		    if (strcmp (p, SmDiscardCommand) == 0)
4868108eb18Smrg			foundDiscard = 1;
4878108eb18Smrg		    state = 3;
4888108eb18Smrg		    break;
4898108eb18Smrg
4908108eb18Smrg		case 3:
4918108eb18Smrg		    state = 4;
4928108eb18Smrg		    break;
4938108eb18Smrg
4948108eb18Smrg		default:
4958108eb18Smrg		    continue;
4968108eb18Smrg	    }
4978108eb18Smrg	} else {
4988108eb18Smrg	    if (state != 4) {
4998108eb18Smrg		continue;
5008108eb18Smrg	    }
5018108eb18Smrg	    if (foundDiscard)
5028108eb18Smrg	    {
5038108eb18Smrg		execute_system_command (p);	/* Discard Command */
5048108eb18Smrg		foundDiscard = 0;
5058108eb18Smrg	    }
5068108eb18Smrg	}
5078108eb18Smrg    }
5088108eb18Smrg
5098108eb18Smrg    fclose(f);
5108108eb18Smrg
5118108eb18Smrg    if (buf)
5128108eb18Smrg	free (buf);
5138108eb18Smrg
5141a650d1eSmrg    return ((remove (filename) == -1) ? 0 : 1);
5158108eb18Smrg}
5168108eb18Smrg
5178108eb18Smrg
5188108eb18Smrg
5198108eb18SmrgBool
5208108eb18Smrggetnextline(char **pbuf, int *plen, FILE *f)
5218108eb18Smrg{
5228108eb18Smrg	int c;
5238108eb18Smrg	int i;
5248108eb18Smrg
5258108eb18Smrg	i = 0;
5268108eb18Smrg	while(1) {
5278108eb18Smrg	    if(i+2 > *plen) {
5288108eb18Smrg		if(*plen) *plen *= 2;
5298108eb18Smrg		else *plen = BUFSIZ;
5308108eb18Smrg		if(*pbuf) *pbuf = (char *) realloc(*pbuf, *plen + 1);
5318108eb18Smrg		else *pbuf = (char *) malloc(*plen + 1);
5328108eb18Smrg	    }
5338108eb18Smrg	    c = getc(f);
5348108eb18Smrg	    if(c == EOF) break;
5358108eb18Smrg	    (*pbuf)[i++] = c;
5368108eb18Smrg	    if(c == '\n') break;
5378108eb18Smrg	}
5388108eb18Smrg	(*pbuf)[i] = '\0';
5398108eb18Smrg	return i;
5408108eb18Smrg}
541