[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

problems compiling plan under libc6



I really don't program in C, so I have no idea if this is something easy
to figure out or needs a great amount of reworking. Anyway, given that
debian will require all packages to be compiled with libc6 in the near
future, I thought I would see if this is fixable. The error message from
gcc is:

  gcc -s -D_POSIX_SOURCE -DNOLOCK -DLINUX -DRABBITS   -c file_r.c
  file_r.c: In function `read_mainlist':
  file_r.c:132: `S_IFDIR' undeclared (first use this function)
  file_r.c:132: (Each undeclared identifier is reported only once
  file_r.c:132: for each function it appears in.)
  make[1]: *** [file_r.o] Error 1
  make[1]: Leaving directory `/home/telmerco/debian/plan-1.6.1/src'
  make: *** [linux] Error 2 

The lines around line 132 in file_r.c are

	if (!stat(user[u].path, &sbuf) && (sbuf.st_mode & S_IFDIR))
		sprintf(path, "%s/%s", user[u].path, DB_FILE);

and the entire file_r.c is attached. The error message seems to be saying
that the code is trying to do a bitwise AND with something that is
undefined. However, I have no idea why this would work with libc5 and not
libc6:)

I really don't know what other information to add except for some lib and
gcc versions (below). Any help is gratefully appreciated. Cheers, Colin. 

ii  libc6           2.0.4-1        The GNU C library version 2
ii  libc6-dev       2.0.4-1        The GNU C library version 2
ii  libc6-doc       2.0.4-1        The GNU C library version 2
ii  gcc             2.7.2.2-5      The GNU C compiler
ii  bash            2.0-3          The GNU Bourne Again SHell

--
	  Colin R. Telmer, Institute of Intergovernmental Relations
		School of Policy Studies, Queen's University
		     Kingston, Ontario, Canada, K7L-3N6
	      (613)545-6000x4219   telmerco@qed.econ.queensu.ca
	   PGP Public Key at <URL:http://terrapin.econ.queensu.ca>


/*
 * read the master list from the ~/.dayplan file. This file is also
 * linked into the daemon program (file_w.c is not).
 *
 *	read_mainlist()		Read all files into mainlist.
 */

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#ifdef MIPS
#include <sys/types.h>
#include <sys/fcntl.h>
#else
#include <stdlib.h>
#endif
#ifdef _APOLLO_SOURCE
#include <sys/types.h>
#include <sys/fcntl.h>
#endif
#ifdef ULTRIX
#include <sys/types.h>
#endif
#include <sys/stat.h>
#include <pwd.h>
#include <time.h>
#include <errno.h>
#include <Xm/Xm.h>
#include "config.h"
#include "proto.h"
#include "version.h"
#ifdef PLANGROK
#include "grok.h"
#include "form.h"
#endif

#define NDAYS		28			/* must agree with cal.h */

#ifdef MIPS
extern char		*getenv();
extern char		*malloc();
#endif
static int		readfile();
static void		make_default_user();
static void		convert_dbase();

extern char		*progname;		/* argv[0] */
extern struct plist	*mainlist;		/* all schedule entries */
extern struct config	config;			/* global configuration data */
struct user		*user;			/* user list for week view */
static int		maxusers;		/* max # of users in u list */
int			nusers;			/* # of users in user list */
char			Print_Spooler[100];	/* print spooling command */


/*
 * read the main list. First, read the main ~/.dayplan file, which also
 * provides the configuration data, including the user list. Next, read
 * the private dayplan file and all user dayplan files. Return a text
 * buffer with error messages; if msg is 0 print themn to stderr. This
 * file can't use create_error_popup because it is used by the daemon too.
 *
 * Depending on the mode, server connections are established after the
 * config part of the .dayplan file (including the user list and server
 * mode) was read in. The actual appointment data is then read from the
 * files or the servers.
 */

BOOL read_mainlist()
{
	struct stat		sbuf;		/* check for directories */
	char			msgbuf[4096];	/* default message buffer */
	char			*msg, *p;	/* where messages are stored */
	char			path[1024];	/* user file name to read */
	int			u;		/* user counter */
	int			error;

	msg  = msgbuf;
	*msg = 0;
	destroy_list(&mainlist);			/* delete appt list */
	create_list(&mainlist);

	if (user) {					/* delete user list */
		for (u=0; u < nusers; u++) {
			if (user[u].name)
				free((char *)user[u].name);
			if (user[u].path)
				free((char *)user[u].path);
			if (user[u].server)
				free((char *)user[u].server);
		}
		free((char *)user);
		user = 0;
	}
	nusers = maxusers = 0;
							/* main data */
	if (error = readfile(&mainlist, DB_PUB_PATH, 0, TRUE))
		sprintf(msg+strlen(msg),
			"Failed to read master file %s, error %d\n",
			DB_PUB_PATH, error);
	else if (!access(DB_PUB_PATH, F_OK) && access(DB_PUB_PATH, W_OK))
		sprintf(msg+strlen(msg),
		      "Warning: own config and data file %s is not writable\n",
								DB_PUB_PATH);

							/* private data */
	if (error = readfile(&mainlist, DB_PRIV_PATH, 0, FALSE))
		sprintf(msg+strlen(msg),
			"Failed to read private file %s, error %d\n",
			DB_PRIV_PATH, error);
	else if (!access(DB_PRIV_PATH, F_OK) && access(DB_PRIV_PATH, W_OK))
		sprintf(msg+strlen(msg),
			"Warning: own private data file %s is not writable\n",
								DB_PRIV_PATH);

	make_default_user(resolve_tilde(DB_PUB_PATH));	/* network connection*/
	if (p = attach_to_network())
		strcat(msg, p);
	read_from_server(&mainlist, 0, 0);
							/* user data */
	for (u=1; u < nusers; u++) {			/* skip 0, 0 is own */
		if (user[u].fromserver) {
			read_from_server(&mainlist, u, 0);
			continue;
		}
		if (!user[u].path || !user[u].name) {
			sprintf(msg+strlen(msg),
				"file of user #%d not read, no name or path\n",
								u);
			continue;
		}
		if (!stat(user[u].path, &sbuf) && (sbuf.st_mode & S_IFDIR))
			sprintf(path, "%s/%s", user[u].path, DB_FILE);
		else
			strcpy(path, user[u].path);
		user[u].readonly = !access(path, F_OK) && !!access(path, W_OK);
		user[u].modified = FALSE;
		user[u].time     = get_time();
		if (config.owner_only && !stat(path, &sbuf)
				      && sbuf.st_uid != getuid())
			user[u].readonly = TRUE;

		if ((error = readfile(&mainlist, path, u, FALSE)) &&
							error != ENOENT)
			sprintf(msg+strlen(msg),
				"Failed to read file %s of user %s, error %d\n",
				user[u].path, user[u].name, error);
	}
	rebuild_repeat_chain(mainlist);

	if (*msg)
		create_error_popup(0, 0,
				"Error while reading files:\n%s", msg);
	mainlist->modified = FALSE;
	return(!*msg);
}


/*
 * read a list from a file. If <list> points to a non-null pointer, the
 * list in the file is merged into the list. As with add_entry(), <list>
 * is a pointer to a pointer to the list because the list might grow and
 * must be re-allocated. If the file is empty, no new list is allocated,
 * and <list> continues to point to a null pointer.
 *
 * If it turns out that appointment data is to be read from servers instead
 * of files after a 'n' (networking) line was read, reading is aborted when
 * the first appointment definition is found (line beginning with a digit):
 * network mode...
 *   1: always read from file
 *   2: only read own: from .dayplan (conf) or .dayplan.priv (!conf&&!name)
 *   3: never read from any file
 *
 * Always read config information if conf==TRUE, it never comes from a server.
 * Returns nonzero if the file could not be read.
 */

static int readfile(list, path, u, conf)
	struct plist		**list;		/* list to add to */
	char			*path;		/* file to read list from */
	int			u;		/* user number, 0=own */
	BOOL			conf;		/* if TRUE, config stuff too */
{
	register struct config	*c = &config;
	FILE			*fp;		/* open file */
	BOOL			writable;	/* can we lock the file? */
	char			line[1024];	/* line buffer */
	int			lineno = 0;	/* first line == "grok"? */

	path = resolve_tilde(path);
	writable = !access(path, W_OK);
	if (!(fp = fopen(path, writable ? "r+" : "r")))
		return(errno);
	if (conf)		/* defaults for 't' line */
		guess_tzone();
	if (writable)
		lockfile(fp, TRUE);
	for (;;) {
		if (!fgets(line, 1024, fp))
			break;
		if (!lineno++ && !strncmp(line, "grok", 4)) {
#ifndef PLANGROK
			create_error_popup(0, 0,
				"%s is a\ngrok database, not supported", path);
#else
			extern FORM *form_create();
			struct user *up = &user[u];
			if (!u)
				create_error_popup(0, 0, "The first file in the file list\n(%s)\nmust not be a grok database!\nTrying to continue, you may lose data.", path);
			form_delete(up->form);
			dbase_delete(up->dbase);
			up->grok     = TRUE;
			up->readonly = TRUE;
			up->form     = form_create();
			up->dbase    = dbase_create();
			if (read_form(up->form, path)) {
				char *p = up->form->dbase?up->form->dbase:path;
				read_dbase(up->dbase, up->form, p);
				convert_dbase(list, up, p);
			}
#endif
			break;
		}
		if (!conf && strchr("OotelaPpmUu", *line))
			continue;
		if (*line >= '0' && *line <= '9' && user
						 && user[u].fromserver)
			break;
		parse_file_line(list, path, user ? user[u].name:0, conf, line);
	}
	if (writable)
		lockfile(fp, FALSE);
	fclose(fp);
	return(0);
}


/*
 * parse a line read from a file or from a server. An entry consists of one
 * or more lines and calls to this routine; remember the entry currently
 * being read and keep adding to it until a new entry starts. If the line
 * begins with '@', it's the first appt line from the network with '@fid rid'
 * prepended to the usual numerical date/time string.
 */

void parse_file_line(list, path, name, conf, line)
	struct plist		**list;		/* list to add to */
	char			*path;		/* file/server to read from */
	char			*name;		/* user name, 0=not yet known*/
	BOOL			conf;		/* if TRUE, config stuff too */
	char			*line;		/* line to be parsed */
{
	register struct config	*c = &config;
	int			fid, rid;	/* network file ID and row ID*/
	char			*instring;	/* string at line[2] or [3] */
	register char		*p, *q;		/* line scan pointer */
	static struct entry	entry;		/* temp entry before adding */
	static struct entry	*ep = 0;	/* list entry being read */
	int			n, m;		/* tmp entry # of ep in list */
	struct tm		tm;		/* m/d/y h:m:s to time conv */
	int			tmp[9];		/* temps for sscanf */
	int			acol;		/* more temps for sscanf */
	char			sflag, pflag, nflag;
	char			nmflag, nyflag, nwflag, noflag, ndflag;
	char			**string;	/* string to add to */
	int			len;		/* new length of string */
	char			buf1[256], buf2[1024], buf3[1024];

	if (*line == '@') {
		sscanf(line+1, "%d %d", &fid, &rid);
		while (*++line != ' ');
		while (*++line == ' ');
		while (*++line != ' ');
		while (*++line == ' ');
		delete_entry_by_id(*list, fid, rid);
	} else
		fid = rid = 0;
	instring = line+2;
	*buf1 = *buf2 = *buf3 = 0;
	switch(*line) {
	  case '\n':
	  case '#':
		return;

	  case 'V':
		line[strlen(line)-1] = 0;
		sprintf(buf1, "plan %s", VERSION);
		if (strcmp(line, buf1))
			fprintf(stderr,
		"%s: WARNING: file %s is version %s, program version is %s\n",
						progname, path, line, buf1);
		break;

	  case 'o':
		c->week_ndays  = 7;
		c->sunday_first   = line[2]  != '-';
		c->ampm           = line[3]  != '-';
		c->mmddyy         = line[4]  != '-';
		c->autodel        = line[5]  != '-';
		c->julian         = line[6]  != '-';
		c->gpsweek        = line[7]  == 'g';
		c->weeknum        = line[7]  != '-';
		c->nopast         = line[8]  != '-';
		c->bigwarning     = line[9]  != '-';
		c->weekwarn       = line[10] != '-';
		c->weekuser       = line[11] != '-';
		c->week_bignotime = line[12] != '-';
		c->fullweek       = line[13] != '-';
		c->colorcode_m    = line[14] != '-';
		c->ownonly	  = line[15] != '-';
		sscanf(line+16, "%d %d %d %d %d %d",
					(int *)&c->early_time,
					(int *)&c->late_time,
					(int *)&c->wintimeout,
					(int *)&c->week_minhour,
					(int *)&c->week_maxhour,
					(int *)&c->week_ndays);
		if (c->week_minhour >= c->week_maxhour) {
			c->week_minhour = 8;
			c->week_maxhour = 20;
		}
		if (c->week_ndays < 1)
			c->week_ndays = 7;
		if (c->week_ndays > NDAYS)
			c->week_ndays = NDAYS;
		break;

	  case 'O':
		c->share_mainwin  = line[2]  != '-';
		c->resize_mainwin = line[3]  != '-';
		break;

	  case 't':
		sscanf(line+2, "%d %d %d %d %d",
					(int *)&c->adjust_time,
					(int *)&c->raw_tzone,
					(int *)&c->dst_flag,
					(int *)&c->dst_begin,
					(int *)&c->dst_end);
		set_tzone();
		break;

	  case 'e':
		c->ewarn_window = line[2] != '-';
		c->ewarn_mail   = line[3] != '-';
		c->ewarn_exec   = line[4] != '-';
		line[strlen(line)-1] = 0;
		if (c->ewarn_prog)
			free(c->ewarn_prog);
		c->ewarn_prog = 0;
		if (line[5] && line[6])
			c->ewarn_prog = mystrdup(line+6);
		break;

	  case 'l':
		c->lwarn_window = line[2] != '-';
		c->lwarn_mail   = line[3] != '-';
		c->lwarn_exec   = line[4] != '-';
		line[strlen(line)-1] = 0;
		if (c->lwarn_prog)
			free(c->lwarn_prog);
		c->lwarn_prog = 0;
		if (line[5] && line[6])
			c->lwarn_prog = mystrdup(line+6);
		break;

	  case 'a':
		c->alarm_window = line[2] != '-';
		c->alarm_mail   = line[3] != '-';
		c->alarm_exec   = line[4] != '-';
		line[strlen(line)-1] = 0;
		if (c->alarm_prog)
			free(c->alarm_prog);
		c->alarm_prog = 0;
		if (line[5] && line[6])
			c->alarm_prog = mystrdup(line+6);
		break;

	  case 'y':
		c->yov_single = line[2] != '-';
		for (p=line+2; *p && *p != ' '; p++);
		sscanf(p, "%d %d %d", &c->yov_nmonths,
				      &c->yov_display,
				      &c->yov_user);
		break;

	  case 'P':
		c->pr_omit_appts  = line[2] != '-';
		c->pr_omit_priv   = line[3] != '-';
		c->pr_omit_others = line[4] != '-';
		c->pr_mode        = atoi(line+13);
		break;

	  case 'p':
		strncpy(Print_Spooler, (const char *)line + 2,
					sizeof(Print_Spooler));
		Print_Spooler[sizeof(Print_Spooler)-1] = 0;
		Print_Spooler[strlen(Print_Spooler)-1] = 0;
		break;

	  case 'm':
		line[strlen(line)-1] = 0;
		if (line[1] && line[2])
			c->mailer = mystrdup(line+2);
		break;

	  case 'U':
		make_default_user(path);
		break;

	  case 'u':
		if (nusers >= maxusers) {
			n = nusers + 10;
			user = user ? realloc(user, n * sizeof(struct user))
				    : malloc(n * sizeof(struct user));
			if (!user)
				fatal("no memory");
			memset(user+maxusers, 0,
					(n-maxusers) * sizeof(struct user));
			maxusers = n;
		}
		sscanf(line+2, "%s %s %d %d %d %d %d %d %s %d\n", buf1, buf2,
				&user[nusers].suspend_w,
				&user[nusers].color,
				&user[nusers].suspend_m,
				&user[nusers].alarm,
				&user[nusers].suspend_o,
				&user[nusers].fromserver, buf3,
				&user[nusers].suspend_d);
		if (!*buf3 && gethostname(buf3, sizeof(buf3)))
			strcpy(buf3, "localhost");
		m = 0;
		do for (n=nusers-1; n >= 0; n--)
			if (!strcmp(user[n].name, buf1)) {
				strcat(buf1, "x");
				break;
			}
		while (n >= 0 && m++ < nusers);
		user[nusers].name    = mystrdup(buf1);
		user[nusers].path    = mystrdup(buf2);
		user[nusers].server  = mystrdup(buf3);
		user[nusers].file_id = -1;
		nusers++;
		break;

	  case '0':
	  case '1':
	  case '2':
	  case '3':
	  case '4':
	  case '5':
	  case '6':
	  case '7':
	  case '8':
	  case '9':
		make_default_user(path);
		clone_entry(&entry, (struct entry *)0);
		sflag = pflag = nflag =
		nmflag = nyflag = nwflag = noflag = ndflag = 0;
		acol = 0;
		sscanf(line,
	"%d/%d/%d %d:%d:%d %d:%d:%d %d:%d:%d %d:%d:%d %c%c%c%c%c%c%c%c-- %d",
			&tm.tm_mon, &tm.tm_mday, &tm.tm_year,
			&tm.tm_hour, &tm.tm_min, &tm.tm_sec,
			tmp+0, tmp+1, tmp+2,
			tmp+3, tmp+4, tmp+5,
			tmp+6, tmp+7, tmp+8,
			&sflag, &pflag, &nflag,
			&nmflag, &nyflag, &nwflag, &noflag, &ndflag, &acol);
		tm.tm_mon--;
		if (tm.tm_year < 70)
			tm.tm_year += 100;
		if (tm.tm_year > 1900)
			tm.tm_year -= 1900;
		if (entry.notime = tm.tm_hour > 23)
			tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
		entry.time         = tm_to_time(&tm);
		entry.length       = tmp[0]*3600 + tmp[1]*60 + tmp[2];
		entry.early_warn   = tmp[3]*3600 + tmp[4]*60 + tmp[5];
		entry.late_warn    = tmp[6]*3600 + tmp[7]*60 + tmp[8];
		entry.suspended    = sflag  == 'S';
		entry.private      = pflag  == 'P';
		entry.noalarm      = nflag  == 'N';
		entry.hide_in_m    = nmflag == 'M';
		entry.hide_in_y    = nyflag == 'Y';
		entry.hide_in_w    = nwflag == 'W';
		entry.hide_in_o    = noflag == 'O';
		entry.hide_in_d    = ndflag == 'D';
		entry.acolor       = acol;
		entry.user	   = name ? mystrdup(name) : 0;
		entry.file	   = fid;
		entry.id	   = rid;
		n = add_entry(list, &entry);	/* sets <list> */
		ep = &(*list)->entry[n];
		break;

	  case 'R':
		sscanf(line+2, "%d %d %d %d %d",
			(int *)&ep->rep_every,
			(int *)&ep->rep_last,
			(int *)&ep->rep_weekdays,
			(int *)&ep->rep_days,
			(int *)&ep->rep_yearly);

		if (ep->time && ep->rep_last && ep->time > ep->rep_last)
			ep->rep_last = 0;
		break;

	  case 'E':
		for (n=0; n < NEXC; n++)
			if (!ep->except[n])
				break;
		if (n < NEXC) {
			sscanf(line+2, "%d/%d/%d",
				&tm.tm_mon, &tm.tm_mday, &tm.tm_year);
			tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
			tm.tm_mon--;
			if (tm.tm_year < 70)
				tm.tm_year += 100;
			if (tm.tm_year > 1900)
				tm.tm_year -= 1900;
			ep->except[n] = tm_to_time(&tm);
		} else
			fprintf(stderr,
				"too many exception dates for appt");
		break;

	  case 'N':
		string = &ep->note;
		ep->hide_in_w |= line[2] == '-';
		if (line[2] == '-' || line[2] == '=') {
			ep->hide_in_m = ep->hide_in_y = TRUE;
			instring++;
		}
		goto add;

	  case 'M':
		string = &ep->message;
		goto add;

	  case 'S':
		string = &ep->script;
add:			len  = *string ? strlen(*string) : 0;
		len += strlen(instring) + 2;
		if (!(p = malloc(len))) {
			fprintf(stderr, "%s: no memory", progname);
			exit(1);
		}
		if (*string) {
			strcpy(p, *string);
			strcat(p, instring);
			free(*string);
		} else
			strcpy(p, instring);
		*string = p;
		break;
	
	  default:
		fprintf(stderr, "%s: %s: illegal line:\n%s",
						progname, path, line);
	}
}


/*
 * When a 'U', 'u', or begin-appointment line is found, user[0] (own) must
 * exist. If not, this routine makes one, and also ensures that <user> is
 * not a null pointer because everybody relies on that.
 */

static void make_default_user(path)
	char		*path;		/* file path for own .dayplan */
{
	struct passwd	*pw;
	char		host[1024], *name;

	if (user && nusers && user[0].name)
		return;
	pw = getpwuid(getuid());
	name = pw ? pw->pw_name : getenv("LOGNAME");
	if (!name)
		name = "unknown";
	if (!user) {
		maxusers = 10;
		if (!(user = malloc(maxusers * sizeof(struct user))))
			fatal("no memory");
		memset(user, 0, maxusers * sizeof(struct user));
	}
	if (gethostname(host, sizeof(host)))
		strcpy(host, "localhost");
	user[0].name    = mystrdup(name);
	user[0].path    = mystrdup(path);
	user[0].server  = mystrdup(host);
	user[0].alarm   = TRUE;
	user[0].file_id = -1;
	nusers = 1;
}


/*
 * convert a grok database to a list of appointment entries
 */

#ifdef PLANGROK
static void convert_dbase(list, up, db)
	struct plist		**list;		/* list to add to */
	register struct user	*up;		/* user with form/dbase */
	char			*db;		/* db name for error messages*/
{
	struct entry		*elist;		/* temporary list of entries */
	register struct entry	*ep;		/* list entry being read */
	ITEM			*item;		/* current field description */
	ROW			*row;		/* curr database row */
	register char		*data;		/* curr database contents */
	int			en, ei;		/* # of entries; curr entry */
	int			fn, fi;		/* # of fields; curr field */
	BOOL			tagged=FALSE;	/* dbase has plan interface? */
	BOOL			have_d, have_n;	/* dbase has date & note? */
	int			def_d, def_n;	/* default date & note fields*/
	int			n;

	if ((en = up->dbase->nrows) < 1 || (fn = up->form->nitems) < 1)
		return;
	if (!(elist = (struct entry *)malloc(en * sizeof(struct entry))))
		fatal("no memory for appointment list");
	for (ep=elist, ei=0; ei < en; ei++, ep++) {
		clone_entry(ep, (struct entry *)0);
		ep->grok_row = ei;
	}
	have_d = have_n = FALSE;			/* have date & note? */
	def_d  = def_n  = -1;
	for (fi=fn-1; fi >= 0; fi--) {
		item = up->form->items[fi];
		tagged |= item->plan_if != 0;
		have_d |= item->plan_if == 't';
		have_n |= item->plan_if == 'n';
		if (item->type == IT_TIME &&
		   (item->timefmt == T_DATE || item->timefmt == T_DATETIME))
			def_d = fi;
		if (item->type == IT_INPUT || item->type == IT_NOTE)
			def_n = fi;
	}
	if (!have_d && def_d < 0) {
		create_error_popup(0, 0, "xmbase-grok database %s\ncannot be read because the calendar\ninterface is %s, and there are no\ndate fields to automatically generate one.", db, tagged ? "incomplete" : "missing");
		return;
	}
	if (!have_d)
		up->form->items[def_d]->plan_if = 't';
	if (!have_n)
		up->form->items[def_n]->plan_if = 'n';

	for (fi=0; fi < fn; fi++) {			/* ok, convert dbase */
		item = up->form->items[fi];
		for (ep=elist, ei=0; ei < en; ei++, ep++) {
			row = up->dbase->row[ei];
			if (row->ncolumns <= item->column)
				continue;
			if (!(data = row->data[item->column]))
				continue;
			switch(item->plan_if) {
			  case 't': if (item->timefmt == T_DATE) {
					ep->notime = TRUE;
					ep->time = atoi(data);
			  	    } else if (item->timefmt == T_DATETIME)
					ep->time = atoi(data);
				    break;
			  case 'l': ep->length	   = atoi(data);	break;
			  case 'w': ep->early_warn = atoi(data);	break;
			  case 'W': ep->late_warn  = atoi(data);	break;
			  case 'r': ep->rep_every  = atoi(data)*86400;	break;
			  case 'e': ep->rep_last   = atoi(data);	break;
			  case 'c': ep->acolor	   = atoi(data) & 7;	break;
			  case 'n': ep->note	   = mystrdup(data);	break;
			  case 'm': ep->message	   = mystrdup(data);	break;
			  case 's': ep->script	   = mystrdup(data);	break;
			  case 'S': ep->suspended  = !!atoi(data);	break;
			  case 'T': ep->notime	   = !!atoi(data);	break;
			  case 'A': ep->noalarm	   = !!atoi(data);	break;
			}
		}
	}
	for (ep=elist, n=ei=0; ei < en; ei++, ep++)	/* sanity checks */
		if (ep->time) {
			n++;
			if (ep->rep_last) {
				if (!ep->rep_every)
					ep->rep_every = 86400;
				if (ep->rep_last < ep->time)
					ep->rep_last = ep->time;
			}
			ep->user = mystrdup(up->name);
			add_entry(list, ep);
		} else
			destroy_entry(ep);
	if (!n)
		create_error_popup(0, 0, "%d of %d appointments from grok database\n%s discarded\nbecause of invalid date/time.", en-n, en, db);

	free((void *)elist);
}
#endif

Reply to: