home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume16
/
month8.7
/
part04
< prev
next >
Wrap
Text File
|
1988-11-08
|
21KB
|
893 lines
Subject: v16i057: A visual calendar and appointment system, Part04/06
Newsgroups: comp.sources.unix
Sender: sources
Approved: rsalz@uunet.UU.NET
Submitted-by: Michael Morrell <hplabs!hpda!morrell>
Posting-number: Volume 16, Issue 57
Archive-name: month8.7/part04
# This is a shell archive. Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
# This archive contains:
# days_in.c event_today.c get_home.c get_month.c
# get_today.c hidden.c how_many.c is_future.c
# is_leap.c is_past.c jan1.c matches.c
# read_sched.c write_sched.c version.c
LANG=""; export LANG
echo x - days_in.c
cat >days_in.c <<'@EOF'
#ifndef lint
static char rcsid[] = "$Header: days_in.c,v 8.2 87/11/13 21:46:25 hull Exp $";
#endif
days_in(month, year)
short month, year;
{
switch(month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
return(31);
case 4:
case 6:
case 9:
case 11:
return(30);
case 2:
return(28 + is_leap_year(year));
}
/* NOTREACHED */
}
@EOF
chmod 644 days_in.c
echo x - event_today.c
cat >event_today.c <<'@EOF'
#ifndef lint
static char rcsid[] = "$Header: event_today.,v 8.2 87/11/13 21:46:29 hull Exp $";
#endif
#include "month.h"
extern struct date_rec current_date;
extern short my_file;
extern int user_id;
event_today(event)
register struct event_rec *event;
{
/* returns 1 if event is visible on the current day, 0 if not */
/* check if this in an anti-event */
if (event->anti)
return(0);
/* check if the file belongs to this user, the event is private,
and the user id does not match the event owner */
if (!my_file && event->private && (user_id != event->event_owner))
return(0);
/* check if event matches the current date */
if (!event_matches_date(event, ¤t_date))
return(0);
/* check if event hidden by anti-event */
if (event_hidden(event, ¤t_date))
return(0);
return(1);
}
@EOF
chmod 644 event_today.c
echo x - get_home.c
cat >get_home.c <<'@EOF'
#ifndef lint
static char rcsid[] = "$Header: get_home.c,v 1.1 87/12/02 18:07:19 hull Exp $";
#endif
#include <pwd.h>
extern char *malloc();
char *
get_home_dir(uid)
int uid;
{
struct passwd *pw;
char *strcpy();
int strlen();
if ((pw = getpwuid(uid)) == (struct passwd *)0)
return((char *)0);
else
return(strcpy(malloc((unsigned)strlen(pw->pw_dir)+1), pw->pw_dir));
}
@EOF
chmod 644 get_home.c
echo x - get_month.c
cat >get_month.c <<'@EOF'
#ifndef lint
static char rcsid[] = "$Header: get_month.c,v 8.2 87/11/13 21:46:38 hull Exp $";
#endif
get_month_start(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);
}
@EOF
chmod 644 get_month.c
echo x - get_today.c
cat >get_today.c <<'@EOF'
#ifndef lint
static char rcsid[] = "$Header: get_today.c,v 8.3 88/04/04 09:58:17 hull Exp $";
#endif
#if SYS5
#include <time.h>
#else
#include <sys/time.h>
#endif
#include "month.h"
extern struct date_rec todays_date;
extern short dhour, dminute, dsecond;
get_todays_date()
{
#if SYS5
long tloc, time();
#else
struct timeval tp;
struct timezone tzp;
#endif
struct tm *tmp;
#if SYS5
if (time(&tloc) == -1)
return(-1);
tmp = localtime(&tloc);
#else
if (gettimeofday(&tp, &tzp) != 0)
return(-1);
tmp = localtime((long *) &tp.tv_sec);
#endif
todays_date.month = tmp->tm_mon + 1;
todays_date.day = tmp->tm_mday;
todays_date.year = 1900 + tmp->tm_year;
/* random values for testing */
/*
todays_date.month = random(12) + 1;
todays_date.day = random(29) + 1;
todays_date.year = 1900 + random(100);
*/
dhour = tmp->tm_hour;
dminute = tmp->tm_min;
dsecond = tmp->tm_sec;
return(0);
}
/* for testing */
/*
random(m)
int m;
{
long lrand48();
return ((int) (lrand48() % m));
}
*/
@EOF
chmod 644 get_today.c
echo x - hidden.c
cat >hidden.c <<'@EOF'
#ifndef lint
static char rcsid[] = "$Header: hidden.c,v 8.2 87/11/13 21:46:43 hull Exp $";
#endif
#include "month.h"
extern struct event_rec events;
event_hidden(event, date)
register struct event_rec *event;
register struct date_rec *date;
{
/* returns 1 if event hidden by anti-event on date, 0 if not */
register struct event_rec *ptr;
extern unsigned short file_owner;
extern int strcmp();
ptr = events.next_event;
while (ptr) {
if (ptr->anti &&
(ptr->start_time.hour == event->start_time.hour) &&
(ptr->start_time.minute == event->start_time.minute) &&
(ptr->duration.hour == event->duration.hour) &&
(ptr->duration.minute == event->duration.minute) &&
(ptr->warning.hour == event->warning.hour) &&
(ptr->warning.minute == event->warning.minute) &&
(strcmp(ptr->event_string, event->event_string) == 0) &&
((ptr->event_owner == event->event_owner) ||
(ptr->event_owner == file_owner)) &&
event_matches_date(ptr, date))
return(1);
ptr = ptr->next_event;
}
return(0);
}
@EOF
chmod 644 hidden.c
echo x - how_many.c
cat >how_many.c <<'@EOF'
#ifndef lint
static char rcsid[] = "$Header: how_many.c,v 8.2 87/11/13 21:46:48 hull Exp $";
#endif
#include "month.h"
how_many_since(edate, cdate)
struct date_rec *edate, *cdate;
{
register total_days_passed;
short i;
if (edate->year < cdate->year) {
total_days_passed = 0;
for (i = edate->month; i <= 12; i++)
total_days_passed += days_in(i, edate->year);
total_days_passed -= (edate->day - 1);
for (i = (edate->year + 1); i < cdate->year; i++)
total_days_passed += (365 + is_leap_year(i));
for (i = 1; i < cdate->month; i++)
total_days_passed += days_in(i, cdate->year);
total_days_passed += cdate->day;
} else if (edate->month == cdate->month)
total_days_passed = cdate->day - edate->day + 1;
else {
total_days_passed = 1 - edate->day;
for (i = edate->month; i < cdate->month; i++)
total_days_passed += days_in(i, cdate->year);
total_days_passed += cdate->day;
}
return(((total_days_passed - 1) / 7) + 1);
}
@EOF
chmod 644 how_many.c
echo x - is_future.c
cat >is_future.c <<'@EOF'
#ifndef lint
static char rcsid[] = "$Header: is_future.c,v 8.2 87/11/13 21:46:50 hull Exp $";
#endif
#include "month.h"
is_future_event(event, date)
struct event_rec *event;
struct date_rec *date;
{
if (date->year < event->start_date.year)
return(1);
if (date->year > event->start_date.year)
return(0);
if (date->month < event->start_date.month)
return(1);
if (date->month > event->start_date.month)
return(0);
if (date->day < event->start_date.day)
return(1);
return(0);
}
@EOF
chmod 644 is_future.c
echo x - is_leap.c
cat >is_leap.c <<'@EOF'
#ifndef lint
static char rcsid[] = "$Header: is_leap.c,v 8.2 87/11/13 21:46:52 hull Exp $";
#endif
is_leap_year(year)
int year;
{
return((((jan1(year + 1) + 7 - jan1(year)) % 7) == 2) ? 1 : 0);
}
@EOF
chmod 644 is_leap.c
echo x - is_past.c
cat >is_past.c <<'@EOF'
#ifndef lint
static char rcsid[] = "$Header: is_past.c,v 8.2 87/11/13 21:46:54 hull Exp $";
#endif
#include "month.h"
is_past_event(event, date)
struct event_rec *event;
struct date_rec *date;
{
register end_month, end_day, end_year;
if (!event->until && (event->monthly || event->yearly || event->every))
return(0);
if (event->until) {
end_month = event->until_date.month;
end_day = event->until_date.day;
end_year = event->until_date.year;
} else {
end_month = event->start_date.month;
end_day = event->start_date.day;
end_year = event->start_date.year;
}
if (end_year > date->year)
return(0);
if (end_year < date->year)
return(1);
if (end_month > date->month)
return(0);
if (end_month < date->month)
return(1);
if (end_day < date->day)
return(1);
return(0);
}
@EOF
chmod 644 is_past.c
echo x - jan1.c
cat >jan1.c <<'@EOF'
#ifndef lint
static char rcsid[] = "$Header: jan1.c,v 8.2 87/11/13 21:46:55 hull Exp $";
#endif
jan1(year)
register year;
{
register day;
day = year + (year + 3) / 4;
if (year > 1800) {
day -= (year - 1701) / 100;
day += (year - 1601) / 400;
}
if (year > 4000)
day -= year / 4000;
return(day % 7);
}
@EOF
chmod 644 jan1.c
echo x - matches.c
cat >matches.c <<'@EOF'
#ifndef lint
static char rcsid[] = "$Header: matches.c,v 8.2 87/11/13 21:47:00 hull Exp $";
#endif
#include "month.h"
#define nth_smtwtfs_of_month(date) (((date->day - 1) / 7) + 1)
#define last_smtwtfs_of_month(date) \
((date->day + 7) > days_in(date->month, date->year) ? 1 : 0)
event_matches_date(event, date)
register struct event_rec *event;
register struct date_rec *date;
{
/* returns 1 if event matches date, 0 if not */
short mnth_start;
int n;
/* check if event is a future or past event */
if (is_future_event(event, date) ||
is_past_event(event, date))
return(0);
/* one time events must match date */
if ((event->start_date.year == date->year) &&
(event->start_date.month == date->month) &&
(event->start_date.day == date->day) && !event->every &&
!event->nth_is_on && !event->last && !event->until) {
return(1);
}
/* once monthly or once yearly events */
if (!event->every && !event->nth_is_on && !event->last) {
if (event->monthly) {
if (event->start_date.day == date->day)
return(1);
} else if (event->yearly) {
if ((event->start_date.month == date->month) &&
(event->start_date.day == date->day))
return(1);
}
}
mnth_start = get_month_start(date->month, date->year);
if (!event->smtwtfs[(date->day - 1 + mnth_start) % 7])
return(0);
/* everys */
if (event->every) {
/* every smtwtfs */
if (!event->nth_is_on && !event->last) {
EVDAY: if (event->smtwtfs[(date->day - 1 + mnth_start) % 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 1st2nd3rd... */
if (event->nth_is_on) {
if (event->monthly && (nth_smtwtfs_of_month(date)
== event->nth))
return(1);
if (event->yearly && (nth_smtwtfs_of_year(date)
== event->nth))
return(1);
}
/* every monthly/yearly with last */
if (event->last) {
if (event->monthly) {
if (last_smtwtfs_of_month(date))
return(1);
}
if (event->yearly) {
if (last_smtwtfs_of_year(date))
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->start_date, date);
if ((n % event->nth) == 1)
return(1);
}
}
return(0);
}
nth_smtwtfs_of_year(date)
struct date_rec *date;
{
short dys, i;
for (i = 1, dys = date->day; i < date->month; i++) {
dys += days_in(i, date->year);
}
return(((dys - 1) / 7) + 1);
}
last_smtwtfs_of_year(date)
struct date_rec *date;
{
short dys, i;
for (i = 1, dys = date->day; i < date->month; i++) {
dys += days_in(i, date->year);
}
return((dys + 7) > (365 + is_leap_year(date->year)) ? 1 : 0);
}
@EOF
chmod 644 matches.c
echo x - read_sched.c
cat >read_sched.c <<'@EOF'
#ifndef lint
static char rcsid[] = "$Header: read_sched.c,v 8.4 88/04/04 11:00:49 hull Exp $";
#endif
#include <sys/types.h>
#include <sys/stat.h>
#if LOCKF
#include <fcntl.h>
#include <unistd.h>
#endif LOCKF
#if FLOCK
#include <sys/file.h>
#endif FLOCK
#include "month.h"
extern unsigned short file_owner;
extern int fd;
extern struct event_rec events;
read_schedule(m_dir, read_mode)
char *m_dir;
short read_mode;
{
char *schedule_file_name;
unsigned rec_size;
struct stat stat_buf;
short file_version;
struct event_rec event_buf, *event_ptr, *chain_ptr;
extern float get_version();
extern char *strcat(), *strcpy();
schedule_file_name = malloc((unsigned) strlen(m_dir)+8);
strcpy(schedule_file_name, m_dir);
strcat(schedule_file_name, "/.month");
rec_size = sizeof(struct event_rec);
umask(0);
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 MULTIUSER
if (read_mode == READ_ONLY)
fd = open(schedule_file_name, O_RDONLY);
else {
if ((fd = open(schedule_file_name, O_RDWR|O_CREAT, 0660)) != -1)
#if LOCKF
if (lockf(fd, F_TLOCK, 0L) == -1) {
close(fd);
fd = -2;
return(-2);
}
#else
#if FLOCK
if (flock(fd, LOCK_EX | LOCK_NB) == -1) {
close(fd);
fd = -2;
return(-2);
}
#endif FLOCK
#endif LOCKF
}
#else
fd = open(schedule_file_name, O_RDWR|O_CREAT, 0660);
#endif MULTIUSER
free(schedule_file_name);
if (fd != -1) {
if (read(fd, (char *) &file_version, sizeof(file_version))
== sizeof(file_version)) {
if (file_version != (int) get_version()) {
close(fd);
fd = -1;
return(file_version);
}
} else { /* no version field so assume empty file */
if (read_mode == READ_ONLY) {
close(fd);
fd = -1;
}
return(0);
}
chain_ptr = &events;
while (read(fd, &event_buf, rec_size) == rec_size) {
if (event_ptr = (struct event_rec *)malloc(rec_size)) {
chain_ptr->next_event = event_ptr;
chain_ptr = event_ptr;
*chain_ptr = event_buf;
chain_ptr->next_event = (struct event_rec *)0;
} else
break;
}
fstat(fd, &stat_buf);
file_owner = stat_buf.st_uid;
if (read_mode == READ_ONLY) {
close(fd);
fd = -1;
}
return(0);
}
/* if here, open failed */
return(-1);
}
@EOF
chmod 644 read_sched.c
echo x - write_sched.c
cat >write_sched.c <<'@EOF'
#ifndef lint
static char rcsid[] = "$Header: write_sched.,v 8.3 87/12/01 23:40:05 hull Exp $";
#endif
#include "month.h"
extern short updating, update_schedule, keep_old;
extern int fd;
extern off_type lseek();
extern struct date_rec todays_date;
extern struct event_rec events;
write_schedule()
{
short file_version;
struct event_rec *chain_ptr;
float get_version();
if (fd < 0) /* file not really open */
return(fd);
if (!update_schedule) {
close(fd);
return(0);
}
updating = 1;
file_version = (int) get_version();
if (lseek(fd, (off_type) 0, 0) == -1) {
close(fd);
return(-1);
}
#if !SYS5
if (ftruncate(fd, (off_type) 0) == -1) {
close(fd);
return(-1);
}
#endif
write(fd, (char *) &file_version, sizeof(short));
chain_ptr = events.next_event;
while (chain_ptr) {
if (keep_old || !is_past_event(chain_ptr, &todays_date))
write(fd, (char *)chain_ptr, sizeof(struct event_rec));
else
delete_event(chain_ptr);
chain_ptr = chain_ptr->next_event;
}
close(fd); /* also releases lock */
update_schedule = updating = 0;
return(0);
}
@EOF
chmod 644 write_sched.c
echo x - version.c
cat >version.c <<'@EOF'
#ifndef lint
static char rcsid[] = "$Header: version.c,v 8.7 88/06/03 22:35:16 hull Exp $";
#endif
/* $Log: version.c,v $
* Revision 8.7 88/06/03 22:35:16 22:35:16 hull (James Hull)
* Changed year_area display to always display "whole" decades.
* Changed semantics of 2-digit year entry.
* Fixed screen-memory-file consistency bug.
*
* Revision 8.6 88/04/04 11:17:12 11:17:12 hull (James Hull)
* Added alarm calls and new_day function so today's date is updated.
* Fixed bug so that 'R' command updates schedule display.
* Various other bug fixes and code clean-ups.
*
* Revision 8.5 88/01/15 10:48:52 10:48:52 hull (James Hull)
* Fixed bug by only calling write_schedule if not in read-only mode.
*
* Revision 8.4 87/12/02 18:49:50 18:49:50 hull (James Hull)
* Moved get_home_dir() out of month.c, monthd.c, and xmonthd.c to a separate file.
* Deleted some unnecessary include files from month.c, monthd.c, xmonthd.c.
*
* Revision 8.3 87/12/01 23:50:22 23:50:22 hull (James Hull)
* Fixed bug in read_schedule which caused monthd to mysteriously die.
* Problem was caused by never closing the file descriptor and eventually
* reaching the open file descriptor limit imposed by the operating system.
*
* Revision 8.2 87/11/13 21:25:07 21:25:07 hull (James Hull)
* Fixed 'd', 'm', 'y' bug which allowed exit from schedule area.
* Fixed user_name bug in 'U' and 'G' commands.
* Added 'a' (print aliases) command.
* Added ',' to list of allowed name separators.
* Fixed security hole in 'a' and 'H' commands.
*
* Revision 8.1 87/11/13 21:24:26 21:24:26 hull (James Hull)
* Added environment flag and command line option for time mode.
* Added 't' (change time mode) command in schedule area.
*
* Revision 8.0 87/11/13 21:21:37 21:21:37 hull (James Hull)
* Added ending time to event_rec structure.
* Changed "monthd", print_sched, print_book to use ending time.
* Changed format of schedule_area.
* Changed all event_rec times to use time_rec structure.
* Cleaned up do_incr and scroll_time so 'n' and 'p' consistent.
* Fixed digit counting bug in enter_number.
* Cleaned up code to "beep" for even more invalid keys.
* Changed "monthd" to use process group to determine user logout.
* Merged write_schedule into "common.a".
*
* Revision 7.7 87/11/13 21:21:06 21:21:06 hull (James Hull)
* Added global alias file for 'G' command.
*
* Revision 7.6 87/11/13 21:20:16 21:20:16 hull (James Hull)
* Changed get_npdeq to only show appropriate keys.
* Cleaned up code to "beep" for most invalid keys.
*
* Revision 7.5 87/11/13 21:19:39 21:19:39 hull (James Hull)
* Split daemon into separate "monthd" program.
* Created "common.a" library.
*
* Revision 7.4 87/11/13 21:18:37 21:18:37 hull (James Hull)
* Changed "goto mark" command from 'G' to '''.
* Added 'G' (group post) command.
* Minor fixes to push_area, pop_area, more, clear_message_line.
*
* Revision 7.3 87/11/13 21:16:35 21:16:35 morrell (Michael Morrell)
* Added 'p' (previous) to 'E' command; now identical to 'S'.
* Fixed security hole in shell escape.
* Added '-O' option and changed 'O' command to track date.
* Cleaned up code to make lint happy.
*
* Revision 7.2 87/11/13 21:15:59 21:15:59 hull (James Hull)
* Added current date to print_sched.
* Added special case for printing zero-length events.
*
* Revision 7.1 87/11/13 21:15:21 21:15:21 hull (James Hull)
* Fixed cursor initialization bug.
*
* Revision 7.0 87/11/13 21:13:09 21:13:09 hull (James Hull)
* Changed functions and event_rec to use date structure.
* Added push/pop ara functions to fix cursor positioning bug.
* Added cursor wraparound in months, days, and years areas.
* Added '!' (shell escape) command.
* Added 'e' (event editing) to 'E' command.
* Added 'W' (write schedule) command.
*
* Revision 6.1 87/11/13 21:12:38 21:12:38 hull (James Hull)
* Fixed next/previous bug in month area when changing years.
*
* Revision 6.0 87/11/13 21:11:55 21:11:55 hull (James Hull)
* Added anti-events.
* Fixed boundary conditions for dates.
* Fixed get_date bug which trashed month, day, year.
*
* Revision 5.3 87/11/13 21:09:22 21:09:22 hull (James Hull)
* '?', 'C', and 'P' commands check area.
* Fixed 'In' printf bug in remind.
* Cleaned up hl_month_year.
* Added hl_day and day selection (this_day underlined).
* Removed warn_day and added return to m, d, or y area.
* Split display.c into hl.c, move.c, print.c, user2.c.
* Added 'a', 'i', 'k', and 'r' command-line options.
* Added border around days area.
* Cleaned up code to make lint happy.
*
* Revision 5.2 87/11/13 21:07:34 21:07:34 hull (James Hull)
* Added MONTH environment variable.
* Fixed memory problem in get_home_dir & get_user_arg.
* Removed many temp print buffers by using mvprintw.
* Changed several numeric constants to named constants.
* Added event description editing and insert-mode flag.
*
* Revision 5.0 87/11/13 21:06:16 21:06:16 hull (James Hull)
* Added warning time to events.
* Made year optional in '/' command and on command line.
* Added '?' (help) command and file.
*
* Revision 4.0 87/11/13 21:05:43 21:05:43 hull (James Hull)
* Added until date to events.
* Replaced Accept/Cancel with ^A.
*
* Revision 3.0 87/11/13 21:04:14 21:04:14 hull (James Hull)
* Added owner to events allowing multi-user access.
* Added read-only flag and '-R' flag.
* Added version values to .month file and month program.
* Wrote chmonth to update .month files to new versions.
*
* Revision 2.0 87/11/13 21:03:22 21:03:22 hull (James Hull)
* Added private flag to events.
* Added direct entry of hours and minutes.
* Added curses keypad input.
*
* Revision 1.0 87/11/13 21:00:40 21:00:40 hull (James Hull)
* Initial revision
*
*/
/*
The integer portion of version changes when the event structure changes.
The fractional portion changes for everything else.
*/
float
get_version()
{
float version;
(void) sscanf("$Revision: 8.7 $", "%*s%f", &version);
return(version);
}
@EOF
chmod 644 version.c
exit 0