[net.sources] vcal and friends Rev 2.0 Part 2

me%pinot@zehntel.UUCP (Mike Essex) (02/20/87)

echo x - README.new
sed 's/^X//' >README.new <<'*-*-END-of-README.new-*-*'
X			VCAL AND FRIENDS                  2/19/87
X
X-------------------------------------------------------------------
XThis is the second release of vcal and friends.
XIt has fixed a number of problems and incorporated some suggestions
XI recieved in your responses.  For the most part I have received
Xenthusiastic replies and I thank you for the responses.  There
Xwere a number of sites who didn't recieve both pieces and some
Xwho had pieces truncated.  Hopefully, this release will get through
Xto all.
X
XChanges include:
X
Xvcal - Changed terminal handler routines to take advantage of 
X       termcap(3) capabilites allow vcal to be used with a greater
X       number of terminal types.  Changed start up cursor position
X       to current date.  Fixed several minor bugs.
X
Xautocall - Fixed a loop bug which was causing core dumps in some
X	   instances.  Changed message buffer size.
X
Xcallme - No change.
X
Xappts.c - Changed message size so that long messages from a manually
X          edited data file does not cause a core dump.
X
Xeappts - Changed message buffer size.
X
Xlcal - Changed message buffer size.
X-------------------------------------------------------------------
Xdef.:  a set of calendar and appointment utility programs to replace
X       the traditional paper calendar.
X       
XVcal and friends allow the user to view a calendar, enter dates and
Xtimes of activities, set times for prompts to the CRT and to produce
Xlists of a month's activities.  Multiple data files may be used to
Xallow the user to have one calendar for personal activities, one for
Xbusiness activities, one for project milestones, etc.
X
XThese programs are written in 'C' and run under UNIX.  To date they
Xhave been compiled and execute on the following systems:
X
XDEC PDP 11/70	UNIX Version 7
XDEC VAX 11/750	UNIX BSD 4.2 and 4.3
XSun 2/170	UNIX BSD 4.2
XSun 3/160	UNIX BSD 4.2
XSun 3/260 	UNIX BSD 4.2
XDEC MicroVAX    ULTRIX
X
XIncluded in this package are six source files, six manual files, a
Xmakefile and this introduction.  The makefile is for use with the
Xstandard "make" utility on a VAX 11/750 under BSD 4.3.  For use with
Xa PDP 11/70 BSD Version 7 change the makefile library entry from
X"termlib" to "termcap".
X
XAll the "vcal" files have been combined here with the "shar" script.
XSince the combined size of the files are greater than 65,000
Xcharacters they have been broken into two parts for transmission.
XPart 1 contains makefile, appts.c, autocall.c and callme.c along
Xwith the manual pages for these.  Part 2 contains eappts.c, lcal.c
Xand vcal.c and their manual pages.
X
XSynopsis of files:
X
Xappts		displays the current or specified day's activities
X
Xautocall	starts background reminder processes for each of the
X		current day's activities
X
Xcallme		starts a background reminder process for a specified
X		time and activity
X
Xeappts		allows activities to be entered into a data file from
X		the command line
X
Xlcal		produces a tabular listing of the current or specified
X		month's activities
X
Xvcal		visual calendar displaying the current or specified
X		month's activities; allows entries to be added, changed
X		or deleted
X
Xmakefile	makefile for all of the "vcal" programs
X
Xmanual pages:	appts.l autocall.l callme.l eappts.l lcal.l vcal.l
X
XComments and suggestions will be appreciated and considered.
X
XMike Essex  (~me)
X
X     ....!ucbvax!zehntel!me
X     ....!decvax!sytek!zehntel!me
X     ...."zehntel!me"@BERKELEY
*-*-END-of-README.new-*-*
echo x - eappts.c
sed 's/^X//' >eappts.c <<'*-*-END-of-eappts.c-*-*'
X/*
X * Module:	eappts.c
X *
X * Purpose:	enters data into appointments file
X *
X * Author:	Mike Essex
X *
X * Date:	Sep. 16, 1986
X *
X * Includes:
X *	stdio.h
X * Discussion:
X *	Inputs data from standard input and writes it to ~/.appointments
X *	file
X * 
X *
X * Edit History
X * ==== =======
X *
X * Date      Who	What
X * ----      ---	----------------------------------------------
X * 12/1/86   me		added multifile capability
X * 12/1/86   me		changed 'home' from *home[80] to home[80]
X *
X */
X
X#include <stdio.h>
X#define		NL	'\010'
X
X
X/*
X * Procedure:	main
X *
X * Function:	inputs data and writes to users .appointments file
X *
X * Discussion:
X *	Prompts users for required appointment information, inputs
X *	that info and then appends it to ~/.appointments file.
X */
X
Xmain(argc,argv)
X
Xint	argc;
Xchar	*argv[];
X
X{
X    FILE	*fptr;
X    char	tmpbuf[80];
X    int		i,j;
X    char	*getenv();
X    char	home[80];
X    char	datedata[20];
X    char	timedata[20];
X    char	msgdata[40];
X    int		month,day,year,time;
X    int		index[5];
X
X    if (argc == 2) {
X	strcpy(home,argv[1]);
X    }
X    else {
X	strcpy(home,getenv("HOME"));
X	strcat(home,"/.appointments");
X    }
X
X    fptr = fopen(home,"a");
X    if (fptr) {
X	printf("What is the date of appointment?  (mm dd yyyy)  ");
X	fgets(datedata,20,stdin);
X	i = 0;
X	j = 0;
X	while(i < 20) {
X	    while ((i < 20) && (datedata[i] == ' ')) i++;
X	    index[j++] = i;
X	    while ((i < 20) && (datedata[i] != ' ')) i++;
X	}
X	month = atoi(&datedata[index[0]]);
X	day = atoi(&datedata[index[1]]);
X	year = atoi(&datedata[index[2]]);
X	if (year < 100) year += 1900;
X
X	printf("What time (24 hour time) is the appointment?  (tttt)  ");
X	fgets(timedata,20,stdin);
X	time = atoi(timedata);
X	printf("What is the message?  ");
X	fgets(msgdata,79,stdin);
X	msgdata[strlen(msgdata)-1] = NULL;
X	fprintf(fptr,"%d,%d,%d,%4d,%s\n",month,day,year,time,msgdata);
X    }
X    else {
X	printf("Error:  Cannot open %s file",argv[1]);
X	abort();
X    }
X    fclose(fptr);
X} /* main */
*-*-END-of-eappts.c-*-*
echo x - eappts.l
sed 's/^X//' >eappts.l <<'*-*-END-of-eappts.l-*-*'
X.TH EAPPTS 1 
X.SH NAME
Xeappts \- enter appointments
X.SH SYNOPSIS
X.B eappts [ filename ]
X.SH DESCRIPTION
X.I Eappts
Xis a program which is used to enter appointment data into the user's
X~/.appointments file by default or the file specified in the optional
Xfilename argument.
X.PP
XThe user is prompted for a date, time and message.
XThe date is entered as three numeric values separated by spaces.
XA two or four digit year value should be used.
X.PP
XData entered using
X.I eappts
Xmay be used by four companion programs.
XThese are:
X.br
X.sp
X.nf
Xvcal            calendar and notes program
Xappts           displays current or seleted day's appoinments
Xautocall        set appointment reminders for the current day
Xlcal            displays the month's appointments in tabular form
X.fi
X.sp
XFor further information on these, reference the appropriate "man"
Xentries.
X.SH AUTHOR
XMike Essex
X.SH FILES
Xeappts
X.br
X~/.appointments
X.br
X.SH "SEE ALSO"
Xvcal(1), appts(1), autocall(1), lcal(1), callme(1)
X.SH BUGS
XThere are year 2000 time bombs.
*-*-END-of-eappts.l-*-*
echo x - lcal.c
sed 's/^X//' >lcal.c <<'*-*-END-of-lcal.c-*-*'
X/*
X * Module:	lcal.c
X *
X * Purpose:	print month's appointments
X *
X * Author:	Mike Essex
X *
X * Date:	Sep. 16, 1986
X *
X * Includes:
X *	time.h, stdio.h, ctype.h, signal.h
X *
X * Discussion:
X *	Reads data from ~/.appointments and/or designated file and
X *      writes to standard *	out any appoinments which fall in
X *      the current or optionally specified month.
X * 
X *
X * Edit History
X * ==== =======
X *
X * Date      Who	What
X * ----      ---	----------------------------------------------
X *
X */
X
X#include <stdio.h>
X#include <signal.h>
X#include <ctype.h>
X#include <time.h>
X
X
Xchar	*malloc();
X
Xint		monthdata[1000];	/* month data */
Xint		daydata[1000];		/* month data */
Xint		yeardata[1000];	/* month data */
Xchar		*msgdata[1000];	/* message pointers */
Xchar		msghold[40];
Xint		maxentries;
Xint		maxmsgs;
Xint		cmonth,cday,cyear;
Xint		argvindex;
X
X
X
X/*
X * Procedure:	main()
X *
X * Function:	prints out listing of appointments
X *
X * Discussion:
X *	Parses command line for optional month and year, initializes
X *	varialbes, calls required funtions.
X */
X
Xmain (argc,argv)
X
X    int		argc;
X    char	*argv[];
X{
X
X    int		month,day,year;
X    int		i;
X    int		tempmonth,tempyear;
X    int		atoi();
X    int		maxindex;
X    extern int	abort();
X
X    timeset();
X    year = cyear;
X    month = cmonth;
X    day = cday;
X
X    if (argc > 2) {
X	tempmonth = atoi(argv[1]);
X	tempyear = atoi(argv[2]);
X	if (tempmonth && tempyear){
X	    month = tempmonth;
X	    year = tempyear;
X	    if (year < 100) year += 1900;
X	    if (argc > 3) {
X		argvindex = 3;
X		maxindex = argc;
X	    }
X	    else {
X		argvindex = 0;
X		maxindex = 1;
X	    }
X	}
X	else {
X	    if (tempmonth || tempyear) {
X		printf("Syntax error:  Incorrect date arguments\n");
X		exit(1);
X	    }
X	    else {
X		argvindex = 1;
X		maxindex = argc;
X	    }
X	}
X    }
X    else {
X        if (argc == 1) {
X	    argvindex = 0;
X	    maxindex = argc;
X	}
X	else {
X	    argvindex = 1;
X	    maxindex = argc;
X	}
X    }
X
X    
X    signal(2,abort);
X    signal(3,abort);
X
X    day = 1;
X    maxentries = 1000;
X    maxmsgs = 18;
X    msghold[0] = NULL;
X
X    printf("                            C A L E N D A R   L I S T\n");
X    while (argvindex < maxindex) {
X	loaddata(argv[argvindex]);
X	table(month,day,year,argv[argvindex]);
X	argvindex++;
X    }
X
X    printf("------------------------------------------------------------------------------\n");
X} /* main */
X
X
X/*
X * Procedure:	abort()
X *
X * Function:	error exit routine
X */
X
Xabort()
X
X{
X    exit(1);
X} /* abort */
X
X
X/*
X * Procedure:	table(month,day,year)
X *
X * Function:	outputs appointments in tabular format
X *
X * Parameters:
X *	p1	- int - month
X *	p2	- int - day
X *	p3	- int - year
X *      p3      - char * - file name
X *
X * Discussion:
X *	Searches data arrays for appointments in the specified
X *	month and year and outputs them in tabular form to standard out.
X */
X
Xtable(month,day,year,filename)
X
X    int		month,day,year;
X    char	*filename;
X
X{
X    int		i,j,k,d,dow,monthday,searchcnt,first;
X    int		getdow();
X
X    static char	*dayw[]= {
X	"Sat   ","Sun   ","Mon   ", "Tue   ",
X	"Wed    ", "Thu    ", "Fri    "
X    };
X
X    static char	*smon[]= {
X    "JANUARY   ", "FEBRUARY   ", "MARCH    ", "APRIL    ",
X    "MAY    ", "JUNE    ", "JULY    ", "AUGUST    ",
X    "SEPTEMBER    ", "OCTOBER    ", "NOVEMBER    ", "DECEMBER    "
X    };
X
X    printf("------------------------------------------------------------------------------\n");
X    if (argvindex) {
X	printf("|  %-10.10s%u                       %30.30s       |\n", smon[month-1], year,filename);
X    }
X    else {
X	printf("|  %-10.10s%u                                                            |\n", smon[month-1], year);
X    }
X    monthday = 0;
X    while (++monthday <= 31) {
X	searchcnt = 0;
X	first = 1;
X	while (searchcnt <= maxentries) {
X	    if ((yeardata[searchcnt] == year) &&
X	      (monthdata[searchcnt] == month) &&
X	      (daydata[searchcnt] == monthday)) {
X		if (first) {
X		    dow = getdow(month,monthday,year);
X		    first = 0;
X		    /* printf("|----------------------------------------------------------------------------|\n"); */
X		     printf("|                                                                            |\n"); 
X		    printf("| %-7.7s%2d  %-64.64s|\n",dayw[dow],monthday,msgdata[searchcnt]);
X		}
X		else {
X		    printf("|            %-64.64s|\n",msgdata[searchcnt]);
X		}
X	    }
X	    searchcnt++;
X	}
X    }
X} /* table */
X
X
X/*
X * Procedure:	getdow(tmonth,tday,tyear)
X *
X * Function:	calculates day of week
X *
X * Parameters:
X *	p1	- int - month
X *	p2	- int - day
X *	p3	- int - year
X *
X * Return Values:
X *	interger value of day of week, sat=0, . . ., etc
X *
X * Discussion:
X *	calculates number of days from 1,1,1979 and determines dow
X */
X
Xgetdow(tmonth,tday,tyear)
X
X    int		tmonth,tday,tyear;
X{
X
X    static    int    mdays[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
X    int    month,day,year,mcnt;
X    long   days;
X    int    tdow;
X
X    month = 1;
X    day = 1;
X    year = 79;
X
X    if ((tmonth == month) && (tyear == year)) {
X	days = abs(day - tday);
X    }
X    else {
X        days = mdays[month] - day;
X        if (tyear == year) {
X            while (++month < tmonth) {
X	        days += mdays[month];
X	        if ((month == 2) && ((year % 4) == 0)) days++;
X	    }
X        }
X        else {
X            while (++month < 13) {
X	        days += mdays[month];
X                if ((month == 2) && ((year % 4) == 0)) days++;
X            }
X	    while (++year < tyear) {
X	        days += 365;
X	        if ((year % 4) == 0 ) days ++;
X            }
X    
X	    mcnt = 0;
X            while (++mcnt < tmonth) {
X	        days += mdays[mcnt];
X	        if ((mcnt == 2) && ((tyear % 4) == 0)) days++;
X	    }
X        }
X        days += tday;
X    }
X
X    tdow = (days%7);
X
X    return(tdow);
X} /* get dow */
X
X
X/*
X * Procedure:	loaddata()
X *
X * Function:	loads appointment data from ~/.appointments file
X *
X * Return Values:
X *	various global arrays loaded with appointment data
X *
X */
X
Xloaddata(filename)
X
Xchar	*filename;
X
X{
X    char	basedata[80];
X    char	tmpbuf[80];
X    char	*getenv();
X    char	home[80];
X    FILE 	*fptr;
X    int		i,j,k,l,field;
X
X    i = 0;
X    while (i < maxentries) {
X	daydata[i] = 0;
X	monthdata[i] = 0;
X	yeardata[i] = 0;
X	msgdata[i] = 0;
X	i++;
X    }
X
X    
X    if (argvindex == 0) {
X	strcpy(home,getenv("HOME"));
X	strcat(home,"/.appointments");
X    }
X    else {
X	strcpy(home,filename);
X    }
X    if ((fptr = fopen(home,"r")) != NULL) {
X	i = 0;
X	while((fgets(basedata,80,fptr) != NULL)) {
X
X	    basedata[strlen(basedata)-1] = NULL;
X
X	    j = 0;
X	    k = 0;
X	    field = 0;
X	    while (basedata[j] != NULL ) {
X                 
X                if (basedata[j] != ',') {
X
X		    tmpbuf[k++] = basedata[j];
X		}
X		else {
X		    switch (field) {
X
X			case 0 : {
X			    tmpbuf[k] = NULL;
X			    monthdata[i] = atoi(tmpbuf);
X			    k = 0;
X			    break;
X			}
X			case 1 : {
X			    tmpbuf[k] = NULL;
X			    daydata[i] = atoi(tmpbuf);
X			    k = 0;
X			    break;
X			}
X			case 2 : {
X			    tmpbuf[k] = NULL;
X			    yeardata[i] = atoi(tmpbuf);
X			    k = 0;
X			    break;
X			}
X			case 3 : {
X			    tmpbuf[k++] = ' ';
X			    tmpbuf[k++] = ' ';
X			    break;
X			}
X		    }
X		    field++;
X		}
X		j++;
X	    }
X	    tmpbuf[k] = '\0';
X	    msgdata[i] = malloc(80);
X	    strncpy(msgdata[i],tmpbuf,80);
X	    msgdata[79] = NULL;
X
X	    if (i >= maxentries) {
X		printf("Warning:  Over 1000 entries in %s file.  Data truncated.\n",filename);
X		break;
X	    }
X	    i++;
X	}
X	fclose(fptr);
X    }
X    else {
X	printf("Error:  Cannot open %s file.\n",filename);
X    }
X} /* loaddata */
X
X
X/*
X * Procedure:	timeset()
X *
X * Function:	Gets current time and date
X *
X * Return Values:
X *	loads time and date info into global variables
X *
X */
X
Xtimeset()
X
X{
X    struct	tm *localtime();
X
X    struct tm *tp;		/* time structure */
X    long	tloc;		/* number of seconds since 1970 */
X
X    time(&tloc);	/* fills tloc */
X
X    tp = localtime(&tloc);
X
X    cyear =	tp->tm_year;
X    cmonth =	tp->tm_mon + 1;
X    cday =	tp->tm_mday;
X
X    cyear += 1900;
X
X} /* timeset */
*-*-END-of-lcal.c-*-*
echo x - lcal.l
sed 's/^X//' >lcal.l <<'*-*-END-of-lcal.l-*-*'
X.TH LCAL 1 
X.SH NAME
Xlcal \- display current or selected month's appointments
X.SH SYNOPSIS
X.B lcal 
X[ month year ] [ filename(s) ]
X.sp
Xwhere
X.I month
Xis a numeric value between 1 and 12,
X.I year
Xis a numeric four digit value and
X.I filename(s)
Xare the data files to be searched.
X.SH DESCRIPTION
X.I Lcal
Xis a program which uses the data stored by "vcal" or "eappts" to
Xdisplay the user's appointments to standard out.
X.PP
XWhen an argument is present,
X.I lcal
Xwill display appointments for the requested month and year.
XThe default argument values are the current month and year.
XIf no filename is specified ~/.appointments will be searched.
XIf one or more filenames arguments are used those files will
Xbe searched.
X.SH AUTHOR
XMike Essex
X.SH FILES
Xlcal
X.br
X~/.appointments
X.br
X.SH "SEE ALSO"
Xvcal(1), appts(1), eappts(1), autocall(1), callme(1)
X.SH BUGS
XThere are year 2000 time bombs.
*-*-END-of-lcal.l-*-*
echo x - vcal.c
sed 's/^X//' >vcal.c <<'*-*-END-of-vcal.c-*-*'
X/*
X * Module:	vcal.c
X *
X * Purpose:	visual appointment calendar
X *
X * Author:	Mike Essex
X *
X * Date:	Sep. 16, 1986
X *
X * Includes:
X *	time.h, stdio.h, ctype.h, signal.h
X *
X * Discussion:
X *	displays a calendar to the screen for the current or optionally
X *	specified month.  User may move the cursor any day of the month
X *	and view or enter appointments for that date.
X * 
X *
X * Edit History
X * ==== =======
X *
X * Date      Who	What
X * ----      ---	----------------------------------------------
X *11/25/86   me         added multiple data file capability
X *11/25/86   me         fixed array "home" from *home[80] to home[80]
X *11/25/86   me         fixed "space" and "area" to be global
X *11/26/86   me		changed help message routines
X * 2/06/86   me		changed calendar header from printing a default
X *			NULL for .appointments file to not printing
X *02/19/86   me		reworked terminal handler to make correct use
X *			of termcap(3) functions for greater terminal
X *			portability.  modified so that cursor comes to
X *			current day of month on startup.  Fixed minor
X *                      bugs and changed a few messages.
X *
X */
X
X#include <stdio.h>
X#include <signal.h>
X#include <ctype.h>
X#include <time.h>
X#include <sgtty.h>
X
X#define		LF	'\012'
X#define		BS	'\010'
X#define		ESC	'\033'
X
Xint		mon[] = {
X    0,
X    31, 29, 31, 30,
X    31, 30, 31, 31,
X    30, 31, 30, 31,
X};
X
Xint	tputc();		/* termcap dependent output */
Xchar	space[BUFSIZ];		/* used by area */
Xchar	*area = space;		/* termcap required variable */
Xchar	*BC;			/* backspace string pointer */
Xchar	*backstring = "\b";	/* backspace string */
Xchar	PC;			/* number pad characters */
Xchar	*UP;			/* cursor up string */
Xextern	short	ospeed;		/* output speed */
Xchar	*CM;			/* cursor motion */
Xchar	*CL;			/* clear screen */
Xchar	*TI;			/* begin cm */
Xchar	*TE;			/* end cm */
Xchar	*SO;			/* standout*/
Xchar	*SE;			/* end standout*/
Xchar	*tgoto();
Xchar	*malloc();
Xchar	tcolumns = 0;		/* terminal columns */
Xchar	tlines = 0;		/* terminal lines */
X
Xint		xposition[32];		/* calendar x axis position */
Xint		yposition[32];		/* calendar y axis position */
Xint		active[33];		/* highlight day array */
X
Xint		monthdata[1000];	/* month data */
Xint		daydata[1000];		/* month data */
Xint		yeardata[1000];	/* month data */
Xchar		*msgdata[1000];	/* message pointers */
Xchar		msghold[80];
Xint		dayindex[18];		/* index to day's msgs */
Xint		maxentries;
Xint		maxmsgs;
Xint		tmonth,tday,tyear;
X
Xint		maxchars;
Xint		notclear;
Xint		help1,help2;		/* help  message flags */
X
Xchar	dayw[] = {
X	"  S    M    T    W    T    F    S   "
X};
X
Xchar	*smon[]= {
X    "JANUARY   ", "FEBRUARY   ", "MARCH    ", "APRIL    ",
X    "MAY    ", "JUNE    ", "JULY    ", "AUGUST    ",
X    "SEPTEMBER    ", "OCTOBER    ", "NOVEMBER    ", "DECEMBER    ",
X};
X
X
X
X/*
X * Procedure:	main(argv[1],argv[2],argv[3])
X *
X * Function:	Front end for calendar program
X *
X * Parameters:
X *	p1	- character pointer - optional month
X *	p2	- character pointer - optional year
X *	p3      - character pointer - optional data file name
X *
X * Discussion:
X *	This module parses command line, intializes variables and calls
X *	init functions.  It then drops into a character interpreter
X *	loop, taking input from standard in.  Each input either changes
X *	cursor position or invokes a function.
X */
X
Xmain (argc,argv)
X
X    int		argc;
X    char	*argv[];
X{
X
X    int		month,day,year;
X    char	key;
X    char	*datafile;
X    extern int	abort();
X    int i;
X
X    datafile = NULL;
X    day = 1;
X    if (argc == 1) {
X	timeset();
X	month = tmonth;
X	day = tday;
X	year = tyear;
X    }
X    else {
X	if (argc == 3) {
X	    month = atoi(argv[1]);
X	    year = atoi(argv[2]);
X	    if (year < 100) year += 1900;
X	    if (!month || !year) {
X		printf("Syntax Error:  non-numeric argument\n");
X		abort(1);
X	    }
X	}
X	else {
X	    if (argc == 2) {
X		timeset();
X		month = tmonth;
X		day = tday;
X		year = tyear;
X		datafile = argv[1];
X	    }
X	    else {
X		if ( argc == 4) {
X		    month = atoi(argv[1]);
X		    year = atoi(argv[2]);
X		    if (year < 100) year += 1900;
X		    if (!month || !year) {
X			printf("Syntax Error:  non-numeric argument\n");
X			abort(1);
X		    }
X		    datafile = argv[3];
X		}
X		else {
X		    printf("Syntax Error:  incorrect number of arguments\n");
X		    abort(1);
X		}
X	    }
X	}
X    }
X    signal(2,abort);
X    signal(3,abort);
X
X    system("stty cbreak -echo");
X
X    tinit();
X    tputs(TI,1,tputc);
X    maxchars = 38;
X    maxentries = 1000;
X    maxmsgs = 18;
X    msghold[0] = NULL;
X    help1 = 0;
X    help2 = 0;
X
X    loaddata(datafile);
X    cal(month,day,year,datafile);
X    movcur(day);
X
X    key = 'a';
X    while (key != LF) {
X
X	key = getchar();
X
X	switch (key) {
X
X            case 'H' :
X
X		helpcal();
X
X	        break;
X
X	    case 'p' :
X
X		if (--month < 1) {
X		    month = 12;
X		    year--;
X		}
X		day = 1;
X		notclear = 0;
X		cal(month,day,year,datafile);
X
X		break;
X
X	    case 'n' :
X		    
X		if (++month == 13) {
X		    month = 1;
X		    year++;
X		}
X		day = 1;
X		notclear = 0;
X		cal(month,day,year,datafile);
X
X		break;
X		    
X	    case 'h' :
X
X		if (--day <= 0) {
X		    day = mon[month];
X		}
X		if (notclear) {
X		    clearmsgs();
X		}
X
X		break;
X
X	    case 'l' :
X
X		if (++day > mon[month]) {
X		    day = 1;
X		}
X		if (notclear) {
X		    clearmsgs();
X		}
X
X		break;
X
X	    case 'j' :
X
X		if ((day += 7) > mon[month]) {
X		    day = day % 7;
X		    if (day == 0) {
X			day = 7;
X		    }
X		}
X		if (notclear) {
X		    clearmsgs();
X		}
X
X		break;
X
X	    case 'k' :
X
X		if ((day -= 7) <= 0) {
X		    day += 35;
X		    if (day > mon[month]) {
X			day -= 7;
X		    }
X		}
X		if (notclear) {
X		    clearmsgs();
X		}
X
X		break;
X
X	    case 'e' :
X
X		day = mon[month];
X		if (notclear) {
X		    clearmsgs();
X		}
X
X		break;
X
X	    case 'b' :
X
X		day = 1;
X		if (notclear) {
X		    clearmsgs();
X		}
X
X		break;
X
X	    case 'c' :
X
X		clearday(month,day,year);
X
X		break;
X
X	    case ' ' :
X
X		notes(month,day,year);
X
X		break;
X
X	    case 'm' :
X
X		modnotes(month,day,year);
X
X		break;
X
X
X	}
X	movcur(day);
X    }
X    closefile(datafile);
X    tputs(TE,1,tputc);
X    system("stty -cbreak echo");
X    if (help1 || help2) {
X	helpclr();
X    }
X    mov(1,24);
X} /* main */
X
X
X/*
X * Procedure:	<routine name>
X *
X * Function:	abort()
X *
X * Discussion:
X *	Reset tty parameters and exits with an error code.
X */
X
Xabort()
X
X{
X    system("stty -cbreak echo");
X    tputs(SE,1,tputc);
X    if (help1 || help2) {
X	helpclr();
X    }
X    mov(1,24);
X    tputs(TE,1,tputc);
X    exit(1);
X} /* abort */
X
X
X
X/*
X * Procedure:	cal(month,day,year,datafile)
X *
X * Function:	produces the visual calendar to the screen
X *
X * Parameters:
X *	p1	- int - month
X *	p2	- int - day
X *	p3	- int - year
X *	p4      - char * - datafile name
X *
X * Discussion:
X *	Calculates current months parameters, such as, starting
X *	day of week, number of days and days on which there are
X *	appointments.  This data is then used to draw a calendar
X *	to the screen.
X */
X
Xcal(month,day,year,datafile)
X
X    int		month,day,year;
X    char	*datafile;
X
X{
X    int		i,j,k,d;
X
X    tputs(CL,24,tputc);
X    if (datafile == NULL) {
X	printf("V I S U A L   C A L E N D A R\n");
X    }
X    else {
X	printf("V I S U A L   C A L E N D A R\t\t%s\n",datafile);
X    }
X    printf("-------------------------------------------------------------------------------\n");
X    printf("\t\t\t\t%s%u\n", smon[month-1], year);
X    printf("-------------------------------------------------------------------------------\n\n");
X    printf("%s\n\n", dayw);
X
X
X    d = jan1(year);
X    mon[2] = 29;
X    mon[9] = 30;
X
X
X    i = 1;
X    while (i <= 32) {
X	active[i++] = 0;
X    }
X
X    i = 0;
X    while (i < maxentries) {
X	if ((yeardata[i] == year) && (monthdata[i] == month) ) {
X	    active[daydata[i]] = 1;
X	}
X	i++;
X    }
X
X    switch((jan1(year+1)+7-d)%7) {
X
X    /*
X     *	non-leap year
X     */
X	case 1:
X	    mon[2] = 28;
X	    break;
X
X    /*
X     *	1752
X     */
X	default:
X	    mon[9] = 19;
X	    break;
X
X    /*
X     *	leap year
X     */
X	case 2:
X		;
X    }
X
X    /* calculate days from beginning of year */
X
X    for(i=1; i<month; i++) {
X	d += mon[i];
X    }
X
X    d %= 7;
X    i = 0;
X
X    /* inset to first day of week position */
X
X    while (i++ < (5*d)) {
X	printf(" ");
X    }
X
X    k = 0;
X    i = d;
X
X    for (j=1;j<=31;j++) {
X	xposition[j] = (i*5) + 2;
X	yposition[j] = (k*2) + 7;
X	if (++i == 7) {
X	    i = 0;
X	    k++;
X	}
X    }
X
X    for(i=1; i<=mon[month]; i++) {
X	if(i==3 && mon[month]==19) {
X	    i += 11;
X	    mon[month] += 11;
X	}
X	if (active[i]) {
X	    if(i > 9) {
X		printf(" ");
X		tputs(SO,1,tputc);
X		printf("%d",i/10);
X		tputs(SE,1,tputc);
X	    }
X	    else {
X		printf(" ");
X		tputs(SO,1,tputc);
X		printf(" ");
X		tputs(SE,1,tputc);
X	    }
X	    tputs(SO,1,tputc);
X	    printf("%d",i%10);
X	    tputs(SE,1,tputc);
X	    if (*SO == NULL) {
X		printf("* ");
X	    }
X	    else {
X		printf("  ");
X	    }
X	}
X	else {
X	    if(i > 9) {
X		printf(" %d",i/10);
X	    }
X	    else {
X		printf("  ");
X	    }
X	    printf("%d  ",i%10);
X	}
X
X	if(++d == 7) {
X	    d = 0;
X	    printf("  \n\n");
X	}
X    }
X    
X    helpclr();
X
X    mov(42,5);
X    printf ("TIME      MESSAGE");
X} /* cal */
X
X
X/*
X * Procedure:	jan1(year)
X *
X * Function:	calculates day of week of Jan 1 on specified year
X *
X * Parameters:
X *	p1	- int - year
X *
X * Return Values:
X *	integer representation day of the week
X */
X
Xjan1(year)
X
X    int		year;
X{
X
X    register y, d;
X/*
X *	normal gregorian calendar
X *	one extra day per four years
X */
X
X    y = year;
X    d = 4+y+(y+3)/4;
X
X/*
X *	julian calendar
X *	regular gregorian
X *	less three days per 400
X */
X
X    if(y > 1800) {
X	d -= (y-1701)/100;
X	d += (y-1601)/400;
X    }
X
X/*
X *	great calendar changeover instant
X */
X
X    if(y > 1752)
X	d += 3;
X
X    return(d%7);
X} /* jan1 */
X
X
X
X/*
X * Procedure:	movcur(day)
X *
X * Function:	moves the cursor to the specified day's position
X *
X * Parameters:
X *	p1	- int - day
X *
X * Discussion:
X *	uses termcap values to move the cursor to a matrix position
X *	stored in a global array
X */
X
Xmovcur(day)
X
X    int	day;
X{
X    tputs( tgoto( CM, xposition[day],yposition[day]), 1, tputc );
X} /* movcur */
X
X
X/*
X * Procedure:	setday(day)
X *
X * Function:	places day in calendar display with appointment
X *		days highlighted
X *
X * Parameters:
X *	p1	- int - day
X *
X * Discussion:
X *	Uses day arguement, termcap values and calendar position
X *	matrices to write a day to the screen with days with appointment
X *	days highlighted.
X */
X
Xsetday(day)
X
X    int		day;
X{
X    tputs( tgoto( CM, xposition[day]-1,yposition[day]), 1, tputc );
X    if (active[day]) {
X	if(day > 9) {
X	    tputs(SO,1,tputc);
X	    printf("%d",day/10);
X	    tputs(SE,1,tputc);
X	}
X	else {
X	    tputs(SO,1,tputc);
X	    printf(" ");
X	    tputs(SE,1,tputc);
X	}
X	tputs(SO,1,tputc);
X	printf("%d",day%10);
X	tputs(SE,1,tputc);
X	if (*SO == NULL) {
X	    printf("*");
X	}
X	else {
X	    printf(" ");
X	}
X    }
X    else {
X	if(day > 9) {
X	    printf("%d",day/10);
X	}
X	else {
X	    printf(" ");
X	}
X	printf("%d ",day%10);
X    }
X} /* setday */
X
X
X
X/*
X * Procedure:	tinit()
X *
X * Function:	gets termcap entries
X *
X * Return Values:
X *	loads global variables with termcap parameters
X *
X * Discussion:
X *	Initial various termcap variables so that they can later
X *	be used to move the cursor and highlight certain displays.
X */
X
Xtinit()	/* termcap initalization */
X
X{
X    struct	sgttyb speed;
X
X    char	term[BUFSIZ];		/* holds termcap entry */
X    char	name[16];		/* terminal name */
X    char	*np;			/* termcap name pointer */
X    char	*NADA = { "\0" };	/* null string */
X    char	*tgetstr();
X    char	*getenv();
X
X    if( (np = getenv( "TERM" )) != NULL ) {
X	    strncpy( name, np, 16 );
X    }
X    else {
X	    printf("TERM environment variable does not exist\n");
X	    abort();
X    }
X
X    if( tgetent( term, name ) != 1 ) {
X	    printf("Termcap for %s does not exist\n",name);
X	    abort();
X    }
X
X    /* if a capability does not exist, point it to a null
X    *  string not NULL
X    */
X
X    gtty(stdout,&speed);
X    ospeed = speed.sg_ospeed;
X
X    tlines = tgetnum( "li" );
X    tcolumns = tgetnum( "co" );
X
X    if( (CM = tgetstr( "cm", &area )) == NULL) {
X	CM = NADA;	
X	printf("Error:  No termcap 'cm' entry for this terminal type\n");
X	abort();
X    }
X    if( (CL = tgetstr( "cl", &area )) == NULL)
X	CL = NADA;
X    if( (UP = tgetstr( "up", &area )) == NULL)
X	UP = NADA;
X    if( (SO = tgetstr( "so", &area )) == NULL)
X	SO = NADA;
X    if( (SE = tgetstr( "se", &area )) == NULL)
X	SE = NADA;
X    if( (TI = tgetstr( "ti", &area)) == NULL)
X	TI = NADA;
X    if( (TE = tgetstr( "te", &area)) == NULL)
X	TE = NADA;
X    if( tgetnum( "sg", &area)  > 0)  {
X	SO = NADA;
X	SE = NADA;
X    }
X    if ( (BC = tgetstr( "bc", &area)) ==  NULL) {
X	BC = backstring;
X    }
X
X} /* tinit */
X
X
X
X/*
X * Procedure:	loaddata(datafile)
X *
X * Function:	loads data file
X *
X * Return Values:
X *	Various global arrays loaded with appointment data
X *
X * Discussion:
X *	Opens user's data file and reads it in, placing
X *	the data in appropriate arrays.
X */
X
Xloaddata(datafile)
X
X    char	*datafile;
X{
X    char	basedata[80];
X    char	tmpbuf[80];
X    char	*getenv();
X    char	home[80];
X    FILE 	*fptr;
X    int		i,j,k,l,field;
X
X    i = 0;
X    while (i < maxentries) {
X	daydata[i] = 0;
X	monthdata[i] = 0;
X	yeardata[i] = 0;
X	msgdata[i] = 0;
X	i++;
X    }
X
X    if (datafile == NULL) {
X	strcpy(home,getenv("HOME"));
X	strcat(home,"/.appointments");
X    }
X    else {
X	strcpy(home,datafile);
X    }
X    if ((fptr = fopen(home,"r")) != NULL) {
X	i = 0;
X	while((fgets(basedata,80,fptr) != NULL)) {
X
X	    basedata[strlen(basedata)-1] = NULL;
X
X	    j = 0;
X	    k = 0;
X	    field = 0;
X	    while (basedata[j] != NULL ) {
X                 
X                if (basedata[j] != ',') {
X
X		    tmpbuf[k++] = basedata[j];
X		}
X		else {
X		    switch (field) {
X
X			case 0 : {
X			    tmpbuf[k] = NULL;
X			    monthdata[i] = atoi(tmpbuf);
X			    k = 0;
X			    break;
X			}
X			case 1 : {
X			    tmpbuf[k] = NULL;
X			    daydata[i] = atoi(tmpbuf);
X			    k = 0;
X			    break;
X			}
X			case 2 : {
X			    tmpbuf[k] = NULL;
X			    yeardata[i] = atoi(tmpbuf);
X			    k = 0;
X			    break;
X			}
X			case 3 : {
X			    tmpbuf[k++] = ' ';
X			    tmpbuf[k++] = ' ';
X			    break;
X			}
X		    }
X		    field++;
X		}
X		j++;
X	    }
X	    tmpbuf[k] = NULL;
X	    msgdata[i] = malloc(80);
X	    strncpy(msgdata[i],tmpbuf,80);
X	    msgdata[79] = NULL;
X
X	    if (i >= maxentries) {
X		printf("Warning:  Over 1000 entries in data file.  Data truncated.\n");
X		break;
X	    }
X	    i++;
X	}
X	fclose(fptr);
X    }
X} /* loaddata */
X
X
X/*
X * Procedure:	closefile(datafile)
X *
X * Function:	writes appointment data to file
X *
X * Discussion:
X *	Opens the user's designated data file and writes the current
X *	data into it.
X */
X
Xclosefile(datafile)
X
Xchar	*datafile;
X{
X    FILE	*fptr;
X    char	tmpbuf[80];
X    int		i;
X    char	*getenv();
X    char	home[80];
X
X    if (datafile == NULL) {
X	strcpy(home,getenv("HOME"));
X	strcat(home,"/.appointments");
X    }
X    else {
X	strcpy(home,datafile);
X    }
X    if ((fptr = fopen(home,"w")) == NULL) {
X	printf("Error:  Cannot open %s file",datafile);
X	abort();
X    }	
X    i = 0;
X    while (i < maxentries) {
X	if (daydata[i]) {
X	    strcpy(tmpbuf,msgdata[i]);
X	    tmpbuf[4] = NULL;
X	    fprintf(fptr,"%d,%d,%d,%4.4s,%s\n",monthdata[i],daydata[i],yeardata[i],tmpbuf,&tmpbuf[6]);
X	}
X	i++;
X    }
X    fclose(fptr);
X} /* closefile */
X
X
X
X
X/*
X * Procedure:	notes(month,day,year)
X *
X * Function:	displays the current day's appointments
X *
X * Parameters:
X *	p1	- int - month
X *	p2	- int - day
X *	p3	- int - year
X *
X * Discussion:
X *	Writes to notes section of screen notes for day to
X *	which the cursor was pointing.
X */
X
Xnotes(month,day,year)
X
X    int		month,day,year;
X{
X    int		i,j,k;
X
X    if (help1) {
X	helpclr();
X	help1 = 0;
X    }
X
X    i = 0;
X    while (i < 18) {
X	dayindex[i++] = 0;
X    }
X
X    mov(64,5);
X    printf("%2d/%2d/%2d",month,day,year);
X
X    i = 0;
X    j = 0;
X    k = 6;
X
X    while (i < maxentries) {
X	if ((yeardata[i] == year) && (monthdata[i] == month) && (daydata[i] == day)) {
X	    dayindex[j++] = i;
X	    notclear++;
X	    mov(42,k++);
X	    printf("%-32.32s",msgdata[i]);
X	}
X	if (j > maxmsgs) {
X	    mov(42,24);
X	    printf("* too many entries to print *");
X	    break;
X	}
X	i++;
X    }
X    i = 0;
X    while (i < maxentries) {
X	if (daydata[i] == 0) {
X	    dayindex[j++] = i;
X	    if (j >= maxmsgs) {
X		break;
X	    }
X	}
X	i++;
X    }
X} /* notes */
X
X
X
X/*
X * Procedure:	modnotes(month,day,year)
X *
X * Function:	add, delete and modify appointment list
X *
X * Parameters:
X *	p1	- int - month
X *	p2	- int - day
X *	p3	- int - year
X *
X * Return Values:
X *	changes data in global message and date arrays
X *
X * Discussion:
X *	Allows the user to add, delete and modify a specified day's
X *	appointment list.  Routine contains a small character
X *	interpreter which moves the cursor through the notes list
X *	and selects routines to modify the list.
X */
X
Xmodnotes (month,day,year)
X
X    int		month,day,year;
X{
X
X    char	key,c;
X    int		xcoord,ycoord;
X    int		i,cnt,total;
X    char	tmpmsg[39];
X
X    notes(month,day,year);
X    xcoord = 42;
X    ycoord = 6;
X    i = 0;
X    mov(xcoord,ycoord);
X    key = 'a';
X
X    while (key != LF) {
X
X	key = getchar();
X
X	switch (key) {
X
X            case 'H' :
X
X		helpnotes();
X
X	        break;
X
X	    case 'j' :
X		i++;
X		if (++ycoord > 23) {
X		    ycoord = 6;
X		    i = 0;
X		}
X		break;
X
X	    case 'k' :
X		i--;
X		if (--ycoord < 6) {
X		    ycoord = 23;
X		    i = 17;
X		}
X		break;
X
X	    case 'd' :
X
X		tputs(SO,1,tputc);
X		printf("                                      ");
X		tputs(SE,1,tputc);
X		mov (xcoord,ycoord);
X		monthdata[dayindex[i]] = 0;
X		daydata[dayindex[i]] = 0;
X		yeardata[dayindex[i]] = 0;
X		strcpy(msghold,msgdata[dayindex[i]]);
X		if (msgdata[dayindex[i]]) {
X		    free(msgdata[dayindex[i]]);
X		    msgdata[dayindex[i]] = 0;
X		}
X		break;
X
X            case 'y' :
X
X		strcpy(msghold,msgdata[dayindex[i]]);
X
X		break;
X
X            case 'p' :
X
X		    if (msgdata[dayindex[i]] == 0) {
X			msgdata[dayindex[i]] = malloc(80);
X		    }
X		    strncpy(msgdata[dayindex[i]],msghold,80);
X		    yeardata[dayindex[i]] = year;
X		    daydata[dayindex[i]] = day;
X		    monthdata[dayindex[i]] = month;
X		    printf("%s",msgdata[dayindex[i]]);
X
X		break;
X
X	    case 'i' :
X
X		tputs(SO,1,tputc);
X		printf("                                      ");
X
X		mov (xcoord,ycoord);
X
X		c = '0';
X		cnt = 0;
X		while (c != ESC) {
X		    c = getchar();
X		    if (c != ESC ) {
X			if (c == BS) {
X			    if (cnt > 0) {
X				cnt--;
X				if (cnt == 5) {
X				    cnt = 3;
X				    mov(46,ycoord);
X				}
X				printf("%s %s",BC,BC);
X			    }
X			}
X			else {
X			    if (c != LF) {
X				if ( cnt < maxchars) {
X				    tmpmsg[cnt] = c;
X				    cnt++;
X				    printf("%c",c);
X				}
X				if (cnt == 4) {
X				    tmpmsg[4] = ' ';
X				    tmpmsg[5] = ' ';
X				    cnt = 6;
X				    mov(48,ycoord);
X				}
X			    }
X			    else {
X				c = ESC;
X			    }
X			}
X		    }
X		}
X		tputs(SE,1,tputc);
X		if (cnt) {
X		    tmpmsg[cnt] = NULL;
X		    if (msgdata[dayindex[i]] == 0) {
X			msgdata[dayindex[i]] = malloc(80);
X		    }
X		    strncpy(msgdata[dayindex[i]],tmpmsg,80);
X		    monthdata[dayindex[i]] = month;
X		    daydata[dayindex[i]] = day;
X		    yeardata[dayindex[i]] = year;
X		}
X		else {
X		    monthdata[dayindex[i]] = 0;
X		    daydata[dayindex[i]] = 0;
X		    yeardata[dayindex[i]] = 0;
X		    if (msgdata[dayindex[i]]) {
X			free(msgdata[dayindex[i]]);
X			msgdata[dayindex[i]] = 0;
X		    }
X		}
X
X		break;
X
X	    default :;
X	}
X	mov (xcoord,ycoord);
X    }
X
X    active[day] = 0;
X    i = 0;
X    while (i < maxentries) {
X	if ((yeardata[i] == year) && (monthdata[i] == month)) {
X	    notclear = 18;
X	    active[daydata[i]] = 1;
X	}
X	i++;
X    }
X
X    notclear = 18;
X    clearmsgs();
X    if (active[day]) {
X	notes(month,day,year);
X    }
X    setday(day);
X    if (help2) {
X	helpclr();
X	help2 = 0;
X    }
X} /* modnotes */
X
X
X/*
X * Procedure:	tputc(character)
X *
X * Function:	moves cursor on screen
X *
X * Parameters:
X *	p1	- int - character
X *
X * Discussion:
X *	Outputs a character to crt.  Used as an argument to tputs().
X */
X
Xtputc(c)
X    int c;
X{
X    putchar(c);
X}
X
X
X/*
X * Procedure:	mov(column,row)
X *
X * Function:	moves cursor on screen
X *
X * Parameters:
X *	p1	- int - crt column
X *	p2	- int - crt row
X *
X * Discussion:
X *	Moves the cursor to specified column and row on screen using
X *	termcap data.
X */
X
Xmov(col, row)
X
Xint	col,row;
X
X{
X    tputs( tgoto( CM, (col - 1),(row - 1)), 1, tputc );
X} /* move */
X
X
X/*
X * Procedure:	clearday(month,day,year)
X *
X * Function:	deletes specified day's appointments
X *
X * Parameters:
X *	p1	- int - month
X *	p2	- int - day
X *	p2	- int - year
X *
X * Return Values:
X *	changes various global arrays
X *
X * Discussion:
X *	Removes appointment entries for the specified day from
X *	message and date tables and from the crt
X */
X
Xclearday (month,day,year)
X
X    int		month,day,year;
X{
X    int		i;
X
X    i = 0;
X    while (i < maxentries) {
X	if ((yeardata[i] == year) && (monthdata[i] == month) && (daydata[i] == day)) {
X	    active[day] = 0;
X	    monthdata[i] = 0;
X	    daydata[i] = 0;
X	    yeardata[i] = 0;
X	    if (msgdata[i])  {
X		free(msgdata[i]);
X		msgdata[i] = 0;
X	    }
X	}
X	i++;
X    }
X    clearmsgs();
X    setday(day);
X} /* clearday */
X
X
X/*
X * Procedure:	clearmsgs()
X *
X * Function:	clears the notes section of the crt
X */
X
Xclearmsgs()
X
X{
X    int		i;
X
X    mov(64,5);
X    printf("          ");
X
X    if (notclear > maxmsgs) notclear = maxmsgs;
X
X    i = 6;
X    while (i < (notclear+6)) {
X	mov(42,i++);
X	printf("                                      ");
X    }
X    mov(42,24);
X    printf("                                   ");
X    notclear = 0;
X} /* clearmsgs */
X
X
X/*
X * Procedure:	helpcal()
X *
X * Function:	displays calendar help messages to crt
X */
X
Xhelpcal()
X
X{
X    mov(1,19);
X    printf("j/k/h/l:  cursor down/up/left/right     \n");
X    printf("b:  first day         e: last day       \n");
X    printf("space: display notes  m: modify notes   \n");
X    printf("c: clear notes        CR: exit program  \n");
X    printf("p: previous month     n: next month     \n");
X    printf("BRK: exit w/o changes                   ");
X    help1++;
X} /* helpcal */
X
X
X/*
X * Procedure:	helpnotes()
X *
X * Function:	displays notes help messages to crt
X */
X
Xhelpnotes() 
X
X{
X    mov(1,19);
X    printf("j/k:  cursor down/up                    \n");
X    printf("i: enter insert      ESC/CR: exit insert\n");
X    printf("d: delete entry      CR: exit notes     \n");
X    printf("y/p: yank/put a line                    \n");
X    printf("                                        \n");
X    printf("                                        ");
X    help2++;
X} /* helpnotes */
X
X
X/*
X * Procedure:	helpclr()
X *
X * Function:	clears notes area of screen
X */
X
Xhelpclr ()
X{
X    mov(1,19);
X    printf("                                        \n");
X    printf("                                        \n");
X    printf("                                        \n");
X    printf("                                        \n");
X    printf("    Type 'H' for help                   \n");
X    printf("                                        ");
X} /* helpclr */
X
X
X/*
X * Procedure:	timeset()
X *
X * Function:	sets current month, day and year variables
X *
X * Return Values:
X *	tday, tmonth and tyear variables set to current date
X */
X
Xtimeset()
X
X{
X    struct	tm *localtime();
X
X    struct tm *tp;		/* time structure */
X    long	tloc;		/* number of seconds since 1970 */
X
X    time(&tloc);	/* fills tloc */
X
X    tp = localtime(&tloc);
X
X    tyear =	tp->tm_year;
X    tmonth =	tp->tm_mon + 1;
X    tday =	tp->tm_mday;
X
X    tyear += 1900;
X
X} /* timeset */
*-*-END-of-vcal.c-*-*
echo x - vcal.l
sed 's/^X//' >vcal.l <<'*-*-END-of-vcal.l-*-*'
X.TH VCAL 1 
X.SH NAME
Xvcal \- visual calendar and notes program
X.SH SYNOPSIS
X.B vcal 
X[ month year ] [ filename ]
X.sp
Xwhere
X.I month
Xis a numeric value between 1 and 12,
X.I year
Xis a numeric four digit value and
X.I filename
Xis the data file to be accessed.
X.SH DESCRIPTION
X.I Vcal 
Xis a visual calendar program which allows the user to enter notes
Xand appointments for each day of the month.  It can be used to
Xreplace the "paper" desk or wall calendar with an electronic one
Xwhich can be accessed from any terminal or modem connected to the
Xcomputer system.
X.PP
XWhen a date argument is present,
X.I vcal
Xwill display the requested month and year.  The default argument values
Xare the current month and year.  When a filename argument is used
X.I vcal
Xwill uses that file instead of the default ~/.appointments file.
XIf ~/.appointments is not used the filename of the current file
Xwill appear at the top of the
X.I vcal
Xcalendar.
X.SH OPERATION
X.I Vcal
Xis entered from UNIX by typing the
Xcommand followed by an optional month and year value.  A calendar
Xwill be displayed on the screen with the cursor located on the first
Xday of the month.  The cursor may be moved to different days
Xin the following manner.
X.br
X.sp
X.nf
Xkey             function
X---             --------
Xj               move cursor down
Xk               move cursor up
Xl               move cursor to the next day
Xh               move cursor to the previous day
Xb               move cursor to the beginning of the month
Xe               move cursor to the end of the month
X.sp
X.fi
X.PP
XPrevious and following months may also be accessed.
X.br
X.sp
X.nf
Xkey             function
X---             --------
Xp               previous month
Xn               next month
X.sp
X.fi
X.PP
XUp to eighteen appointments may be entered on each day of the month.
XThese may be displayed, modified or cleared in with the following keys.
XThey will operate on the day selected by the current cursor position.
X.br
X.sp 4
X.nf
Xkey             function
X---             --------
Xspace           display appointments for the selected day
Xm               enter or modify appointments
Xc               clear all appointments for the selected day
X.sp
X.fi
X.PP
XWhen the 'm' is pressed
X.I vcal
Xenters notes mode.  While in this mode notes may be added, modified,
Xdeleted, yanked or put.
X.br
X.sp
X.nf
Xkey             function
X---             --------
Xj               move cursor down
Xk               move cursor up
Xi               begin data insertion
XESC/CR          end data insertion (only while in insert)
Xd               delete the selected line
Xy               hold the current line
Xp               insert the held message
XCR              exit notes mode and return to the calendar
X.sp
X.fi
XData must begin with the appointment time in 24 hour format
X(no ':' should be used).  Entering new data will erase the current
Xmessage on that line.  A held line will be available to insert until
Xit is changed or the user exits
X.I vcal.
XA line which is deleted using the 'd' key will be placed in the hold
Xbuffer.
X.PP
XWhen the cursor is on the calendar a carriage return will cause the
Xthe appointment data to be saved and
X.I vcal
Xto exit.  Break or delete will cause
X.I vcal
Xto exit without updating the ~/.appointments file.
X.PP
XA 'H' will display help messages.  A calendar help message
Xwill be printed when
Xthe cursor is on calendar days.  A notes help message
Xis printed when the cursor is in the notes area.
X.PP
XFive companion programs are available to use with the
X.I vcal
Xprogram.  These are:
X.br
X.sp
X.nf
Xappts           display current or selected days appointments
Xeappts          enter appointments from the UNIX command line
Xautocall        set appointment reminders for the current day
Xlcal            displays month's appointments in tabular form
Xcallme          sets appointment reminders
X.fi
X.sp
XFor further information on these, reference the appropriate "man"
Xentries.
X.SH AUTHOR
XMike Essex
X.SH FILES
Xvcal
X.br
X/etc/termcap
X.br
X~/.appointments
X.br
X.SH "SEE ALSO"
Xappts(1), eappts(1), autocall(1), lcal(1), callme(1)
X.SH BUGS
X.I Vcal
Xmay not work with extremely brain damaged terminals.  There must be
Xa 'CM' entry in the termcap for 
X.I vcal
Xto draw the screen.  There are year 2000 time bombs.
X.br
*-*-END-of-vcal.l-*-*
exit