Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

v09i049: REPOST of Visual calendar program, Part01/02

2 views
Skip to first unread message

sources...@mirror.uucp

unread,
Apr 14, 1987, 6:22:46 PM4/14/87
to
Submitted by: ihnp4!sdcrdcf!trwrb!ries (Marc Ries)
Mod.sources: Volume 9, Issue 49
Archive-name: month/Part01

[ This time I've got all my marbles -- and all the pieces. --r$ ]

The following is a stable version of "month", being in
"production" mode for several months without major incident.

The man page is very complete.

Marc A. Ries

sdcrdcf!---\
ihnp4!------\----- trwrb! --- ries

# Cut_Here-----Cut_Here-----Cut_Here---------Cut_Here
# !/bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh).
#
# This archive created: Mar 10 1987
# By: Marc Ries
#
export PATH; PATH=/bin:/usr/bin:$PATH
#
if `test ! -s ./help.c`
then
echo "writting ./help.c"
cat > ./help.c << 'RiesES_PIECES'
/*
* Modification History
*
* Origional Author: Jeff Bauer@ETA Systems[eta!bauer]
* Modifications by: Marc Ries@TRW[trwrb!ries]
*
*/

#include <curses.h>

help()
{
clear();
standout();
mvaddstr(0, 25, " Keys and their Functions");
standend();
mvaddstr(1, 2, "h, l, k, j - move cursor left, right, up, down");
mvaddstr(2, 2, "<CR> and <LF> - select items/commands/scroll-areas");
mvaddstr(3, 2, "0-9 - direct entry of date or marker numbers");
mvaddstr(4, 2, "/ - directly type in complete date (i.e. 5/6/86) | <ESC> - abort function");
mvaddstr(5, 2, "<SPACE>/<BACKSPACE> - scroll hours/minutes forward/backward");
mvaddstr(6, 2, "m, d - and y - move into the months, days, years areas");
mvaddstr(7, 2, "n or +, p or '-' - go to the next or previous month, day, or year");
mvaddstr(8, 2, "M - mark the currently displayed date | G - go to a previously marked date");
mvaddstr(9, 2, "; - go to last visited date outside of current displayed month");
mvaddstr(10, 2, "T - go to today's actual date (initial date displayed)");
mvaddstr(11, 2, "O - display schedule grid for currently displayed day");
mvaddstr(12, 2, "A - show days in current month that have items scheduled");
mvaddstr(13, 2, "S - scan the events for the currently displayed day");
mvaddstr(14, 2, " n : go to next event p : go to previous event d : delete this event");
mvaddstr(15, 2, " e : edit this event q : quit the scan <ESC>: same as 'q'");
mvaddstr(16, 2, "E - scan every stored event");
mvaddstr(17, 2, "F - save events on disk file");
mvaddstr(18, 2, "P - post an event (see man page)");
mvaddstr(19, 2, "L - print picture of moon for 11:00 PM of current day");
mvaddstr(20, 2, "Q - quit, store any event changes");
mvaddstr(21, 2, "^L, ^R - redraw screen (including this page)");
mvaddstr(22, 2, "^C, ^\ - quit, ignore any event changes");
standout();
mvaddstr(23, 18, " Press any key to return to your calendar.");
standend();
refresh();
get_char();
clear();
print_screen();
}
RiesES_PIECES
else
echo "will not over write ./help.c"
fi
if `test ! -s ./lunar.c`
then
echo "writting ./lunar.c"
cat > ./lunar.c << 'RiesES_PIECES'
/*
* Modification History
*
* Origional Author: Tom Stoehn@Tektronics[zeus!tims]
* Modifications by: Marc Ries@TRW[trwrb!ries]
*
*/

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

/* Globals. */
double Fraction;

/* Linked in later. */
time_t time();
struct tm *localtime();


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

extern short month, day, year;

long
Calculate(julian, year, hour, minute)
long year, julian, hour, minute;
{
register long Length;
register long Phase;
register long Delta;
register long offset;
/*
* time_t tick;
*
* static short called_before = 0;
*
* if (!called_before) { tick = time((time_t *)0); tm =
* localtime(&tick); called_before = 1; } else { tm->tm_yday++; }
* julian = tm->tm_yday + 1; year = tm->tm_year - 78; hour
* = tm->tm_hour; minute = tm->tm_min;
*/

year -= 78;
Length = (double) 2551 / 60 * 1000 + (double) 443 / 60;
offset = ((year * 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);
}
move(LINES - 1, 0);
refresh();
}

lunar()
{
long yday;
extern int lflag;

yday = (long) (days_since_jan1(month, day, year) + 1);
(void) Calculate(yday, ((long) (year - 1900)), 11L, 0L);
Draw();
refresh();
if (lflag) {
clear();
endwin();
exit(0);
}
else {
get_char();
clear();
print_screen();
}
}
RiesES_PIECES
else
echo "will not over write ./lunar.c"
fi
if `test ! -s ./month.1`
then
echo "writting ./month.1"
cat > ./month.1 << 'RiesES_PIECES'
.TH MONTH 1L "Pyramid OSx" "" "User Contributed Software"
.SH NAME
month \- a visual calendar and time/event organizer
.SH SYNOPSIS
.B month
[
.B \-ABCdv
] [
.B \-N
[ arg ]]
.SH OPTIONS
.TP
.B \-d
Create background daemon that will wake up at 15 minute intervals
during the current login session,
check your event database, and print a message to your
terminal with a bell if it finds an event that is 15 minutes, or less, away.
It will do this on invocation, then
every 15-minutes until killed or you log out.
.TP
.B \-A
Output the
.I month
data file in a format compatible with
.I appt (1).
.TP
.B \-B
Output the current day's events.
.TP
.B \-C
Output the
.I month
data file in a format compatible with
.I calendar (1).
.TP
.B \-L
Output the lunar picture of what the moon will
look like at 11:00PM of the current day, and exit.
.TP
.B \-N [ arg ]
Output the current day's events in a format compatable with
.I nag (1).
An optional argument
.B arg
specifies what program
.I nag
should invoke for the user (the default is
.I echo
).
.TP
.B \-v
Output the version ID of
.I month
being run.
.SH DESCRIPTION
.TP
.B Overview
.br
.sp 1
.I Month
displays a calendar of the current month of the current year,
with the current day highlighted.
It then allows the user to browse to any month/day/year,
and to schedule and recall events for a day or for some regular
repeating series of days.
Note that the UPPER/lower case of commands are significant.
.br
.TP
.B Screen Areas
.br
.sp 1
There are four distinct areas of the screen: the
.I days
area where the days of the month are listed in calendar format, the
.I months
area where the months of the year are listed, the
.I years
area where a sequence of years are listed, and the
.I schedule
area, which may be blank and occupies lines 19-24 on the terminal
(lines below 24 are not used).
.br
.TP
.B Commands
.br
.I Quitting
.br
.sp 1
You may type 'Q' almost any time to quit. This will update
the event database if any changes have been made.
The event database is a file called
.B .month
in your home directory.
.I <CNTL-c>
can be used any time for an immediate abort and no event database update.
When you quit, you will be informed of the update status of your event database.
.br
.sp 1
.I Cursor motion
.br
.sp 1
The
.B h, l, k,
and
.B j
keys are used to move the cursor left, right, up and down respectively
within a screen area.
Sometimes, as explained later,
.B j
and
.B k
will not work, and a
.I <TAB>
or
.I <CR>
provides movement between fields in a circular fashion.
.br
.sp 1
.I Selection
.br
.sp 1
.I <CR>
and
.I <LF>
are used to select items/commands at the cursor position.
.br
.sp 1
.I Direct entry of numbers
.br
.sp 1
The user may type the number of a desired month, day, or year
whenever the cursor is appropriately positioned.
This is true in all screen areas.
.I <ESC>
can be used to abort any function.
.br
.sp 1
.I Scrolling numbers
.br
.sp 1
In the schedule area, numbers may be scrolled forwards and
backwards with the
.I <SPACE>
and
.I <BACKSPACE>
keys respectively.
This is the only way to change hours and minutes.
.br
.sp 1
.I Time browsing
.br
.sp 1
The keys 'm', 'd' and 'y' are used to move into the months area, the
days area or the years area respectively. This is only when
time browsing in these three panes. To get to a particular
month or year, move to the appropriate area and onto the
desired month or year, and select it via
.I <CR>.
Years may be
scrolled a year at a time by using the scroll areas marked
by '<<' and '>>'. Attempting to move passed these areas will
scroll by one year, selecting them scrolls by ten years.
The last month of the previous year, or the first month of
next year, may be obtained by selecting the area above
January or below December respectively.
The cursor is the positioned for immediate return via a later selection.
.br
.sp 1
The keys
.B n
and
.B p
can be used to go to the next or previous month,
day, or year, depending on the screen area you are in.
.br
.sp 1
The
.B M
key will mark a specific date. You will be prompted for
an identifier that is a single digit between '0' and '9'.
Once a mark has been set at a certain date, you may jump to
that date from any other date with the command below.
.br
.sp 1
The
.B G
key controls movement to a previously set mark.
You will be prompted for the mark's identifying digit.
.br
.sp 1
The key
.B ';'
provides access directly to the last date you viewed that
was in a different month than currently displayed.
Use the same command again to return to where you were originally.
.br
.sp 1
The
.B T
key goes directly to the actual, real current date.
This is the date initially displayed on startup.
.br
.sp 1
The key
.B '/'
allows direct access to a date to be fully specified by the user.
A prompt is given and the user should respond with
a date in the form m/d/y, such as 5/6/86. Years less than
100 are assumed to be in this century, hence, 5/6/80 is the same as 5/6/1986.
.TP
.B Overviewing a day
.br
.sp 1
The
.B O
key will fill the schedule area with a read only view
of your day according to your event database.
Four six-hour grids appear showing the hours of the day
that have been pre-scheduled.
The cursor must be placed on the day to be viewed with this function.
.TP
.B Overviewing a month
.br
.sp 1
The
.B A
key will mark all the days on the calendar that have
at least one event posted. This feature is especially
useful before scanning; described next.
.TP
.B Scanning events
.br
.sp 1
The
.B S
key will cause a sequential list of events for the current day
to be displayed in the schedule area. The events for any given
day may be scanned, deleted, or modified.
After displaying each one, the prompt "
.B [n,p,d,e,q]
" is put up and will respond to these character commands:
.br
.sp 1
.I 'n':
go to next event
.br
.I 'p':
go to previous event
.br
.I 'd':
delete this event
.br
.I 'e':
edit this event as during a posting described below
.br
.I 'q':
quit the scan and return to calendar
.br
.I <ESC>:
same as 'q'
.br
.TP
.B Every event scan
.sp 1
.I 'E'
will display, one at a time, absolutely every event
in your event database. The prompt "
.B ['n','q']
" is displayed
and will respond to these character commands:
.br
.I 'n':
go to next event
.br
.I 'q':
quit the scan and return to calendar
.br
.I <ESC>:
same as 'q'
.br
.TP
.B Posting an event
.sp 1
.I 'P'
is the command used to post an event. The
cursor is placed into the schedule area with a host of
information displayed.
.sp 1
To abort at any point, use
.I <ESC>.
.sp 1
The cursor first appears on the first line of the schedule area.
This line gives the starting date for the event, and when it shall occur.
The user may move through the highlighted starting date field
(using the
.B h
and
.B l
keys) and change the month, day or year by scrolling with
.I <SPACE>
and
.I <BACKSPACE>,
or by direct input.
.br
.sp
The other fields in this first line may also be moved onto and selected
in a similar fashion (but without direct entry).
.br
.sp
.I <TAB>
will move the cursor to the next line that contains the
time that the event occurs.
Again, the
.B h,
.B l,
.I <SPACE>,
and
.I <BACKSPACE>
keys manipulate the hours and minutes fields.
The AM/PM indicator changes as the hours scroll across 12:00 boundaries.
.br
.sp
.I <TAB>
will move the cursor to the next line that gives the duration of the event,
and it is edited in the same fashion.
.br
.sp
.I <TAB>
moves the cursor to the next line that is a one line description of the
event, to be typed whenever the cursor is placed here.
.I <TAB>
moves the cursor the last line in the schedule area and
allows the user to select ACCEPT or CANCEL.
The
.B h
and
.B l
keys toggle between ACCEPT and CANCEL.
Pressing
.I <RETURN>
when the cursor is in the ACCEPT field will put the event
into the user's event database, after verification.
CANCEL aborts the process.
.br
.sp
The
.I <TAB>
key can be used to circulate through the fields.
.TP
.B Event scheduling
.sp 1
When and how often will an event occur? This information
is contained in the first line of the schedule area. The
date entered there is the starting date for the event,
that is, the event will not be recalled until that date.
This date is best entered by browsing to it, placing the
cursor in the days area on the desired day, and then
type 'P' to post the event, in which case the desired date
automatically appears as the default, but may be edited.
.br
.sp
In the following examples, only the fields that need to be
selected are mentioned, all others should be turned off.
(not highlighted) Examples:
.ta +2.5i
.br
.sp 1
.I March 5, 1990 (once only):
.B 3/5/1990
.br
.sp 1
.I Every Tuesday and Wednesday:
.B m/d/y every TueWed
.br
.sp 1
.I The 7th of each month:
.B m/7/y monthly
.br
.sp 1
.I Each July 4th:
.B 7/4/y yearly
.br
.sp 1
.I The 2nd and last sunday of
.I each month:
.B m/d/y monthly every 2nd last Sun
.br
.sp 1
.I The 1st and last friday of
.I each year:
.B \ \ m/d/y yearly every 1st last Fri
.br
.sp 1
.I Every other thursday:
.B m/d/y every 2nd Thu
.br
.sp 1
Note, this will include the 1st, 3rd, 5th, 7th, etc.
thursday,
.I starting
from the specified m/d/y
.TP
.B Miscellaneous
.sp 1
The
.B L
key stands for lunar, and causes a picture of what the moon will
look like at 11:00PM on the day on which the cursor is placed.
.I <CNTL-L>
or
.I <CNTL-R>
will redraw the screen.
.br
.sp 1
The
.B F
key is used for storing event descriptions to a file.
The user is prompted for whether he would like to store ALL the events
in his database or just those for the current day.
The user is then prompted for a file name, and if that file exists already,
the user is given a chance to abort the operation or continue.
.SH EXAMPLES
.br
.sp 1
.ti +1i
cp \ $HOME/.apptrc \ $HOME/.appt\ ;\ month -A \ >> \ $HOME/.appt
.sp
.br
month -N > \ $HOME/.nag\ ;\ nag
.sp
.ti -1i
.SH AUTHORS
.ta +1.15i
Jeff Bauer (bauer@etc)
.br
Robert Dextor (robertd@tekigm2)
.br
Marc Ries (ries@trwrb)
.br
Tom Stoehn (tims@zeus)
.SH FILES
$HOME/.month
.SH SEE ALSO
appt (1), calendar (1), and nag (1).
.SH DIAGNOSTICS
month: unknown option \fIarg\fR
.br
Usage: month [-A] [-B] [-C] [-d] [-N [arg]] [-v]
.SH BUGS
Few attempts have been made to prevent the user from browsing
through negatively numbered years or years with more than four
digits in them, the latter causing the years area to get messed up,
but remains functional.
Rarely, events with a starting date before the year 1753,
will not be recalled correctly.

With the
.B -A
flag, any date that does not have a time that pertains
to it (i.e. birthdays, holidays, ...), set the starting time to 12:00 AM.
.I Month
requires a starting time whereas
.I appt
does not.
.SH DATE
2/9/87
RiesES_PIECES
else
echo "will not over write ./month.1"
fi
if `test ! -s ./month.c`
then
echo "writting ./month.c"
cat > ./month.c << 'RiesES_PIECES'
/* Modification History
*
* Origional Author: Tom Stoehn@Tektronics[zeus!tims]
* Modifications by: Marc Ries@TRW[trwrb!ries]
*
*/

#include <curses.h>
#include <signal.h>
#include <sys/types.h>
#include <utmp.h>
#include "month.h"

short initd = 0;
short dhour, dminute, dsecond;
extern short crow, ccol, update_schedule, updating;
extern short this_month, this_day, this_year, SCHEDULE_ROW, SKID_ROW;
extern struct event_rec events;
extern struct mdate mdates[];
extern char *strcpy();

extern short start_day;

short calflag, nagflag;
char *nagprog = "";

int lflag = 0;

main(argc, argv)
int argc;
char **argv;
{
extern int optind;
extern char *optarg;
int argch;

while ( (argch=getopt(argc,argv,"ABCN:Ldhv?")) != EOF ) {
switch (argch) {
case 'd': /* Place in background */
if (!fork()) {
(void) signal(SIGINT, SIG_IGN);
(void) signal(SIGQUIT, SIG_IGN);
daemonize();
}
exit(0);
case 'N': /* Output in nag format */
nagflag++;
if (optind > argc) {
(void) strcpy(nagprog, "echo");
} else {
nagprog = optarg;
}
case 'B': /* Output Time and Event */
get_current_date();
read_schedule();
psched2();
exit(0);
break;
case 'C': /* Output in calendar format */
calflag++;
case 'A': /* Output in APPT format */
get_current_date();
read_schedule();
scan_every_event_for_appt();
exit(0);
break;
case 'L': /* Output Lunar display only */
init();
get_current_date();
++lflag;
lunar();
exit(0);
case 'v': /* Output Version Info */
(void) fprintf(stderr, " MONTH [version %s]\n", VERSION);
sleep(3);
break;
case '?':
case 'h':
default:
(void) printf("Usage: %s [-A] [-B] [-C] [-L] [-d] [-N [arg]] [-v]\n", *argv);
(void) printf(" | | | | | | | |\n");
(void) printf(" | | | | | | | +-- version id\n");
(void) printf(" | | | | | | +-- program to \"nag\" with\n");
(void) printf(" | | | | | +-- .nag format\n");
(void) printf(" | | | | +-- daemonize\n");
(void) printf(" | | | +-- lunar display\n");
(void) printf(" | | +-- calendar format\n");
(void) printf(" | +-- today's events\n");
(void) printf(" +-- .appt format\n");
terminate();
}
}
init();
print_screen();
start_display();
user();
terminate();
}

init()
{
int blast_out(), i;

(void) signal(SIGINT, blast_out);
(void) signal(SIGQUIT, blast_out);
get_current_date();
read_schedule();

for (i = 0; i < 12; i++) {
mdates[i].month = this_month;
mdates[i].year = this_year;
}
initscr();
SCHEDULE_ROW = (LINES < 25) ? 17 : 18;
SKID_ROW = 18;
initd = 1;
crmode();
noecho();
}

terminate()
{
if (updating) {
return;
}
(void) signal(SIGINT, SIG_IGN);
#ifdef BSD
(void) signal(SIGTSTP, SIG_IGN);
#endif
(void) signal(SIGQUIT, SIG_IGN);
(void) signal(SIGHUP, SIG_IGN);

if (initd) {
if (update_schedule) {
mvaddstr(0, 0, "updating schedule\t");
} else {
mvaddstr(0, 0, "schedule unchanged\t");
}
refresh();
if (update_schedule) {
if (write_schedule() == -1) {
sound_bell();
mvaddstr(0, 0, "cannot create .month");
}
}
move(LINES-1, 0);
clrtoeol();
refresh();
endwin();
}
exit(0);
}

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

daemonize()
{
int do_nothing();
struct event_rec *eptr;
short minutes, eminutes, diff;
unsigned short seconds;

(void) fflush(stdout);
AGAIN:
get_current_date();
minutes = (60 * dhour) + dminute;

seconds = (60 * (15 - (dminute % 15) - 1)) + (60 - dsecond);
if (seconds < 60) {
seconds = 900;
}
(void) signal(SIGALRM, do_nothing);
(void) alarm(seconds);
if (!logged_in()) {
terminate();
}
read_schedule();

eptr = events.next_event;

while (eptr) {

if (event_matches_date(eptr)) {
eminutes = (((short)60) * ((short)eptr->hour)) +
((short)eptr->minute);
diff = eminutes - minutes;
if ((diff >= 0) && (diff <= 15)) {
remind(eptr->event_string, diff);
}
}
eptr = eptr->next_event;
}
pause();
goto AGAIN;
}

logged_in()
{
static struct utmp u_buf;
struct utmp t_buf;
int fd, retval = 0;
static short called_before = 0;
char *ttyname(), *tname;
AGAIN:
if ((fd = open("/etc/utmp", 0)) < 0) {
return(0);
}
if (!called_before) {
tname = ttyname(0) + 5;
}
while (read(fd, (char *)&t_buf, sizeof(struct utmp)) > 0) {
if (!called_before) {
if (!strcmp(tname, t_buf.ut_line)) {
u_buf = t_buf;
break;
}
} else if (byte_comp((char *)&u_buf, (char *)&t_buf, sizeof(struct utmp))) {
(void) close(fd);
retval = 1;
break;
}
}
(void) close(fd);
if (!called_before) {
called_before = 1;
goto AGAIN;
}
return(retval);
}

do_nothing()
{
}

byte_comp(s1, s2, n)
register char *s1, *s2;
register int n;
{
short i;

for (i = 0; i < n; i++) {
if (*(s1++) != *(s2++)) {
return(0);
}
}
return(1);
}

#ifdef BSD
/* File : getopt.c
Author : Henry Spencer, University of Toronto
Updated: 28 April 1984
Purpose: get option letter from argv.
*/

extern char *index();

#ifndef NullS
#define NullS (char*)0
#endif NullS

char *optarg; /* Global argument pointer. */
int optind = 0; /* Global argv index. */

int getopt(argc, argv, optstring)
int argc;
char *argv[];
char *optstring;
{
register int c;
register char *place;
static char *scan = NullS; /* Private scan pointer. */

optarg = NullS;

if (scan == NullS || *scan == '\0') {
if (optind == 0) optind++;
if (optind >= argc) return EOF;
place = argv[optind];
if (place[0] != '-' || place[1] == '\0') return EOF;
optind++;
if (place[1] == '-' && place[2] == '\0') return EOF;
scan = place+1;
}

c = *scan++;
place = index(optstring, c);
if (place == NullS || c == ':') {
(void) fprintf(stderr, "%s: unknown option %c\n", argv[0], c);
return '?';
}
if (*++place == ':') {
if (*scan != '\0') {
optarg = scan, scan = NullS;
} else {
optarg = argv[optind], optind++;
}
}
return c;
}
#endif BSD
RiesES_PIECES
else
echo "will not over write ./month.c"
fi
if `test ! -s ./month.h`
then
echo "writting ./month.h"
cat > ./month.h << 'RiesES_PIECES'
#define VERSION "1.4 (USENET) 03/01/87" /* Version number! SCCS should agree */

#define TOP_MONTH_ROW 3
#define YEAR_ROW 16
#define YEAR_COL 12
#define TIME_ROW 20
#define DURATION_ROW 21
#define DESCRIPTION_ROW 22
#define ACCEPT_ROW 23
#define LAST_YEAR_COL 75
#define DATE_COL 0
#define MONTHLY_COL 15
#define YEARLY_COL 23
#define EVERY_COL 30
#define NTH_COL 36
#define LAST_COL 41
#define SMTWTFS_COL 46
#define TIME_COL 11
#define MINUTE_COL 14
#define ACCEPT_COL 11
#define CANCEL_COL 18
#define SMONTH_COL 0
#define SDAY_COL 3
#define SYEAR_COL 6

#define MONTHS 0
#define YEARS 1
#define DAYS 2
#define SCHEDULE 3

#define MAX_EVENTS 250

#define MAX_EVENT_STRING_LENGTH 70

#define NOTHING 0
#define ACCEPT 1
#define CANCEL 2

struct event_rec {
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 relevent? */
char nth, last; /* does event occurn on an nth or last somehting? */
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 span_hours; /* hours event lasts */
char span_minutes; /* minutes event lasts, multiple of 15 */
char event_string[MAX_EVENT_STRING_LENGTH]; /* short description of event */
struct event_rec *next_event; /* next event */
};

struct mdate {
short month;
short year;
};
RiesES_PIECES
else
echo "will not over write ./month.h"
fi
if `test ! -s ./psched.c`
then
echo "writting ./psched.c"
cat > ./psched.c << 'RiesES_PIECES'
/*
* Modification History
*
* Origional Author: Tom Stoehn@Tektronics[zeus!tims] Modifications by: Marc
* Ries@TRW[trwrb!ries]
*
*/

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

/*
* A routine that will print out the schedule for the day, i.e.,
*
* 8:45 - 9:45 Foo Bar Baz and so on...
*/

extern short nagflag, month, day, year;
extern char *nagprog;

psched()
{
short i, shour, sminute, ehour, eminute, n;
struct event_rec *events_today[MAX_EVENTS];

get_daily_events(events_today);
for (n = 0; events_today[n]; n++);
sort_events(events_today, n);

clear();
move(0, 0);
i = 0;
while (events_today[i])
{

shour = events_today[i]->hour;
sminute = events_today[i]->minute;
ehour = shour + (events_today[i]->span_hours);
eminute = sminute + (events_today[i]->span_minutes);

printw("%2d:%02d%2s-%2d:%02d%2s %s\n",
(shour <= 12) ? shour : (shour % 12), sminute,
((shour < 12) ? "AM" : "PM"),
(ehour <= 12) ? ehour : (ehour % 12), eminute,
(((ehour % 24) < 12) ? "AM" : "PM"),
events_today[i]->event_string);
i++;
}
refresh();
get_char();
clear();
print_screen();
}

psched2()
{
short i, shour, sminute, ehour, eminute, n;
struct event_rec *events_today[MAX_EVENTS];

get_daily_events(events_today);
for (n = 0; events_today[n]; n++);
sort_events(events_today, n);

i = 0;
while (events_today[i])
{

shour = events_today[i]->hour;
sminute = events_today[i]->minute;
ehour = shour + (events_today[i]->span_hours);
eminute = sminute + (events_today[i]->span_minutes);

if (nagflag)
{
(void) printf(" %02d/%02d/%d", month, day, year);
(void) printf(" %02d:%02d%2s ",
(shour <= 12) ? shour : (shour % 12), sminute,
((shour < 12) ? "AM" : "PM"));
(void) printf("-20:-9:-6:-4:-2 ");
(void) printf("%s \"%s at \$then in \$pretime minutes.\"\n",
nagprog, events_today[i]->event_string);
} else
{
(void) printf("%2d:%02d%2s-%2d:%02d%2s ",
(shour <= 12) ? shour : (shour % 12), sminute,
((shour < 12) ? "AM" : "PM"),
(ehour <= 12) ? ehour : (ehour % 12), eminute,
((ehour < 12) ? "AM" : "PM"));
(void) printf("%s\n", events_today[i]->event_string);
}
i++;
}
}
RiesES_PIECES
else
echo "will not over write ./psched.c"
fi
if `test ! -s ./schedule.c`
then
echo "writting ./schedule.c"
cat > ./schedule.c << 'RiesES_PIECES'
/*
* Modification History
*
* Origional Author: Tom Stoehn@Tektronics[zeus!tims] Modifications by: Marc
* Ries@TRW[trwrb!ries]
*
*/

#include <curses.h>
#include "month.h"
#include <sys/types.h>
#include <sys/file.h>

extern char *strcpy(), *strcat();
extern char *getenv(), *malloc();

#ifndef F_OK
#define F_OK 00
#endif

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};
struct event_rec current_event = {0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0},
1, 0, 0, 10, 0, 1, 0, "", 0};
short update_schedule = 0;
short updating = 0, edit_flag = 0, put_into_schedule, parsed_correctly;
char schedule_file_name[75];
short SCHEDULE_ROW, SKID_ROW;

char *grids[] = {
"mid. . . 1a . . . 2a . . . 3a . . . 4a . . . 5a . . . 6a",
"6a . . . 7a . . . 8a . . . 9a . . . 10a. . . 11a. . . noon",
"noon . . 1p . . . 2p . . . 3p . . . 4p . . . 5p . . . 6p",
"6p . . . 7p . . . 8p . . . 9p . . . 10p. . . 11p. . . mid"
};
extern short month, day, year, days, message_line_filled;

post_event(month, day, year)
short month, day, year;
{
goto_schedule();
current_event.event_month = month;
current_event.event_day = day;
current_event.event_year = year;
display_event(&current_event);
}

read_schedule()
{
char *s;
int fd, rec_size;
struct event_rec *event_ptr, *chain_ptr;

chain_ptr = events.next_event; /* free old events */
while (chain_ptr)
{
event_ptr = chain_ptr;
chain_ptr = chain_ptr->next_event;
free((char *)event_ptr);
}
events.next_event = 0;

if (!(s = getenv("HOME")))
{
s = ".";
}
(void) strcpy(schedule_file_name, s);
(void) strcat(schedule_file_name, "/.month");

rec_size = sizeof(struct event_rec);

if ((fd = open(schedule_file_name, 0)) != -1)
{

chain_ptr = &events;

for (;;)
{
if ((!(event_ptr = (struct event_rec *) malloc(rec_size))) ||
(read(fd, (char *)event_ptr, rec_size) != rec_size))
{
break;
}
chain_ptr->next_event = event_ptr;
chain_ptr = event_ptr;
chain_ptr->next_event = (struct event_rec *) 0;
}
(void) close(fd);
}
}

write_schedule()
{
int fd;
struct event_rec *chain_ptr;

updating = 1;

if ((fd = creat(schedule_file_name, 0640)) == -1)
{
return (-1);
}
chain_ptr = events.next_event;

while (chain_ptr)
{
if (!is_passed_event(chain_ptr))
{
(void) write(fd, (char *) chain_ptr, sizeof(struct event_rec));
}
chain_ptr = chain_ptr->next_event;
}
(void) close(fd);
updating = 0;
return (0);
}

select_regularity_col(col)
register col;
{
short i, hflag;

switch (col)
{
case MONTHLY_COL:
hl_all(&current_event, (current_event.monthly ? 0 : 1),
0, -1, -1, -1, -1);
break;
case YEARLY_COL:
hl_all(&current_event, 0, (current_event.yearly ? 0 : 1),
-1, -1, -1, -1);
break;
case EVERY_COL:
hl_all(&current_event, -1, -1,
(current_event.every ? 0 : 1), -1, -1, -1);
break;
case SMTWTFS_COL:
case SMTWTFS_COL + 3:
case SMTWTFS_COL + 6:
case SMTWTFS_COL + 9:
case SMTWTFS_COL + 12:
case SMTWTFS_COL + 15:
case SMTWTFS_COL + 18:
i = (col - SMTWTFS_COL) / 3;
hflag = (current_event.smtwtfs[i] = !current_event.smtwtfs[i]);
hl_schedule(col, hflag);
hl_all(&current_event, -1, -1, -1, -1, -1, -1);
break;
case NTH_COL:
hl_all(&current_event, -1, -1, -1,
(current_event.nth_is_on ? 0 : 1), -1, -1);
break;
case LAST_COL:
hl_all(&current_event, -1, -1, -1, -1,
(current_event.last ? 0 : 1), -1);
break;
}
}

accept_cancel(is_accept)
short is_accept;
{
if (is_accept)
{
accept_current_event();
} else
{
cancel_current_event();
display_event(&current_event);
}
if (edit_flag)
{
clear_message_line();
} else
{
message_line_filled = 1;
}
goto_day(day);
}

accept_current_event()
{
if ((parse_event(&current_event) != -1))
{
if (get_answer("Put into schedule? ", "change cancelled", "done",
'n', 'y')
== 'y')
{
if (!edit_flag)
{
link_event(&current_event);
}
put_into_schedule = 1;
}
}
}

cancel_current_event()
{
if (!edit_flag)
{
current_event = events;
}
}

link_event(event)
struct event_rec *event;
{
struct event_rec *t, *ptr;

if (!(ptr = (struct event_rec *)
malloc(sizeof(struct event_rec))))
{
return;
}
*ptr = *event;
t = events.next_event;
events.next_event = ptr;
ptr->next_event = t;
update_schedule++;
}

parse_event(event)
struct event_rec *event;
{
short hs;

hs = has_smtwtfs(event->smtwtfs);

if ((event->every || event->nth_is_on || event->last) && !hs)
{
error_message("missing day of week", 1);
return (-1);
}
if (hs && !event->every && !event->nth_is_on && !event->last)
{
MQ: error_message("missing qualifier", 1);
return (-1);
}
if (!event->every &&
(event->monthly || event->yearly) &&
(event->nth_is_on || event->last))
{
error_message("need 'every'", 1);
return (-1);
}
if (event->last && !event->monthly && !event->yearly)
{
error_message("monthly or yearly?", 1);
return (-1);
}
if ((event->nth_is_on || event->last) &&
(!event->monthly && !event->yearly && !event->every))
{
goto MQ;
}
parsed_correctly = 1;
return (0);
}


overview()
{
short i, j, row, col, hour, minute, span, n;
struct event_rec *event_list[MAX_EVENTS];
char *grid;

(void) get_daily_events(event_list);

clear_schedule_area();

for (i = 0; i < 4; i++)
{
mvaddstr((SCHEDULE_ROW + i + i), 1, grids[i]);
}

standout();
i = 0;

while (event_list[i])
{

hour = event_list[i]->hour;
minute = event_list[i]->minute;

row = SCHEDULE_ROW + ((hour / 6) * 2);

if (row > (LINES - 1))
{
break;
}
span = (event_list[i]->span_hours * 60) +
event_list[i]->span_minutes;
col = 1 + (12 * (hour % 6)) + (3 * (minute / 15));
n = hour / 6;
grid = grids[n];
span /= 15;

move(row, col);

for (j = 0; j < span; j++)
{
addch(grid[col - 1]);
addch(grid[col]);
addch(grid[col + 1]);

col += 3;
if (col > 72)
{
col = 1;
row += 2;

if (row > (SCHEDULE_ROW + 6))
{
row = SCHEDULE_ROW;
}
move(row, col);
grid = grids[++n % 4];
}
}
i++;
}
standend();
}

get_daily_events(event_list)
struct event_rec *event_list[];
{
short i = 0;
struct event_rec *eptr;

eptr = events.next_event;

while (eptr && (i < (MAX_EVENTS - 1)))
{
if (event_matches_date(eptr))
{
event_list[i++] = eptr;
}
eptr = eptr->next_event;
}
event_list[i] = 0;
return (i);
}

get_every_event(event_list)
struct event_rec *event_list[];
{
short i = 0;
struct event_rec *eptr;

eptr = events.next_event;

while (eptr && (i < (MAX_EVENTS - 1)))
{
event_list[i++] = eptr;
eptr = eptr->next_event;
}
event_list[i] = 0;
return (i);
}

scan_events(schar)
int schar;
{
struct event_rec *event_list[MAX_EVENTS];
short i, j, k, ch, n;

if (schar == 'S')
{ /* scan todays events */
if ((n = get_daily_events(event_list)) <= 0)
{
error_message("No events this day", 0);
clear_schedule_area();
return;
}
} else
{ /* scan all events */
if ((n = get_every_event(event_list)) <= 0)
{
error_message("No events", 0);
clear_schedule_area();
return;
}
}
sort_events(event_list, n);

for (i = 0; i < n; i++)
{
current_event = *event_list[i];
display_event(event_list[i]);
GETCH:
ch = get_npdeq();

switch (ch)
{
case '\0':
i--;
break;
case '\033':
case 'q':
goto OUT;
case 'n':
j = i + 1;
while ((j < n) && (!event_list[j]))
{
j++;
}
if (j >= n)
{
/*
* sound_bell(); goto GETCH;
*/
goto OUT;
}
i = j - 1;
break;
case 'p':
j = i - 1;
while ((j >= 0) && (!event_list[j]))
{
j--;
}
if (j < 0)
{
sound_bell();
goto GETCH;
}
i = j - 1;
break;
case 'd':
delete_event(event_list[i]);
event_list[i] = 0;
for (k = i + 1; k < n; k++)
{
if (event_list[k] != 0)
{
i = k;
break;
}
}
if (event_list[i] == 0)
{
for (k = i - 1; k >= 0; k--)
{
if (event_list[k] != 0)
{
i = k;
break;
}
}
}
if (event_list[i] != 0)
{
i--;
} else
{
goto OUT;
}
break;
case 'e':
EDIT: goto_schedule();
edit_flag = 1;
parsed_correctly = 0;
put_into_schedule = 0;
if (user() == ACCEPT)
{
if (parsed_correctly && put_into_schedule)
{
*event_list[i] = current_event;
update_schedule++;
} else if (!parsed_correctly)
{
goto EDIT;
}
} else
{
display_event(event_list[i]);
}
edit_flag = 0;
i--;
break;
}
}
OUT: goto_day(day);
}

delete_event(event)
struct event_rec *event;
{
struct event_rec *ptr;

ptr = &events;

while (ptr && (ptr->next_event != event))
{
ptr = ptr->next_event;
}
if (ptr)
{
ptr->next_event = ptr->next_event->next_event;
free((char *) event);
}
update_schedule++;
}

sort_events(e, n)
register struct event_rec *e[];
int n;
{
register struct event_rec *t;
register i, j;
short f;

for (i = 0; i < n; i++)
{
for (j = (n - 1), f = 0; j > 0; j--)
{
if ((e[j]->hour < e[j - 1]->hour) ||
((e[j]->hour == e[j - 1]->hour) &&
(e[j]->minute < e[j - 1]->minute)))
{
t = e[j];
e[j] = e[j - 1];
e[j - 1] = t;
f++;
}
}
if (f == 0)
{
break;
}
}
}

show_all_events(month, year)
register month, year;
{
register struct event_rec *eptr;
short i;
char match_list[32];
short tday;

tday = day;

for (i = 1; i <= days; i++)
{

eptr = events.next_event;
match_list[i] = 0;
day = i;

while (eptr)
{
if (event_matches_date(eptr))
{
if (!eptr->monthly && !eptr->yearly && !eptr->every)
{
match_list[i] = 2;
break;
} else
{
match_list[i] = 1;
}
}
eptr = eptr->next_event;
}
}
day = tday;
print_cal(month, year, match_list);
}

file_events()
{
struct event_rec *event_list[MAX_EVENTS];
short i, ch, n;
char buf[256];
int fd;

if ((ch = get_answer("all, or current? [ac] ",
"", "", 'a', 'c')) == 'c')
{
if ((n = get_daily_events(event_list)) <= 0)
{
error_message("No events this day", 0);
return;
}
} else if (ch == 'a')
{ /* scan all events */
if ((n = get_every_event(event_list)) <= 0)
{
error_message("No events", 0);
return;
}
} else
{
return;
}
if (!get_input_line("file: ", buf))
{
return;
}
if (!access(buf, F_OK))
{
if (get_answer("file already exists, use it? ", "aborted", "OK",
'n', 'y') == 'n')
{
return;
}
}
if ((fd = creat(buf, 0640)) < 0)
{
error_message("permission denied", 1);
} else
{
if (ch == 'c')
{
(void) strcpy(buf, "\n\t\t\tEvents for ");
print_date(event_list[0]->event_month, event_list[0]->event_day,
event_list[0]->event_year, buf + strlen(buf));
} else
{
(void) strcpy(buf, "\n\t\t\tAll Events Listing");
}
(void) strcat(buf, "\n\n\n");
(void) write(fd, buf, strlen(buf));
for (i = 0; i < n; i++)
{
(void) strcpy(buf, " ");
print_time(event_list[i], buf + strlen(buf));
(void) strcat(buf, "\n");
print_span(event_list[i], buf + strlen(buf));
(void) strcat(buf, "\n ");
print_event_description(event_list[i], buf + strlen(buf));
(void) strcat(buf, "\n\n* * * * * * * * * *\n\n");
(void) write(fd, buf, strlen(buf));
}
(void) close(fd);
error_message("done", 0);
}
}

scan_every_event_for_appt()
{
struct event_rec *ptr;

ptr = events.next_event;

while (ptr)
{
current_event = *ptr;
display_appt(ptr);

ptr = ptr->next_event;
}
}
RiesES_PIECES
else
echo "will not over write ./schedule.c"
fi
if `test ! -s ./time.c`
then
echo "writting ./time.c"
cat > ./time.c << 'RiesES_PIECES'
/*
* Modification History
*
* Origional Author: Tom Stoehn@Tektronics[zeus!tims] Modifications by: Marc
* Ries@TRW[trwrb!ries]
*
*/

#ifdef BSD
# include <sys/time.h>
#else
#include <sys/types.h>
# include <time.h>
#endif

#include <ctype.h>

#ifdef BSD
# undef tolower
# undef toupper
#endif

#include "month.h"

#ifdef BSD
char *timezone();
#else
extern char *tzname[];
#endif


short month, year, day;
short this_month, this_day, this_year;
short start_day;
long time();

extern short dhour, dminute, dsecond, days;

get_current_date()
{
struct tm *tmp, /* Time structure, see CTIME(3C) */
*localtime();
long junk; /* time in seconds.... */
#ifdef BSD
struct timeval tp;
struct timezone tzp;
#endif

#ifdef BSD
(void) gettimeofday(&tp, &tzp);
junk = tp.tv_sec;
#else
junk = (long) time(0); /* this must be here for it to work! */
#endif
tmp = localtime(&junk);
year = this_year = 1900 + tmp->tm_year;
month = this_month = tmp->tm_mon + 1;
day = this_day = tmp->tm_mday;
dhour = tmp->tm_hour;
dminute = tmp->tm_min;
dsecond = tmp->tm_sec;

start_day = get_start_day(this_month, this_year);
}

jan1(year)
register year;
{
register day;

day = 4 + year + (year + 3) / 4;

if (year > 1800)
{
day -= (year - 1701) / 100;
day += (year - 1601) / 400;
}
if (year > 1752)
day += 3;

return (day % 7);
}

is_leap_year(year)
int year;
{
int day;

day = jan1(year);
return ((((jan1(year + 1) + 7 - day) % 7) == 2) ? 1 : 0);
}

get_start_day(month, year)
register month, year;
{
short day, i;

day = jan1(year);

for (i = 1; i < month; i++)
{
day = (day + days_in(i, year)) % 7;
}
return (day);
}

days_in(month, year)
register month, year;
{
int days;

switch (month)
{
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
days = 31;
break;
case 4:
case 6:
case 9:
case 11:
days = 30;
break;
case 2:
days = 28 + is_leap_year(year);
break;
}
return (days);
}

is_passed_event(event)
struct event_rec *event;
{
if (event->monthly || event->yearly || event->every ||
(event->event_year > this_year))
{
return (0);
}
if (event->event_year < this_year)
{
return (1);
}
/* now we know it's this year */
if (event->event_month > this_month)
{
return (0);
}
if (event->event_month < this_month)
{
return (1);
}
/* now we know it's this month */
if (event->event_day < this_day)
{
return (1);
}
return (0);
}

is_before(m, d, y, month, day, year)
register m, d, y, month, day, year;
{
if (y < year)
{
return (1);
}
if (y > year)
{
return (0);
}
if (m < month)
{
return (1);
}
if (m > month)
{
return (0);
}
if (d < day)
{
return (1);
}
return (0);
}

has_smtwtfs(smtwtfs)
register char *smtwtfs;
{
register i;

for (i = 0; i < 7; i++)
{
if (smtwtfs[i])
{
return (1);
}
}
return (0);
}

event_matches_date(event)
register struct event_rec *event;
{
short last;
int n;
/* check if current date is before start date of event */

if (is_before(month, day, year, event->event_month, event->event_day,
event->event_year))
{
return (0);
}
/* one time events */

if ((event->event_year == year) && (event->event_month == month) &&
(event->event_day == day) && !event->every &&
!event->nth_is_on && !event->last)
{
return (1);
}
/* once monthly or once yearly events */

if (!event->every && !event->nth_is_on && !event->last)
{
if (event->monthly)
{
if (event->event_day == day)
{
return (1);
}
} else if (event->yearly)
{
if ((event->event_month == month) &&
(event->event_day == day))
{
return (1);
}
}
}
if ((event->monthly || event->yearly) && !event->every &&
!event->nth_is_on && !event->last)
{
if (event->monthly && (event->event_day == day))
{
return (1);
}
if (event->yearly && (event->event_month == month) &&
(event->event_day == day))
{
return (1);
}
}
if (!event->smtwtfs[(day - 1 + start_day) % 7])
{
return (0);
}
/* everys */

if (event->every)
{

/* every smtwtf */

if (!event->nth_is_on && !event->last)
{
EVDAY: if (event->smtwtfs[((day - 1 + start_day) % 7)])
{
return (1);
}
return (0);
}
/* every monthly/yearly */

if (event->monthly || event->yearly)
{
/* every monthly not-1st2nd3rdlast */
if (!event->nth_is_on && !event->last)
{
goto EVDAY;
}
/* every monthly/yearly with one of 1st2nd3rdlast */

if (event->nth_is_on)
{
if (event->monthly &&
(nth_smtwtfs_of_month(&last) ==
(event->nth - 1)))
{
return (1);
}
if (event->yearly &&
(nth_smtwtfs_of_year(&last) ==
(event->nth - 1)))
{
return (1);
}
}
if (event->last)
{
if (event->monthly)
{
(void) nth_smtwtfs_of_month(&last);
if (last)
{
return (1);
}
}
if (event->yearly)
{
(void) nth_smtwtfs_of_year(&last);
if (last)
{
return (1);
}
}
}
} else
{
/* every not-monthly and not-yearly */
if (!event->nth_is_on && !event->last)
{
goto EVDAY;
}
/* every nth/dayofweek */
if (event->nth == 1)
{
return (1);
}
n = how_many_since(event->event_month,
event->event_day, event->event_year);
if ((n % (event->nth)) == 1)
{
return (1);
}
}
}
return (0);
}

nth_smtwtfs_of_month(last)
short *last;
{
*last = ((day + 7) > days) ? 1 : 0;
return ((day - 1) / 7);
}

nth_smtwtfs_of_year(last)
short *last;
{
short days, i;

for (i = 1, days = day; i < month; i++)
{
days += days_in(i, year);
}

*last = ((days + 7) > (365 + is_leap_year(year))) ? 1 : 0;
return ((days - 1) / 7);
}

how_many_since(m, d, y)
int m, d, y;
{
register total_days_passed;
int i;

if (y < year)
{
total_days_passed = 0;
for (i = m; i <= 12; i++)
{
total_days_passed += days_in(i, y);
}
total_days_passed -= (d - 1);
for (i = (y + 1); i < year; i++)
{
total_days_passed += (365 + is_leap_year(i));
}
for (i = 1; i < month; i++)
{
total_days_passed += days_in(i, year);
}
total_days_passed += day;
} else if (m == month)
{
total_days_passed = day - d + 1;
} else
{
total_days_passed = 1 - d;
for (i = m; i < month; i++)
{
total_days_passed += days_in(i, year);
}
total_days_passed += day;
}
return ((((total_days_passed - 1) / 7) + 1));
}

days_since_jan1(month, day, year)
{
int days = 0, i;

for (i = 1; i < month; i++)
{
days += days_in(i, year);
}
days += day;
return (days);
}
RiesES_PIECES
else
echo "will not over write ./time.c"
fi
if `test ! -s ./user.c`
then
echo "writting ./user.c"
cat > ./user.c << 'RiesES_PIECES'
/*
* Modification History
*
* Origional Author: Tom Stoehn@Tektronics[zeus!tims] Modifications by: Jeff
* Bauer@ETA Systems[eta!bauer] Marc Ries@TRW[trwrb!ries]
*
*/

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

extern short crow, ccol, current_area, month, day, year, edit_flag;
extern short this_month, this_day, this_year, message_line_filled, days;
extern struct event_rec current_event;
extern struct mdate mdates[];
struct mdate mdates[12];

user()
{
register short ch;
short n, m, y;
char *prompt;
struct mdate tmp;

for (;;)
{
MR: move(crow, ccol);
refresh();

m = month;
y = year;
GETCH:
ch = get_char();

switch (ch)
{
case '/':
date_search();
break;
case ';':
case ':':
if (current_area != SCHEDULE)
{
goto_this_day(mdates[10].month, 1, mdates[10].year);
tmp = mdates[10];
mdates[10] = mdates[11];
mdates[11] = tmp;
goto MR;
}
break;
case 'Q':
if (current_area != SCHEDULE)
{
terminate();
}
break;
case '\033':
if (edit_flag)
{
return (CANCEL);
} else if (current_area == SCHEDULE)
{
accept_cancel(0);
}
break;
case 'L':
if (current_area == DAYS)
{
lunar();
} else if ((current_area == MONTHS) || (current_area == YEARS))
{
warn_day();
}
break;
case 'j':
case 'k':
case 'l':
case 'h':
case 'y':
case 'm':
case 'd':
case '\t':
move_cursor(ch);
break;
case 'n':
case '+':
case 'p':
case '-':
incr(ch);
break;
case '\n':
case '\r':
if ((n = selection()) != NOTHING)
{
return (n);
}
break;
case ' ':
case '\b':
scroll_time(ch);
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
switch (current_area)
{
case DAYS:
prompt = "day: ";
break;
case MONTHS:
prompt = "month: ";
break;
case YEARS:
prompt = "year: ";
break;
case SCHEDULE:
switch (ccol)
{
case SMONTH_COL:
prompt = "month: ";
break;
case SDAY_COL:
prompt = "day: ";
break;
case SYEAR_COL:
prompt = "year: ";
break;
case NTH_COL:
prompt = "nth: ";
break;
default:
goto GETCH;
}
break;
default:
goto GETCH;
}
if ((n = enter_number(ch, prompt)) >= 0)
{
do_number(n);
}
break;
case 'P':
if (current_area == DAYS)
{
post_event(month, day, year);
} else
{
warn_day();
}
break;
case 'A':
if (current_area != SCHEDULE)
{
show_all_events(month, year);
}
break;
case 'F':
file_events();
break;
case 'S':
if (current_area == DAYS)
{
scan_events(ch);
} else if ((current_area == MONTHS) || (current_area == YEARS))
{
warn_day();
}
break;
case 'E':
if (current_area != SCHEDULE)
{
scan_events(ch);
}
break;
case 'O':
if (current_area == DAYS)
{
overview();
} else if ((current_area == MONTHS) || (current_area == YEARS))
{
clear_schedule_area();
warn_day();
}
break;
case 'T':
if (current_area != SCHEDULE)
{
goto_this_day(this_month, this_day, this_year);
}
break;
case 'M':
case 'G':
if (current_area != SCHEDULE)
{
mark_day((ch == 'G'));
}
break;
case 'B':
psched();
break;
case '?':
help();
break;
default:
standout();
mvaddstr(23, 60, " Press ? for help");
standend();
refresh();
goto GETCH;
break;
}
if ((m != month) || (y != year))
{ /* changed months */
mdates[10] = mdates[11];
mdates[11].month = month;
mdates[11].year = year;
}
}
}

enter_number(ch, prompt)
short ch;
char *prompt;
{
char nbuf[6];
short col, first_col, i = 0;
int retval = -1;

first_col = col = strlen(prompt);

mvaddstr(0, 0, prompt);

for (;;)
{
if ((ch >= '0') && (ch <= '9'))
{
if ((col < (first_col + 2)) ||
(((current_area == YEARS) ||
((current_area == SCHEDULE)) &&
(ccol == SYEAR_COL)) &&
(col < (first_col + 4))))
{
nbuf[i++] = ch;
mvaddch(0, col++, ch);
refresh();
}
} else if ((ch == '\n') || (ch == '\r'))
{
nbuf[i] = 0;
retval = atoi(nbuf);
break;
} else if (ch == '\b')
{
if (col > first_col)
{
i--;
col--;
mvaddch(0, col, ' ');
move(0, col);
refresh();
}
} else if (ch == '\033')
{
break;
}
ch = get_char();
}
clear_message_line();
return (retval);
}

do_number(n)
short n;
{
if (current_area == YEARS)
{
if (n > 0)
{
shift_years(n - year);
goto_year(year);
}
} else if (current_area == MONTHS)
{
if ((n <= 12) && (n >= 1))
{
crow = TOP_MONTH_ROW + n;
selection();
}
} else if (current_area == DAYS)
{
if ((n >= 1) && (n <= days))
{
goto_day(n);
}
} else if (current_area == SCHEDULE)
{
switch (ccol)
{
case SMONTH_COL:
if ((n >= 1) && (n <= 12))
{
current_event.event_month = n;
}
break;
case SDAY_COL:
if ((n >= 1) && (n <= days))
{
current_event.event_day = n;
}
break;
case SYEAR_COL:
if (n > 0)
{
current_event.event_year = n;
}
break;
case NTH_COL:
if ((n > 0) && (n <= 53))
{
current_event.nth = n;
current_event.nth_is_on = 1;
print_nth(&current_event);
}
break;
default:
return;
}
if (ccol != NTH_COL)
{
print_date(current_event.event_month,
current_event.event_day, current_event.event_year, 0);
}
}
}

handle_event_description()
{
short ch;

for (;;)
{
move(crow, ccol);
refresh();
ch = get_char();

if ((ch >= ' ') && (ch <= '~'))
{
if (ccol <= 78)
{
addch(ch);
current_event.event_string[ccol - TIME_COL] = ch;
ccol++;
current_event.event_string[ccol - TIME_COL] = 0;
}
} else
{
switch (ch)
{
case '\n':
case '\r':
case '\t':
schedule_move_cursor(ch);
return;
break;
case '\b':
if (ccol > TIME_COL)
{
ccol--;
mvaddch(crow, ccol, ' ');
current_event.event_string
[ccol - TIME_COL] = 0;
}
break;
case '\004':
case '\025':
case '\030':
current_event.event_string[0] = 0;
ccol = TIME_COL;
move(crow, TIME_COL);
clrtoeol();
break;
case '\027':
while ((ccol > TIME_COL) && (current_event.event_string
[--ccol - TIME_COL] == ' '));
while ((ccol > TIME_COL) && (current_event.event_string
[(ccol - 1) - TIME_COL] != ' '))
{
ccol--;
}
move(crow, ccol);
clrtoeol();
break;
}
}
}
}

get_answer(prompt, yes_string, no_string, char1, char2)
char *prompt, *yes_string, *no_string;
int char1, char2;
{
char *s;
short retval, col;

mvaddstr(0, 0, prompt);
refresh();

do
{
retval = get_char();
if ((retval == (char1 - 32)) || (retval == (char2 - 32)))
{
retval += 32;
}
} while ((retval != char1) && (retval != char2) && (retval != '\033'));

s = (retval == char1) ? yes_string : no_string;
mvaddstr(0, 0, s);
col = strlen(s);

if (edit_flag)
{
addstr(" -more-");
move(0, col + 7);
blank_out(col + 7);
move(0, col + 7);
refresh();
(void) get_char();
} else
{
blank_out(col);
}
message_line_filled = 1;
return (retval);
}

get_nq()
{
register ch;

mvaddstr(0, 0, "[n,q] ");
refresh();

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

switch (ch)
{
case 'q':
case '\033':
clear_message_line();
return ('q');
break;
case 'n':
case '\n':
case '\r':
clear_message_line();
return ('n');
break;
}
}
}

get_npdeq()
{
register ch;

mvaddstr(0, 0, "[n,p,d,e,q] ");
refresh();

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

switch (ch)
{
case '\n':
case '\r':
ch = 'n'; /* no break statement */
case 'n':
case 'p':
case 'e':
case '\033':
case 'q':
clear_message_line();
return (ch);
break;
case 'd':
ch = get_answer("really delete? ", "", "", 'n', 'y');
if (ch == 'y')
{
mvaddstr(0, 0, "deleted");
} else
{
mvaddstr(0, 0, "not deleted");
}
addstr(" -more-");
refresh();
(void) get_char();
clear_message_line();
return ((ch == 'y') ? 'd' : '\0');
break;
}
}
}

mark_day(goto_flag)
short goto_flag;
{
short ch;

mvaddstr(0, 0, "mark: ");
refresh();

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

switch (ch)
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':

mvaddch(0, 6, ch);
refresh();
message_line_filled = 1;

ch -= '0';

if (goto_flag)
{
goto_this_day(mdates[ch].month, 1, mdates[ch].year);
} else
{
mdates[ch].month = month;
mdates[ch].year = year;
}
return;
break;
case '\033':
case '\n':
case '\r':
clear_message_line();
return;
break;
}
}
}

get_char()
{
register int ch;
GETCH:
ch = getchar() & 0377;

if (message_line_filled)
{
clear_message_line();
}
switch (ch)
{
case '\014':
case '\022':
wrefresh(curscr);
goto GETCH;
break;
}
return (ch);
}

date_search()
{
register short ch;
short col, slash_count;
char buf[16];
int m, d, y;

STARTOVER:

mvaddstr(0, 0, "date: ");
buf[col = 0] = 0;
slash_count = 0;

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

switch (ch)
{
case '\b':
if (col > 0)
{
if (buf[col - 1] == '/')
{
slash_count--;
}
buf[--col] = 0;
mvaddch(0, col + 6, ' ');
move(0, col + 6);
}
break;
case '/':
if ((slash_count >= 2) || ((col > 0) && (buf[col - 1] == '/')) ||
(col == 0))
{
sound_bell();
} else
{
addch(ch);
buf[col++] = ch;
buf[col] = 0;
slash_count++;
}
break;
case '0':
if ((col == 0) || (buf[col - 1] == '/'))
{
goto GETCH;
} /* no break statement */
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();
goto GETCH;
} else
{
addch(ch);
buf[col++] = ch;
buf[col] = 0;
}
break;
case '\n':
case '\r':
if ((slash_count < 2) || (buf[col - 1] == '/'))
{
sound_bell();
goto GETCH;
} else
{
(void) sscanf(buf, "%d/%d/%d", &m, &d, &y);
if (y < 100)
{
y += 1900;
}
goto_this_day(m, d, y); /* no break statement! */
}
case '\033':
goto RET;
break;
case '\004':
case '\025':
case '\030':
clear_message_line();
goto STARTOVER;
break;
default:
goto GETCH;
break;
}
}
RET:
clear_message_line();
}

warn_day()
{
error_message("put cursor on day", 1);
}

get_input_line(prompt, buf)
char *prompt, *buf;
{
short col, i = 0, ch;

clear_message_line();
mvaddstr(0, 0, prompt);
col = strlen(prompt);
move(0, col);
refresh();

while (((ch = get_char()) != '\n') && (ch != '\r') && (ch != '\033'))
{
if ((ch > ' ') && (ch < '~'))
{
if ((i + col) <= 30)
{
buf[i++] = ch;
addch(ch);
refresh();
}
} else if (ch == '\b')
{
if (i > 0)
{
i--;
mvaddch(0, (col + i), ' ');
move(0, (col + i));
refresh();
}
}
}
buf[i] = 0;
clear_message_line();
if ((i == 0) || (ch == '\033'))
{
return (0);
}
return (1);
}
RiesES_PIECES
else
echo "will not over write ./user.c"
fi
echo "Finished archive 1 of 2"
exit 0

0 new messages