home *** CD-ROM | disk | FTP | other *** search
- /*
- * $Header: cal2ct.c,v 2.1 89/05/09 14:18:41 billr Exp $
- */
- /*
- * cal2ct - convert calendar reminder files to calentool style files
- *
- * Author: Bill Randle, Tektronix, Inc. <billr@saab.CNA.TEK.COM>
- *
- * Copyright (C) 1989 Tektronix, Inc. All Rights Reserved
- *
- * Permission is hereby granted to use and modify this code in source
- * or binary form as long as it is not sold for profit and this copyright
- * notice remains intact.
- */
-
- #include "ct.h"
- #include <stdio.h>
- #include <ctype.h>
- #include <sys/time.h>
-
- struct appt_entry appts, *aptr;
- char filename[128], *file;
- FILE *fp;
- struct tm current, today, *localtime();
- struct timeval tp;
-
- extern char *getenv();
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- if (argc > 1)
- file = argv[1];
- else {
- strcpy(filename, getenv("HOME"));
- strcat(filename, "/calendar");
- file = filename;
- }
-
- if ((fp = fopen(file, "r")) == NULL) {
- fprintf(stderr, "can't open calendar file for reading\n");
- exit(1);
- }
- gettimeofday(&tp, NULL);
- today = *localtime(&tp.tv_sec);
- if (!read_cal_file()) {
- fprintf(stderr, "no reminders read from %s\n", file);
- exit(1);
- }
- fclose(fp);
- strcpy(filename, getenv("HOME"));
- strcat(filename, "/.appointments");
- if ((fp = fopen(filename, "w")) == NULL) {
- fprintf(stderr, "can't open .appointments file for writing\n");
- exit(1);
- }
- write_ct_file();
- }
-
- /*
- * read dates from calendar file and stuff into appts struct
- */
- read_cal_file()
- {
- char *fgets();
- char buf[512];
- struct appt_entry *optr;
-
- aptr = &appts;
- while (fgets(buf, 512, fp) != NULL) {
- aptr->repeat = aptr->lookahead = 0;
- aptr->flags = A_NOTE;
- aptr->next = NULL;
- if (!parse_date(buf))
- return(1);
- aptr->next = (struct appt_entry *)malloc(sizeof(struct appt_entry));
- if (aptr->next == NULL) {
- fprintf(stderr, "out of memory\n");
- return;
- }
- optr = aptr;
- aptr = aptr->next;
- }
- if (aptr == &appts)
- return(0); /* nothing read */
- /* don't need the last one */
- free(aptr);
- optr->next = NULL;
- return(1);
- }
-
- /*
- * write out the new .appointments file
- */
- write_ct_file()
- {
- aptr = &appts;
- fputs(HEADER, fp);
- while (aptr) {
- if (put_aentry(fp, aptr)) {
- fprintf(stderr, "error writing .appointments file\n");
- return;
- }
- aptr = aptr->next;
- }
- }
-
- char *dayname[7] = {"SU", "MO", "TU", "WE", "TH", "FR", "SA"};
- char *monthname[12] = {"JAN", "FEB", "MAR", "APR", "MAY", "JUN",
- "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"};
-
- /*
- * parse the date on the command line and reset the "current"
- * date to reflect that date. The date may take the form of a
- * day name (e.g. Tu, Tue, Tuesday) or a date in m/d/y format
- * where the month and/or year may be missing (e.g. 27 = 27th
- * of this month, 8/27 = August 27 of this year, 8/27/89 =
- * August 27 of 1989. month may also be a string (e.g. "Dec"
- * or "december") or a '*' (all months).
- */
- parse_date(str)
- char *str;
- {
- char c[4];
- int i, dow = -1, mon = -1, m = -1, d = -1;
-
- current = today; /* start with this month, day, year */
- while (isspace(*str))
- ++str;
-
- if (isdigit(*str)) {
- /* must be a m/d date */
- /* assume it's a month first */
- m = *str++ - '0';
- if (isdigit(*str))
- m = m*10 + *str++ - '0';
- if (*str != '/') {
- /* no more chars => day only */
- d = m;
- m = -1;
- } else {
- ++str;
- while (isspace(*str))
- ++str;
- if (isdigit(*str)) {
- d = *str++ - '0';
- if (isdigit(*str))
- d = d*10 + *str++ - '0';
- } else {
- fprintf(stderr, "badly formed date: %s\n", str-2);
- return(0);
- }
- }
- if (m > 0)
- current.tm_mon = m - 1;
- if (d > 0)
- current.tm_mday = d;
- } else if (*str == '*') {
- aptr->flags |= ALL_MONTHS;
- ++str;
- while (isspace(*str) || *str == '/')
- ++str;
- d = *str++ - '0';
- if (isdigit(*str))
- d = d*10 + *str++ - '0';
- current.tm_mday = d;
- } else {
- /* day of week or month name */
- /* check for day names */
- c[0] = islower(*str) ? toupper(*str) : *str;
- ++str;
- c[1] = islower(*str) ? toupper(*str) : *str;
- if (*++str) {
- c[2] = islower(*str) ? toupper(*str) : *str;
- c[3] = '\0';
- } else
- c[2] = '\0';
- while (!isspace(*str))
- ++str;
- /* check month names */
- for (i=0; i<12; i++) {
- if (!strcmp(c, monthname[i])) {
- mon = i;
- break;;
- }
- }
- if (mon >= 0) {
- /* match found */
- current.tm_mon = mon;
- while (!isspace(*str))
- ++str;
- d = *++str - '0';
- ++str;
- if (isdigit(*str))
- d = d*10 + *str++ - '0';
- current.tm_mday = d;
- } else {
- /* check day names */
- c[2] = '\0';
- for (i=0; i<7; i++) {
- if (!strcmp(c, dayname[i])) {
- dow = i;
- break;
- }
- }
- if (dow >= 0) {
- /* match found */
- current.tm_mday += dow - current.tm_wday;
- fix_current_day();
- } else
- fprintf(stderr, "badly formed date: %s\n", str-2);
- }
- }
- while (isspace(*str))
- ++str;
- strcpy(aptr->str, str);
- aptr->year = current.tm_year;
- aptr->month = current.tm_mon;
- aptr->day = current.tm_mday;
- return(1);
- }
-
- /*
- * Reset some values in current tm structure. Year, month and
- * day-of-month are valid but day and/or month may be < 0 or
- * greater than the maximum value, in which case they are adjusted
- * accordingly. Day-of-year and day-of-week are then recalculated.
- */
- fix_current_day()
- {
- int month, totdays = 0;
- struct tm from, to;
-
- if (current.tm_mon < JAN) {
- current.tm_mon = DEC;
- current.tm_year--;
- } else if (current.tm_mon > DEC) {
- current.tm_mon = JAN;
- current.tm_year++;
- }
- if (current.tm_mday < 1) {
- current.tm_mon--;
- if (current.tm_mon < JAN) {
- current.tm_mon = DEC;
- current.tm_year--;
- }
- current.tm_mday += monthlength(current.tm_mon);
- } else if (current.tm_mday > monthlength(current.tm_mon)) {
- current.tm_mday -= monthlength(current.tm_mon);
- current.tm_mon++;
- if (current.tm_mon > DEC) {
- current.tm_mon = JAN;
- current.tm_year++;
- }
- }
- current.tm_yday = current.tm_mday - 1;
- for (month = 0; month < current.tm_mon; month++) {
- current.tm_yday += monthlength(month);
- }
- if ((current.tm_year < today.tm_year)
- || ((current.tm_year == today.tm_year)
- && (current.tm_yday < today.tm_yday))) {
- from = current;
- to = today;
- } else {
- from = today;
- to = current;
- }
- if (from.tm_year != to.tm_year) {
- for (totdays = 0; from.tm_year < to.tm_year; from.tm_year++)
- totdays += dysize(from.tm_year + 1900);
- }
- totdays += to.tm_yday - from.tm_yday;
- if ((current.tm_year < today.tm_year)
- || ((current.tm_year == today.tm_year)
- && (current.tm_yday < today.tm_yday)))
- totdays = -totdays;
- current.tm_wday =
- ((totdays % 7) + 7 + today.tm_wday) % 7;
- }
-
- int
- monthlength(month)
- int month;
- {
- static int monthlengths[] = {31,28,31,30,31,30,31,31,30,31,30,31};
-
- if (month == FEB && (dysize(current.tm_year + 1900) == 366))
- return(29);
- else
- return(monthlengths[month]);
- }
-