"SfR Fresh" - the SfR Freeware/Shareware Archive

Member "tulp-4.2.1/src/l.c" of archive tulp-4.2.1.tar.gz:


As a special service "SfR Fresh" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. That can be also achieved for any archive member file by clicking within an archive contents listing on the first character of the file(path) respectively on the according byte size field.
    1 /*
    2  * TULP - Unix Mailing List manager
    3  *        (sub-set of FRECP's Bitnet Listserv tool)
    4  *
    5  * Copyright (C) 1991-2000  Kimmo Suominen, Christophe Wolfhugel
    6  *
    7  * Please read the files COPYRIGHT and AUTHORS for the extended
    8  * copyrights refering to this file.
    9  *
   10  * This program is free software; you can redistribute it and/or modify
   11  * it under the terms of the GNU General Public License as published by
   12  * the Free Software Foundation; either version 1, or (at your option)
   13  * any later version.
   14  *
   15  * This program is distributed in the hope that it will be useful,
   16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   18  * GNU General Public License for more details.
   19  *
   20  * You should have received a copy of the GNU General Public License
   21  * along with this program; if not, write to the Free Software
   22  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   23  */
   24 
   25 #include <stdio.h>
   26 #include <string.h>
   27 #include <signal.h>
   28 #include <dirent.h>
   29 #include <time.h>
   30 #include <unistd.h>
   31 #include <ctype.h>
   32 #include <errno.h>
   33 #include <sys/ioctl.h>
   34 #include <sys/param.h>
   35 #include <sys/times.h>
   36 #include <sys/types.h>
   37 #include <sys/stat.h>
   38 #include "conf.h"
   39 #include "ext.h"
   40 #include "lp.h"
   41 #include "str.h"
   42 #include "popen.h"
   43 #include "ad.h"
   44 #include "lc.h"
   45 #include "messages.h"
   46 #ifdef FAKESYSLOG
   47 # include "fakesyslog.h"
   48 #else
   49 # include <syslog.h>
   50 #endif /* FAKESYSLOG */
   51 
   52 RCSID("@(#)l.c,v 1.15 2000/03/07 22:16:29 kim Exp")
   53 
   54 int Debug = 0;
   55 
   56 short subj;
   57 
   58 int done = 0;
   59 char listName[256], fname[256];
   60 char From[MAXLINE], To[MAXLINE], ReplyTo[MAXLINE], Approved[MAXLINE];
   61 char buf[MAXLINE], rcpt[MAXFIELD];
   62 int d, h, m, s;
   63 long startTime, endTime, msgSize;
   64 struct tms t;
   65 
   66 static int ctr;
   67 
   68 void lTodhms(long t)
   69 {
   70   d = t / (24 * 3600L);
   71   h = (t % (24 * 3600L)) / 3600;
   72   m = (t % 3600) / 60;
   73   s = t % 60;
   74 }
   75 
   76 char *instring(char *s1, char *s2)
   77 {
   78   if ((int) strlen(s2) > (int) strlen(s1))
   79     return (NULL);
   80   for (; *(s1 + strlen(s2) - 1); s1++)
   81     if (strncasecmp(s1, s2, strlen(s2)) == 0)
   82       return (s1);
   83   return (NULL);
   84 }
   85 
   86 char *strlwr(char *s)
   87 {
   88   char *p = s;
   89 
   90   if (s == NULL)
   91     return (NULL);
   92   for (; *s; s++)
   93     *s = tolower(*s);
   94   return (p);
   95 }
   96 
   97 char *strupr(char *s)
   98 {
   99   char *p = s;
  100 
  101   if (s == NULL)
  102     return (NULL);
  103   for (; *s; s++)
  104     *s = toupper(*s);
  105   return (p);
  106 }
  107 
  108 void pruneHeader(FILE *f, FILE *h)
  109 {
  110   char cmd[MAXFIELD + 256], *p;
  111   int c;
  112 
  113   while (fgets(cmd, sizeof(cmd), f) != NULL && cmd[0] != '\n') {
  114     /* if the line is too long, throw the rest away */
  115     if (strchr(cmd, '\n') == NULL) {
  116       while ((c = getc(f)) != '\n' && c != EOF)
  117 	continue;
  118     }
  119     while ((c = getc(f)) == ' ' || c == '\t') {
  120       p = &cmd[strlen(cmd)];
  121       *p++ = ' ';
  122       if (fgets(p, sizeof(cmd) - (p - cmd), f) == NULL)
  123 	break;
  124     }
  125     if (!feof(f) && !ferror(f))
  126       ungetc(c, f);
  127 
  128     /* We weed out all Resent- headers not to confuse MTAs */
  129     if (strncasecmp(cmd, "Resent-", 7) == 0)
  130       continue;
  131     /* We use Comments for our purposes */
  132     if (strncasecmp(cmd, "Comments: ", 10) == 0)
  133       continue;
  134     /* Prevent messages from showing up as "old" for recipients */
  135     if (strncasecmp(cmd, "Status: ", 8) == 0)
  136       continue;
  137     /* We will be putting in our own Precedence header */
  138     if (strncasecmp(cmd, "Precedence: ", 12) == 0)
  139       continue;
  140     if (strncasecmp(cmd, "X-Envelope-To: ", 15) == 0)
  141       continue;
  142     /* This is our internal header, do not forward it */
  143     if (strncasecmp(cmd, "X-Listserv-To: ", 15) == 0)
  144       continue;
  145     /* Broken mailer or deliver script seen somewhere */
  146     if (strncasecmp(cmd, ">From ", 6) == 0)
  147       continue;
  148     /* No, don't ack everyone to our request person */
  149     if (strncasecmp(cmd, "Return-Receipt-To: ", 19) == 0)
  150       continue;
  151     /*
  152      * X.400 loop detection is looking at these headers.  We remove
  153      * them to allow copies to be distributed to users behind X.400.
  154      * The stupid systems will bounce messages if they originated on
  155      * or behind the gateway thus preventing anyone anywhere on X.400
  156      * from getting their copy of the message.
  157      */
  158     if (strncasecmp(cmd, "X400-Received: ", 15) == 0)
  159       continue;
  160 #ifdef STRIP_RECEIVED
  161     /* Prevent loop detection */
  162     if (strncasecmp(cmd, "Received: ", 10) == 0)
  163       continue;
  164 #endif
  165     if (ReplyTo[0] != 0 && strncasecmp(cmd, "Reply-To: ", 10) == 0)
  166       continue;
  167     if (*GetErrorsTo() != '\0' && strncasecmp(cmd, "Errors-To: ", 11) == 0)
  168       continue;
  169 #ifdef ADD_SENDER
  170     if (strncasecmp(cmd, "Sender: ", 8) == 0)
  171       continue;
  172 #endif
  173     fputs(cmd, h);
  174   }
  175   fputs("Precedence: list\n", h);
  176 #ifdef ADD_SENDER
  177   fputs(versSender, h);
  178 #endif
  179 }
  180 
  181 void mailMsg(char *to, char *subj)
  182 {
  183   FILE *f, *g;
  184   char cmd[MAXLINE + 256];
  185 
  186   if ((f = fopen(fname, "r")) == NULL) {
  187     syslog(LOG_ERR, "mailMsg - fopen failed: %m");
  188     exit(2);
  189   }
  190   g = getMTA(to, "listserv", MTA_MAIL);
  191   fprintf(g, "To: %s\n", to);
  192   fprintf(g, "Subject: %s\n", subj);
  193   fprintf(g, "\n------- Forwarded message follows -------\n\n");
  194   while (fgets(cmd, sizeof(cmd), f) != NULL) {
  195     if (cmd[0] == '-') {
  196       fprintf(g, "- ");
  197     }
  198     fputs(cmd, g);
  199   }
  200   fprintf(g, "\n------- End of forwarded message -------\n");
  201   l_pclose(g);
  202   fclose(f);
  203 }
  204 
  205 void resendMsg(char *to, char *comment)
  206 {
  207   FILE *f, *g;
  208   char cmd[MAXLINE + 256];
  209 
  210   if ((f = fopen(fname, "r")) == NULL) {
  211     syslog(LOG_ERR, "resendMsg - fopen failed: %m");
  212     exit(2);
  213   }
  214   g = getMTA(to, "listserv", MTA_RESEND);
  215   pruneHeader(f, g);
  216   fprintf(g, "Resent-To: %s\n", to);
  217   fprintf(g, "Comments: %s\n", comment);
  218   fprintf(g, "\n");
  219   while (fgets(cmd, sizeof(cmd), f) != NULL) {
  220     fputs(cmd, g);
  221   }
  222   fclose(f);
  223   l_pclose(g);
  224 }
  225 
  226 void sendMsg()
  227 {
  228   char cmd[MAXFIELD + 256];
  229   FILE *f, *g;
  230 
  231   if ((f = fopen(fname, "r")) == NULL) {
  232     syslog(LOG_ERR, "sendMsg - fopen failed: %m");
  233     exit(2);
  234   }
  235   g = getMTA(rcpt, listName, MTA_RELAY);
  236   pruneHeader(f, g);
  237   if (*GetErrorsTo() != '\0')
  238     fprintf(g, "Errors-To: %s\n", GetErrorsTo());
  239   if (ReplyTo[0] != 0)
  240     fprintf(g, "Reply-To: %s\n", ReplyTo);
  241   if (subj == 0)
  242     fprintf(g, "Subject: <none>\n");
  243   if (ctr != 0)
  244     fprintf(g, "X-Sequence: %d\n", ctr);
  245   fprintf(g, "\n");
  246   while (fgets(cmd, sizeof(cmd), f) != NULL) {
  247     fputs(cmd, g);
  248   }
  249   fclose(f);
  250   l_pclose(g);
  251 }
  252 
  253 void saveMsg()
  254 {
  255   FILE *f, *g;
  256   long ti;
  257   struct tm *t;
  258   int dir = 0, oldfile = 0;
  259   char cmd[64];
  260   struct stat st;
  261 
  262   time(&ti);
  263   t = localtime(&ti);
  264   f = fopen(fname, "r");
  265   if (chdir(listName) == -1) {
  266     fclose(f);
  267     return;
  268   } else {
  269     dir = 1;
  270     sprintf(cmd, "log%04d%02d", t->tm_year + 1900, t->tm_mon + 1);
  271     oldfile = stat(cmd, &st) + 1;
  272     g = fopen(cmd, "a");
  273   }
  274   if (!oldfile) {
  275     fprintf(g, "This digest for list %s has been created on %s\n\n",
  276 	    listName, asctime(t));
  277     fputs("------- THIS IS A RFC934 COMPLIANT DIGEST, YOU CAN BURST IT -------\n\n", g);
  278   }
  279   while (fgets(buf, sizeof(buf), f) != NULL && buf[0] != '\n') {
  280     if (strncmp(buf, "Subject:", 8) == 0 || strncmp(buf, "Date:", 5) == 0)
  281       fputs(buf, g);
  282     if (strncmp(buf, "From:", 5) == 0) {
  283       fprintf(g, "From: %s\n", From);
  284       if (subj == 0)
  285 	fprintf(g, "Subject: <none>\n");
  286     }
  287     strlwr(buf);
  288   }
  289   if (ctr != 0)
  290     fprintf(g, "X-Sequence: %d\n", ctr);
  291   do {
  292     if (buf[0] == '-') {
  293       fprintf(g, "- ");
  294     }
  295     fputs(buf, g);
  296   } while (fgets(buf, sizeof(buf), f) != NULL);
  297   fputs("------- CUT --- CUT --- CUT --- CUT --- CUT --- CUT --- CUT -------\n\n", g);
  298   fclose(f);
  299   fclose(g);
  300   if (dir == 1)
  301     chdir(TULPDIR);
  302 }
  303 
  304 void reqMsg()
  305 {
  306   char cmd[128];
  307 
  308   strcpy(listName, To);
  309   if (ReadUserList(listName) == -1) {
  310     syslog(LOG_INFO, "Sending error (list not found)");
  311     mailMsg("listman", "List not found");
  312   } else {
  313     syslog(LOG_INFO, "List %s - Request from %s forwarded", listName, From);
  314     RewindOwnerList();
  315     while (GetOwner(cmd) != NULL)
  316       resendMsg(strtok(cmd, " \t\r\n"), "Request mail");
  317     CloseUserList();
  318   }
  319   unlink(fname);
  320 }
  321 
  322 void fwdMsg()
  323 {
  324   FILE *f, *g, *h;
  325   int i;
  326   char *p;
  327   char cmd[128];
  328 
  329   strcpy(listName, To);
  330   if (ReadUserList(listName) == -1) {
  331     syslog(LOG_INFO, "Sending error (list not found)");
  332     mailMsg("listman", "List not found");
  333     unlink(fname);
  334     return;
  335   }
  336   strcpy(buf, GetReplyTo());
  337   if (ReplyTo[0] == 0 || instring(buf, ",respect") == NULL) {
  338     if (strncasecmp(buf, "list", 4) == 0) {
  339       strcpy(cmd, listName);
  340       strupr(cmd);
  341       sprintf(ReplyTo, "%s Distribution List <%s@%s>", cmd, listName, HOST);
  342     } else if (strncasecmp(buf, "sender", 6) != 0)
  343       sprintf(ReplyTo, "%s", strtok(buf, ","));
  344   }
  345   RewindUserList();
  346   if (strcasecmp(GetSend(), "private") == 0 && !IsUser(From)) {
  347     syslog(LOG_INFO,
  348 	   "Mail to list %s from %s - Refused, this user is not allowed",
  349 	   listName, From);
  350     sprintf(buf, "%s %s", SENDMAIL, strtok(From, " "));	/* NAK to sender */
  351     if ((g = l_popen(buf, "w")) == NULL) {
  352       syslog(LOG_ERR, "fwdMsg - popen failed: %m");
  353       unlink(fname);
  354       CloseUserList();
  355       return;
  356     }
  357     if ((f = fopen(fname, "r")) == NULL) {
  358       syslog(LOG_ERR, "fwdMsg - fopen failed: %m");
  359       unlink(fname);
  360       CloseUserList();
  361       return;
  362     }
  363     fprintf(g, TULP_HDRMAILNAK(From, listName));
  364     fprintf(g, TULP_MAILPRIVATE);
  365     while (fgets(buf, sizeof(buf), f) != NULL)	/* unsent message */
  366       fputs(buf, g);
  367     l_pclose(g);
  368     fclose(f);
  369     RewindOwnerList();
  370     while (GetOwner(buf) != NULL)
  371       mailMsg(strtok(buf, " \t\r\n"), "Sent by a non-subscriber");
  372   } else if (strcasecmp(GetSend(), "editor") == 0
  373 	     && !IsEditor(Approved) && !IsEditor(From)) {
  374     syslog(LOG_INFO, "Mail to list %s from %s - Article to moderate",
  375 	   listName, From);
  376     RewindEditorList();
  377     while (GetEditor(buf) != NULL)
  378       mailMsg(strtok(buf, " \t\r\n"), "Article to moderate");
  379   } else {			/* Ok to send */
  380     strcpy(buf, listName);	/* X-Sequence - update listName.n */
  381     strcat(buf, ".n");
  382     ctr = 0;
  383     h = fopen(buf, "r+");
  384     if (h != NULL) {
  385       fscanf(h, "%d", &ctr);
  386       rewind(h);
  387       fprintf(h, "%d\n", ++ctr);
  388       fclose(h);
  389     }
  390     syslog(LOG_INFO, "List %s - Msg from %s accepted", listName, From);
  391     saveMsg();			/* save Msg in log file */
  392     i = 0;
  393     p = rcpt;
  394     while (GetUser(buf) != NULL) {
  395       strtok(buf, "\t\r\n ");
  396       if ((((p - rcpt) + strlen(buf) + 2) > sizeof(rcpt))
  397 	  || (i++ > BATCHSIZE - 1)) {
  398 	i = 1;
  399 	p = rcpt;
  400 	sendMsg();
  401       }
  402       sprintf(p, "%s ", buf);
  403       p += strlen(p);
  404     }
  405     if (i != 0)
  406       sendMsg();
  407   }
  408   unlink(fname);
  409   CloseUserList();
  410 }
  411 
  412 int copyMail(char *file)
  413 {
  414   FILE *h;
  415   char *p;
  416   int c;
  417   struct stat st;
  418 
  419   if ((h = fopen(file, "r")) == NULL)
  420     return (-1);
  421   To[0] = 0;
  422   fstat(fileno(h), &st);
  423   msgSize = st.st_size;
  424   subj = 0;
  425   To[0] = ReplyTo[0] = Approved[0] = 0;
  426   while (fgets(buf, sizeof(buf), h) != NULL && buf[0] != '\n') {
  427     /* if the line is too long, throw the rest away */
  428     if (strchr(buf, '\n') == NULL) {
  429       while ((c = getc(h)) != '\n' && c != EOF)
  430 	continue;
  431     }
  432     while ((c = getc(h)) == ' ' || c == '\t') {
  433       p = &buf[strlen(buf) - 1];
  434       *p++ = ' ';
  435       if (fgets(p, sizeof(buf) - (p - buf), h) == NULL)
  436 	break;
  437     }
  438     if (!feof(h) && !ferror(h))
  439       ungetc(c, h);
  440     strtok(buf, "\n");
  441     if (Debug)
  442       fprintf(stderr, "Collected line: %s\n", buf);
  443     if (strlen(buf) > MAXLINE) {
  444       syslog(LOG_ERR, "Header line too long: %s", strtok(buf, ":"));
  445       fclose(h);
  446       return (-2);
  447     }
  448     if (strncmp(buf, "Reply-To: ", 10) == 0)
  449       strcpy(ReplyTo, buf + 10);
  450     if (strncmp(buf, "Subject: ", 9) == 0) {
  451       /* We could save subject here, but we don't need it */
  452       subj = 1;
  453       continue;
  454     }
  455     if (strncmp(buf, "From: ", 6) == 0) {
  456       /* Usually just one author */
  457       strcpy(From, buf + 6);
  458       continue;
  459     }
  460     if (strncmp(buf, "Approved: ", 10) == 0) {
  461       strcpy(Approved, buf + 10);
  462       continue;
  463     }
  464     if (strncmp(buf, "X-Listserv-To: ", 15) == 0) {
  465       strcpy(To, buf + 15);
  466       continue;
  467     }
  468   }
  469   adChange(From);
  470   strlwr(To);
  471   fclose(h);
  472   if (To[0] == 0) {
  473     syslog(LOG_ERR, "X-Listserv-To is empty or not found");
  474     return (-2);
  475   }
  476   return (0);
  477 }
  478 
  479 void sTe()
  480 {
  481   done = 1;
  482 }
  483 
  484 void main(int argn, char **argv)
  485 {
  486   struct sigaction sa;
  487   int i;
  488   long clk_tck;
  489   char *p;
  490   extern void reapchild();
  491   DIR *qdir;
  492   struct dirent *qfile;
  493 
  494   while ((i = getopt(argn, argv, "d")) != EOF) {
  495     switch (i) {
  496     case 'd':
  497       Debug = 1;
  498       break;
  499     default:
  500       fprintf(stderr, "usage: %s [-d]\n", *argv);
  501       exit(1);
  502     }
  503   }
  504   if (chdir(TULPDIR) == -1) {
  505     perror("Can't chdir' to TULPDIR. Aborting.");
  506     exit(2);
  507   }
  508   versInit();
  509   setbuf(stdout, NULL);
  510   printf("%s: daemon started for %s\n\r", vers, HOST);
  511   printf("Copyright (C) 1991-1997  Kimmo Suominen, Christophe Wolfhugel\n");
  512   printf("Listserv comes with ABSOLUTELY NO WARRANTY; for details see\n");
  513   printf("the GNU General Public License that is furnished with the\n");
  514   printf("sources of this package.\n");
  515   if (Debug == 0)
  516     if (fork())
  517       exit(0);			/* Dissociate us from tty */
  518   times(&t);
  519   time(&startTime);
  520   nice(NICENESS);
  521   if (Debug == 0) {
  522     freopen("/dev/null", "w", stdout);
  523     freopen("/dev/null", "w", stderr);
  524     close(fileno(stdin));
  525     setpgid(0, 0);
  526   }
  527   sigemptyset(&sa.sa_mask);
  528 #ifdef SA_RESTART
  529   sa.sa_flags = SA_RESTART;	/* Restart system calls?  SA_RESTART */
  530   /* Children?  SA_NOCLDWAIT, SA_NOCLDSTOP */
  531 #else
  532   sa.sa_flags = 0;
  533 #endif
  534   sa.sa_handler = sTe;
  535   sigaction(SIGTERM, &sa, NULL);
  536 #ifdef SIGURGENT
  537   sigaction(SIGURGENT, &sa, NULL);
  538 #endif
  539   sa.sa_handler = SIG_IGN;
  540   /* SA_RESETHAND: Reset to SIG_DFL, not blocked */
  541   /* sa.sa_flags = SA_RESETHAND; */
  542   sa.sa_handler = reapchild;
  543   sigaction(SIGCHLD, &sa, NULL);
  544   umask(022);
  545   openlog("listserv", LOG_PID, LOG_MAIL);
  546   syslog(LOG_INFO, "Listserv Started");
  547   umask(077);
  548   while (!done) {
  549     qdir = opendir(QUEUEDIR);
  550     if (qdir == NULL) {
  551       syslog(LOG_CRIT, "Failed to open Qdir");
  552       exit(1);
  553     }
  554     while (!done && (qfile = readdir(qdir)) != NULL) {
  555       if (qfile->d_name[0] < '0' || qfile->d_name[0] > '9')
  556 	continue;
  557       sprintf(fname, "%s/%s", QUEUEDIR, qfile->d_name);
  558       if ((i = copyMail(fname)) == -1)
  559 	continue;
  560       if (i == -2) {
  561 	mailMsg("listman", "Unknown error, see syslog");
  562 	unlink(fname);
  563 	continue;
  564       }
  565       if ((strcmp(To, "listman") == 0) ||
  566 	  (strcmp(To, "postmaster") == 0) ||
  567 	  (strcmp(To, "listserv-request") == 0)) {
  568 	syslog(LOG_INFO, "Mail for ListMan");
  569 	resendMsg("listman", "Mail for ListMan");
  570 	unlink(fname);
  571 	continue;
  572       }
  573       if (((p = strrchr(To, '-')) != NULL) && (strcmp(p, "-request") == 0)) {
  574 	*p = '\0';
  575 	reqMsg();
  576 	continue;
  577       }
  578       if (instring(From, "mailer-") != NULL ||
  579 	  instring(From, "mailer@") != NULL ||
  580 	  instring(From, "postmaster@") != NULL ||
  581 	  instring(From, "listserv@") != NULL ||
  582 	  instring(From, "root@") != NULL ||
  583 	  instring(From, "system@") != NULL ||
  584 	  instring(From, "-request@") != NULL ||
  585 	  instring(From, "owner-") != NULL) {
  586 	syslog(LOG_INFO, "Message from Mailer-Daemon");
  587 	mailMsg("listman", "Message from Mailer-Daemon");
  588 	unlink(fname);
  589 	continue;
  590       }
  591       if (strcmp(To, "listserv") == 0) {
  592 	listservCmd(fname);
  593 	continue;
  594       }
  595       fwdMsg();
  596     }
  597     closedir(qdir);
  598     sleep(60);
  599   }
  600   clk_tck = sysconf(_SC_CLK_TCK);
  601   if (clk_tck < 0) {
  602     syslog(LOG_ERR, "Could not get CLK_TCK, defaulting to 100\n");
  603     syslog(LOG_ERR, "sysconf(_SC_CLK_TCK): %s\n", strerror(errno));
  604     clk_tck = 100;
  605   }
  606   syslog(LOG_INFO, "Listserv has been terminated");
  607   time(&endTime);
  608   lTodhms(endTime - startTime);
  609   times(&t);
  610   t.tms_utime += t.tms_cutime;
  611   t.tms_stime += t.tms_cstime;
  612   syslog(LOG_INFO, "Total elapsed time: +%dd %02d:%02d:%02d\n", d, h, m, s);
  613   lTodhms(t.tms_utime / clk_tck);
  614   syslog(LOG_INFO, "User CPU time:      +%dd %02d:%02d:%02d\n", d, h, m, s);
  615   lTodhms(t.tms_stime / clk_tck);
  616   syslog(LOG_INFO, "System CPU time:    +%dd %02d:%02d:%02d\n", d, h, m, s);
  617   lTodhms((t.tms_utime += t.tms_stime) / clk_tck);
  618   syslog(LOG_INFO, "Total CPU time:     +%dd %02d:%02d:%02d\n", d, h, m, s);
  619   syslog(LOG_INFO, "%% CPU used:  %02.02f%%\n",
  620     (float) (t.tms_utime / clk_tck * 100) / (float) (endTime - startTime + 1));
  621   closelog();
  622   exit(0);
  623 }