This is init.c in view mode; [Download] [Up]
/***************************************************************/ /* */ /* INIT.C */ /* */ /* Initialize remind; perform certain tasks between */ /* iterations in calendar mode; do certain checks after end */ /* in normal mode. */ /* */ /* This file is part of REMIND. */ /* Copyright (C) 1992, 1993, 1994 by David F. Skoll. */ /* */ /***************************************************************/ #define L_IN_INIT 1 #include "config.h" #include <stdio.h> #include <string.h> #ifdef HAVE_STDLIB_H #include <stdlib.h> #endif #ifdef HAVE_MALLOC_H #include <malloc.h> #endif #ifdef UNIX #include <sys/types.h> #include <pwd.h> #ifdef HAVE_UNISTD #include <unistd.h> #endif #endif #include <ctype.h> #include "types.h" #include "protos.h" #include "expr.h" #include "err.h" #include "version.h" #include "globals.h" /*************************************************************** * * Command line options recognized: * * -n = Output next trigger date of each reminder in * simple calendar format. * -r = Disallow RUN mode * -c[n] = Produce a calendar for n months (default = 1) * -w[n,n,n] = Specify output device width, padding and spacing * -s[n] = Produce calendar in "simple calendar" format * -p[n] = Produce calendar in format compatible with rem2ps * -v = Verbose mode * -o = Ignore ONCE directives * -a = Don't issue timed reminders which will be queued * -q = Don't queue timed reminders * -t = Trigger all reminders (infinite delta) * -h = Hush mode * -f = Do not fork * -dchars = Debugging mode: Chars are: * e = Echo input lines * x = Display expression evaluation * t = Display trigger dates * v = Dump variables at end * l = Display entire line in error messages * -e = Send messages normally sent to stderr to stdout instead * -z[n] = Daemon mode waking up every n (def 5) minutes. * -bn = Time format for cal (0, 1, or 2) * -xn = Max. number of iterations for SATISFY * -uname = Run as user 'name' - only valid when run by root. If run * by non-root, changes environment but not effective uid. * -kcmd = Run 'cmd' for MSG-type reminders instead of printing to stdout * -iVAR=EXPR = Initialize and preserve VAR. * -m = Start calendar with Monday instead of Sunday. * A minus sign alone indicates to take input from stdin * **************************************************************/ /* For parsing an integer */ #define PARSENUM(var, s) \ var = 0; \ while (isdigit(*(s))) { \ var *= 10; \ var += *(s) - '0'; \ s++; \ } #ifdef UNIX PRIVATE void ChgUser ARGS((char *uname)); #endif PRIVATE void InitializeVar ARGS ((char *str)); static char *BadDate = "Illegal date on command line\n"; /***************************************************************/ /* */ /* InitRemind */ /* */ /* Initialize the system - called only once at beginning! */ /* */ /***************************************************************/ #ifdef HAVE_PROTOS PUBLIC void InitRemind(int argc, char *argv[]) #else void InitRemind(argc, argv) int argc; char *argv[]; #endif { char *arg; int i; int y, m, d, rep; Token tok; y = NO_YR; m = NO_MON; d = NO_DAY; rep = NO_REP; RealToday = SystemDate(&CurYear, &CurMon, &CurDay); if (RealToday < 0) { fprintf(ErrFp, ErrMsg[M_BAD_SYS_DATE], BASE); exit(1); } JulianToday = RealToday; FromJulian(JulianToday, &CurYear, &CurMon, &CurDay); #if !defined(HAVE_QUEUED) DontFork = 1; DontQueue = 1; NumQueued = 0; DontIssueAts = 0; Daemon = 0; #elif defined(_MSC_VER) || defined(__BORLANDC__) DontFork = 1; #elif defined(__OS2__) && defined (__MSDOS__) if (DOSMODE) DontFork = 1; #endif /* Parse the command-line options */ i = 1; while (i < argc) { arg = argv[i]; if (*arg != '-') break; /* Exit the loop if it's not an option */ i++; arg++; if (!*arg) { UseStdin = 1; IgnoreOnce = 1; i--; break; } while (*arg) { switch(*arg++) { case 'i': case 'I': InitializeVar(arg); while(*arg) arg++; break; case 'n': case 'N': NextMode = 1; #ifdef HAVE_QUEUED DontQueue = 1; Daemon = 0; #endif break; case 'r': case 'R': RunDisabled = 1; break; case 'm': case 'M': MondayFirst = 1; break; case 'o': case 'O': IgnoreOnce = 1; break; case 't': case 'T': InfiniteDelta = 1; break; case 'e': case 'E': ErrFp = stdout; break; case 'h': case 'H': Hush = 1; break; case 'g': case 'G': SortByDate = SORT_ASCEND; SortByTime = SORT_ASCEND; SortByPrio = SORT_ASCEND; if (*arg) { if (*arg == 'D' || *arg == 'd') SortByDate = SORT_DESCEND; arg++; } if (*arg) { if (*arg == 'D' || *arg == 'd') SortByTime = SORT_DESCEND; arg++; } if (*arg) { if (*arg == 'D' || *arg == 'd') SortByPrio = SORT_DESCEND; arg++; } break; #if defined(UNIX) && defined(WANT_U_OPTION) case 'u': case 'U': ChgUser(arg); while (*arg) arg++; break; #endif #ifdef HAVE_QUEUED case 'z': case 'Z': DontFork = 1; PARSENUM(Daemon, arg); if (Daemon<5) Daemon=5; else if (Daemon>60) Daemon=60; break; case 'a': case 'A': DontIssueAts = 1; break; case 'q': case 'Q': DontQueue = 1; break; case 'f': case 'F': DontFork = 1; break; #endif case 'c': case 'C': DoCalendar = 1; if (*arg == '+') { arg++; PARSENUM(CalWeeks, arg); if (!CalWeeks) CalWeeks = 1; } else { PARSENUM(CalMonths, arg); if (!CalMonths) CalMonths = 1; } break; case 's': case 'S': DoSimpleCalendar = 1; if (*arg == '+') { arg++; PARSENUM(CalWeeks, arg); if (!CalWeeks) CalWeeks = 1; } else { PARSENUM(CalMonths, arg); if (!CalMonths) CalMonths = 1; } break; case 'p': case 'P': DoSimpleCalendar = 1; PsCal = 1; PARSENUM(CalMonths, arg); if (!CalMonths) CalMonths = 1; break; case 'w': case 'W': if (*arg != ',') { PARSENUM(CalWidth, arg); if (CalWidth < 80) CalWidth = 80; } if (*arg == ',') { arg++; if (*arg != ',') { PARSENUM(CalLines, arg); if (CalLines > 20) CalLines = 20; } if (*arg == ',') { arg++; PARSENUM(CalPad, arg); if (CalPad > 20) CalPad = 20; } } break; case 'd': case 'D': while (*arg) { switch(*arg++) { case 'e': case 'E': DebugFlag |= DB_ECHO_LINE; break; case 'x': case 'X': DebugFlag |= DB_PRTEXPR; break; case 't': case 'T': DebugFlag |= DB_PRTTRIG; break; case 'v': case 'V': DebugFlag |= DB_DUMP_VARS; break; case 'l': case 'L': DebugFlag |= DB_PRTLINE; break; default: fprintf(ErrFp, ErrMsg[M_BAD_DB_FLAG], *(arg-1)); } } break; case 'v': case 'V': DebugFlag |= DB_PRTLINE; ShowAllErrors = 1; break; case 'b': case 'B': PARSENUM(ScFormat, arg); if (ScFormat<0 || ScFormat>2) ScFormat=SC_AMPM; break; case 'x': case 'X': PARSENUM(MaxSatIter, arg); if (MaxSatIter < 10) MaxSatIter=10; break; case 'k': case 'K': MsgCommand = arg; while (*arg) arg++; /* Chew up remaining chars in this arg */ break; default: fprintf(ErrFp, ErrMsg[M_BAD_OPTION], *(arg-1)); } } } /* Get the filename. */ if (i >= argc) { Usage(); exit(1); } InitialFile = argv[i++]; /* Get the date, if any */ if (i < argc) { while (i < argc) { arg = argv[i++]; FindToken(arg, &tok); switch (tok.type) { case T_Time: if (SysTime != -1L) Usage(); else { SysTime = (long) tok.val * 60L; #ifdef HAVE_QUEUED DontQueue = 1; Daemon = 0; #endif } break; case T_Month: if (m != NO_MON) Usage(); else m = tok.val; break; case T_Day: if (d != NO_DAY) Usage(); else d = tok.val; break; case T_Year: if (y != NO_YR) Usage(); else y = tok.val; break; case T_Rep: if (rep != NO_REP) Usage(); else rep = tok.val; break; default: Usage(); } } if (rep > 0) { Iterations = rep; DontQueue = 1; Daemon = 0; } /* Must supply date in the form: day, mon, yr OR mon, yr */ if (m != NO_MON || y != NO_YR || d != NO_DAY) { if (m == NO_MON || y == NO_YR) { if (rep == NO_REP) Usage(); else if (m != NO_MON || y != NO_YR) Usage(); else { m = CurMon; y = CurYear; if (d == NO_DAY) d = CurDay; } } if (d == NO_DAY) d=1; if (d > DaysInMonth(m, y)) { fprintf(ErrFp, BadDate); Usage(); } JulianToday = Julian(y, m, d); if (JulianToday == -1) { fprintf(ErrFp, BadDate); Usage(); } CurYear = y; CurMon = m; CurDay = d; if (JulianToday != RealToday) IgnoreOnce = 1; } } /* Figure out the offset from UTC */ if (CalculateUTC) (void) CalcMinsFromUTC(JulianToday, SystemTime(1)/60, &MinsFromUTC, NULL); } /***************************************************************/ /* */ /* Usage */ /* */ /* Print the usage info. */ /* */ /***************************************************************/ #ifndef L_USAGE_OVERRIDE #ifdef HAVE_PROTOS PUBLIC void Usage(void) #else void Usage() #endif /* HAVE_PROTOS */ { fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-1994 by David F. Skoll\n", VERSION, L_LANGNAME); #ifdef BETA fprintf(ErrFp, ">>>> BETA VERSION <<<<\n"); #endif fprintf(ErrFp, "Usage: remind [options] filename [date] [time] [*rep]\n"); fprintf(ErrFp, "Options:\n"); fprintf(ErrFp, " -n Output next occurrence of reminders in simple format\n"); fprintf(ErrFp, " -r Disable RUN directives\n"); fprintf(ErrFp, " -c[n] Produce a calendar for n (default 1) months\n"); fprintf(ErrFp, " -c+[n] Produce a calendar for n (default 1) weeks\n"); fprintf(ErrFp, " -w[n[,p[,s]]] Specify width, padding and spacing of calendar\n"); fprintf(ErrFp, " -s[+][n] Produce 'simple calendar' for n (1) months (weeks)\n"); fprintf(ErrFp, " -p[n] Same as -s, but input compatible with rem2ps\n"); fprintf(ErrFp, " -v Verbose mode\n"); fprintf(ErrFp, " -o Ignore ONCE directives\n"); fprintf(ErrFp, " -t Trigger all future reminders regardless of delta\n"); fprintf(ErrFp, " -h 'Hush' mode - be very quiet\n"); #ifdef HAVE_QUEUED fprintf(ErrFp, " -a Don't trigger timed reminders immediately - just queue them\n"); fprintf(ErrFp, " -q Don't queue timed reminders\n"); fprintf(ErrFp, " -f Trigger timed reminders by staying in foreground\n"); fprintf(ErrFp, " -z[n] Enter daemon mode, waking every n (5) minutes.\n"); #endif fprintf(ErrFp, " -d... Debug: e=echo x=expr-eval t=trig v=dumpvars l=showline\n"); fprintf(ErrFp, " -e Divert messages normally sent to stderr to stdout\n"); fprintf(ErrFp, " -b[n] Time format for cal: 0=am/pm, 1=24hr, 2=none\n"); fprintf(ErrFp, " -x[n] Iteration limit for SATISFY clause (def=150)\n"); fprintf(ErrFp, " -kcmd Run 'cmd' for MSG-type reminders\n"); fprintf(ErrFp, " -g[ddd] Sort reminders by date, time and priority before issuing\n"); fprintf(ErrFp, " -ivar=val Initialize var to val and preserve var\n"); fprintf(ErrFp, " -m Start calendar with Monday rather than Sunday\n"); exit(1); } #endif /* L_USAGE_OVERRIDE */ /***************************************************************/ /* */ /* ChgUser */ /* */ /* Run as a specified user. Can only be used if Remind is */ /* started by root. This changes the real and effective uid, */ /* the real and effective gid, and sets the HOME, SHELL and */ /* USER environment variables. */ /* */ /***************************************************************/ #if defined(UNIX) && defined(WANT_U_OPTION) #ifdef HAVE_PROTOS PRIVATE void ChgUser(char *user) #else static void ChgUser(user) char *user; #endif /* HAVE_PROTOS */ { #ifdef SYSV /* uid_t myuid; This seems to mess up on XENIX, so forget it... */ int myuid; #else int myuid; #endif struct passwd *pwent; static char *home, *shell, *username, *logname; myuid = getuid(); pwent = getpwnam(user); if (!pwent) { fprintf(ErrFp, ErrMsg[M_BAD_USER], user); exit(1); } if (!myuid && setgid(pwent->pw_gid)) { fprintf(ErrFp, ErrMsg[M_NO_CHG_GID], pwent->pw_gid); exit(1); } if (!myuid && setuid(pwent->pw_uid)) { fprintf(ErrFp, ErrMsg[M_NO_CHG_UID], pwent->pw_uid); exit(1); } home = malloc(strlen(pwent->pw_dir) + 6); if (!home) { fprintf(ErrFp, ErrMsg[M_NOMEM_ENV]); exit(1); } sprintf(home, "HOME=%s", pwent->pw_dir); putenv(home); shell = malloc(strlen(pwent->pw_shell) + 7); if (!shell) { fprintf(ErrFp, ErrMsg[M_NOMEM_ENV]); exit(1); } sprintf(shell, "SHELL=%s", pwent->pw_shell); putenv(shell); if (pwent->pw_uid) { username = malloc(strlen(pwent->pw_name) + 6); if (!username) { fprintf(ErrFp, ErrMsg[M_NOMEM_ENV]); exit(1); } sprintf(username, "USER=%s", pwent->pw_name); putenv(username); logname= malloc(strlen(pwent->pw_name) + 9); if (!logname) { fprintf(ErrFp, ErrMsg[M_NOMEM_ENV]); exit(1); } sprintf(logname, "LOGNAME=%s", pwent->pw_name); putenv(logname); } } #endif /* UNIX && WANT_U_OPTION */ /***************************************************************/ /* */ /* InitializeVar */ /* */ /* Initialize and preserve a variable */ /* */ /***************************************************************/ #ifdef HAVE_PROTOS PRIVATE void InitializeVar(char *str) #else static void InitializeVar(str) char *str; #endif { char *varname, *expr; Value val; int r; /* Scan for an '=' sign */ varname = str; while (*str && *str != '=') str++; if (!*str) { fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[E_MISS_EQ]); return; } *str = 0; if (!*varname) { fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[E_MISS_VAR]); return; } expr = str+1; if (!*expr) { fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[E_MISS_EXPR]); return; } r=EvalExpr(&expr, &val); if (r) { fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[r]); return; } if (*varname == '$') { r=SetSysVar(varname+1, &val); if (r) fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[r]); return; } r=SetVar(varname, &val); if (r) { fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[r]); return; } r=PreserveVar(varname); if (r) fprintf(ErrFp, ErrMsg[M_I_OPTION], ErrMsg[r]); return; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.