tims@zeus.UUCP (Tim Stoehr) (05/09/86)
I got a report of a couple bugs which are fixed in the files included herein. Pardon the redundancy as this is being posted to both net.sources and mod.sources. This is for the 'month' program I recently posted. #!/bin/sh-----cut here-----cut here-----cut here-----cut here----- # shar: Shell Archiver # Run the following text with /bin/sh to create: # display.c # month.c # schedule.c echo shar: extracting display.c cat - << \SHAR_EOF > display.c #include <curses.h> #include "month.h" short days; short crow, ccol; short current_area; short message_line_filled; char *blankout = " "; extern short SCHEDULE_ROW, SKID_ROW; char *days_of_week = "Sunday Monday Tuesday Wednesday Thursday Friday Saturday"; short schedule_cols[] = { 0, SMONTH_COL, SDAY_COL, SYEAR_COL, MONTHLY_COL, YEARLY_COL, EVERY_COL, NTH_COL, LAST_COL, SMTWTFS_COL, SMTWTFS_COL+3, SMTWTFS_COL+6, SMTWTFS_COL+9, SMTWTFS_COL+12, SMTWTFS_COL+15, SMTWTFS_COL+18, -1 }; char *month_names[] = { " ", "JANUARY ", "FEBRUARY ", "MARCH ", "APRIL ", "MAY ", "JUNE ", "JULY ", "AUGUST ", "SEPTEMBER", "OCTOBER ", "NOVEMBER ", "DECEMBER " , " " }; char *smtwtfs_names[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", }; extern short month, day, year, start_day, edit_flag; extern short this_month, this_day, this_year; extern struct event_rec current_event; short first_year; print_screen() { print_month(month); print_year(year); print_day_headers(); print_cal(month, year, 0); print_all_months(); print_all_years(year); hl_month_year(month, 1, year, 1); } print_month(month) int month; { mvaddstr(0, 35, month_names[month]); } print_year(year) int year; { char nbuf[8]; sprintf(nbuf, "%4d", year); mvaddstr(0, 47, nbuf); } print_day_headers() { mvaddstr(2, 12, days_of_week); } print_cal(month, year, all_events_list) register month, year; char *all_events_list; { short i, month_is_current, cday; short row = 4, col = 13, standing_out = 0; char nbuf[6]; start_day = get_start_day(month, year); days = days_in(month, year); if (day > days) { day = days; } else if (day < 1) { day = 1; } month_is_current = ((month == this_month) && (year == this_year)); for (i = 1, cday = 1; i <= 42; i++) { if ((cday <= days) && (i >= (start_day + 1))) { if (all_events_list && all_events_list[cday]) { sprintf(nbuf, "(%2d)", cday); } else { sprintf(nbuf, " %2d ", cday); } cday++; } else { strcpy(nbuf, " "); } if (month_is_current && ((cday-1) == this_day)) { standout(); standing_out = 1; month_is_current = 0; } mvaddstr(row, col, nbuf); if (standing_out) { standing_out = 0; standend(); } if ((i % 7) == 0) { row += 2; col = 13; } else { col += 10; } } } print_all_months() { short i; standout(); for (i = 0; i <= 13; i++) { mvaddstr(TOP_MONTH_ROW + i, 0, month_names[i]); } standend(); } print_all_years(year) int year; { short i; char nbuf[8]; first_year = year - 4; standout(); move(YEAR_ROW, YEAR_COL); addstr("<<"); for (i = first_year; i < (first_year + 10); i++) { sprintf(nbuf, " %4d ", i); addstr(nbuf); } addstr(">>"); standend(); } hl_month_year(month, mflag, year, yflag) short month, mflag, year, yflag; { short i; if (mflag != -1) { if (!mflag) { standout(); } mvaddstr(TOP_MONTH_ROW + month, 0, month_names[month]); if (!mflag) { standend(); } } if (yflag != -1) { if (!yflag) { standout(); } move(YEAR_ROW, 14 + (6 * (year - first_year))); for (i = 0; i < 6; i++) { addch(inch()); } if (!yflag) { standend(); } } } start_display() { goto_day(day); } goto_this_day(gmonth, gday, gyear) int gmonth, gday, gyear; { month = gmonth; year = gyear; day = gday; print_screen(); switch(current_area) { case MONTHS: goto_month(month); break; case DAYS: goto_day(day); break; case YEARS: goto_year(year); break; } } goto_month(month) int month; { crow = TOP_MONTH_ROW + month; ccol = 9; current_area = MONTHS; } goto_day(tday) short tday; { day = tday; get_row_col_from_day(&crow, &ccol, day); current_area = DAYS; } goto_year(year) int year; { crow = YEAR_ROW; ccol = YEAR_COL + 3 + (6 * (year - first_year)); current_area = YEARS; } goto_schedule() { current_area = SCHEDULE; crow = SKID_ROW; ccol = MONTHLY_COL; } move_cursor(dir) register short dir; { short mday, row, col; if ((current_area != SCHEDULE) && ((dir == 'm') || (dir == 'y') || (dir == 'd'))) { if (dir == 'm') { goto_month(month); } else if (dir == 'y') { goto_year(year); } else { goto_day(day); } return; } switch (current_area) { case MONTHS: switch(dir) { case 'j': if (crow <= (TOP_MONTH_ROW + 12)) { crow++; } break; case 'k': if (crow > TOP_MONTH_ROW) { crow--; } break; } break; case YEARS: switch(dir) { case 'h': if (ccol > YEAR_COL) { if (ccol == (YEAR_COL + 3)) { ccol = YEAR_COL; } else { ccol -= 6; } } else { shift_years(-1); } break; case 'l': if (ccol < LAST_YEAR_COL) { if (ccol == (LAST_YEAR_COL - 6)) { ccol = LAST_YEAR_COL; } else if (ccol == YEAR_COL) { ccol = YEAR_COL + 3; } else { ccol += 6; } } else { shift_years(1); } break; } break; case DAYS: row = crow; col = ccol; switch(dir) { case 'h': if (col > 15) { col -= 10; } break; case 'j': if (row < 14) { row += 2; } break; case 'k': if (row > 4) { row -= 2; } break; case 'l': if (col < 74 ) { col += 10; } break; } if ((mday = get_day_from_row_col(row, col)) > 0) { day = mday; crow = row; ccol = col; } break; case SCHEDULE: schedule_move_cursor(dir); break; } } schedule_move_cursor(dir) short dir; { short i; switch(dir) { case 'H': if (crow == SKID_ROW) { ccol = DATE_COL; } break; case 'L': if (crow == SKID_ROW) { ccol = SMTWTFS_COL + 18; } break; case 'h': case 'l': if (crow == SKID_ROW) { i = 0; while (schedule_cols[++i] != ccol) ; i += ((dir == 'h') ? -1 : 1); if (schedule_cols[i] != -1) { ccol = schedule_cols[i]; } } else if ((crow == TIME_ROW) || (crow == DURATION_ROW)) { ccol = (dir == 'h') ? TIME_COL : MINUTE_COL; } else if (crow == ACCEPT_ROW) { ccol = (dir == 'h') ? ACCEPT_COL : CANCEL_COL; } break; case '\t': case '\n': case '\r': if (crow == SKID_ROW) { crow += 2; ccol = TIME_COL; } else if (crow == DESCRIPTION_ROW) { crow = ACCEPT_ROW; ccol = ACCEPT_COL; } else if (crow == ACCEPT_ROW) { crow = SKID_ROW; ccol = MONTHLY_COL; } else if (crow == DURATION_ROW) { crow = DESCRIPTION_ROW; ccol = TIME_COL + strlen(current_event.event_string); handle_event_description(); } else { crow++; } break; case '\033': goto_day(day); break; } } selection() { short new_year; int x; switch(current_area) { case MONTHS: if ((crow - TOP_MONTH_ROW) != month) { if (crow <= TOP_MONTH_ROW) { hl_month_year(month, 0, 0, -1); month = 12; shift_years(-1); hl_month_year(month, 1, 0, -1); crow = TOP_MONTH_ROW + 13; } else if (crow > (TOP_MONTH_ROW + 12)) { hl_month_year(month, 0, 0, -1); month = 1; shift_years(1); hl_month_year(month, 1, 0, -1); crow = TOP_MONTH_ROW; } else { hl_month_year(month, 0, 0, -1); month = crow - TOP_MONTH_ROW; hl_month_year(month, 1, 0, -1); print_cal(month, year, 0); } print_month(month); } break; case YEARS: if (ccol == YEAR_COL) { shift_years(-10); } else if (ccol == LAST_YEAR_COL) { shift_years(10); } else { new_year = first_year + ((ccol - (YEAR_COL + 3)) / 6); if (new_year != year) { hl_month_year(0, -1, year, 0); year = new_year; } print_cal_hl_year(month, year); } break; case SCHEDULE: if (crow == SKID_ROW) { select_regularity_col(ccol); } else if (crow == ACCEPT_ROW) { x = (ccol == ACCEPT_COL) ? ACCEPT : CANCEL; accept_cancel(ccol == ACCEPT_COL); if (edit_flag) { return(x); } } else { move_cursor('\t'); } break; } return(NOTHING); } shift_years(shift) short shift; { if (((year + shift) < (first_year + 10)) && ((year + shift) >= first_year)) { hl_month_year(0, -1, year, 0); year += shift; hl_month_year(0, -1, year, 1); } else { year += shift; print_all_years(first_year + shift + 4); } print_cal_hl_year(month, year); } print_cal_hl_year(month, year) int month, year; { print_cal(month, year, 0); print_year(year); hl_month_year(0, -1, year, 1); } get_row_col_from_day(row, col, day) short *row, *col, day; { *row = 4 + (((start_day + day - 1) / 7) * 2); *col = 15 + (((start_day + day - 1) % 7) * 10); } get_day_from_row_col(row, col) short row, col; { short mday; mday = (7 * ((row - 4)) / 2) + ((col - 14) / 10) - start_day + 1; if ((mday <= days) && (mday > 0)) { return(mday); } return(0); } print_event_regularity(event) struct event_rec *event; { if (event->monthly) { standout(); } mvaddstr(SKID_ROW, MONTHLY_COL, "monthly"); standend(); if (event->yearly) { standout(); } mvaddstr(SKID_ROW, YEARLY_COL, "yearly"); standend(); if (event->every) { standout(); } mvaddstr(SKID_ROW, EVERY_COL, "every"); standend(); print_smtwtfs(event->smtwtfs); print_nth(event); if (event->last) { standout(); } mvaddstr(SKID_ROW, LAST_COL, "last"); standend(); } print_smtwtfs(smtwtfs) char smtwtfs[]; { short i; char *s; move(SKID_ROW, SMTWTFS_COL); for (i = 0; i < 7; i++) { if (smtwtfs[i]) { standout(); } addstr(smtwtfs_names[i]); if (smtwtfs[i]) { standend(); } } } hl_schedule(col, hflag) register col, hflag; { register int ch; short i; move(SKID_ROW, col); if (hflag) { standout(); } if ((col < SMTWTFS_COL) || (col > (SMTWTFS_COL+18))) { while((ch = inch()) != ' ') { move(SKID_ROW, col); addch(ch); col++; } } else { move(SKID_ROW, col); for (i = 0; i < 3; i++) { addch(inch()); } } standend(); } display_event(event) struct event_rec *event; { clear_schedule_area(); print_date(event->event_month, event->event_day, event->event_year); print_event_regularity(event); print_time(event); print_duration(event); print_event_description(event); print_accept(); } print_accept() { mvaddstr(ACCEPT_ROW, TIME_COL, "Accept/Cancel"); } print_time(event) struct event_rec *event; { char buf[32]; short hour; char *apm; hour = event->hour; apm = (hour < 12) ? "AM" : "PM"; if (hour > 12) { hour = hour % 12; } if (hour == 0) { hour = 12; } sprintf(buf, "time: %2d:%02d %s", hour, event->minute, apm); mvaddstr(TIME_ROW, 4, buf); } print_duration(event) struct event_rec *event; { char buf[32]; sprintf(buf, "duration: %2d:%02d", event->duration_hours, event->duration_minutes); mvaddstr(DURATION_ROW, 0, buf); } print_event_description(event) struct event_rec *event; { char buf[100]; sprintf(buf, "event: %s", event->event_string); mvaddstr(DESCRIPTION_ROW, 3, buf); } scroll_time(dir) register dir; { short hour, minute, d; if (crow == TIME_ROW) { hour = current_event.hour; minute = current_event.minute; } else if (crow == DURATION_ROW) { hour = current_event.duration_hours; minute = current_event.duration_minutes; } else if (crow != SKID_ROW) { return; } if (ccol == TIME_COL) { if (dir == ' ') { hour = (hour + 1) % 24; } else { hour = (hour + 23) % 24; } } else if (ccol == MINUTE_COL) { if (dir == ' ') { minute = (minute + 15) % 60; } else { minute = (minute + 45) % 60; } } else { if (ccol == SMONTH_COL) { current_event.event_month += ((dir == ' ') ? 1 : -1); if (current_event.event_month > 12) { current_event.event_month = 1; } else if (current_event.event_month <= 0) { current_event.event_month = 12; } } else if (ccol == SDAY_COL) { d = days_in(current_event.event_month, current_event.event_year); current_event.event_day += ((dir == ' ') ? 1 : -1); if (current_event.event_day > d) { current_event.event_day = 1; } else if (current_event.event_day <= 0) { current_event.event_day = d; } } else if (ccol == SYEAR_COL) { current_event.event_year += ((dir == ' ') ? 1 : -1); if (current_event.event_year < 0) { current_event.event_year = this_year; } } else if (ccol == NTH_COL) { current_event.nth += ((dir == ' ') ? 1 : -1); if (current_event.nth < 1) { current_event.nth = 53; } else if (current_event.nth > 53) { current_event.nth = 1; } } } if (crow == TIME_ROW) { current_event.hour = hour; current_event.minute = minute; print_time(¤t_event); } else if (crow == DURATION_ROW) { current_event.duration_hours = hour; current_event.duration_minutes = minute; print_duration(¤t_event); } else if (ccol <= SYEAR_COL) { print_date(current_event.event_month, current_event.event_day, current_event.event_year); } else if (ccol == NTH_COL) { current_event.nth_is_on = 1; print_nth(¤t_event); } } hl_all(event, mf, yf, ef, nf, lf, xf) struct event_rec *event; register mf, yf, ef, nf, lf, xf; { short i; 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); if (xf != -1) { for (i = 0; i < 7; i++) { toggle_char(&(event->smtwtfs[i]), xf, (SMTWTFS_COL+(3*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) { if (*c) { *c = 0; hl_schedule(col, f); } } } print_date(month, day, year) int month, day, year; { char buf[64]; standout(); sprintf(buf, "%2d/%2d/%4d", month, day, year); mvaddstr(SKID_ROW, DATE_COL, buf); standend(); } error_message(str, sound) char *str; int sound; { mvaddstr(0, 0, blankout); mvaddstr(0, 0, str); refresh(); if (sound) { sound_bell(); } message_line_filled = 1; } sound_bell() { putchar(7); fflush(stdout); } clear_schedule_area() { move(SCHEDULE_ROW, 0); clrtobot(); } blank_out(col) int col; { while (col < 35) { addch(' '); col++; } } print_nth(event) struct event_rec *event; { char *ns, buf[10]; short n; if (event->nth_is_on) { standout(); } n = event->nth; if (event->nth > 13) { n %= 10; } switch(n) { case 0: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: ns = "th"; break; case 1: ns = "st"; break; case 2: ns = "nd"; break; case 3: ns = "rd"; break; } sprintf(buf, "%02d%s", event->nth, ns); mvaddstr(SKID_ROW, NTH_COL, buf); standend(); } remind(str, minutes) char *str; int minutes; { char s[50]; if (minutes > 1) { sprintf(s, "In %d minutes", minutes); } else if (minutes == 1) { strcpy(s, "In 1 minute"); } else { strcpy(s, "Right now"); } printf("\n%s \n%s. \n", str, s); sound_bell(); } clear_message_line() { message_line_filled = 0; mvaddstr(0, 0, blankout); } incr(ch) int ch; { short inc; inc = ((ch == 'n') || (ch == '+')) ? 1 : -1; switch (current_area) { case MONTHS: hl_month_year(month, 0, 0, -1); if ((month == 1) && (inc < 0)) { shift_years(-1); month = 12; } else if ((month == 12) && (inc > 0)) { shift_years(1); month = 1; } else { month += inc; } hl_month_year(month, 1, 0, -1); print_month(month); goto_month(month); print_cal(month, year, 0); break; case DAYS: if (((inc > 0) && (day < days)) || ((inc < 0) && (day > 1))) { goto_day(day + inc); } break; case YEARS: shift_years(inc); goto_year(year); break; } } SHAR_EOF echo shar: extracting month.c cat - << \SHAR_EOF > month.c #include <curses.h> #include <signal.h> #include <utmp.h> #include "month.h" short initialized = 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[]; main(argc, argv) int argc; char *argv[]; { check_args(argc, argv); initialize(); print_screen(); start_display(); user(); terminate(); } initialize() { int blast_out(), i; signal(SIGINT, blast_out); 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; initialized = 1; crmode(); noecho(); } terminate() { if (updating) { return; } signal(SIGINT, SIG_IGN); signal(SIGTSTP, SIG_IGN); signal(SIGQUIT, SIG_IGN); signal(SIGHUP, SIG_IGN); if (initialized) { 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(); } check_args(argc, argv) int argc; char *argv[]; { short i, daemon = 0; for (i = 1; i < argc; i++) { if (argv[i][0] == '-') { switch(argv[i][1]) { case 'd': daemon = i; break; default: goto BA; } } else { BA: printf("Bad argument: %s\n", argv[i]); terminate(); } } if (daemon) { if (!fork()) { signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); signal(SIGTSTP, SIG_IGN); daemonize(); } exit(0); } } daemonize() { int do_nothing(); struct event_rec *eptr; short minutes, eminutes, diff, seconds; printf("daemon started\n"); fflush(stdout); AGAIN: get_current_date(); minutes = (60 * dhour) + dminute; seconds = (60 * (15 - (dminute % 15) - 1)) + (60 - dsecond); if (seconds < 60) { seconds = 900; } signal(SIGALRM, do_nothing); 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, &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(&u_buf, &t_buf, sizeof(struct utmp))) { close(fd); retval = 1; break; } } 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); } SHAR_EOF echo shar: extracting schedule.c cat - << \SHAR_EOF > schedule.c #include <curses.h> #include "month.h" 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; 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(¤t_event); } read_schedule() { char *getenv(), *malloc(), *s; int fd, rec_size; struct event_rec event_buf, *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(event_ptr); } events.next_event = 0; if (!(s = getenv("HOME"))) { s = "."; } strcpy(schedule_file_name, s); strcat(schedule_file_name, "/.month"); rec_size = sizeof(struct event_rec); if ((fd = open(schedule_file_name, 0)) != -1) { 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; } } 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)) { write(fd, (char *)chain_ptr, sizeof(struct event_rec)); } chain_ptr = chain_ptr->next_event; } close(fd); updating = 0; return(0); } select_regularity_col(col) register col; { short i, hflag; switch(col) { case MONTHLY_COL: hl_all(¤t_event, (current_event.monthly ? 0 : 1), 0, -1, -1, -1, -1); break; case YEARLY_COL: hl_all(¤t_event, 0, (current_event.yearly ? 0 : 1), -1, -1, -1, -1); break; case EVERY_COL: hl_all(¤t_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(¤t_event, -1, -1, -1, -1, -1, -1); break; case NTH_COL: hl_all(¤t_event, -1, -1, -1, (current_event.nth_is_on ? 0 : 1), -1, -1); break; case LAST_COL: hl_all(¤t_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(¤t_event); } goto_day(day); } accept_current_event() { if ((parse_event(¤t_event) != -1)) { if (get_answer("Put into schedule? ", "done", "change cancelled") == 'y') { if (!edit_flag) { link_event(¤t_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; char *malloc(); 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, duration, n; struct event_rec *events_today[MAX_DAILY_EVENTS]; char *grid; get_daily_events(events_today); clear_schedule_area(); for (i = 0; i < 4; i++) { mvaddstr((SCHEDULE_ROW + i + i), 1, grids[i]); } standout(); i = 0; while (events_today[i]) { hour = events_today[i]->hour; minute = events_today[i]->minute; row = SCHEDULE_ROW + ((hour / 6) * 2); if (row > (LINES - 1)) { break; } duration = (events_today[i]->duration_hours * 60) + events_today[i]->duration_minutes; col = 1 + (12 * (hour % 6)) + (3 * (minute / 15)); n = hour / 6; grid = grids[n]; duration /= 15; move(row, col); for (j = 0; j < duration; 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(events_today) struct event_rec *events_today[]; { short i = 0; struct event_rec *eptr; eptr = events.next_event; while (eptr && (i < (MAX_DAILY_EVENTS - 1))) { if (event_matches_date(eptr)) { if (!events_today) { return(1); } events_today[i++] = eptr; } eptr = eptr->next_event; } if (events_today) { events_today[i] = 0; } return(i); } scan_today_events() { struct event_rec *events_today[MAX_DAILY_EVENTS]; short i, j, k, ch, n; if ((n = get_daily_events(events_today)) <= 0) { error_message("No events this day", 0); clear_schedule_area(); return; } sort_events(events_today, n); for (i = 0; i < n; i++) { current_event = *events_today[i]; display_event(events_today[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) && (!events_today[j])) { j++; } if (j >= n) { /*sound_bell(); goto GETCH;*/ goto OUT; } i = j - 1; break; case 'p': j = i - 1; while ((j >= 0) && (!events_today[j])) { j--; } if (j < 0) { sound_bell(); goto GETCH; } i = j - 1; break; case 'd': delete_event(events_today[i]); events_today[i] = 0; for (k = i+1; k < n; k++) { if (events_today[k] != 0) { i = k; break; } } if (events_today[i] == 0) { for (k = i-1; k >= 0; k--) { if (events_today[k] != 0) { i = k; break; } } } if (events_today[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) { *events_today[i] = current_event; update_schedule++; } else if (!parsed_correctly) { goto EDIT; } } else { display_event(events_today[i]); } edit_flag = 0; i--; break; } } OUT: goto_day(day); } scan_every_event() { register short ch; struct event_rec *ptr; ptr = events.next_event; while (ptr) { current_event = *ptr; display_event(ptr); ch = get_nq(); switch(ch) { case 'n': ptr = ptr->next_event; break; case 'q': goto RET; break; } } RET: ; } 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)) { match_list[i] = 1; break; } eptr = eptr->next_event; } } day = tday; print_cal(month, year, match_list); } SHAR_EOF