rsalz@uunet.uu.net (Rich Salz) (11/10/88)
Submitted-by: Michael Morrell <hplabs!hpda!morrell> Posting-number: Volume 16, Issue 55 Archive-name: month8.7/part02 # This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # This archive contains: # month.h month2.h month3.h month4.h # month5.h month6.h month7.h month8.h # get.c hl.c lunar.c month.c # move.c LANG=""; export LANG echo x - month.h cat >month.h <<'@EOF' /* * @(#)$Header: month.h,v 8.4 88/04/04 10:46:35 hull Exp $ */ #define USER_COL 40 /* first column of "User:" */ #define FLAG_COL 69 /* first column of flags */ #define MONTH_ROW 3 /* top row of month area */ #define CAL_ROW 3 /* top row of calendar area */ #define CAL_COL 13 /* leftmost column of calendar area */ #define DAY_ROW 1 /* row for list of days */ #define DAY_COL 12 /* first column of list of days */ #define YEAR_ROW 15 /* row for year list */ #define YEAR_COL 15 /* first column of year list */ #define SCHEDULE_ROW 17 /* top row of schedule area */ #define SMONTH_COL 0 /* first column of start month */ #define SDAY_COL 3 /* first column of start day */ #define SYEAR_COL 6 /* first column of start year */ #define PRIVATE_COL 12 /* first column of "priv" */ #define ANTI_COL 17 /* first column of "anti" */ #define MONTHLY_COL 22 /* first column of "monthly" */ #define YEARLY_COL 30 /* first column of "yearly" */ #define EVERY_COL 37 /* first column of "every" */ #define NTH_COL 43 /* first column of "Nth" */ #define LAST_COL 48 /* first column of "last" */ #define SMTWTFS_COL 53 /* first column of "SuMoTuWeThFrSa" */ #define UMONTH_COL 68 /* first column of until month */ #define UDAY_COL 71 /* first column of until day */ #define UYEAR_COL 74 /* first column of until year */ #define TIME_ROW 20 /* row for event times */ #define START_COL 3 /* first column of start time */ #define DURATION_COL 21 /* first column of duration */ #define END_COL 37 /* first column of end time */ #define WARNING_COL 53 /* first column of warning time */ #define OWNER_ROW 20 /* row for event owner */ #define OWNER_COL 68 /* first column for event owner */ #define DESCRIPTION_ROW 22 /* row for event description */ #define DESCRIPTION_COL 7 /* first column of event description */ #define START_MODE 'S' /* start time mode */ #define DURATION_MODE 'D' /* duration mode */ #define END_MODE 'E' /* end time mode */ #define ALIAS 'a' /* alias area */ #define MONTHS 'm' /* months area */ #define DAYS 'd' /* days area */ #define YEARS 'y' /* years area */ #define SCAN 'n' /* scan area */ #define SCHEDULE 's' /* schedule area */ #define SCHED_SCAN 'S' /* scan and schedule area */ #define BOOK 'B' /* book area */ #define HELP 'H' /* help area */ #define LUNAR 'L' /* lunar area */ #define FIRST_YEAR 1760 /* 1/1/1760 is the beginning of time */ #define LAST_YEAR 9999 /* 12/31/9999 is the end of time */ #define MAX_EVENT_STRING_LENGTH 70 /* maximum length of an event string */ #define MAX_ALIAS_LEVEL 16 /* maximum number of alias levels */ #define NOTHING 0 /* no change in event status */ #define ACCEPT 1 /* event was accepted */ #define CANCEL 2 /* event change was cancelled */ #define NO_BELL 0 /* print message with no bell */ #define BELL 1 /* print message with bell */ #define HL_OFF 0 /* print without highlighting */ #define HL_ON 1 /* print with highlighting */ #define READ_WRITE 0 /* open .month with read/write access */ #define READ_ONLY 1 /* open .month with read-only access */ #define NUM_MARKS 12 /* maximum number of marked dates */ #define SEMI_MARK (NUM_MARKS-2) /* special marked date for ";" */ #define CUR_MARK (NUM_MARKS-1) /* currently marked date */ #define BUFSIZE 40 /* size of temporary buffers */ #define MAXLINE 1024 /* maximum line length in alias file */ #define MAXAREAS 5 /* size of area stack */ #define current_area areas[area_ptr-1].area /* top of area stack */ /* shell used for shell escape */ /* environment variable "SHELL" if defined, else "SHELLPROG" */ extern char *getenv(); #define SH (getenv("SHELL") ? getenv("SHELL") : SHELLPROG) /* pager used for printing help file */ /* environment variable "PAGER" if defined, else "PAGERPROG" */ #define PG (getenv("PAGER") ? getenv("PAGER") : PAGERPROG) #if !SYS5CURSES #define attron(arg) standout() /* use standout for all highlighting */ #define attroff(arg) standend() #define A_CHARTEXT 0177 /* mask to strip attributes */ #endif #if !CVOID #define void int #endif extern char *malloc(); #if SYS5 extern void exit(), free(); #endif #ifdef hpux #define alarm_t unsigned long #else #define alarm_t unsigned #endif /* structure of an area */ struct area_rec { short area; short row; short col; }; /* structure of a date */ struct date_rec { short month; short day; short year; }; /* structure of a time */ struct time_rec { short hour; short minute; }; /* structure of an event pointer */ struct eptr_rec { struct event_rec *event; /* event */ struct eptr_rec *prev_event; /* previous event */ struct eptr_rec *next_event; /* next event */ }; /* structure of a name */ struct name_rec { char *name; /* name */ struct name_rec *next_name /* next name */ }; #include "month8.h" @EOF chmod 644 month.h echo x - month2.h cat >month2.h <<'@EOF' /* * @(#)$Header: month2.h,v 2.0 87/11/13 22:58:00 hull Exp $ */ struct event_rec2 { char event_month; /* month of the event */ char event_day; /* day of the event */ short event_year; /* year of the event */ char monthly; /* does event occur monthly? */ char yearly; /* does event occur yearly? */ char every; /* does event occur on every something? */ char smtwtfs[7]; /* which days of the week are relevant? */ char nth, last; /* does event occur on an nth or last something? */ char nth_is_on; /* is 'nth' selected by user, n is nth above */ char hour; /* hour of the event */ char minute; /* minute of the event */ char duration_hours; /* hours event lasts */ char duration_minutes; /* minutes event lasts, multiple of 15 */ char event_string[MAX_EVENT_STRING_LENGTH]; /* short description of event */ char private; /* is event private? */ struct event_rec2 *next_event; /* next event */ }; @EOF chmod 444 month2.h echo x - month3.h cat >month3.h <<'@EOF' /* * @(#)$Header: month3.h,v 3.0 87/11/13 22:58:40 hull Exp $ */ struct event_rec3 { char event_month; /* month of the event */ char event_day; /* day of the event */ short event_year; /* year of the event */ char monthly; /* does event occur monthly? */ char yearly; /* does event occur yearly? */ char every; /* does event occur on every something? */ char smtwtfs[7]; /* which days of the week are relevant? */ char nth, last; /* does event occur on an nth or last something? */ char nth_is_on; /* is 'nth' selected by user, n is nth above */ char hour; /* hour of the event */ char minute; /* minute of the event */ char duration_hours; /* hours event lasts */ char duration_minutes; /* minutes event lasts, multiple of 15 */ char event_string[MAX_EVENT_STRING_LENGTH]; /* short description of event */ char private; /* is event private? */ int event_owner; /* owner of event */ struct event_rec3 *next_event; /* next event */ }; @EOF chmod 444 month3.h echo x - month4.h cat >month4.h <<'@EOF' /* * @(#)$Header: month4.h,v 4.0 87/11/13 22:59:20 hull Exp $ */ struct event_rec4 { char start_month; /* starting month of the event */ char start_day; /* starting day of the event */ short start_year; /* starting year of the event */ char monthly; /* does event occur monthly? */ char yearly; /* does event occur yearly? */ char every; /* does event occur on every something? */ char smtwtfs[7]; /* which days of the week are relevant? */ char nth; /* does event occur on an nth something? */ char last; /* does event occur on a last something? */ char nth_is_on; /* is 'nth' selected by user, n is nth above */ char hour; /* hour of the event */ char minute; /* minute of the event */ char duration_hours; /* hours event lasts */ char duration_minutes; /* minutes event lasts */ char event_string[MAX_EVENT_STRING_LENGTH]; /* description of event */ char private; /* is event private? */ int event_owner; /* owner of event */ char until; /* does event occur until some date? */ char until_month; /* month event goes until */ char until_day; /* day event goes until */ short until_year; /* year event goes until */ struct event_rec4 *next_event; /* next event */ }; @EOF chmod 444 month4.h echo x - month5.h cat >month5.h <<'@EOF' /* * @(#)$Header: month5.h,v 5.0 87/11/13 22:59:48 hull Exp $ */ struct event_rec5 { char start_month; /* starting month of the event */ char start_day; /* starting day of the event */ short start_year; /* starting year of the event */ char monthly; /* does event occur monthly? */ char yearly; /* does event occur yearly? */ char every; /* does event occur on every something? */ char smtwtfs[7]; /* which days of the week are relevant? */ char nth; /* does event occur on an nth something? */ char last; /* does event occur on a last something? */ char nth_is_on; /* is 'nth' selected by user, n is nth above */ char hour; /* hour of the event */ char minute; /* minute of the event */ char duration_hours; /* hours event lasts */ char duration_minutes; /* minutes event lasts */ char warning_hours; /* hours of warning before event */ char warning_minutes; /* minutes of warning before event */ char event_string[MAX_EVENT_STRING_LENGTH]; /* description of event */ char private; /* is event private? */ int event_owner; /* owner of event */ char until; /* does event occur until some date? */ char until_month; /* month event goes until */ char until_day; /* day event goes until */ short until_year; /* year event goes until */ struct event_rec5 *next_event; /* next event */ }; @EOF chmod 444 month5.h echo x - month6.h cat >month6.h <<'@EOF' /* * @(#)$Header: month6.h,v 6.0 87/11/13 23:00:18 hull Exp $ */ struct event_rec6 { char start_month; /* starting month of the event */ char start_day; /* starting day of the event */ short start_year; /* starting year of the event */ char monthly; /* does event occur monthly? */ char yearly; /* does event occur yearly? */ char every; /* does event occur on every something? */ char smtwtfs[7]; /* which days of the week are relevant? */ char nth; /* does event occur on an nth something? */ char last; /* does event occur on a last something? */ char nth_is_on; /* is 'nth' selected by user, n is nth above */ char hour; /* hour of the event */ char minute; /* minute of the event */ char duration_hours; /* hours event lasts */ char duration_minutes; /* minutes event lasts */ char warning_hours; /* hours of warning before event */ char warning_minutes; /* minutes of warning before event */ char event_string[MAX_EVENT_STRING_LENGTH]; /* description of event */ char private; /* is event private? */ char anti; /* is this an anti-event? */ int event_owner; /* owner of event */ char until; /* does event occur until some date? */ char until_month; /* month event goes until */ char until_day; /* day event goes until */ short until_year; /* year event goes until */ struct event_rec6 *next_event; /* next event */ }; @EOF chmod 444 month6.h echo x - month7.h cat >month7.h <<'@EOF' /* * @(#)$Header: month7.h,v 7.0 87/11/13 23:01:04 hull Exp $ */ /* structure of an event */ struct event_rec7 { struct date_rec start_date; /* starting date of the event */ char monthly; /* does event occur monthly? */ char yearly; /* does event occur yearly? */ char every; /* does event occur on every something? */ char smtwtfs[7]; /* which days of the week are relevant? */ char nth; /* does event occur on an nth something? */ char last; /* does event occur on a last something? */ char nth_is_on; /* is 'nth' selected by user, n is nth above */ char hour; /* hour of the event */ char minute; /* minute of the event */ char duration_hours; /* hours event lasts */ char duration_minutes; /* minutes event lasts */ char warning_hours; /* hours of warning before event */ char warning_minutes; /* minutes of warning before event */ char event_string[MAX_EVENT_STRING_LENGTH]; /* description of event */ char private; /* is event private? */ char anti; /* is this an anti-event? */ int event_owner; /* owner of event */ char until; /* does event occur until some date? */ struct date_rec until_date; /* date event goes until */ struct event_rec7 *next_event; /* next event */ }; @EOF chmod 444 month7.h echo x - month8.h cat >month8.h <<'@EOF' /* * @(#)$Header: month8.h,v 8.0 87/11/13 22:50:14 hull Exp $ */ /* structure of an event */ struct event_rec { struct date_rec start_date; /* starting date of the event */ char monthly; /* does event occur monthly? */ char yearly; /* does event occur yearly? */ char every; /* does event occur on every something? */ char smtwtfs[7]; /* which days of the week are relevant? */ char nth; /* does event occur on an nth something? */ char last; /* does event occur on a last something? */ char nth_is_on; /* is 'nth' selected by user, n is nth above */ struct time_rec start_time; /* starting time of the event */ struct time_rec duration; /* duration of the event */ struct time_rec warning; /* warning of the event */ struct time_rec end_time; /* ending time of the event */ char event_string[MAX_EVENT_STRING_LENGTH]; /* description of event */ char private; /* is event private? */ char anti; /* is this an anti-event? */ int event_owner; /* owner of event */ char until; /* does event occur until some date? */ struct date_rec until_date; /* date event goes until */ struct event_rec *next_event; /* next event */ }; @EOF chmod 444 month8.h echo x - get.c cat >get.c <<'@EOF' #ifndef lint static char rcsid[] = "$Header: get.c,v 8.5 88/04/04 10:41:04 hull Exp $"; #endif #include <curses.h> #if SYS5 #include <string.h> #else #include <strings.h> #endif #include "month.h" extern short crow, ccol, area_ptr; extern short ins_mode, keep_old, my_file, read_only, event_status; extern short delchar, kilchar, update_schedule; extern int user_id; extern char *home_dir, *month_dir, *user_name; extern struct date_rec current_date; extern struct event_rec current_event; extern struct area_rec areas[]; get_description() { short i, pos, len, at_end; int ch; pos = len = strlen(current_event.event_string); crow = DESCRIPTION_ROW; for (;;) { at_end = (pos == len); ccol = DESCRIPTION_COL + pos; move(crow, ccol); refresh(); ch = get_char(); if ((ch >= ' ') && (ch <= '~')) if (ins_mode) { if (len < MAX_EVENT_STRING_LENGTH - 2) { #if SYS5CURSES insch((chtype) ch); #else insch((char) ch); #endif for (i = ++len; i > pos; i--) current_event.event_string[i] = current_event.event_string[i - 1]; current_event.event_string[pos++] = ch; } } else { if (pos < MAX_EVENT_STRING_LENGTH - 2) { addch(ch); current_event.event_string[pos++] = ch; if (at_end) current_event.event_string[++len] = '\0'; } } else switch(ch) { case '\001': /* ^A */ event_status = ACCEPT; return; case '\033': /* ^[ */ event_status = CANCEL; return; #if SYS5CURSES case KEY_UP: schedule_move_cursor('k'); return; case KEY_DOWN: #endif case '\n': schedule_move_cursor('\n'); return; case '\b': if (ins_mode) { if (pos > 0) { for (i = pos--; i <= len; i++) current_event.event_string[i - 1] = current_event.event_string[i]; len--; mvdelch(crow, ccol - 1); } } else if (pos > 0) { mvaddch(crow, ccol - 1, ' '); current_event.event_string[--pos] = ' '; if (at_end) current_event.event_string[--len] = '\0'; } break; case '\025': /* ^U */ current_event.event_string[pos = len = 0] = '\0'; move(crow, DESCRIPTION_COL); clrtoeol(); break; case '\027': /* ^W */ while ((pos > 0) && (current_event.event_string[pos - 1] == ' ')) pos--; while ((pos > 0) && (current_event.event_string[pos - 1] != ' ')) { current_event.event_string[--pos] = ' '; mvaddch(crow, DESCRIPTION_COL + pos, ' '); } if (at_end) current_event.event_string[len = pos] = '\0'; break; #if SYS5CURSES case KEY_IC: case KEY_EIC: #endif case '\t': /* ^I */ toggle_flag('I'); break; #if SYS5CURSES case KEY_LEFT: #endif case '\002': /* ^B */ if (pos > 0) pos--; break; #if SYS5CURSES case KEY_DC: #endif case '\004': /* ^D */ if (!at_end) { for (i = pos; i < len; i++) current_event.event_string[i] = current_event.event_string[i + 1]; len--; delch(); } break; #if SYS5CURSES case KEY_RIGHT: #endif case '\006': /* ^F */ if (pos < len) pos++; break; } } } get_npdeq(n_ok, p_ok, ed_ok) int n_ok, p_ok, ed_ok; { register ch; char buf[16]; sprintf(buf, "["); if (n_ok) strcat(buf, "n,"); if (p_ok) strcat(buf, "p,"); if (ed_ok) strcat(buf, "d,e,"); strcat(buf, "q] "); ccol = print_message(buf, NO_BELL); for (;;) { ch = get_char(); switch(ch) { case '\n': case 'n': if (n_ok) return('n'); else sound_bell(); break; case 'p': if (p_ok) return('p'); else sound_bell(); break; case 'd': if (ed_ok) { ccol = print_message("really delete? ", NO_BELL); ch = get_char(); if (ch == 'y') ccol = print_message("deleted", NO_BELL); else ccol = print_message("not deleted", NO_BELL); more(); if (ch == 'y') return('d'); else ccol = print_message(buf, NO_BELL); } else sound_bell(); break; case 'e': if (ed_ok) return('e'); else sound_bell(); break; case 'q': case '\033': /* ^[ */ return('q'); default: sound_bell(); } } } get_char() { register int ch; GETCH: ch = getch(); if (ch == delchar) /* convert user's delete char to \b */ ch = '\b'; else if (ch == kilchar) /* convert user's kill char to ^U */ ch = '\025'; switch(ch) { case '\005': /* ^E */ ch = '\033'; /* convert to ESC */ break; case '\r': ch = '\n'; break; case '\014': /* ^L */ case '\022': /* ^R */ wrefresh(curscr); goto GETCH; } #if SYS5CURSES if (crow != DESCRIPTION_ROW) switch(ch) { /* convert curses chars to normal chars */ case KEY_PPAGE: ch = 'p'; break; case KEY_NPAGE: ch = 'n'; break; case KEY_LEFT: ch = 'h'; break; case KEY_RIGHT: ch = 'l'; break; case KEY_UP: ch = 'k'; break; case KEY_DOWN: ch = 'j'; break; } #endif return(ch); } get_date(date, prompt) struct date_rec *date; char *prompt; { register short ch; short col, slash_count, newm, newd, newy; char buf[BUFSIZE]; int ret; void convert_year(); if (current_area == SCHEDULE) push_area(SCHED_SCAN); else push_area(SCAN); ccol = print_message(prompt, NO_BELL); col = 0; slash_count = 0; for (;;) { refresh(); ch = get_char(); switch(ch) { case '\b': if (col > 0) { if (buf[col - 1] == '/') { slash_count--; } --col; ccol--; mvaddch(0, ccol, ' '); move(0, ccol); } break; case '/': if ((slash_count >= 2) || (col == 0) || (buf[col-1] == '/')) sound_bell(); else { addch(ch); buf[col++] = ch; slash_count++; ccol++; } break; case '0': if ((col == 0) || (buf[col-1] == '/' && slash_count < 2)) break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if ( ((col == 2) && (buf[col-1] != '/')) || ((slash_count == 1)&&(buf[col-1] != '/')&&(buf[col-2] != '/'))|| ((slash_count == 2) && (buf[col-1] != '/') && (buf[col-2] != '/') && (buf[col-3] != '/') && (buf[col-4] != '/')) || ((col == 1) && ((ch > '2') || (buf[0] > '1'))) ) sound_bell(); else { addch(ch); buf[col++] = ch; ccol++; } break; case '\n': if ((slash_count == 0) || (buf[col-1] == '/')) sound_bell(); else { buf[col] = 0; ret = sscanf(buf, "%hd/%hd/%hd", &newm, &newd, &newy); if (ret == 3) convert_year(current_date.year, &newy); else newy = current_date.year; if (newy < FIRST_YEAR) sound_bell(); else { date->month = newm; date->day = newd; date->year = newy; clear_message_line(); pop_area(); return(1); } } break; case '\033': /* ^[ */ clear_message_line(); pop_area(); return(0); case '\025': /* ^U */ ccol = print_message(prompt, NO_BELL); col = 0; slash_count = 0; break; default: break; } } } #if MULTIUSER get_user() { short i = 0; char *new_dir, new_name[16], buf[BUFSIZE], *get_user_arg(); static char name[16]; push_area(SCAN); ccol = print_message("user: ", NO_BELL); crow = 0; if (get_string(new_name) == 0) { clear_message_line(); pop_area(); return; } if ((new_dir = get_user_arg(new_name)) != NULL) { if (update_schedule) ccol = print_message("updating schedule", NO_BELL); else ccol = print_message("schedule unchanged", NO_BELL); if (!read_only && write_schedule() < 0) { more(); ccol = print_message("cannot write .month", BELL); } if ((i = read_schedule(new_dir, read_only)) == -2) { more(); sprintf(buf, "%s's .month file locked", new_name); ccol = print_message(buf, BELL); i = read_schedule(new_dir, READ_ONLY); if (i == 0) read_only = 1; } if (i != 0) { more(); if (i == -1) sprintf(buf, "cannot open %s's .month", new_name); else sprintf(buf, "cannot read %s's .month version %d", new_name, i); ccol = print_message(buf, BELL); if ((i = read_schedule(month_dir, read_only)) == -2) { more(); ccol = print_message(".month file locked", BELL); i = read_schedule(month_dir, READ_ONLY); if (i == 0) read_only = 1; } if (i != 0) { more(); if (i == -1) ccol = print_message("cannot open .month", BELL); else { sprintf(buf, "cannot read .month version %d", i); ccol = print_message(buf, BELL); } } show_all_events(current_date.month, current_date.year); pop_area(); return; } keep_old = 1; month_dir = new_dir; my_file = (strcmp(home_dir, month_dir) == 0); strcpy(name, new_name); user_name = name; print_screen(); } else print_message("invalid user", BELL); pop_area(); } get_string(name) char name[]; { short ch, first_col, i = 0; first_col = ccol; crow = 0; ch = get_char(); for (;;) { if (ch == '\n') { name[i] = 0; break; } else if (ch > 0377) { ; } else if (ch == '\b') { if (ccol > first_col) { i--; ccol--; mvaddch(0, ccol, ' '); move(0, ccol); refresh(); } } else if (ch == '\025') { /* ^U */ while (ccol > first_col) { i--; ccol--; mvaddch(0, ccol, ' '); move(0, ccol); } refresh(); } else if (ch == '\033') { /* ^[ */ return(0); } else { name[i++] = ch; mvaddch(0, ccol++, ch); refresh(); } ch = get_char(); } return(1); } #endif MULTIUSER @EOF chmod 644 get.c echo x - hl.c cat >hl.c <<'@EOF' #ifndef lint static char rcsid[] = "$Header: hl.c,v 8.2 87/11/13 21:46:46 hull Exp $"; #endif #include <curses.h> #include "month.h" extern short all_flag; extern char *month_names[]; extern struct date_rec current_date, todays_date; hl_month(month, mflag) short month, mflag; { if (mflag == HL_ON) attron(A_REVERSE); mvaddstr(MONTH_ROW + month - 1, 0, month_names[month - 1]); if (mflag == HL_ON) attroff(A_REVERSE); } hl_day(day, dflag) short day, dflag; { short row, col; get_row_col_from_day(&row, &col, day); if (dflag == HL_ON) attron(A_REVERSE); if (current_date.month == todays_date.month && day == todays_date.day && current_date.year == todays_date.year) attron(A_UNDERLINE); if (all_flag && is_event_today()) mvprintw(row, col, "(%2d)", day); else mvprintw(row, col, " %2d ", day); attroff(A_REVERSE | A_UNDERLINE); } hl_year(year, yflag) short year, yflag; /* assumes year is currently displayed in year area */ { if (yflag == HL_ON) attron(A_REVERSE); move(YEAR_ROW, YEAR_COL + (6 * (year % 10))); printw(" %4d ", year); if (yflag == HL_ON) attroff(A_REVERSE); } hl_schedule(col, hflag) register col, hflag; { register int ch; short i; move(SCHEDULE_ROW, col); if (hflag) attron(A_BOLD); if (col < SMTWTFS_COL) { while((ch = (inch() & A_CHARTEXT)) != ' ') { move(SCHEDULE_ROW, col); addch(ch & A_CHARTEXT); col++; } } else if (col > SMTWTFS_COL+12) { move(SCHEDULE_ROW, col); for (i = 0; i < 10; i++) { addch((char) (inch() & A_CHARTEXT)); } } else { move(SCHEDULE_ROW, col); for (i = 0; i < 2; i++) { addch((char) (inch() & A_CHARTEXT)); } } attroff(A_BOLD); } hl_all(event, pf, af, mf, yf, ef, nf, lf, uf, xf) struct event_rec *event; register pf, af, mf, yf, ef, nf, lf, uf, xf; { short i; toggle_char(&(event->private), pf, PRIVATE_COL); toggle_char(&(event->anti), af, ANTI_COL); toggle_char(&(event->monthly), mf, MONTHLY_COL); toggle_char(&(event->yearly), yf, YEARLY_COL); toggle_char(&(event->every), ef, EVERY_COL); toggle_char(&(event->nth_is_on), nf, NTH_COL); toggle_char(&(event->last), lf, LAST_COL); toggle_char(&(event->until), uf, UMONTH_COL); if (xf != -1) { for (i = 0; i < 7; i++) { toggle_char(&(event->smtwtfs[i]), xf, (SMTWTFS_COL+(2*i))); } } } toggle_char(c, f, col) char *c; register f, col; { if (f == 1) { if (!(*c)) { *c = 1; hl_schedule(col, f); } } else if (f == 0) { if (*c) { *c = 0; hl_schedule(col, f); } } } @EOF chmod 644 hl.c echo x - lunar.c cat >lunar.c <<'@EOF' #ifndef lint static char rcsid[] = "$Header: lunar.c,v 8.2 87/11/13 21:46:58 hull Exp $"; #endif #include <curses.h> #include <math.h> #include <sys/types.h> /* Globals. */ double Fraction; #define CENTER ((COLS - 2 * LINES) / 2) #define BRIGHT '@' #define LEDGE '(' #define REDGE ')' #define FULL 0.5 #define TwoPi (2 * 3.14159) #define ZERO 0.03 long calculate(julian, yr, hour, minute) long julian, yr, hour, minute; { register long Length; register long Phase; register long Delta; register long offset; yr -= 78; Length = (double)2551 / 60 * 1000 + (double)443 / 60; offset = ((yr * 365L + julian) * 24L + hour) * 60L + minute; Delta = offset - (273L * 24L + 13L) * 60L + 23L; Phase = Delta - (Delta / Length) * Length; Fraction = (double)Phase / Length; return(Phase); } int charpos(x) double x; { register int i; i = x * LINES + 0.5; if ((i += LINES + CENTER) < 1) i = 1; return(i); } draw() { register char *p; register int i; register int end; register double y; register double cht; register double squisher; register double horizon; register double terminator; char Buffer[256]; int line = 1; /* clear screen */ clear(); if (Fraction < FULL) squisher = cos(TwoPi * Fraction); else squisher = cos(TwoPi * (Fraction - FULL)); cht = (double)2.0 / (LINES - 6.0); for (y = 0.93; y > -1.0; y -= cht) { for (i = sizeof Buffer, p = Buffer; --i >= 0; ) *p++ = ' '; horizon = sqrt(1.0 - y * y); Buffer[ charpos(-horizon)] = LEDGE; Buffer[i = charpos( horizon)] = REDGE; Buffer[++i] = '\0'; terminator = horizon * squisher; if (Fraction > ZERO && Fraction < (1.0 - ZERO)) { if (Fraction < FULL) { i = charpos( terminator); end = charpos( horizon); } else { i = charpos(-horizon); end = charpos( terminator); } while (i <= end) Buffer[i++] = BRIGHT; } mvaddstr(line++, 1, Buffer); } } @EOF chmod 644 lunar.c echo x - month.c cat >month.c <<'@EOF' #ifndef lint static char rcsid[] = "$Header: month.c,v 8.6 88/04/04 10:00:35 hull Exp $"; #endif /*********************************************************** * Month - Visual Monthly Calendar and Time/Event Browser * * Original Author: Tim Stoehn (zeus!tims) * "Book code" originally written by Scott Turner (srt@ucla-cs.ARPA) * Subsequent Modifications: Jim Hull (hull@hpda) and * Michael Morrell (morrell@hpda) * * ***********************************************************/ #include <curses.h> #include <signal.h> #if SYS5 #include <string.h> #else #include <strings.h> #endif #include <sys/types.h> #if FCNTL #include <fcntl.h> #else #include <sys/file.h> #endif #include <pwd.h> #include <ctype.h> #include "month.h" short initialized = 0; short date_flag = 0; short my_file = 1; short all_flag = 0; short ins_mode = 0; short keep_old = 0; short over_flag = 0; short read_only = READ_WRITE; short ver_flag = 0; short book = 0; short daemon = 0; short dint = 15; short dhour, dminute, dsecond; short delchar, kilchar; short days; short month_start; short event_status = NOTHING; short crow, ccol; short area_ptr = 0; char time_mode = END_MODE; char *home_dir = NULL; char *month_dir = NULL; char *user_name = NULL; char *prog_name; int user_id; struct date_rec current_date, todays_date; struct date_rec mdates[NUM_MARKS]; struct area_rec areas[MAXAREAS]; struct event_rec events = {{0, 0, 0}, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0}, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 0, 0, 0, 0, 0, {0, 0, 0}, 0}; extern short update_schedule, updating; extern struct event_rec events, current_event; extern struct passwd *getpwnam(); extern char *get_home_dir(); extern alarm_t alarm(); extern unsigned short getuid(); main(argc, argv) int argc; char *argv[]; { prog_name = argv[0]; user_id = (int) getuid(); home_dir = get_home_dir(user_id); if (get_todays_date() != 0) { printf("%s: Cannot get today's date\n", prog_name); exit(1); } check_env(); check_args(argc, argv); initialize(); print_screen(); (void) user(); terminate(); /* NOTREACHED */ } initialize() { int blast_out(), new_day(), /* stop(), */ i; #ifndef killchar char killchar(), erasechar(); #endif signal(SIGINT, blast_out); signal(SIGQUIT, blast_out); signal(SIGHUP, terminate); signal(SIGALRM, new_day); /* #ifdef SIGTSTP signal(SIGTSTP, stop); #endif */ if (!date_flag) { current_date.month = todays_date.month; current_date.day = todays_date.day; current_date.year = todays_date.year; } month_start = get_month_start(current_date.month, current_date.year); days = days_in(current_date.month, current_date.year); push_area(DAYS); for (i = 0; i < NUM_MARKS; i++) { mdates[i].month = current_date.month; mdates[i].day = current_date.day; mdates[i].year = current_date.year; } current_event.until_date.month = current_date.month; current_event.until_date.day = current_date.day; current_event.until_date.year = current_date.year; if ((i = read_schedule(month_dir, read_only)) == -2) { printf("%s: .month file locked\n", prog_name); sound_bell(); read_only = READ_ONLY; i = read_schedule(month_dir, read_only); } if (i == -1) { printf("%s: Cannot open .month\n", prog_name); sound_bell(); terminate(); } else if (i > 0) { printf("%s: Cannot read .month version %d\n", prog_name, i); sound_bell(); terminate(); } initscr(); crmode(); noecho(); #if SYS5CURSES keypad(stdscr, TRUE); #endif kilchar = (short) killchar(); delchar = (short) erasechar(); /* alarm call below should pop at midnight -- extra 2 seconds will * guarantee that it's really tomorrow. */ alarm((alarm_t) 86402 - (dhour * 3600 + dminute * 60 + dsecond)); /* for testing -- wake up every minute */ /* alarm((alarm_t) 62 - dsecond); */ initialized = 1; } new_day() { if (get_todays_date() != 0) { printf("%s: Cannot get today's date\n", prog_name); exit(1); } /* fprintf(stderr, "new_day: %d/%d/%d %d:%02d:%02d current_area=%c\n", todays_date.month, todays_date.day, todays_date.year, dhour, dminute, dsecond, (char) current_area); */ switch(current_area) { case MONTHS: case DAYS: case YEARS: case SCAN: case SCHED_SCAN: case SCHEDULE: show_all_events(current_date.month, current_date.year); move(crow, ccol); refresh(); break; } /* reset alarm for midnight tomorrow (plus 2 seconds) */ signal(SIGALRM, new_day); alarm((alarm_t) 86402 - (dhour * 3600 + dminute * 60 + dsecond)); /* for testing -- wake up every minute */ /* alarm((alarm_t) 62 - dsecond); */ } terminate() { if (updating) return; signal(SIGINT, SIG_IGN); #ifdef SIGTSTP signal(SIGTSTP, SIG_IGN); #endif #ifdef SIGTTOU signal(SIGTTOU, SIG_IGN); #endif signal(SIGQUIT, SIG_IGN); signal(SIGHUP, SIG_IGN); alarm((alarm_t) 0); if (initialized) { if (update_schedule) ccol = print_message("updating schedule", NO_BELL); else ccol = print_message("schedule unchanged", NO_BELL); if (!read_only && write_schedule() < 0) { more(); ccol = print_message("cannot write .month", BELL); } move(LINES-1, 0); clrtoeol(); refresh(); endwin(); } exit(0); /* NOTREACHED */ } blast_out() { update_schedule = 0; terminate(); } /* #ifdef SIGTSTP stop() { signal(SIGTSTP, SIG_DFL); signal(SIGINT, SIG_DFL); move(23,0); refresh(); resetterm(); kill(0, SIGTSTP); fixterm(); signal(SIGINT, blast_out); signal(SIGTSTP, stop); clearok(curscr, TRUE); refresh(); } #endif */ get_date_arg(arg) char *arg; { short month, day, year; int ret; void convert_year(); if (date_flag || daemon) return(1); if ((ret = sscanf(arg, "%hd/%hd/%hd", &month, &day, &year)) == 3) convert_year(todays_date.year, &year); else if (ret == 2) year = todays_date.year; else return(1); if (year < FIRST_YEAR || year > LAST_YEAR || month < 1 || month > 12 || day < 1 || day > days_in(month, year)) return(1); current_date.month = month; current_date.day = day; current_date.year = year; return(0); } #if MULTIUSER char * get_user_arg(arg) char *arg; { struct passwd *pw; if ((pw = getpwnam(arg)) == NULL) return(NULL); else return(strcpy(malloc((unsigned)strlen(pw->pw_dir)+1), pw->pw_dir)); } #endif MULTIUSER check_env() { char *month_env; if ((month_env = getenv("MONTH")) != NULL) while (*month_env) { switch(*month_env) { case 't': if (*(month_env+1) == 'S' || *(month_env+1) == 'D' || *(month_env+1) == 'E') time_mode = *(++month_env); else { printf("%s: Bad environment flag -- %c%c\n", prog_name, *month_env, *(month_env+1)); exit(1); } break; case 'A': all_flag = 1; break; case 'I': ins_mode = 1; break; case 'K': keep_old = 1; break; case 'O': over_flag = 1; break; case 'R': read_only = READ_ONLY; break; default: printf("%s: Bad environment flag -- %c\n", prog_name, *month_env); exit(1); } month_env++; } } check_args(argc, argv) int argc; char *argv[]; { short i, j; extern float get_version(); for (i = 1; i < argc; i++) { if (argv[i][0] == '-') { for (j = 1; j < strlen(argv[i]); j++) { switch(argv[i][j]) { case 'a': all_flag = 0; break; case 'i': ins_mode = 0; break; case 'k': keep_old = 0; break; case 'o': over_flag = 0; break; case 'r': read_only = READ_WRITE; break; case 'A': all_flag = 1; break; case 'I': ins_mode = 1; break; case 'K': keep_old = 1; break; case 'O': over_flag = 1; break; case 'R': read_only = READ_ONLY; break; case 'B': book = i; break; case 'V': ver_flag = i; break; case 'd': if (date_flag) goto BA; daemon = i; break; case 't': if (argv[i][j+1] == 'S' || argv[i][j+1] == 'D' || argv[i][j+1] == 'E') time_mode = argv[i][++j]; else goto BA; break; default: goto BA; } if (argv[i][j] == 'B' || argv[i][j] == 'V' || argv[i][j] == 'd') break; } } else if (get_date_arg(argv[i]) == 0) { date_flag = 1; #if MULTIUSER } else if ((month_dir = get_user_arg(argv[i])) != NULL) { my_file = 0; keep_old = 1; user_name = argv[i]; } else { BA: printf("%s: Bad argument -- %s\n", prog_name, argv[i]); printf("Usage: %s [-AaIiKkOoRr] [-{tS|tD|tE}] [-Bn] [-V] [-dn] [m/d/y] [user]\n", prog_name); #else } else { BA: printf("%s: Bad argument -- %s\n", prog_name, argv[i]); printf("Usage: %s [-AaIiKkOo] [-{tS|tD|tE}] [-Bn] [-V] [-dn] [m/d/y]\n", prog_name); #endif MULTIUSER exit(1); } } if (month_dir == NULL) month_dir = home_dir; if (ver_flag) printf("month version %-3.3g\n\n", get_version()); if (book) if (argv[book][2] == '\0') { if (print_book(1)) printf("%s: Cannot print schedule\n", prog_name); } else if (print_book(atoi(&argv[book][2]))) printf("%s: Cannot print schedule\n", prog_name); if (daemon) { if (isdigit(argv[daemon][2]) && (argv[daemon][2] > '0')) dint = atoi(&argv[daemon][2]); if (!fork()) { signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); #ifdef SIGTSTP signal(SIGTSTP, SIG_IGN); #endif #ifdef SIGTTOU signal(SIGTTOU, SIG_IGN); #endif daemonize(); } } if (ver_flag || book || daemon) exit(0); } daemonize() { char arg1[16]; printf("WARNING: The -d option of month has been superseded by the\n"); printf("monthd program. For now, month -d will automatically invoke\n"); printf("monthd, but future versions of month will not support -d.\n"); if (dint == 15) { printf("Invoking: monthd\n"); fflush(stdout); execlp("monthd", "monthd", 0); } else { sprintf(arg1, "-i%d", dint); printf("Invoking: monthd %s\n", arg1); fflush(stdout); execlp("monthd", "monthd", arg1, 0); } /* NOTREACHED */ } #if !SYS5CURSES #ifndef killchar #include <sgtty.h> char killchar() { struct sgttyb arg; ioctl(0, TIOCGETP, &arg); return(arg.sg_kill); } char erasechar() { struct sgttyb arg; ioctl(0, TIOCGETP, &arg); return(arg.sg_erase); } #endif #endif @EOF chmod 644 month.c echo x - move.c cat >move.c <<'@EOF' #ifndef lint static char rcsid[] = "$Header: move.c,v 8.3 88/04/04 10:47:39 hull Exp $"; #endif #include "month.h" extern char time_mode; extern short area_ptr; extern short crow, ccol, month_start, days; extern struct date_rec current_date; extern struct area_rec areas[]; goto_this_day(date) struct date_rec *date; { /* current_area assumed to be MONTHS, DAYS, or YEARS */ current_date.month = date->month; current_date.day = date->day; current_date.year = date->year; show_all_events(current_date.month, current_date.year); print_all_months(); print_all_years(); goto_area(); } pop_area() { if (area_ptr <= 0) { printf("area stack underflow\n"); blast_out(); } if (--area_ptr > 0) { crow = areas[area_ptr].row; ccol = areas[area_ptr].col; } } push_area(area) short area; { if (area_ptr >= MAXAREAS) { printf("area stack overflow\n"); blast_out(); } areas[area_ptr].row = crow; areas[area_ptr].col = ccol; areas[area_ptr++].area = area; goto_area(); } goto_area() { switch(current_area) { case MONTHS: goto_month(); break; case DAYS: goto_day(); break; case YEARS: goto_year(); break; case SCHEDULE: goto_schedule(); break; case SCAN: case SCHED_SCAN: goto_scan(); break; } } goto_month() { crow = MONTH_ROW + current_date.month - 1; ccol = 9; } goto_day() { get_row_col_from_day(&crow, &ccol, current_date.day); ccol += 2; } goto_year() { /* assumes the current year is displayed in YEARS area */ crow = YEAR_ROW; ccol = YEAR_COL + 4 + (6 * (current_date.year % 10)); } goto_schedule() { crow = SCHEDULE_ROW; ccol = PRIVATE_COL; } goto_scan() { crow = 0; ccol = 0; } move_cursor(dir) register short dir; { switch(current_area) { case MONTHS: switch(dir) { case 'j': if (crow < MONTH_ROW + 11) crow++; else crow = MONTH_ROW; break; case 'k': if (crow > MONTH_ROW) crow--; else crow = MONTH_ROW + 11; break; } break; case YEARS: switch(dir) { case 'h': if (ccol == YEAR_COL + 4) ccol = YEAR_COL + 58; else ccol -= 6; break; case 'l': if (ccol == YEAR_COL + 58) ccol = YEAR_COL + 4; else ccol += 6; break; } break; case DAYS: switch(dir) { case 'h': ccol -= 10; if (get_day_from_row_col(crow, ccol) == 0) ccol = CAL_COL + 62; while (get_day_from_row_col(crow, ccol) == 0) ccol -= 10; break; case 'j': crow += 2; if (get_day_from_row_col(crow, ccol) == 0) crow = CAL_ROW; while (get_day_from_row_col(crow, ccol) == 0) crow += 2; break; case 'k': crow -= 2; if (get_day_from_row_col(crow, ccol) == 0) crow = CAL_ROW + 10; while (get_day_from_row_col(crow, ccol) == 0) crow -= 2; break; case 'l': ccol += 10; if (get_day_from_row_col(crow, ccol) == 0) ccol = CAL_COL + 2; while (get_day_from_row_col(crow, ccol) == 0) ccol += 10; break; } break; case SCHEDULE: schedule_move_cursor(dir); break; } } schedule_move_cursor(dir) short dir; { short inc, *cols; static short schedule_cols[] = { UYEAR_COL, SMONTH_COL, SDAY_COL, SYEAR_COL, PRIVATE_COL, ANTI_COL, MONTHLY_COL, YEARLY_COL, EVERY_COL, NTH_COL, LAST_COL, SMTWTFS_COL, SMTWTFS_COL+2, SMTWTFS_COL+4, SMTWTFS_COL+6, SMTWTFS_COL+8, SMTWTFS_COL+10, SMTWTFS_COL+12, UMONTH_COL, UDAY_COL, UYEAR_COL, SMONTH_COL }; static short start_mode_cols[] = { WARNING_COL+3, DURATION_COL, DURATION_COL+3, END_COL, END_COL+3, WARNING_COL, WARNING_COL+3, DURATION_COL }; static short duration_mode_cols[] = { WARNING_COL+3, START_COL, START_COL+3, END_COL, END_COL+3, WARNING_COL, WARNING_COL+3, START_COL }; static short end_mode_cols[] = { WARNING_COL+3, START_COL, START_COL+3, DURATION_COL, DURATION_COL+3, WARNING_COL, WARNING_COL+3, START_COL }; switch(dir) { case 'h': case 'l': inc = (dir == 'h') ? -1 : 1; if (crow == SCHEDULE_ROW) { cols = schedule_cols; while (*(++cols) != ccol) ; ccol = *(cols+inc); } else if (crow == TIME_ROW) { switch(time_mode) { case START_MODE: cols = start_mode_cols; break; case DURATION_MODE: cols = duration_mode_cols; break; case END_MODE: cols = end_mode_cols; break; } while (*(++cols) != ccol) ; ccol = *(cols+inc); } break; case '\n': case 'j': switch(crow) { case SCHEDULE_ROW: crow = TIME_ROW; switch(time_mode) { case START_MODE: ccol = DURATION_COL; break; default: ccol = START_COL; break; } break; case TIME_ROW: get_description(); break; case DESCRIPTION_ROW: crow = SCHEDULE_ROW; ccol = PRIVATE_COL; break; } break; case 'k': switch(crow) { case SCHEDULE_ROW: get_description(); break; case TIME_ROW: crow = SCHEDULE_ROW; ccol = PRIVATE_COL; break; case DESCRIPTION_ROW: crow = TIME_ROW; switch(time_mode) { case START_MODE: ccol = DURATION_COL; break; default: ccol = START_COL; break; } break; default: crow--; break; } break; case '\033': /* ^[ */ pop_area(); break; } } get_row_col_from_day(row, col, day) short *row, *col, day; { *row = CAL_ROW + (((month_start + day - 1) / 7) * 2); *col = CAL_COL + (((month_start + day - 1) % 7) * 10); } get_day_from_row_col(row, col) short row, col; { short mday; if (row < CAL_ROW || row > CAL_ROW + 10 || col < CAL_COL + 2 || col > CAL_COL + 62) return(0); mday = (7 * ((row - CAL_ROW)) / 2) + ((col - CAL_COL) / 10) - month_start + 1; if ((mday <= days) && (mday > 0)) return(mday); return(0); } @EOF chmod 644 move.c exit 0 -- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.