[BACK]Return to calendar.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / calendar

Diff for /src/usr.bin/calendar/calendar.c between version 1.6 and 1.15

version 1.6, 1997/01/15 23:42:16 version 1.15, 2001/09/03 15:53:00
Line 47 
Line 47 
 #endif  #endif
 #endif /* not lint */  #endif /* not lint */
   
   #include <sys/stat.h>
   #include <sys/types.h>
   #include <sys/wait.h>
 #include <err.h>  #include <err.h>
 #include <errno.h>  #include <errno.h>
 #include <locale.h>  #include <locale.h>
   #include <login_cap.h>
 #include <pwd.h>  #include <pwd.h>
   #include <signal.h>
 #include <stdio.h>  #include <stdio.h>
 #include <stdlib.h>  #include <stdlib.h>
 #include <string.h>  #include <string.h>
 #include <time.h>  #include <time.h>
   #include <tzfile.h>
 #include <unistd.h>  #include <unistd.h>
   
 #include "pathnames.h"  #include "pathnames.h"
 #include "calendar.h"  #include "calendar.h"
   
   char *calendarFile = "calendar";  /* default calendar file */
   char *calendarHome = ".calendar"; /* HOME */
   char *calendarNoMail = "nomail";  /* don't sent mail if this file exists */
   
 struct passwd *pw;  struct passwd *pw;
 int doall = 0;  int doall = 0;
 time_t f_time = 0;  time_t f_time = 0;
Line 67 
Line 77 
 int f_dayAfter = 0; /* days after current date */  int f_dayAfter = 0; /* days after current date */
 int f_dayBefore = 0; /* days before current date */  int f_dayBefore = 0; /* days before current date */
   
   struct specialev spev[NUMEV];
   
   void childsig __P((int));
   
 int  int
 main(argc, argv)  main(argc, argv)
         int argc;          int argc;
Line 75 
Line 89 
         int ch;          int ch;
         char *caldir;          char *caldir;
   
         (void) setlocale(LC_ALL, "");          (void)setlocale(LC_ALL, "");
   
         while ((ch = getopt(argc, argv, "?-af:t:A:B:")) != -1)          while ((ch = getopt(argc, argv, "-af:t:A:B:")) != -1)
                 switch (ch) {                  switch (ch) {
                 case '-':               /* backward contemptible */                  case '-':               /* backward contemptible */
                 case 'a':                  case 'a':
                         if (getuid())                          if (getuid())
                                 errx(1, strerror(EPERM));                                  errx(1, "%s", strerror(EPERM));
                         doall = 1;                          doall = 1;
                         break;                          break;
   
   
                 case 'f': /* other calendar file */                  case 'f': /* other calendar file */
                         calendarFile = optarg;                          calendarFile = optarg;
                         break;                          break;
   
                 case 't': /* other date, undocumented, for tests */                  case 't': /* other date, undocumented, for tests */
                         f_time = Mktime (optarg);                          if ((f_time = Mktime(optarg)) <= 0)
                                   errx(1, "specified date is outside allowed range");
                         break;                          break;
   
                 case 'A': /* days after current date */                  case 'A': /* days after current date */
Line 103 
Line 117 
                         f_dayBefore = atoi(optarg);                          f_dayBefore = atoi(optarg);
                         break;                          break;
   
                 case '?':  
                 default:                  default:
                         usage();                          usage();
                 }                  }
Line 117 
Line 130 
         if (f_time <= 0)          if (f_time <= 0)
             (void)time(&f_time);              (void)time(&f_time);
   
         settime(f_time);          if (f_dayBefore) {
                   /* Move back in time and only look forwards */
                   f_dayAfter += f_dayBefore;
                   f_time -= SECSPERDAY * f_dayBefore;
                   f_dayBefore = 0;
           }
           settime(&f_time);
   
         if (doall)          if (doall) {
                   pid_t kid, deadkid;
                   int kidstat, kidreaped, runningkids;
                   int acstat;
                   struct stat sbuf;
                   time_t t;
                   unsigned int sleeptime;
   
                   signal(SIGCHLD, childsig);
                   runningkids = 0;
                   t = time(NULL);
                 while ((pw = getpwent()) != NULL) {                  while ((pw = getpwent()) != NULL) {
                         (void)setegid(pw->pw_gid);                          acstat = 0;
                         (void)initgroups(pw->pw_name, pw->pw_gid);                          /* Avoid unnecessary forks.  The calendar file is only
                         (void)seteuid(pw->pw_uid);                           * opened as the user later; if it can't be opened,
                         if (!chdir(pw->pw_dir))                           * it's no big deal.  Also, get to correct directory.
                            * Note that in an NFS environment root may get EACCES
                            * on a chdir(), in which case we have to fork.  As long as
                            * we can chdir() we can stat(), unless the user is
                            * modifying permissions while this is running.
                            */
                           if (chdir(pw->pw_dir)) {
                                   if (errno == EACCES)
                                           acstat = 1;
                                   else
                                           continue;
                           }
                           if (stat(calendarFile, &sbuf) != 0) {
                                   if (chdir(calendarHome)) {
                                           if (errno == EACCES)
                                                   acstat = 1;
                                           else
                                                   continue;
                                   }
                                   if (stat(calendarNoMail, &sbuf) == 0 ||
                                       stat(calendarFile, &sbuf) != 0)
                                           continue;
                           }
                           sleeptime = USERTIMEOUT;
                           switch ((kid = fork())) {
                           case -1:        /* error */
                                   warn("fork");
                                   continue;
                           case 0: /* child */
                                   (void)setlocale(LC_ALL, "");
                                   if (setusercontext(NULL, pw, pw->pw_uid,
                                       LOGIN_SETALL ^ LOGIN_SETLOGIN))
                                           err(1, "unable to set user context (uid %d)",
                                               (int)pw->pw_uid);
                                   if (acstat) {
                                           if (chdir(pw->pw_dir) ||
                                               stat(calendarFile, &sbuf) != 0 ||
                                               chdir(calendarHome) ||
                                               stat(calendarNoMail, &sbuf) == 0 ||
                                               stat(calendarFile, &sbuf) != 0)
                                                   exit(0);
                                   }
                                 cal();                                  cal();
                         (void)seteuid(0);                                  exit(0);
                           }
                           /* parent: wait a reasonable time, then kill child if
                            * necessary.
                            */
                           runningkids++;
                           kidreaped = 0;
                           do {
                                   sleeptime = sleep(sleeptime);
                                   /* Note that there is the possibility, if the sleep
                                    * stops early due to some other signal, of the child
                                    * terminating and not getting detected during the next
                                    * sleep.  In that unlikely worst case, we just sleep
                                    * too long for that user.
                                    */
                                   for (;;) {
                                           deadkid = waitpid(-1, &kidstat, WNOHANG);
                                           if (deadkid <= 0)
                                                   break;
                                           runningkids--;
                                           if (deadkid == kid) {
                                                   kidreaped = 1;
                                                   sleeptime = 0;
                                           }
                                   }
                           } while (sleeptime);
   
                           if (!kidreaped) {
                                   /* It doesn't _really_ matter if the kill fails, e.g.
                                    * if there's only a zombie now.
                                    */
                                   (void)kill(kid, SIGTERM);
                                   warnx("uid %d did not finish in time", (int)pw->pw_uid);
                           }
                           if (time(NULL) - t >= SECSPERDAY)
                                   errx(2, "'calendar -a' took more than a day; stopped at uid %d",
                                       (int)pw->pw_uid);
                 }                  }
                   for (;;) {
                           deadkid = waitpid(-1, &kidstat, WNOHANG);
                           if (deadkid <= 0)
                                   break;
                           runningkids--;
                   }
                   if (runningkids)
                           warnx(
   "%d child processes still running when 'calendar -a' finished", runningkids);
           }
         else if ((caldir = getenv("CALENDAR_DIR")) != NULL) {          else if ((caldir = getenv("CALENDAR_DIR")) != NULL) {
                 if(!chdir(caldir))                  if(!chdir(caldir))
                         cal();                          cal();
Line 142 
Line 258 
 usage()  usage()
 {  {
         (void)fprintf(stderr,          (void)fprintf(stderr,
                       "usage: calendar [-a] [-A days] [-B days] [-f calendarfile]\n");              "usage: calendar [-a] [-A num] [-B num] [-t [[[cc]yy][mm]]dd] "
               "[-f calendarfile]\n");
         exit(1);          exit(1);
   }
   
   
   void
   childsig(sig)
           int sig;
   {
 }  }

Legend:
Removed from v.1.6  
changed lines
  Added in v.1.15