[comp.sources.unix] v16i055: A visual calendar and appointment system, Part02/06

rsalz@uunet.uu.net (Rich Salz) (11/10/88)

Submitted-by: Michael Morrell <hplabs!hpda!morrell>
Posting-number: Volume 16, Issue 55
Archive-name: month8.7/part02

# This is a shell archive.  Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
# This archive contains:
#	month.h		month2.h	month3.h	month4.h	
#	month5.h	month6.h	month7.h	month8.h	
#	get.c		hl.c		lunar.c		month.c		
#	move.c		
LANG=""; export LANG

echo x - month.h
cat >month.h <<'@EOF'
/*
 * @(#)$Header: month.h,v 8.4 88/04/04 10:46:35 hull Exp $
 */

#define USER_COL	40		/* first column of "User:" */
#define FLAG_COL	69		/* first column of flags */
#define MONTH_ROW	3		/* top row of month area */
#define CAL_ROW		3		/* top row of calendar area */
#define CAL_COL		13		/* leftmost column of calendar area */
#define DAY_ROW		1		/* row for list of days */
#define DAY_COL		12		/* first column of list of days */
#define YEAR_ROW	15		/* row for year list */
#define YEAR_COL	15		/* first column of year list */
#define SCHEDULE_ROW	17		/* top row of schedule area */
#define SMONTH_COL	0		/* first column of start month */
#define SDAY_COL	3		/* first column of start day */
#define SYEAR_COL	6		/* first column of start year */
#define PRIVATE_COL	12		/* first column of "priv" */
#define ANTI_COL	17		/* first column of "anti" */
#define MONTHLY_COL	22		/* first column of "monthly" */
#define YEARLY_COL	30		/* first column of "yearly" */
#define EVERY_COL	37		/* first column of "every" */
#define NTH_COL		43		/* first column of "Nth" */
#define LAST_COL	48		/* first column of "last" */
#define SMTWTFS_COL	53		/* first column of "SuMoTuWeThFrSa" */
#define UMONTH_COL	68		/* first column of until month */
#define UDAY_COL	71		/* first column of until day */
#define UYEAR_COL	74		/* first column of until year */
#define TIME_ROW	20		/* row for event times */
#define START_COL	3		/* first column of start time */
#define DURATION_COL	21		/* first column of duration */
#define END_COL		37		/* first column of end time */
#define WARNING_COL	53		/* first column of warning time */
#define OWNER_ROW	20		/* row for event owner */
#define OWNER_COL	68		/* first column for event owner */
#define DESCRIPTION_ROW	22		/* row for event description */
#define DESCRIPTION_COL	7		/* first column of event description */

#define START_MODE	'S'		/* start time mode */
#define DURATION_MODE	'D'		/* duration mode */
#define END_MODE	'E'		/* end time mode */

#define ALIAS		'a'		/* alias area */
#define MONTHS		'm'		/* months area */
#define DAYS		'd'		/* days area */
#define YEARS		'y'		/* years area */
#define SCAN    	'n'		/* scan area */
#define SCHEDULE	's'		/* schedule area */
#define SCHED_SCAN    	'S'		/* scan and schedule area */
#define BOOK    	'B'		/* book area */
#define HELP    	'H'		/* help area */
#define LUNAR    	'L'		/* lunar area */

#define FIRST_YEAR	1760		/* 1/1/1760 is the beginning of time */
#define LAST_YEAR	9999		/* 12/31/9999 is the end of time */

#define MAX_EVENT_STRING_LENGTH	70	/* maximum length of an event string */
#define MAX_ALIAS_LEVEL	16		/* maximum number of alias levels */

#define NOTHING		0		/* no change in event status */
#define ACCEPT		1		/* event was accepted */
#define CANCEL		2		/* event change was cancelled */

#define NO_BELL		0		/* print message with no bell */
#define BELL		1		/* print message with bell */

#define HL_OFF		0		/* print without highlighting */
#define HL_ON		1		/* print with highlighting */

#define READ_WRITE	0		/* open .month with read/write access */
#define READ_ONLY	1		/* open .month with read-only access */

#define NUM_MARKS	12		/* maximum number of marked dates */
#define SEMI_MARK	(NUM_MARKS-2)	/* special marked date for ";" */
#define CUR_MARK	(NUM_MARKS-1)	/* currently marked date */

#define BUFSIZE		40		/* size of temporary buffers */
#define MAXLINE		1024		/* maximum line length in alias file */

#define MAXAREAS	5		/* size of area stack */
#define current_area	areas[area_ptr-1].area	/* top of area stack */

/* shell used for shell escape */
/* environment variable "SHELL" if defined, else "SHELLPROG" */
extern char *getenv();
#define SH	(getenv("SHELL") ? getenv("SHELL") : SHELLPROG)

/* pager used for printing help file */
/* environment variable "PAGER" if defined, else "PAGERPROG" */
#define PG	(getenv("PAGER") ? getenv("PAGER") : PAGERPROG)

#if !SYS5CURSES
#define attron(arg)	standout()	/* use standout for all highlighting */
#define attroff(arg)	standend()
#define A_CHARTEXT	0177		/* mask to strip attributes */
#endif

#if !CVOID
#define void	int
#endif

extern char *malloc();
#if SYS5
extern void exit(), free();
#endif
#ifdef hpux
#define alarm_t unsigned long
#else
#define alarm_t unsigned
#endif

/* structure of an area */
struct area_rec {
	short area;
	short row;
	short col;
};

/* structure of a date */
struct date_rec {
	short month;
	short day;
	short year;
};

/* structure of a time */
struct time_rec {
	short hour;
	short minute;
};

/* structure of an event pointer */
struct eptr_rec {
	struct event_rec *event;	/* event */
	struct eptr_rec *prev_event;	/* previous event */
	struct eptr_rec *next_event;	/* next event */
};

/* structure of a name */
struct name_rec {
	char *name;			/* name */
	struct name_rec *next_name	/* next name */
};

#include "month8.h"
@EOF

chmod 644 month.h

echo x - month2.h
cat >month2.h <<'@EOF'
/*
 * @(#)$Header: month2.h,v 2.0 87/11/13 22:58:00 hull Exp $
 */

struct event_rec2 {
	char event_month;	/* month of the event */
	char event_day;		/* day of the event */
	short event_year;	/* year of the event */
	char monthly;		/* does event occur monthly? */
	char yearly;		/* does event occur yearly? */
	char every;		/* does event occur on every something? */
	char smtwtfs[7];	/* which days of the week are relevant? */
	char nth, last;		/* does event occur on an nth or last something? */
	char nth_is_on;		/* is 'nth' selected by user, n is nth above */
	char hour;		/* hour of the event */
	char minute;		/* minute of the event */
	char duration_hours;	/* hours event lasts */
	char duration_minutes;	/* minutes event lasts, multiple of 15 */
	char event_string[MAX_EVENT_STRING_LENGTH];	/* short description of event */
	char private;		/* is event private? */
	struct event_rec2 *next_event;	/* next event */
};
@EOF

chmod 444 month2.h

echo x - month3.h
cat >month3.h <<'@EOF'
/*
 * @(#)$Header: month3.h,v 3.0 87/11/13 22:58:40 hull Exp $
 */

struct event_rec3 {
	char event_month;	/* month of the event */
	char event_day;		/* day of the event */
	short event_year;	/* year of the event */
	char monthly;		/* does event occur monthly? */
	char yearly;		/* does event occur yearly? */
	char every;		/* does event occur on every something? */
	char smtwtfs[7];	/* which days of the week are relevant? */
	char nth, last;		/* does event occur on an nth or last something? */
	char nth_is_on;		/* is 'nth' selected by user, n is nth above */
	char hour;		/* hour of the event */
	char minute;		/* minute of the event */
	char duration_hours;	/* hours event lasts */
	char duration_minutes;	/* minutes event lasts, multiple of 15 */
	char event_string[MAX_EVENT_STRING_LENGTH];	/* short description of event */
	char private;		/* is event private? */
	int event_owner;	/* owner of event */
	struct event_rec3 *next_event;	/* next event */
};
@EOF

chmod 444 month3.h

echo x - month4.h
cat >month4.h <<'@EOF'
/*
 * @(#)$Header: month4.h,v 4.0 87/11/13 22:59:20 hull Exp $
 */

struct event_rec4 {
	char start_month;	/* starting month of the event */
	char start_day;		/* starting day of the event */
	short start_year;	/* starting year of the event */
	char monthly;		/* does event occur monthly? */
	char yearly;		/* does event occur yearly? */
	char every;		/* does event occur on every something? */
	char smtwtfs[7];	/* which days of the week are relevant? */
	char nth;		/* does event occur on an nth something? */
	char last;		/* does event occur on a last something? */
	char nth_is_on;		/* is 'nth' selected by user, n is nth above */
	char hour;		/* hour of the event */
	char minute;		/* minute of the event */
	char duration_hours;	/* hours event lasts */
	char duration_minutes;	/* minutes event lasts */
	char event_string[MAX_EVENT_STRING_LENGTH];  /* description of event */
	char private;		/* is event private? */
	int event_owner;	/* owner of event */
	char until;		/* does event occur until some date? */
	char until_month;	/* month event goes until */
	char until_day;		/* day event goes until */
	short until_year;	/* year event goes until */
	struct event_rec4 *next_event;	/* next event */
};
@EOF

chmod 444 month4.h

echo x - month5.h
cat >month5.h <<'@EOF'
/*
 * @(#)$Header: month5.h,v 5.0 87/11/13 22:59:48 hull Exp $
 */

struct event_rec5 {
	char start_month;	/* starting month of the event */
	char start_day;		/* starting day of the event */
	short start_year;	/* starting year of the event */
	char monthly;		/* does event occur monthly? */
	char yearly;		/* does event occur yearly? */
	char every;		/* does event occur on every something? */
	char smtwtfs[7];	/* which days of the week are relevant? */
	char nth;		/* does event occur on an nth something? */
	char last;		/* does event occur on a last something? */
	char nth_is_on;		/* is 'nth' selected by user, n is nth above */
	char hour;		/* hour of the event */
	char minute;		/* minute of the event */
	char duration_hours;	/* hours event lasts */
	char duration_minutes;	/* minutes event lasts */
	char warning_hours;	/* hours of warning before event */
	char warning_minutes;	/* minutes of warning before event */
	char event_string[MAX_EVENT_STRING_LENGTH];  /* description of event */
	char private;		/* is event private? */
	int event_owner;	/* owner of event */
	char until;		/* does event occur until some date? */
	char until_month;	/* month event goes until */
	char until_day;		/* day event goes until */
	short until_year;	/* year event goes until */
	struct event_rec5 *next_event;	/* next event */
};
@EOF

chmod 444 month5.h

echo x - month6.h
cat >month6.h <<'@EOF'
/*
 * @(#)$Header: month6.h,v 6.0 87/11/13 23:00:18 hull Exp $
 */

struct event_rec6 {
	char start_month;	/* starting month of the event */
	char start_day;		/* starting day of the event */
	short start_year;	/* starting year of the event */
	char monthly;		/* does event occur monthly? */
	char yearly;		/* does event occur yearly? */
	char every;		/* does event occur on every something? */
	char smtwtfs[7];	/* which days of the week are relevant? */
	char nth;		/* does event occur on an nth something? */
	char last;		/* does event occur on a last something? */
	char nth_is_on;		/* is 'nth' selected by user, n is nth above */
	char hour;		/* hour of the event */
	char minute;		/* minute of the event */
	char duration_hours;	/* hours event lasts */
	char duration_minutes;	/* minutes event lasts */
	char warning_hours;	/* hours of warning before event */
	char warning_minutes;	/* minutes of warning before event */
	char event_string[MAX_EVENT_STRING_LENGTH];  /* description of event */
	char private;		/* is event private? */
	char anti;		/* is this an anti-event? */
	int event_owner;	/* owner of event */
	char until;		/* does event occur until some date? */
	char until_month;	/* month event goes until */
	char until_day;		/* day event goes until */
	short until_year;	/* year event goes until */
	struct event_rec6 *next_event;	/* next event */
};
@EOF

chmod 444 month6.h

echo x - month7.h
cat >month7.h <<'@EOF'
/*
 * @(#)$Header: month7.h,v 7.0 87/11/13 23:01:04 hull Exp $
 */

/* structure of an event */
struct event_rec7 {
	struct date_rec start_date;	/* starting date of the event */
	char monthly;		/* does event occur monthly? */
	char yearly;		/* does event occur yearly? */
	char every;		/* does event occur on every something? */
	char smtwtfs[7];	/* which days of the week are relevant? */
	char nth;		/* does event occur on an nth something? */
	char last;		/* does event occur on a last something? */
	char nth_is_on;		/* is 'nth' selected by user, n is nth above */
	char hour;		/* hour of the event */
	char minute;		/* minute of the event */
	char duration_hours;	/* hours event lasts */
	char duration_minutes;	/* minutes event lasts */
	char warning_hours;	/* hours of warning before event */
	char warning_minutes;	/* minutes of warning before event */
	char event_string[MAX_EVENT_STRING_LENGTH];  /* description of event */
	char private;		/* is event private? */
	char anti;		/* is this an anti-event? */
	int event_owner;	/* owner of event */
	char until;		/* does event occur until some date? */
	struct date_rec until_date;	/* date event goes until */
	struct event_rec7 *next_event;	/* next event */
};
@EOF

chmod 444 month7.h

echo x - month8.h
cat >month8.h <<'@EOF'
/*
 * @(#)$Header: month8.h,v 8.0 87/11/13 22:50:14 hull Exp $
 */

/* structure of an event */
struct event_rec {
	struct date_rec start_date;	/* starting date of the event */
	char monthly;		/* does event occur monthly? */
	char yearly;		/* does event occur yearly? */
	char every;		/* does event occur on every something? */
	char smtwtfs[7];	/* which days of the week are relevant? */
	char nth;		/* does event occur on an nth something? */
	char last;		/* does event occur on a last something? */
	char nth_is_on;		/* is 'nth' selected by user, n is nth above */
	struct time_rec start_time;	/* starting time of the event */
	struct time_rec duration;	/* duration of the event */
	struct time_rec warning;	/* warning of the event */
	struct time_rec end_time;	/* ending time of the event */
	char event_string[MAX_EVENT_STRING_LENGTH];  /* description of event */
	char private;		/* is event private? */
	char anti;		/* is this an anti-event? */
	int event_owner;	/* owner of event */
	char until;		/* does event occur until some date? */
	struct date_rec until_date;	/* date event goes until */
	struct event_rec *next_event;	/* next event */
};
@EOF

chmod 444 month8.h

echo x - get.c
cat >get.c <<'@EOF'
#ifndef lint
static char rcsid[] = "$Header: get.c,v 8.5 88/04/04 10:41:04 hull Exp $";
#endif

#include <curses.h>
#if SYS5
#include <string.h>
#else
#include <strings.h>
#endif
#include "month.h"

extern short crow, ccol, area_ptr;
extern short ins_mode, keep_old, my_file, read_only, event_status;
extern short delchar, kilchar, update_schedule;
extern int user_id;
extern char *home_dir, *month_dir, *user_name;
extern struct date_rec current_date;
extern struct event_rec current_event;
extern struct area_rec areas[];

get_description()
{
	short i, pos, len, at_end;
	int ch;

	pos = len = strlen(current_event.event_string);
	crow = DESCRIPTION_ROW;

	for (;;) {
	    at_end = (pos == len);
	    ccol = DESCRIPTION_COL + pos;
	    move(crow, ccol);
	    refresh();
	    ch = get_char();

	    if ((ch >= ' ') && (ch <= '~'))
		if (ins_mode) {
		    if (len < MAX_EVENT_STRING_LENGTH - 2) {
#if SYS5CURSES
			insch((chtype) ch);
#else
			insch((char) ch);
#endif
			for (i = ++len; i > pos; i--)
			    current_event.event_string[i] =
			    current_event.event_string[i - 1];
			current_event.event_string[pos++] = ch;
		    }
		} else {
		    if (pos < MAX_EVENT_STRING_LENGTH - 2) {
			addch(ch);
			current_event.event_string[pos++] = ch;
			if (at_end)
			    current_event.event_string[++len] = '\0';
		    }
		}
	    else
		switch(ch) {
		case '\001':  /* ^A */
		    event_status = ACCEPT;
		    return;
		case '\033':  /* ^[ */
		    event_status = CANCEL;
		    return;
#if SYS5CURSES
		case KEY_UP:
		    schedule_move_cursor('k');
		    return;
		case KEY_DOWN:
#endif
		case '\n':
		    schedule_move_cursor('\n');
		    return;
		case '\b':
		    if (ins_mode) {
			if (pos > 0) {
			    for (i = pos--; i <= len; i++)
				current_event.event_string[i - 1] =
				current_event.event_string[i];
			    len--;
			    mvdelch(crow, ccol - 1);
			}
		    } else
			if (pos > 0) {
			    mvaddch(crow, ccol - 1, ' ');
			    current_event.event_string[--pos] = ' ';
			    if (at_end)
				current_event.event_string[--len] = '\0';
			}
		    break;
		case '\025':	/* ^U */
		    current_event.event_string[pos = len = 0] = '\0';
		    move(crow, DESCRIPTION_COL);
		    clrtoeol();
		    break;
		case '\027':	/* ^W */
		    while ((pos > 0) &&
			   (current_event.event_string[pos - 1] == ' '))
			pos--;
		    while ((pos > 0) &&
			   (current_event.event_string[pos - 1] != ' ')) {
			current_event.event_string[--pos] = ' ';
			mvaddch(crow, DESCRIPTION_COL + pos, ' ');
		    }
		    if (at_end)
			current_event.event_string[len = pos] = '\0';
		    break;
#if SYS5CURSES
		case KEY_IC:
		case KEY_EIC:
#endif
		case '\t':	/* ^I */
		    toggle_flag('I');
		    break;
#if SYS5CURSES
		case KEY_LEFT:
#endif
		case '\002':	/* ^B */
		    if (pos > 0)
			pos--;
		    break;
#if SYS5CURSES
		case KEY_DC:
#endif
		case '\004':	/* ^D */
		    if (!at_end) {
			for (i = pos; i < len; i++)
			    current_event.event_string[i] =
			    current_event.event_string[i + 1];
			len--;
			delch();
		    }
		    break;
#if SYS5CURSES
		case KEY_RIGHT:
#endif
		case '\006':	/* ^F */
		    if (pos < len)
			pos++;
		    break;
		}
	}
}

get_npdeq(n_ok, p_ok, ed_ok)
int n_ok, p_ok, ed_ok;
{
	register ch;
	char buf[16];

	sprintf(buf, "[");

	if (n_ok)
	    strcat(buf, "n,");
	if (p_ok)
	    strcat(buf, "p,");
	if (ed_ok)
	    strcat(buf, "d,e,");
	strcat(buf, "q] ");

	ccol = print_message(buf, NO_BELL);

	for (;;) {
		ch = get_char();

		switch(ch) {
		case '\n':
		case 'n':
			if (n_ok)
			    return('n');
			else
			    sound_bell();
			break;
		case 'p':
			if (p_ok)
			    return('p');
			else
			    sound_bell();
			break;
		case 'd':
			if (ed_ok) {
			    ccol = print_message("really delete? ", NO_BELL);
			    ch = get_char();
			    if (ch == 'y')
				ccol = print_message("deleted", NO_BELL);
			    else
				ccol = print_message("not deleted", NO_BELL);
			    more();
			    if (ch == 'y')
				return('d');
			    else
				ccol = print_message(buf, NO_BELL);
			} else
			    sound_bell();
			break;
		case 'e':
			if (ed_ok)
			    return('e');
			else
			    sound_bell();
			break;
		case 'q':
		case '\033':	/* ^[ */
			return('q');
		default:
			sound_bell();
		}
	}
}

get_char()
{
	register int ch;

GETCH:
	ch = getch();

	if (ch == delchar)	/* convert user's delete char to \b */
	    ch = '\b';
	else if (ch == kilchar)	/* convert user's kill char to ^U */
	    ch = '\025';

	switch(ch) {
	case '\005':	/* ^E */
	    ch = '\033';	/* convert to ESC */
	    break;
	case '\r':
	    ch = '\n';
	    break;
	case '\014':	/* ^L */
	case '\022':	/* ^R */
	    wrefresh(curscr);
	    goto GETCH;
	}

#if SYS5CURSES
	if (crow != DESCRIPTION_ROW)
	    switch(ch) {	/* convert curses chars to normal chars */
	    case KEY_PPAGE:
		ch = 'p';
		break;
	    case KEY_NPAGE:
		ch = 'n';
		break;
	    case KEY_LEFT:
		ch = 'h';
		break;
	    case KEY_RIGHT:
		ch = 'l';
		break;
	    case KEY_UP:
		ch = 'k';
		break;
	    case KEY_DOWN:
		ch = 'j';
		break;
	    }
#endif
	return(ch);
}

get_date(date, prompt)
struct date_rec *date;
char *prompt;
{
	register short ch;
	short col, slash_count, newm, newd, newy;
	char buf[BUFSIZE];
	int ret;
	void convert_year();

	if (current_area == SCHEDULE)
	    push_area(SCHED_SCAN);
	else
	    push_area(SCAN);

	ccol = print_message(prompt, NO_BELL);
	col = 0;
	slash_count = 0;

	for (;;) {
		refresh();
		ch = get_char();

		switch(ch) {
		case '\b':
			if (col > 0) {
				if (buf[col - 1] == '/') {
					slash_count--;
				}
				--col; ccol--;
				mvaddch(0, ccol, ' ');
				move(0, ccol);
			}
			break;
		case '/':
			if ((slash_count >= 2) || (col == 0) ||
			   (buf[col-1] == '/'))
				sound_bell();
			else {
				addch(ch);
				buf[col++] = ch;
				slash_count++;
				ccol++;
			}
			break;
		case '0':
			if ((col == 0) ||
			    (buf[col-1] == '/' && slash_count < 2))
				break;
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':
			if (
			((col == 2) && (buf[col-1] != '/')) ||
			((slash_count == 1)&&(buf[col-1] != '/')&&(buf[col-2] != '/'))||
			((slash_count == 2) && (buf[col-1] != '/') && (buf[col-2] != '/') &&
				(buf[col-3] != '/') && (buf[col-4] != '/')) ||
			((col == 1) && ((ch > '2') || (buf[0] > '1')))
			)
				sound_bell();
			else {
				addch(ch);
				buf[col++] = ch;
				ccol++;
			}
			break;
		case '\n':
			if ((slash_count == 0) || (buf[col-1] == '/'))
				sound_bell();
			else {
				buf[col] = 0;
				ret = sscanf(buf, "%hd/%hd/%hd",
				    &newm, &newd, &newy);
				if (ret == 3)
				    convert_year(current_date.year, &newy);
				else
				    newy = current_date.year;
				if (newy < FIRST_YEAR)
				    sound_bell();
				else {
				    date->month = newm;
				    date->day = newd;
				    date->year = newy;
				    clear_message_line();
				    pop_area();
				    return(1);
				}
			}
			break;
		case '\033':	/* ^[ */
			clear_message_line();
			pop_area();
			return(0);
		case '\025':	/* ^U */
			ccol = print_message(prompt, NO_BELL);
			col = 0;
			slash_count = 0;
			break;
		default:
			break;
		}
	}
}

#if MULTIUSER
get_user()
{
	short i = 0;
	char *new_dir, new_name[16], buf[BUFSIZE], *get_user_arg();
	static char name[16];

	push_area(SCAN);
	ccol = print_message("user: ", NO_BELL);
	crow = 0;

	if (get_string(new_name) == 0) {
	    clear_message_line();
	    pop_area();
	    return;
	}

	if ((new_dir = get_user_arg(new_name)) != NULL) {
	    if (update_schedule)
		ccol = print_message("updating schedule", NO_BELL);
	    else
		ccol = print_message("schedule unchanged", NO_BELL);

	    if (!read_only && write_schedule() < 0) {
		more();
		ccol = print_message("cannot write .month", BELL);
	    }

	    if ((i = read_schedule(new_dir, read_only)) == -2) {
		more();
		sprintf(buf, "%s's .month file locked", new_name);
		ccol = print_message(buf, BELL);
		i = read_schedule(new_dir, READ_ONLY);
		if (i == 0)
		    read_only = 1;
	    }

	    if (i != 0) {
		more();
		if (i == -1)
		    sprintf(buf, "cannot open %s's .month", new_name);
		else
		    sprintf(buf, "cannot read %s's .month version %d",
			new_name, i);
		ccol = print_message(buf, BELL);
		if ((i = read_schedule(month_dir, read_only)) == -2) {
		    more();
		    ccol = print_message(".month file locked", BELL);
		    i = read_schedule(month_dir, READ_ONLY);
		    if (i == 0)
			read_only = 1;
	    	}
		if (i != 0) {
		    more();
		    if (i == -1)
			ccol = print_message("cannot open .month", BELL);
		    else {
			sprintf(buf, "cannot read .month version %d", i);
			ccol = print_message(buf, BELL);
		    }
		}
		show_all_events(current_date.month, current_date.year);
		pop_area();
		return;
	    }

	    keep_old = 1;
	    month_dir = new_dir;
	    my_file = (strcmp(home_dir, month_dir) == 0);
	    strcpy(name, new_name);
	    user_name = name;
	    print_screen();
	} else
	    print_message("invalid user", BELL);
	pop_area();
}

get_string(name)
char name[];
{
	short ch, first_col, i = 0;

	first_col = ccol;
	crow = 0;
	ch = get_char();

	for (;;) {
	    if (ch == '\n') {
		name[i] = 0;
		break;
	    } else if (ch > 0377) {
		;
	    } else if (ch == '\b') {
		if (ccol > first_col) {
		    i--; ccol--;
		    mvaddch(0, ccol, ' ');
		    move(0, ccol);
		    refresh();
		}
	    } else if (ch == '\025') {	/* ^U */
		while (ccol > first_col) {
		    i--; ccol--;
		    mvaddch(0, ccol, ' ');
		    move(0, ccol);
		}
		refresh();
	    } else if (ch == '\033') {	/* ^[ */
		return(0);
	    } else {
		name[i++] = ch;
		mvaddch(0, ccol++, ch);
		refresh();
	    }
	    ch = get_char();
	}
	return(1);
}
#endif MULTIUSER
@EOF

chmod 644 get.c

echo x - hl.c
cat >hl.c <<'@EOF'
#ifndef lint
static char rcsid[] = "$Header: hl.c,v 8.2 87/11/13 21:46:46 hull Exp $";
#endif

#include <curses.h>
#include "month.h"

extern short all_flag;
extern char *month_names[];
extern struct date_rec current_date, todays_date;

hl_month(month, mflag)
short month, mflag;
{
	if (mflag == HL_ON)
	    attron(A_REVERSE);
	mvaddstr(MONTH_ROW + month - 1, 0, month_names[month - 1]);
	if (mflag == HL_ON)
	    attroff(A_REVERSE);
}

hl_day(day, dflag)
short day, dflag;
{
	short row, col;

	get_row_col_from_day(&row, &col, day);

	if (dflag == HL_ON)
	    attron(A_REVERSE);

	if (current_date.month == todays_date.month &&
		day == todays_date.day &&
		current_date.year == todays_date.year)
	    attron(A_UNDERLINE);

	if (all_flag && is_event_today())
	    mvprintw(row, col, "(%2d)", day);
	else
	    mvprintw(row, col, " %2d ", day);

	attroff(A_REVERSE | A_UNDERLINE);
}

hl_year(year, yflag)
short year, yflag;
/* assumes year is currently displayed in year area */
{
	if (yflag == HL_ON)
	    attron(A_REVERSE);
	move(YEAR_ROW, YEAR_COL + (6 * (year % 10)));
	printw(" %4d ", year);
	if (yflag == HL_ON)
	    attroff(A_REVERSE);
}

hl_schedule(col, hflag)
register col, hflag;
{
	register int ch;
	short i;

	move(SCHEDULE_ROW, col);

	if (hflag)
		attron(A_BOLD);

	if (col < SMTWTFS_COL) {
		while((ch = (inch() & A_CHARTEXT)) != ' ') {
			move(SCHEDULE_ROW, col);
			addch(ch & A_CHARTEXT);
			col++;
		}
	} else if (col > SMTWTFS_COL+12) {
		move(SCHEDULE_ROW, col);

		for (i = 0; i < 10; i++) {
			addch((char) (inch() & A_CHARTEXT));
		}
	} else {
		move(SCHEDULE_ROW, col);

		for (i = 0; i < 2; i++) {
			addch((char) (inch() & A_CHARTEXT));
		}
	}
	attroff(A_BOLD);
}

hl_all(event, pf, af, mf, yf, ef, nf, lf, uf, xf)
struct event_rec *event;
register pf, af, mf, yf, ef, nf, lf, uf, xf;
{
	short i;

	toggle_char(&(event->private), pf, PRIVATE_COL);
	toggle_char(&(event->anti), af, ANTI_COL);
	toggle_char(&(event->monthly), mf, MONTHLY_COL);
	toggle_char(&(event->yearly), yf, YEARLY_COL);
	toggle_char(&(event->every), ef, EVERY_COL);
	toggle_char(&(event->nth_is_on), nf, NTH_COL);
	toggle_char(&(event->last), lf, LAST_COL);
	toggle_char(&(event->until), uf, UMONTH_COL);

	if (xf != -1) {
		for (i = 0; i < 7; i++) {
			toggle_char(&(event->smtwtfs[i]), xf,
			    (SMTWTFS_COL+(2*i)));
		}
	}
}

toggle_char(c, f, col)
char *c;
register f, col;
{
	if (f == 1) {
		if (!(*c)) {
			*c = 1;
			hl_schedule(col, f);
		}
	} else if (f == 0) {
		if (*c) {
			*c = 0;
			hl_schedule(col, f);
		}
	}
}
@EOF

chmod 644 hl.c

echo x - lunar.c
cat >lunar.c <<'@EOF'
#ifndef lint
static char rcsid[] = "$Header: lunar.c,v 8.2 87/11/13 21:46:58 hull Exp $";
#endif

#include <curses.h>
#include <math.h>
#include <sys/types.h>

/* Globals. */
double		 Fraction;

#define CENTER		((COLS - 2 * LINES) / 2)
#define BRIGHT		'@'
#define LEDGE		'('
#define REDGE		')'
#define FULL		0.5
#define TwoPi		(2 * 3.14159)
#define ZERO		0.03

long
calculate(julian, yr, hour, minute)
long julian, yr, hour, minute;
{
	register long	 Length;
	register long	 Phase;
	register long	 Delta;
	register long	 offset;

	yr -= 78;
	Length	= (double)2551 / 60 * 1000 + (double)443 / 60;
	offset	= ((yr * 365L + julian) * 24L + hour) * 60L + minute;
	Delta	= offset - (273L * 24L + 13L) * 60L + 23L;
	Phase	= Delta - (Delta / Length) * Length;

	Fraction	= (double)Phase / Length;
	return(Phase);
}

int
charpos(x)
	double		x;
{
	register int	i;

	i = x * LINES + 0.5;
	if ((i += LINES + CENTER) < 1)
	i = 1;
	return(i);
}


draw()
{
	register char	*p;
	register int	 i;
	register int	 end;
	register double	 y;
	register double	 cht;
	register double	 squisher;
	register double	 horizon;
	register double	 terminator;
	char		 Buffer[256];
	int line = 1;

	/* clear screen */
	clear();

	if (Fraction < FULL)
	    squisher = cos(TwoPi * Fraction);
	else
	    squisher = cos(TwoPi * (Fraction - FULL));

	cht = (double)2.0 / (LINES - 6.0);
	for (y = 0.93; y > -1.0; y -= cht) {
	    for (i = sizeof Buffer, p = Buffer; --i >= 0; )
		*p++ = ' ';
	    horizon = sqrt(1.0 - y * y);
	    Buffer[    charpos(-horizon)]	= LEDGE;
	    Buffer[i = charpos( horizon)]	= REDGE;
	    Buffer[++i]			= '\0';
	    terminator = horizon * squisher;
	    if (Fraction > ZERO && Fraction < (1.0 - ZERO)) {
		if (Fraction < FULL) {
		    i   = charpos( terminator);
		    end = charpos( horizon);
		} else {
		    i   = charpos(-horizon);
		    end = charpos( terminator);
		}
		while (i <= end)
		    Buffer[i++] = BRIGHT;
	    }
	    mvaddstr(line++, 1, Buffer);
	}
}
@EOF

chmod 644 lunar.c

echo x - month.c
cat >month.c <<'@EOF'
#ifndef lint
static char rcsid[] = "$Header: month.c,v 8.6 88/04/04 10:00:35 hull Exp $";
#endif

/***********************************************************
 *  Month - Visual Monthly Calendar and Time/Event Browser
 *
 *  Original Author: Tim Stoehn (zeus!tims)
 *  "Book code" originally written by Scott Turner (srt@ucla-cs.ARPA)
 *  Subsequent Modifications: Jim Hull (hull@hpda) and
 *                            Michael Morrell (morrell@hpda)
 *
 *
 ***********************************************************/

#include <curses.h>
#include <signal.h>
#if SYS5
#include <string.h>
#else
#include <strings.h>
#endif
#include <sys/types.h>
#if FCNTL
#include <fcntl.h>
#else
#include <sys/file.h>
#endif
#include <pwd.h>
#include <ctype.h>
#include "month.h"

short initialized = 0;
short date_flag = 0;
short my_file = 1;
short all_flag = 0;
short ins_mode = 0;
short keep_old = 0;
short over_flag = 0;
short read_only = READ_WRITE;
short ver_flag = 0;
short book = 0;
short daemon = 0;
short dint = 15;
short dhour, dminute, dsecond;
short delchar, kilchar;
short days;
short month_start;
short event_status = NOTHING;
short crow, ccol;
short area_ptr = 0;
char time_mode = END_MODE;
char *home_dir = NULL;
char *month_dir = NULL;
char *user_name = NULL;
char *prog_name;
int user_id;
struct date_rec current_date, todays_date;
struct date_rec mdates[NUM_MARKS];
struct area_rec areas[MAXAREAS];
struct event_rec events = {{0, 0, 0}, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0},
0, 0, 0, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 0, 0, 0, 0, 0, {0, 0, 0}, 0};

extern short update_schedule, updating;
extern struct event_rec events, current_event;
extern struct passwd *getpwnam();
extern char *get_home_dir();
extern alarm_t alarm();
extern unsigned short getuid();

main(argc, argv)
int argc;
char *argv[];
{
	prog_name = argv[0];
	user_id = (int) getuid();
	home_dir = get_home_dir(user_id);
	if (get_todays_date() != 0) {
	    printf("%s: Cannot get today's date\n", prog_name);
	    exit(1);
	}
	check_env();
	check_args(argc, argv);
	initialize();
	print_screen();
	(void) user();
	terminate();
	/* NOTREACHED */
}

initialize()
{
	int blast_out(), new_day(), /* stop(), */ i;
#ifndef killchar
	char killchar(), erasechar();
#endif

	signal(SIGINT, blast_out);
	signal(SIGQUIT, blast_out);
	signal(SIGHUP, terminate);
	signal(SIGALRM, new_day);
/*
#ifdef SIGTSTP
	signal(SIGTSTP, stop);
#endif
*/
	if (!date_flag) {
	    current_date.month = todays_date.month;
	    current_date.day = todays_date.day;
	    current_date.year = todays_date.year;
	}

	month_start = get_month_start(current_date.month, current_date.year);
	days = days_in(current_date.month, current_date.year);
	push_area(DAYS);

	for (i = 0; i < NUM_MARKS; i++) {
		mdates[i].month = current_date.month;
		mdates[i].day = current_date.day;
		mdates[i].year = current_date.year;
	}

	current_event.until_date.month = current_date.month;
	current_event.until_date.day = current_date.day;
	current_event.until_date.year = current_date.year;

	if ((i = read_schedule(month_dir, read_only)) == -2) {
	    printf("%s: .month file locked\n", prog_name);
	    sound_bell();
	    read_only = READ_ONLY;
	    i = read_schedule(month_dir, read_only);
	}

	if (i == -1) {
	    printf("%s: Cannot open .month\n", prog_name);
	    sound_bell();
	    terminate();
	} else if (i > 0) {
	    printf("%s: Cannot read .month version %d\n", prog_name, i);
	    sound_bell();
	    terminate();
	}
	
	initscr();
	crmode();
	noecho();
#if SYS5CURSES
	keypad(stdscr, TRUE);
#endif
	kilchar = (short) killchar();
	delchar = (short) erasechar();
	/* alarm call below should pop at midnight -- extra 2 seconds will
	 * guarantee that it's really tomorrow.
	 */
	alarm((alarm_t) 86402 - (dhour * 3600 + dminute * 60 + dsecond));
	/* for testing -- wake up every minute */
	/*
	alarm((alarm_t) 62 - dsecond);
	*/
	initialized = 1;
}

new_day()
{
	if (get_todays_date() != 0) {
	    printf("%s: Cannot get today's date\n", prog_name);
	    exit(1);
	}
	/*
	fprintf(stderr, "new_day: %d/%d/%d %d:%02d:%02d current_area=%c\n",
	    todays_date.month, todays_date.day, todays_date.year,
	    dhour, dminute, dsecond, (char) current_area);
	*/
	switch(current_area) {
	case MONTHS:
	case DAYS:
	case YEARS:
	case SCAN:
	case SCHED_SCAN:
	case SCHEDULE:
	    show_all_events(current_date.month, current_date.year);
	    move(crow, ccol);
	    refresh();
	    break;
	}
	/* reset alarm for midnight tomorrow (plus 2 seconds) */
	signal(SIGALRM, new_day);
	alarm((alarm_t) 86402 - (dhour * 3600 + dminute * 60 + dsecond));
	/* for testing -- wake up every minute */
	/*
	alarm((alarm_t) 62 - dsecond);
	*/
}

terminate()
{
	if (updating)
	    return;

	signal(SIGINT, SIG_IGN);
#ifdef SIGTSTP
	signal(SIGTSTP, SIG_IGN);
#endif
#ifdef SIGTTOU
	signal(SIGTTOU, SIG_IGN);
#endif
	signal(SIGQUIT, SIG_IGN);
	signal(SIGHUP, SIG_IGN);
	alarm((alarm_t) 0);

	if (initialized) {
	    if (update_schedule)
		ccol = print_message("updating schedule", NO_BELL);
	    else
		ccol = print_message("schedule unchanged", NO_BELL);

	    if (!read_only && write_schedule() < 0) {
		more();
		ccol = print_message("cannot write .month", BELL);
	    }
	    move(LINES-1, 0);
	    clrtoeol();
	    refresh();
	    endwin();
	}

	exit(0);
	/* NOTREACHED */
}

blast_out()
{
	update_schedule = 0;
	terminate();
}

/*
#ifdef SIGTSTP
stop()
{
	signal(SIGTSTP, SIG_DFL);
	signal(SIGINT, SIG_DFL);
	move(23,0);
	refresh();
	resetterm();
	kill(0, SIGTSTP);
	fixterm();
	signal(SIGINT, blast_out);
	signal(SIGTSTP, stop);
	clearok(curscr, TRUE);
	refresh();
}
#endif
*/

get_date_arg(arg)
char *arg;
{
	short month, day, year;
	int ret;
	void convert_year();

	if (date_flag || daemon)
	    return(1);

	if ((ret = sscanf(arg, "%hd/%hd/%hd", &month, &day, &year)) == 3)
	    convert_year(todays_date.year, &year);
	else if (ret == 2)
	    year = todays_date.year;
	else
	    return(1);

	if (year < FIRST_YEAR || year > LAST_YEAR ||
	    month < 1 || month > 12 ||
	    day < 1 || day > days_in(month, year))
	    return(1);

	current_date.month = month;
	current_date.day = day;
	current_date.year = year;
	return(0);
}

#if MULTIUSER
char *
get_user_arg(arg)
char *arg;
{
	struct passwd *pw;

	if ((pw = getpwnam(arg)) == NULL)
	    return(NULL);
	else
	    return(strcpy(malloc((unsigned)strlen(pw->pw_dir)+1), pw->pw_dir));
}
#endif MULTIUSER

check_env()
{
	char *month_env;

	if ((month_env = getenv("MONTH")) != NULL)
	    while (*month_env) {
		switch(*month_env) {
		case 't':
			if (*(month_env+1) == 'S' || *(month_env+1) == 'D' ||
			    *(month_env+1) == 'E')
			    time_mode = *(++month_env);
			else {
			    printf("%s: Bad environment flag -- %c%c\n",
				prog_name, *month_env, *(month_env+1));
			    exit(1);
			}
			break;
		case 'A':
			all_flag = 1;
			break;
		case 'I':
			ins_mode = 1;
			break;
		case 'K':
			keep_old = 1;
			break;
		case 'O':
			over_flag = 1;
			break;
		case 'R':
			read_only = READ_ONLY;
			break;
		default:
			printf("%s: Bad environment flag -- %c\n",
			    prog_name, *month_env);
			exit(1);
		}
		month_env++;
	    }
}

check_args(argc, argv)
int argc;
char *argv[];
{
	short i, j;
	extern float get_version();

	for (i = 1; i < argc; i++) {
	    if (argv[i][0] == '-') {
		for (j = 1; j < strlen(argv[i]); j++) {
		    switch(argv[i][j]) {
		    case 'a':
			all_flag = 0;
			break;
		    case 'i':
			ins_mode = 0;
			break;
		    case 'k':
			keep_old = 0;
			break;
		    case 'o':
			over_flag = 0;
			break;
		    case 'r':
			read_only = READ_WRITE;
			break;
		    case 'A':
			all_flag = 1;
			break;
		    case 'I':
			ins_mode = 1;
			break;
		    case 'K':
			keep_old = 1;
			break;
		    case 'O':
			over_flag = 1;
			break;
		    case 'R':
			read_only = READ_ONLY;
			break;
		    case 'B':
			book = i;
			break;
		    case 'V':
			ver_flag = i;
			break;
		    case 'd':
			if (date_flag)
			    goto BA;
			daemon = i;
			break;
		    case 't':
			if (argv[i][j+1] == 'S' || argv[i][j+1] == 'D' ||
			    argv[i][j+1] == 'E')
			    time_mode = argv[i][++j];
			else
			    goto BA;
			break;
		    default:
			goto BA;
		    }
		    if (argv[i][j] == 'B' || argv[i][j] == 'V' ||
			   argv[i][j] == 'd')
			break;
		}
	    } else if (get_date_arg(argv[i]) == 0) {
		date_flag = 1;
#if MULTIUSER
	    } else if ((month_dir = get_user_arg(argv[i])) != NULL) {
		my_file = 0;
		keep_old = 1;
		user_name = argv[i];
	    } else {
BA:		printf("%s: Bad argument -- %s\n", prog_name, argv[i]);
		printf("Usage: %s [-AaIiKkOoRr] [-{tS|tD|tE}] [-Bn] [-V] [-dn] [m/d/y] [user]\n", prog_name);
#else
	    } else {
BA:		printf("%s: Bad argument -- %s\n", prog_name, argv[i]);
		printf("Usage: %s [-AaIiKkOo] [-{tS|tD|tE}] [-Bn] [-V] [-dn] [m/d/y]\n", prog_name);
#endif MULTIUSER
		exit(1);
	    }
	}
	if (month_dir == NULL)
	    month_dir = home_dir;
	
	if (ver_flag)
	    printf("month version %-3.3g\n\n", get_version());

	if (book)
	    if (argv[book][2] == '\0') {
		if (print_book(1))
		    printf("%s: Cannot print schedule\n", prog_name);
	    } else
		if (print_book(atoi(&argv[book][2])))
		    printf("%s: Cannot print schedule\n", prog_name);

	if (daemon) {
	    if (isdigit(argv[daemon][2]) && (argv[daemon][2] > '0'))
		dint = atoi(&argv[daemon][2]);

	    if (!fork()) {
		signal(SIGINT, SIG_IGN);
		signal(SIGQUIT, SIG_IGN);
#ifdef SIGTSTP
		signal(SIGTSTP, SIG_IGN);
#endif
#ifdef SIGTTOU
		signal(SIGTTOU, SIG_IGN);
#endif
		daemonize();
	    }
	}

	if (ver_flag || book || daemon)
	    exit(0);
}

daemonize()
{
    char arg1[16];

    printf("WARNING: The -d option of month has been superseded by the\n");
    printf("monthd program.  For now, month -d will automatically invoke\n");
    printf("monthd, but future versions of month will not support -d.\n");
    if (dint == 15) {
	printf("Invoking: monthd\n");
	fflush(stdout);
	execlp("monthd", "monthd", 0);
    } else {
	sprintf(arg1, "-i%d", dint);
	printf("Invoking: monthd %s\n", arg1);
	fflush(stdout);
	execlp("monthd", "monthd", arg1, 0);
    }
    /* NOTREACHED */
}

#if !SYS5CURSES
#ifndef killchar
#include <sgtty.h>
char
killchar()
{
	struct sgttyb arg;

	ioctl(0, TIOCGETP, &arg);
	return(arg.sg_kill);
}

char
erasechar()
{
	struct sgttyb arg;

	ioctl(0, TIOCGETP, &arg);
	return(arg.sg_erase);
}
#endif
#endif
@EOF

chmod 644 month.c

echo x - move.c
cat >move.c <<'@EOF'
#ifndef lint
static char rcsid[] = "$Header: move.c,v 8.3 88/04/04 10:47:39 hull Exp $";
#endif

#include "month.h"

extern char time_mode;
extern short area_ptr;
extern short crow, ccol, month_start, days;
extern struct date_rec current_date;
extern struct area_rec areas[];

goto_this_day(date)
struct date_rec *date;
{
	/* current_area assumed to be MONTHS, DAYS, or YEARS */
	current_date.month = date->month;
	current_date.day = date->day;
	current_date.year = date->year;

	show_all_events(current_date.month, current_date.year);
	print_all_months();
	print_all_years();
	goto_area();
}

pop_area()
{
	if (area_ptr <= 0) {
	    printf("area stack underflow\n");
	    blast_out();
	}
	if (--area_ptr > 0) {
	    crow = areas[area_ptr].row;
	    ccol = areas[area_ptr].col;
	}
}

push_area(area)
short area;
{
	if (area_ptr >= MAXAREAS) {
	    printf("area stack overflow\n");
	    blast_out();
	}
	areas[area_ptr].row = crow;
	areas[area_ptr].col = ccol;
	areas[area_ptr++].area = area;
	goto_area();
}

goto_area()
{
	switch(current_area) {
	case MONTHS:
		goto_month();
		break;
	case DAYS:
		goto_day();
		break;
	case YEARS:
		goto_year();
		break;
	case SCHEDULE:
		goto_schedule();
		break;
	case SCAN:
	case SCHED_SCAN:
		goto_scan();
		break;
	}
}

goto_month()
{
	crow = MONTH_ROW + current_date.month - 1;
	ccol = 9;
}

goto_day()
{
	get_row_col_from_day(&crow, &ccol, current_date.day);
	ccol += 2;
}

goto_year()
{
	/* assumes the current year is displayed in YEARS area */
	crow = YEAR_ROW;
	ccol = YEAR_COL + 4 + (6 * (current_date.year % 10));
}

goto_schedule()
{
	crow = SCHEDULE_ROW;
	ccol = PRIVATE_COL;
}

goto_scan()
{
	crow = 0;
	ccol = 0;
}

move_cursor(dir)
register short dir;
{
	switch(current_area) {
	case MONTHS:
		switch(dir) {
		case 'j':
			if (crow < MONTH_ROW + 11)
				crow++;
			else
				crow = MONTH_ROW;
			break;
		case 'k':
			if (crow > MONTH_ROW)
				crow--;
			else
				crow = MONTH_ROW + 11;
			break;
		}
		break;
	case YEARS:
		switch(dir) {
		case 'h':
			if (ccol == YEAR_COL + 4)
			    ccol = YEAR_COL + 58;
			else
			    ccol -= 6;
			break;
		case 'l':
			if (ccol == YEAR_COL + 58)
			    ccol = YEAR_COL + 4;
			else
			    ccol += 6;
			break;
		}
		break;
	case DAYS:
		switch(dir) {
		case 'h':
			ccol -= 10;
			if (get_day_from_row_col(crow, ccol) == 0)
			    ccol = CAL_COL + 62;
			while (get_day_from_row_col(crow, ccol) == 0)
			    ccol -= 10;
			break;
		case 'j':
			crow += 2;
			if (get_day_from_row_col(crow, ccol) == 0)
			    crow = CAL_ROW;
			while (get_day_from_row_col(crow, ccol) == 0)
			    crow += 2;
			break;
		case 'k':
			crow -= 2;
			if (get_day_from_row_col(crow, ccol) == 0)
			    crow = CAL_ROW + 10;
			while (get_day_from_row_col(crow, ccol) == 0)
			    crow -= 2;
			break;
		case 'l':
			ccol += 10;
			if (get_day_from_row_col(crow, ccol) == 0)
			    ccol = CAL_COL + 2;
			while (get_day_from_row_col(crow, ccol) == 0)
			    ccol += 10;
			break;
		}
		break;
	case SCHEDULE:
		schedule_move_cursor(dir);
		break;
	}
}

schedule_move_cursor(dir)
short dir;
{
	short inc, *cols;
	static short schedule_cols[] = {
	    UYEAR_COL, SMONTH_COL, SDAY_COL, SYEAR_COL, PRIVATE_COL,
	    ANTI_COL, MONTHLY_COL, YEARLY_COL, EVERY_COL, NTH_COL, LAST_COL,
	    SMTWTFS_COL, SMTWTFS_COL+2, SMTWTFS_COL+4, SMTWTFS_COL+6,
	    SMTWTFS_COL+8, SMTWTFS_COL+10, SMTWTFS_COL+12,
	    UMONTH_COL, UDAY_COL, UYEAR_COL, SMONTH_COL
	};
	static short start_mode_cols[] = {
	    WARNING_COL+3, DURATION_COL, DURATION_COL+3, END_COL, END_COL+3,
	    WARNING_COL, WARNING_COL+3, DURATION_COL
	};
	static short duration_mode_cols[] = {
	    WARNING_COL+3, START_COL, START_COL+3, END_COL, END_COL+3,
	    WARNING_COL, WARNING_COL+3, START_COL
	};
	static short end_mode_cols[] = {
	    WARNING_COL+3, START_COL, START_COL+3, DURATION_COL, DURATION_COL+3,
	    WARNING_COL, WARNING_COL+3, START_COL
	};

	switch(dir) {
	case 'h':
	case 'l':
		inc = (dir == 'h') ? -1 : 1;
		if (crow == SCHEDULE_ROW) {
			cols = schedule_cols;
			while (*(++cols) != ccol) ;
			ccol = *(cols+inc);
		} else if (crow == TIME_ROW) {
			switch(time_mode) {
			case START_MODE:
			    cols = start_mode_cols;
			    break;
			case DURATION_MODE:
			    cols = duration_mode_cols;
			    break;
			case END_MODE:
			    cols = end_mode_cols;
			    break;
			}
			while (*(++cols) != ccol) ;
			ccol = *(cols+inc);
		}
		break;
	case '\n':
	case 'j':
		switch(crow) {
		case SCHEDULE_ROW:
			crow = TIME_ROW;
			switch(time_mode) {
			case START_MODE:
			    ccol = DURATION_COL;
			    break;
			default:
			    ccol = START_COL;
			    break;
			}
			break;
		case TIME_ROW:
			get_description();
			break;
		case DESCRIPTION_ROW:
			crow = SCHEDULE_ROW;
			ccol = PRIVATE_COL;
			break;
		}
		break;
	case 'k':
		switch(crow) {
		case SCHEDULE_ROW:
			get_description();
			break;
		case TIME_ROW:
			crow = SCHEDULE_ROW;
			ccol = PRIVATE_COL;
			break;
		case DESCRIPTION_ROW:
			crow = TIME_ROW;
			switch(time_mode) {
			case START_MODE:
			    ccol = DURATION_COL;
			    break;
			default:
			    ccol = START_COL;
			    break;
			}
			break;
		default:
			crow--;
			break;
		}
		break;
	case '\033':	/* ^[ */
		pop_area();
		break;
	}
}

get_row_col_from_day(row, col, day)
short *row, *col, day;
{
	*row = CAL_ROW + (((month_start + day - 1) / 7) * 2);
	*col = CAL_COL + (((month_start + day - 1) % 7) * 10);
}

get_day_from_row_col(row, col)
short row, col;
{
	short mday;

	if (row < CAL_ROW || row > CAL_ROW + 10 ||
	    col < CAL_COL + 2 || col > CAL_COL + 62)
	    return(0);

	mday = (7 * ((row - CAL_ROW)) / 2) +
	       ((col - CAL_COL) / 10) - month_start + 1;

	if ((mday <= days) && (mday > 0))
	    return(mday);

	return(0);
}
@EOF

chmod 644 move.c

exit 0

-- 
Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.