Index: stable/10/usr.bin/calendar/calcpp.c =================================================================== --- stable/10/usr.bin/calendar/calcpp.c (revision 285290) +++ stable/10/usr.bin/calendar/calcpp.c (nonexistent) @@ -1,229 +0,0 @@ -/*- - * Copyright (c) 2013 Diane Bruce - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -/* calendar fake cpp does a very limited cpp version */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "pathnames.h" -#include "calendar.h" - -#define MAXFPSTACK 50 -static FILE *fpstack[MAXFPSTACK]; -static int curfpi; -static void pushfp(FILE *fp); -static FILE *popfp(void); -static int tokenscpp(char *buf, char *string); - -#define T_INVALID -1 -#define T_INCLUDE 0 -#define T_DEFINE 1 -#define T_IFNDEF 2 -#define T_ENDIF 3 - -#define MAXSYMS 100 -static char *symtable[MAXSYMS]; -static void addsym(const char *name); -static int findsym(const char *name); - -FILE * -fincludegets(char *buf, int size, FILE *fp) -{ - char name[MAXPATHLEN]; - FILE *nfp=NULL; - char *p; - int ch; - - if (fp == NULL) - return(NULL); - - if (fgets(buf, size, fp) == NULL) { - *buf = '\0'; - fclose(fp); - fp = popfp(); - return (fp); - } - if ((p = strchr(buf, '\n')) != NULL) - *p = '\0'; - else { - /* Flush this line */ - while ((ch = fgetc(fp)) != '\n' && ch != EOF); - if (ch == EOF) { - *buf = '\0'; - fclose(fp); - fp = popfp(); - return(fp); - } - } - switch (tokenscpp(buf, name)) { - case T_INCLUDE: - *buf = '\0'; - if ((nfp = fopen(name, "r")) != NULL) { - pushfp(fp); - fp = nfp; - } - break; - case T_DEFINE: - addsym(name); - break; - case T_IFNDEF: - if (findsym(name)) { - fclose(fp); - fp = popfp(); - *buf = '\0'; - } - break; - case T_ENDIF: - *buf = '\0'; - break; - default: - break; - } - return (fp); -} - -static int -tokenscpp(char *buf, char *string) -{ - char *p; - char *s; - - if ((p = strstr(buf, "#define")) != NULL) { - p += 8; - while (isspace((unsigned char)*p)) - p++; - s = p; - while(!isspace((unsigned char)*p)) - p++; - strncpy(string, s, MAXPATHLEN); - return(T_DEFINE); - } else if ((p = strstr(buf, "#ifndef")) != NULL) { - p += 8; - while (isspace((unsigned char)*p)) - p++; - s = p; - while(!isspace((unsigned char)*p)) - p++; - *p = '\0'; - strncpy(string, s, MAXPATHLEN); - return(T_IFNDEF); - } else if ((p = strstr(buf, "#endif")) != NULL) { - return(T_ENDIF); - } if ((p = strstr(buf, "#include")) != NULL) { - p += 8; - while (isspace((unsigned char)*p)) - p++; - if (*p == '<') { - s = p+1; - if ((p = strchr(s, '>')) != NULL) - *p = '\0'; - snprintf (string, MAXPATHLEN, "%s/%s", - _PATH_INCLUDE, s); - } else if (*p == '(') { - s = p+1; - if ((p = strchr(p, '>')) != NULL) - *p = '\0'; - snprintf (string, MAXPATHLEN, "%s", s); - } - return(T_INCLUDE); - } - return(T_INVALID); -} - -static void -pushfp(FILE *fp) -{ - curfpi++; - if (curfpi == MAXFPSTACK) - errx(1, "Max #include reached"); - fpstack[curfpi] = fp; -} - -static -FILE *popfp(void) -{ - FILE *tmp; - - assert(curfpi >= 0); - tmp = fpstack[curfpi]; - curfpi--; - return(tmp); -} - -void -initcpp(void) -{ - int i; - - for (i=0; i < MAXSYMS; i++) - symtable[i] = NULL; - fpstack[0] = NULL; - curfpi = 0; -} - - -static void -addsym(const char *name) -{ - int i; - - if (!findsym(name)) - for (i=0; i < MAXSYMS; i++) { - if (symtable[i] == NULL) { - symtable[i] = strdup(name); - if (symtable[i] == NULL) - errx(1, "malloc error in addsym"); - return; - } - } - errx(1, "symbol table full\n"); -} - -static int -findsym(const char *name) -{ - int i; - - for (i=0; i < MAXSYMS; i++) - if (symtable[i] != NULL && strcmp(symtable[i],name) == 0) - return (1); - return (0); -} Property changes on: stable/10/usr.bin/calendar/calcpp.c ___________________________________________________________________ Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -FreeBSD=%H \ No newline at end of property Deleted: svn:mime-type ## -1 +0,0 ## -text/plain \ No newline at end of property Index: stable/10/usr.bin/calendar/Makefile =================================================================== --- stable/10/usr.bin/calendar/Makefile (revision 285290) +++ stable/10/usr.bin/calendar/Makefile (revision 285291) @@ -1,40 +1,40 @@ # @(#)Makefile 8.1 (Berkeley) 6/6/93 # $FreeBSD$ .include PROG= calendar SRCS= calendar.c locale.c events.c dates.c parsedata.c io.c day.c \ - ostern.c paskha.c pom.c sunpos.c calcpp.c + ostern.c paskha.c pom.c sunpos.c DPADD= ${LIBM} LDADD= -lm INTER= de_AT.ISO_8859-15 de_DE.ISO8859-1 fr_FR.ISO8859-1 \ hr_HR.ISO8859-2 hu_HU.ISO8859-2 pt_BR.ISO8859-1 \ pt_BR.UTF-8 ru_RU.KOI8-R ru_RU.UTF-8 uk_UA.KOI8-U DE_LINKS= de_DE.ISO8859-15 FR_LINKS= fr_FR.ISO8859-15 TEXTMODE?= 444 beforeinstall: ${INSTALL} -o ${BINOWN} -g ${BINGRP} -m ${TEXTMODE} \ ${.CURDIR}/calendars/calendar.* ${DESTDIR}${SHAREDIR}/calendar .for lang in ${INTER} mkdir -p ${DESTDIR}${SHAREDIR}/calendar/${lang} ${INSTALL} -o ${BINOWN} -g ${BINGRP} -m ${TEXTMODE} \ ${.CURDIR}/calendars/${lang}/calendar.* \ ${DESTDIR}${SHAREDIR}/calendar/${lang} .endfor .for link in ${DE_LINKS} rm -rf ${DESTDIR}${SHAREDIR}/calendar/${link} ln -s de_DE.ISO8859-1 ${DESTDIR}${SHAREDIR}/calendar/${link} .endfor .for link in ${FR_LINKS} rm -rf ${DESTDIR}${SHAREDIR}/calendar/${link} ln -s fr_FR.ISO8859-1 ${DESTDIR}${SHAREDIR}/calendar/${link} .endfor .if ${MK_TESTS} != "no" SUBDIR+= tests .endif .include Index: stable/10/usr.bin/calendar/calendar.c =================================================================== --- stable/10/usr.bin/calendar/calendar.c (revision 285290) +++ stable/10/usr.bin/calendar/calendar.c (revision 285291) @@ -1,228 +1,232 @@ /*- * Copyright (c) 1989, 1993, 1994 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef lint static const char copyright[] = "@(#) Copyright (c) 1989, 1993\n\ The Regents of the University of California. All rights reserved.\n"; #endif #if 0 #ifndef lint static char sccsid[] = "@(#)calendar.c 8.3 (Berkeley) 3/25/94"; #endif #endif #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include "calendar.h" #define UTCOFFSET_NOTSET 100 /* Expected between -24 and +24 */ #define LONGITUDE_NOTSET 1000 /* Expected between -360 and +360 */ struct passwd *pw; int doall = 0; int debug = 0; static char *DEBUG = NULL; static time_t f_time = 0; double UTCOffset = UTCOFFSET_NOTSET; int EastLongitude = LONGITUDE_NOTSET; static void usage(void) __dead2; int main(int argc, char *argv[]) { int f_dayAfter = 0; /* days after current date */ int f_dayBefore = 0; /* days before current date */ int Friday = 5; /* day before weekend */ int ch; struct tm tp1, tp2; (void)setlocale(LC_ALL, ""); while ((ch = getopt(argc, argv, "-A:aB:D:dF:f:l:t:U:W:?")) != -1) switch (ch) { case '-': /* backward contemptible */ case 'a': if (getuid()) { errno = EPERM; err(1, NULL); } doall = 1; break; case 'W': /* we don't need no steenking Fridays */ Friday = -1; /* FALLTHROUGH */ case 'A': /* days after current date */ f_dayAfter = atoi(optarg); + if (f_dayAfter < 0) + errx(1, "number of days must be positive"); break; case 'B': /* days before current date */ f_dayBefore = atoi(optarg); + if (f_dayBefore < 0) + errx(1, "number of days must be positive"); break; case 'D': /* debug output of sun and moon info */ DEBUG = optarg; break; case 'd': /* debug output of current date */ debug = 1; break; case 'F': /* Change the time: When does weekend start? */ Friday = atoi(optarg); break; case 'f': /* other calendar file */ calendarFile = optarg; break; case 'l': /* Change longitudal position */ EastLongitude = strtol(optarg, NULL, 10); break; case 't': /* other date, for tests */ f_time = Mktime(optarg); break; case 'U': /* Change UTC offset */ UTCOffset = strtod(optarg, NULL); break; case '?': default: usage(); } argc -= optind; argv += optind; if (argc) usage(); /* use current time */ if (f_time <= 0) (void)time(&f_time); /* if not set, determine where I could be */ { if (UTCOffset == UTCOFFSET_NOTSET && EastLongitude == LONGITUDE_NOTSET) { /* Calculate on difference between here and UTC */ time_t t; struct tm tm; long utcoffset, hh, mm, ss; double uo; time(&t); localtime_r(&t, &tm); utcoffset = tm.tm_gmtoff; /* seconds -> hh:mm:ss */ hh = utcoffset / SECSPERHOUR; utcoffset %= SECSPERHOUR; mm = utcoffset / SECSPERMINUTE; utcoffset %= SECSPERMINUTE; ss = utcoffset; /* hh:mm:ss -> hh.mmss */ uo = mm + (100.0 * (ss / 60.0)); uo /= 60.0 / 100.0; uo = hh + uo / 100; UTCOffset = uo; EastLongitude = UTCOffset * 15; } else if (UTCOffset == UTCOFFSET_NOTSET) { /* Base on information given */ UTCOffset = EastLongitude / 15; } else if (EastLongitude == LONGITUDE_NOTSET) { /* Base on information given */ EastLongitude = UTCOffset * 15; } } settimes(f_time, f_dayBefore, f_dayAfter, Friday, &tp1, &tp2); generatedates(&tp1, &tp2); /* * FROM now on, we are working in UTC. * This will only affect moon and sun related events anyway. */ if (setenv("TZ", "UTC", 1) != 0) errx(1, "setenv: %s", strerror(errno)); tzset(); if (debug) dumpdates(); if (DEBUG != NULL) { dodebug(DEBUG); exit(0); } if (doall) while ((pw = getpwent()) != NULL) { (void)setegid(pw->pw_gid); (void)initgroups(pw->pw_name, pw->pw_gid); (void)seteuid(pw->pw_uid); if (!chdir(pw->pw_dir)) cal(); (void)seteuid(0); } else cal(); exit(0); } static void __dead2 usage(void) { fprintf(stderr, "%s\n%s\n%s\n", "usage: calendar [-A days] [-a] [-B days] [-D sun|moon] [-d]", " [-F friday] [-f calendarfile] [-l longitude]", " [-t dd[.mm[.year]]] [-U utcoffset] [-W days]" ); exit(1); } Index: stable/10/usr.bin/calendar/calendar.h =================================================================== --- stable/10/usr.bin/calendar/calendar.h (revision 285290) +++ stable/10/usr.bin/calendar/calendar.h (revision 285291) @@ -1,201 +1,197 @@ /*- * Copyright (c) 1989, 1993, 1994 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ #include #include #define SECSPERDAY (24 * 60 * 60) #define SECSPERHOUR (60 * 60) #define SECSPERMINUTE (60) #define MINSPERHOUR (60) #define HOURSPERDAY (24) #define FSECSPERDAY (24.0 * 60.0 * 60.0) #define FSECSPERHOUR (60.0 * 60.0) #define FSECSPERMINUTE (60.0) #define FMINSPERHOUR (60.0) #define FHOURSPERDAY (24.0) #define DAYSPERYEAR 365 #define DAYSPERLEAPYEAR 366 /* Not yet categorized */ extern struct passwd *pw; extern int doall; extern time_t t1, t2; extern const char *calendarFile; extern int yrdays; extern struct fixs neaster, npaskha, ncny, nfullmoon, nnewmoon; extern struct fixs nmarequinox, nsepequinox, njunsolstice, ndecsolstice; extern double UTCOffset; extern int EastLongitude; #define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0) /* Flags to determine the returned values by determinestyle() in parsedata.c */ #define F_NONE 0x00000 #define F_MONTH 0x00001 #define F_DAYOFWEEK 0x00002 #define F_DAYOFMONTH 0x00004 #define F_MODIFIERINDEX 0x00008 #define F_MODIFIEROFFSET 0x00010 #define F_SPECIALDAY 0x00020 #define F_ALLMONTH 0x00040 #define F_ALLDAY 0x00080 #define F_VARIABLE 0x00100 #define F_EASTER 0x00200 #define F_CNY 0x00400 #define F_PASKHA 0x00800 #define F_NEWMOON 0x01000 #define F_FULLMOON 0x02000 #define F_MAREQUINOX 0x04000 #define F_SEPEQUINOX 0x08000 #define F_JUNSOLSTICE 0x10000 #define F_DECSOLSTICE 0x20000 #define F_YEAR 0x40000 #define STRING_EASTER "Easter" #define STRING_PASKHA "Paskha" #define STRING_CNY "ChineseNewYear" #define STRING_NEWMOON "NewMoon" #define STRING_FULLMOON "FullMoon" #define STRING_MAREQUINOX "MarEquinox" #define STRING_SEPEQUINOX "SepEquinox" #define STRING_JUNSOLSTICE "JunSolstice" #define STRING_DECSOLSTICE "DecSolstice" #define MAXCOUNT 125 /* Random number of maximum number of * repeats of an event. Should be 52 * (number of weeks per year), if you * want to show two years then it * should be 104. If you are seeing * more than this you are using this * program wrong. */ /* * All the astronomical calculations are carried out for the meridian 120 * degrees east of Greenwich. */ #define UTCOFFSET_CNY 8.0 extern int debug; /* show parsing of the input */ extern int year1, year2; /* events.c */ /* * Event sorting related functions: * - Use event_add() to create a new event * - Use event_continue() to add more text to the last added event * - Use event_print_all() to display them in time chronological order */ struct event *event_add(int, int, int, char *, int, char *, char *); void event_continue(struct event *events, char *txt); void event_print_all(FILE *fp); struct event { int year; int month; int day; int var; char *date; char *text; char *extra; struct event *next; }; /* locale.c */ struct fixs { char *name; size_t len; }; extern const char *days[]; extern const char *fdays[]; extern const char *fmonths[]; extern const char *months[]; extern const char *sequences[]; extern struct fixs fndays[8]; /* full national days names */ extern struct fixs fnmonths[13]; /* full national months names */ extern struct fixs ndays[8]; /* short national days names */ extern struct fixs nmonths[13]; /* short national month names */ extern struct fixs nsequences[10]; void setnnames(void); void setnsequences(char *); /* day.c */ extern const struct tm tm0; extern char dayname[]; void settimes(time_t,int before, int after, int friday, struct tm *tp1, struct tm *tp2); time_t Mktime(char *); /* parsedata.c */ int parsedaymonth(char *, int *, int *, int *, int *, char **); void dodebug(char *type); /* io.c */ void cal(void); void closecal(FILE *); FILE *opencalin(void); FILE *opencalout(void); -/* calcpp.c */ -void initcpp(void); -FILE *fincludegets(char *buf, int size, FILE *fp); - /* ostern.c / paskha.c */ int paskha(int); int easter(int); int j2g(int); /* dates.c */ extern int cumdaytab[][14]; extern int monthdaytab[][14]; extern int debug_remember; void generatedates(struct tm *tp1, struct tm *tp2); void dumpdates(void); int remember_ymd(int y, int m, int d); int remember_yd(int y, int d, int *rm, int *rd); int first_dayofweek_of_year(int y); int first_dayofweek_of_month(int y, int m); int walkthrough_dates(struct event **e); void addtodate(struct event *e, int year, int month, int day); /* pom.c */ #define MAXMOONS 18 void pom(int year, double UTCoffset, int *fms, int *nms); void fpom(int year, double utcoffset, double *ffms, double *fnms); /* sunpos.c */ void equinoxsolstice(int year, double UTCoffset, int *equinoxdays, int *solsticedays); void fequinoxsolstice(int year, double UTCoffset, double *equinoxdays, double *solsticedays); int calculatesunlongitude30(int year, int degreeGMToffset, int *ichinesemonths); Index: stable/10/usr.bin/calendar/io.c =================================================================== --- stable/10/usr.bin/calendar/io.c (revision 285290) +++ stable/10/usr.bin/calendar/io.c (revision 285291) @@ -1,334 +1,501 @@ /*- * Copyright (c) 1989, 1993, 1994 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef lint static const char copyright[] = "@(#) Copyright (c) 1989, 1993\n\ The Regents of the University of California. All rights reserved.\n"; #endif #if 0 #ifndef lint static char sccsid[] = "@(#)calendar.c 8.3 (Berkeley) 3/25/94"; #endif #endif #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include +#include +#define _WITH_GETLINE #include #include #include +#include #include #include "pathnames.h" #include "calendar.h" +enum { + T_OK = 0, + T_ERR, + T_PROCESS, +}; + const char *calendarFile = "calendar"; /* default calendar file */ static const char *calendarHomes[] = {".calendar", _PATH_INCLUDE}; /* HOME */ static const char *calendarNoMail = "nomail";/* don't sent mail if file exist */ static char path[MAXPATHLEN]; struct fixs neaster, npaskha, ncny, nfullmoon, nnewmoon; struct fixs nmarequinox, nsepequinox, njunsolstice, ndecsolstice; +static int cal_parse(FILE *in, FILE *out); + +static StringList *definitions = NULL; +static struct event *events[MAXCOUNT]; +static char *extradata[MAXCOUNT]; + +static void +trimlr(char **buf) +{ + char *walk = *buf; + + while (isspace(*walk)) + walk++; + while (isspace(walk[strlen(walk) -1])) + walk[strlen(walk) -1] = '\0'; + + *buf = walk; +} + +static FILE * +cal_fopen(const char *file) +{ + FILE *fp; + char *home = getenv("HOME"); + unsigned int i; + + if (home == NULL || *home == '\0') { + warnx("Cannot get home directory"); + return (NULL); + } + + if (chdir(home) != 0) { + warnx("Cannot enter home directory"); + return (NULL); + } + + for (i = 0; i < sizeof(calendarHomes)/sizeof(calendarHomes[0]) ; i++) { + if (chdir(calendarHomes[i]) != 0) + continue; + + if ((fp = fopen(file, "r")) != NULL) + return (fp); + } + + warnx("can't open calendar file \"%s\"", file); + + return (NULL); +} + +static int +token(char *line, FILE *out, bool *skip) +{ + char *walk, c, a; + + if (strncmp(line, "endif", 5) == 0) { + *skip = false; + return (T_OK); + } + + if (*skip) + return (T_OK); + + if (strncmp(line, "include", 7) == 0) { + walk = line + 7; + + trimlr(&walk); + + if (*walk == '\0') { + warnx("Expecting arguments after #include"); + return (T_ERR); + } + + if (*walk != '<' && *walk != '\"') { + warnx("Excecting '<' or '\"' after #include"); + return (T_ERR); + } + + a = *walk; + walk++; + c = walk[strlen(walk) - 1]; + + switch(c) { + case '>': + if (a != '<') { + warnx("Unterminated include expecting '\"'"); + return (T_ERR); + } + break; + case '\"': + if (a != '\"') { + warnx("Unterminated include expecting '>'"); + return (T_ERR); + } + break; + default: + warnx("Unterminated include expecting '%c'", + a == '<' ? '>' : '\"' ); + return (T_ERR); + } + walk[strlen(walk) - 1] = '\0'; + + if (cal_parse(cal_fopen(walk), out)) + return (T_ERR); + + return (T_OK); + } + + if (strncmp(line, "define", 6) == 0) { + if (definitions == NULL) + definitions = sl_init(); + walk = line + 6; + trimlr(&walk); + + if (*walk == '\0') { + warnx("Expecting arguments after #define"); + return (T_ERR); + } + + sl_add(definitions, strdup(walk)); + return (T_OK); + } + + if (strncmp(line, "ifndef", 6) == 0) { + walk = line + 6; + trimlr(&walk); + + if (*walk == '\0') { + warnx("Expecting arguments after #ifndef"); + return (T_ERR); + } + + if (definitions != NULL && sl_find(definitions, walk) != NULL) + *skip = true; + + return (T_OK); + } + + return (T_PROCESS); + +} + #define REPLACE(string, slen, struct_) \ if (strncasecmp(buf, (string), (slen)) == 0 && buf[(slen)]) { \ if (struct_.name != NULL) \ free(struct_.name); \ if ((struct_.name = strdup(buf + (slen))) == NULL) \ errx(1, "cannot allocate memory"); \ struct_.len = strlen(buf + (slen)); \ continue; \ } -void -cal(void) +static int +cal_parse(FILE *in, FILE *out) { - char *pp, p; - FILE *fpin; - FILE *fpout; - int l; - int count, i; + char *line = NULL; + char *buf; + size_t linecap = 0; + ssize_t linelen; + ssize_t l; + static int d_first = -1; + static int count = 0; + int i; int month[MAXCOUNT]; int day[MAXCOUNT]; int year[MAXCOUNT]; - char **extradata; /* strings of 20 length */ - int flags; - static int d_first = -1; - char buf[2048 + 1]; - struct event *events[MAXCOUNT]; - struct tm tm; + bool skip = false; char dbuf[80]; + char *pp, p; + struct tm tm; + int flags; - initcpp(); - extradata = (char **)calloc(MAXCOUNT, sizeof(char *)); - for (i = 0; i < MAXCOUNT; i++) { - extradata[i] = (char *)calloc(1, 20); - } - /* Unused */ tm.tm_sec = 0; tm.tm_min = 0; tm.tm_hour = 0; tm.tm_wday = 0; - count = 0; - if ((fpin = opencalin()) == NULL) { - free(extradata); - return; - } - if ((fpout = opencalout()) == NULL) { - fclose(fpin); - free(extradata); - return; - } - while ((fpin = fincludegets(buf, sizeof(buf), fpin)) != NULL) { - if (*buf == '\0') + if (in == NULL) + return (1); + + while ((linelen = getline(&line, &linecap, in)) > 0) { + if (linelen == 0) continue; - for (l = strlen(buf); + + if (*line == '#') { + switch (token(line+1, out, &skip)) { + case T_ERR: + free(line); + return (1); + case T_OK: + continue; + case T_PROCESS: + break; + default: + break; + } + } + + if (skip) + continue; + + buf = line; + for (l = linelen; l > 0 && isspace((unsigned char)buf[l - 1]); l--) ; buf[l] = '\0'; if (buf[0] == '\0') continue; /* Parse special definitions: LANG, Easter, Paskha etc */ if (strncmp(buf, "LANG=", 5) == 0) { (void)setlocale(LC_ALL, buf + 5); d_first = (*nl_langinfo(D_MD_ORDER) == 'd'); setnnames(); continue; } REPLACE("Easter=", 7, neaster); REPLACE("Paskha=", 7, npaskha); REPLACE("ChineseNewYear=", 15, ncny); REPLACE("NewMoon=", 8, nnewmoon); REPLACE("FullMoon=", 9, nfullmoon); REPLACE("MarEquinox=", 11, nmarequinox); REPLACE("SepEquinox=", 11, nsepequinox); REPLACE("JunSolstice=", 12, njunsolstice); REPLACE("DecSolstice=", 12, ndecsolstice); if (strncmp(buf, "SEQUENCE=", 9) == 0) { setnsequences(buf + 9); continue; } /* * If the line starts with a tab, the data has to be * added to the previous line */ if (buf[0] == '\t') { for (i = 0; i < count; i++) event_continue(events[i], buf); continue; } /* Get rid of leading spaces (non-standard) */ while (isspace((unsigned char)buf[0])) memcpy(buf, buf + 1, strlen(buf)); /* No tab in the line, then not a valid line */ if ((pp = strchr(buf, '\t')) == NULL) continue; /* Trim spaces in front of the tab */ while (isspace((unsigned char)pp[-1])) pp--; p = *pp; *pp = '\0'; if ((count = parsedaymonth(buf, year, month, day, &flags, extradata)) == 0) continue; *pp = p; if (count < 0) { /* Show error status based on return value */ if (debug) fprintf(stderr, "Ignored: %s\n", buf); if (count == -1) continue; count = -count + 1; } /* Find the last tab */ while (pp[1] == '\t') pp++; if (d_first < 0) d_first = (*nl_langinfo(D_MD_ORDER) == 'd'); for (i = 0; i < count; i++) { tm.tm_mon = month[i] - 1; tm.tm_mday = day[i]; tm.tm_year = year[i] - 1900; (void)strftime(dbuf, sizeof(dbuf), d_first ? "%e %b" : "%b %e", &tm); if (debug) fprintf(stderr, "got %s\n", pp); events[i] = event_add(year[i], month[i], day[i], dbuf, ((flags &= F_VARIABLE) != 0) ? 1 : 0, pp, extradata[i]); } } + free(line); + fclose(in); + + return (0); +} + +void +cal(void) +{ + FILE *fpin; + FILE *fpout; + int i; + + for (i = 0; i < MAXCOUNT; i++) + extradata[i] = (char *)calloc(1, 20); + + + if ((fpin = opencalin()) == NULL) + return; + + if ((fpout = opencalout()) == NULL) { + fclose(fpin); + return; + } + + if (cal_parse(fpin, fpout)) + return; + event_print_all(fpout); closecal(fpout); - free(extradata); } FILE * opencalin(void) { - size_t i; - int found; struct stat sbuf; FILE *fpin; /* open up calendar file */ if ((fpin = fopen(calendarFile, "r")) == NULL) { if (doall) { if (chdir(calendarHomes[0]) != 0) return (NULL); if (stat(calendarNoMail, &sbuf) == 0) return (NULL); if ((fpin = fopen(calendarFile, "r")) == NULL) return (NULL); } else { - char *home = getenv("HOME"); - if (home == NULL || *home == '\0') - errx(1, "cannot get home directory"); - if (chdir(home) != 0) - errx(1, "cannot enter home directory"); - for (found = i = 0; i < sizeof(calendarHomes) / - sizeof(calendarHomes[0]); i++) - if (chdir(calendarHomes[i]) == 0 && - (fpin = fopen(calendarFile, "r")) != NULL) { - found = 1; - break; - } - if (!found) - errx(1, - "can't open calendar file \"%s\": %s (%d)", - calendarFile, strerror(errno), errno); + fpin = cal_fopen(calendarFile); } } return (fpin); } FILE * opencalout(void) { int fd; /* not reading all calendar files, just set output to stdout */ if (!doall) return (stdout); /* set output to a temporary file, so if no output don't send mail */ snprintf(path, sizeof(path), "%s/_calXXXXXX", _PATH_TMP); if ((fd = mkstemp(path)) < 0) return (NULL); return (fdopen(fd, "w+")); } void closecal(FILE *fp) { uid_t uid; struct stat sbuf; int nread, pdes[2], status; char buf[1024]; if (!doall) return; rewind(fp); if (fstat(fileno(fp), &sbuf) || !sbuf.st_size) goto done; if (pipe(pdes) < 0) goto done; switch (fork()) { case -1: /* error */ (void)close(pdes[0]); (void)close(pdes[1]); goto done; case 0: /* child -- set stdin to pipe output */ if (pdes[0] != STDIN_FILENO) { (void)dup2(pdes[0], STDIN_FILENO); (void)close(pdes[0]); } (void)close(pdes[1]); uid = geteuid(); if (setuid(getuid()) < 0) { warnx("setuid failed"); _exit(1); }; if (setgid(getegid()) < 0) { warnx("setgid failed"); _exit(1); } if (setuid(uid) < 0) { warnx("setuid failed"); _exit(1); } execl(_PATH_SENDMAIL, "sendmail", "-i", "-t", "-F", "\"Reminder Service\"", (char *)NULL); warn(_PATH_SENDMAIL); _exit(1); } /* parent -- write to pipe input */ (void)close(pdes[0]); write(pdes[1], "From: \"Reminder Service\" <", 26); write(pdes[1], pw->pw_name, strlen(pw->pw_name)); write(pdes[1], ">\nTo: <", 7); write(pdes[1], pw->pw_name, strlen(pw->pw_name)); write(pdes[1], ">\nSubject: ", 11); write(pdes[1], dayname, strlen(dayname)); write(pdes[1], "'s Calendar\nPrecedence: bulk\n\n", 30); while ((nread = read(fileno(fp), buf, sizeof(buf))) > 0) (void)write(pdes[1], buf, nread); (void)close(pdes[1]); done: (void)fclose(fp); (void)unlink(path); while (wait(&status) >= 0); } Index: stable/10 =================================================================== --- stable/10 (revision 285290) +++ stable/10 (revision 285291) Property changes on: stable/10 ___________________________________________________________________ Modified: svn:mergeinfo ## -0,0 +0,1 ## Merged /head:r259152,259219,262011,279597