[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.13 and 1.23

version 1.13, 2000/06/30 16:00:11 version 1.23, 2004/12/10 15:31:01
Line 12 
Line 12 
  * 2. Redistributions in binary form must reproduce the above copyright   * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the   *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.   *    documentation and/or other materials provided with the distribution.
  * 3. All advertising materials mentioning features or use of this software   * 3. Neither the name of the University nor the names of its contributors
  *    must display the following acknowledgement:  
  *      This product includes software developed by the University of  
  *      California, Berkeley and its contributors.  
  * 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   *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.   *    without specific prior written permission.
  *   *
Line 43 
Line 39 
 #if 0  #if 0
 static const char sccsid[] = "@(#)calendar.c  8.3 (Berkeley) 3/25/94";  static const char sccsid[] = "@(#)calendar.c  8.3 (Berkeley) 3/25/94";
 #else  #else
 static char rcsid[] = "$OpenBSD$";  static const char rcsid[] = "$OpenBSD$";
 #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>
Line 61 
Line 62 
 #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;
   int bodun_always = 0;
   
 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];  struct specialev spev[NUMEV];
   
   void childsig(int);
   
 int  int
 main(argc, argv)  main(int argc, char *argv[])
         int argc;  
         char *argv[];  
 {  {
         int ch, i;          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, "abf:t:A:B:-")) != -1)
                 switch (ch) {                  switch (ch) {
                 case '-':               /* backward contemptible */                  case '-':               /* backward contemptible */
                 case 'a':                  case 'a':
Line 89 
Line 95 
                         doall = 1;                          doall = 1;
                         break;                          break;
   
                   case 'b':
                           bodun_always++;
                           break;
   
                 case 'f': /* other calendar file */                  case 'f': /* other calendar file */
                         calendarFile = optarg;                          calendarFile = optarg;
                         break;                          break;
Line 128 
Line 138 
         settime(&f_time);          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)setlocale(LC_ALL, "");                          acstat = 0;
                         (void)setegid(pw->pw_gid);                          /* Avoid unnecessary forks.  The calendar file is only
                         (void)initgroups(pw->pw_name, pw->pw_gid);                           * opened as the user later; if it can't be opened,
                         (void)seteuid(pw->pw_uid);                           * it's no big deal.  Also, get to correct directory.
                         if (!chdir(pw->pw_dir)) {                           * 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 %u)",
                                               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();
                                 /* Keep user settings from propogating */                                  exit(0);
                                 for (i = 0; i < NUMEV; i++)  
                                         if (spev[i].uname != NULL)  
                                                 free(spev[i].uname);  
                         }                          }
                         (void)seteuid(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 %u did not finish in time", pw->pw_uid);
                           }
                           if (time(NULL) - t >= SECSPERDAY)
                                   errx(2, "'calendar -a' took more than a day; stopped at uid %u",
                                       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))
Line 154 
Line 254 
   
   
 void  void
 usage()  usage(void)
 {  {
         (void)fprintf(stderr,          (void)fprintf(stderr,
             "usage: calendar [-a] [-A days] [-B days] [-f calendarfile] [-t [[[yy]yy][mm]]dd]\n");              "usage: calendar [-ab] [-A num] [-B num] [-f calendarfile] "
               "[-t [[[cc]yy][mm]]dd]\n");
         exit(1);          exit(1);
   }
   
   
   void
   childsig(int signo)
   {
 }  }

Legend:
Removed from v.1.13  
changed lines
  Added in v.1.23