home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / Fravia / fravia / remailer.c < prev    next >
C/C++ Source or Header  |  2000-05-25  |  36KB  |  1,150 lines

  1. /* Cypherpunks Type 1 Anonymous Remailer */
  2. /* Code published on http://www.fravia.org on 26 November 98 */
  3.  
  4. #undef CONFIGURED
  5.  
  6. /* REMAILER INSTALLATION AND CONFIGURATION INSTRUCTIONS
  7.  
  8. First, load the file remailer.c into your favorite editor.  You will see a
  9. series of #define statements at the beginning.  These should be changed to
  10. suit your needs.  The values are:
  11.  
  12. DIR - The directory path where the remailer is.
  13.  
  14. ANONFROM - This is what is used as the From line when the remailer sends
  15.  an anonymous message.  It should begin with From: and end with a \n
  16.  
  17. ANONREPLYTO - This is used for "Reply-To: wherever \n" to discourage replies.
  18.  
  19. REMAILERFROM - This is what should go in the From line when the remailer
  20.  returns a help or stats response.  It should also begin with From: and
  21.  end with \n
  22.  
  23. REMAILERADDRESS - The address of the remailer.  This should contain the
  24.  remailer's email address only.
  25.  
  26. RETURN (Optional) - If defined, the remailer calls sendmail with the -f
  27.  option and uses this as the return address.  Generally, errors or bounces
  28.  will get sent to this address.
  29.  
  30. DISCLAIMER - Any header you want inserted into an anonymous message to
  31.  identify where to send complaints, etc
  32.  
  33. NONANONDISC - A header to be inserted into messages when sent with the
  34.  non-anonymous forwarding feature.
  35.  
  36. SPOOL - The file to append non-remailer messages to.  Usually
  37.  /var/spool/mail/remailer if the account is named "remailer".
  38.  
  39. SPAM_THRESHOLD (optional) - If more than this number of messages arrive
  40.  before they can be processed, the remailer will stop processing
  41.  messages.  This is to prevent spams and mailbombs.  If this happens,
  42.  you will need to remove the extra messages from the in.queue directory
  43.  before the remailer will function again. 
  44.  
  45. WAIT_SEC (optional) - After delivering a message, the remailer will wait
  46.  this many seconds before delivering another one.  Increasing this value
  47.  can reduce system load, but will make it possible to reach the spam
  48.  threshold more easily.
  49.  
  50. DEFAULT_LATENCY (optional) - If this is defined, any message which does
  51.  not have a latent-time header will have a random delay added to it, not
  52.  exceeding this number of seconds.  (1 hour = 3600 seconds)
  53.  
  54. PGP - The pathname of your PGP executable
  55. PGPPASS - The password to the remailer's PGP secret key.
  56. PGPPATH - Sets the PGPPATH environment variable.  Normally the same as DIR
  57.  
  58. INEWS - The pathname to the INEWS executable for usenet posts.  
  59.  If this is not defined, the remailer does not allow posting.
  60.  Often /usr/lib/news/inews, but may be different depending on your system.
  61. NNTPSERVER - The NNTP server to use for posting.  If defined, sets the
  62.  enviornment variable NNTPSERVER when calling INEWS.
  63.  
  64. LS - The ls program.  Usually /bin/ls
  65. SENDMAIL - Sendmail.  Usually /usr/lib/sendmail
  66.  
  67. The rest are the names of the files the remailer uses.  They are all
  68. relative to DIR, and except for remailer-help, are created by the remailer
  69. if they do not exist.  You shouldn't need to change them.  They are:
  70. BLOCKFROM: the name of the source block list (default: source.block)
  71. BLOCKTO: the name of the destination block list (default: dest.block)
  72. INQUEUE: The directory for incoming messages (default: in.queue)
  73. OUTQUEUE: The directory for outgoing messages (default: out.queue)
  74. TEMPDIR: Directory for temporary files (default: temp)
  75. STATSDATA: File to keep usage statistics in (default: statsdata)
  76. HELPFILE: The "remailer-help" file
  77.  
  78.  
  79. After setting up the remailer, compile it by typing:
  80.  gcc remailer.c -o remailer
  81.  
  82. Next, create a PGP key for the remailer.  Be sure the password matches the
  83. one you put in remailer.c, and put the pubring and secring in the directory
  84. you set for PGPPATH.  Extract the key with ascii armor and put it into the
  85. remailer-help file.  Be sure to have a randseed.bin file in the directory,
  86. or PGP will not run properly.
  87.  
  88. Finally, create a .forward file in your home directory.  In it, put a | as
  89. the first character, followed by the complete pathname of the remailer
  90. executable.  For example, if the remailer was in the home directory of the
  91. account "remailer", and user directories were under /home, you would put:
  92. |/home/remailer/remailer
  93.  
  94. The remailer should now be operational.  Send a test message from another
  95. account to be sure it works.  If you defined a default latency, you will
  96. need to put a Latent-Time: +0:00 header to get an immediate response.
  97.  
  98.  
  99. Address Blocking
  100.  
  101. Two files specify lists of addresses to block.  Any message coming from an
  102. address specified in the source.block file is discarded.  Any message sent
  103. to an address in the dest.block file is similarly discarded.  The dest.block
  104. file can also be used to block posts to newsgroups.  The blocking files
  105. consist of a list of addresses, one on each line.  Addresses will be matched
  106. regardless of whether it is upper or lower case.  A * may be used as a
  107. wildcard.  For example, spammer@*.velveeta.com would block the address
  108. spammer at any subdomain of velveeta.com.  Any line beginning with
  109. a ! is an exclusion, and the address following it will be unblocked even
  110. if it matched a previous line.  An exclusion must come after the line
  111. which would block it.  Any line beginning with a # is treated as a comment
  112. line, and is ignored.
  113.  
  114.  
  115. Message Delivery and Cron
  116.  
  117. Every time the remailer is run, it also checks the outgoing message queue
  118. to see if there are any latent messages to be delivered.  Ordinarilly the
  119. messages will be delayed until the next time a message comes in, but you
  120. can set up a cron job to deliver the waiting messages in a more timely
  121. fashion.  To get the remailer to deliver queued messages, execute the
  122. remailer and send it an empty message with the command: remailer </dev/null
  123.  
  124. /* END OF INSTALLATION INSTRUCTIONS */
  125.  
  126.  
  127. /* ----------------------------------------- */
  128. /* Modify these variables to fit your system */
  129. /* ----------------------------------------- */
  130.  
  131. #ifndef CONFIGURED
  132.  
  133. #define DIR "/home/remailer"
  134. #define ANONFROM "From: nobody@foo.com (Anonymous)\n"
  135. #define ANONREPLYTO "Reply-To: unsupported@localhost (This remailer doesn't support replies)\n"
  136. #define REMAILERFROM "From: remailer@foo.com (Foo Remailer)\n"
  137. #define REMAILERADDRESS "remailer@foo.com"
  138. #define RETURN "remailer@foo.com"
  139. #define DISCLAIMER "Comments: Please report misuse of this automated remailing service to <remailer-admin@foo.com>\nComments: The message sender's identity is unknown, unlogged, and not replyable.\n"
  140. #define NONANONDISC "Comments: This message was forwarded by an automated remailing service.  No attempt was made to verify the sender's identity, whcihis unknown and not logged.  Reply messages will not reach the sender.  Please report misuse to <complaints@site>\n"
  141. #define SPOOL "/var/spool/mail/remailer"
  142. #define SPAM_THRESHOLD 25
  143. #define WAIT_SEC 30
  144. #define DEFAULT_LATENCY 3600
  145.  
  146. #define PGP "/usr/local/bin/pgp"
  147. #define PGPPASS "password"
  148. /* Boy is this real secure leaving the password around like this! */
  149. #define PGPPATH DIR
  150. #define INEWS "/usr/lib/news/inews"
  151. #define NNTPSERVER "127.0.0.1"
  152. #define LS "/bin/ls"
  153. #define SENDMAIL "/usr/lib/sendmail"
  154.  
  155. #define BLOCKFROM "source.block"
  156. #define BLOCKTO "dest.block"
  157. #define INQUEUE "in.queue"
  158. #define OUTQUEUE "out.queue"
  159. #define TEMPDIR "temp"
  160. #define HELPFILE "remailer-help"
  161. #define STATSDATA "statsdata"
  162. #define SPAMWARNFILE "spam-warn"
  163. #endif CONFIGURED
  164.  
  165. /* ------------------------------------------------------ */
  166. /* You shouldn't need to modify anything beyond this line */
  167. /* ------------------------------------------------------ */
  168.  
  169. /* History 
  170.  
  171.    Matt Ghio version on usura, Bill Stewart modified
  172.  
  173. /* End of history */
  174.  
  175. #include <stdio.h>
  176. #include <stdlib.h>
  177. #include <unistd.h>
  178. #include <signal.h>
  179. #include <time.h>
  180. #include <sys/time.h> /* some os need this one also */
  181. /*File io stuff:*/
  182. #include <sys/types.h>
  183. #include <sys/stat.h>
  184. #include <fcntl.h>
  185.  
  186. /* arrays need to be at least 1001 long to accommodate RFC822 */
  187. #define    MAXLEN    1024
  188.  
  189. /* added stuff to fake out djgpp for testing under DOS */
  190. #ifdef __GO32__
  191. #define SIGCONT 99
  192. #endif
  193.  
  194.  
  195. FILE *infile;
  196. FILE *outfile;
  197. FILE *tempfile;
  198. FILE *file2;
  199. char from[MAXLEN]="";
  200. char from_address[MAXLEN]="";
  201. char cutmarks[MAXLEN]="";
  202. int anon_flag=0;
  203. int help_flag=0;
  204. int stat_flag=0;
  205. int pgp_flag=0;
  206. char replykey[80]="";
  207. char idbuf[17];
  208. int idcount=0;
  209. struct timeval tp;
  210. unsigned long latime;
  211. int blockflag;
  212. int nospamcheck_flag=0;
  213.  
  214. /* extract name and address from From: line input */
  215. /* ASSERT: Bounds checking not needed because main() does it */
  216. void getfrom(char *input){
  217.   int x=0,y=0;
  218.   while(input[x]!=':'){x=x+1;}
  219.   x=x+1;
  220.   while(input[x]<=32){x=x+1;}
  221.   while(input[x]>32){
  222.     from_address[y]=input[x];
  223.     x=x+1;y=y+1;
  224.   }
  225.   from_address[y]=0;
  226.   x=0; /* look for <address> */
  227.   while(input[x]>31&&input[x]!='<'){x=x+1;}
  228.   if(input[x]=='<'){
  229.     y=0;x=x+1;
  230.     while(input[x]>32&&input[x]!='>'){
  231.       from_address[y]=input[x];
  232.       x=x+1;y=y+1;
  233.     }
  234.     from_address[y]=0;
  235.   }
  236. }
  237.  
  238. /* block any addresses matching patterns in file */
  239. /* returns result by zeroing address[0] */
  240. /* crude wildcarding (*) case-insensitive matches */
  241. /* ASSERT: Bounds checking not needed because main() does it */
  242. void block_addr(char address[],char *file) {
  243.   char input[MAXLEN];
  244.   int match=0;
  245.   int x,y,z;
  246.   int exclude;
  247.  
  248.   FILE *killfile;
  249.  
  250.   chdir(DIR);
  251.   if(killfile=fopen(file,"r")){
  252.     while(fscanf(killfile,"%s",input)>0) {
  253.       if (input[0]!='#'&&input[0]>32) {
  254.         x=0;exclude=0;z=0;
  255.         if (input[0]=='!') {exclude=1;z++;} 
  256.     while(address[x]!=0) {
  257.           y=0;
  258.           while ((address[x+y]|32)==(input[y+z]|32)&&input[y+z]!='*'
  259.               &&input[y+z]!=0&&address[x+y]!=0) {
  260.             y++;
  261.       }
  262.           if (input[y+z]==0) match=(1^exclude);
  263.           if (input[y+z]=='*') {z=z+y+1;x=x+y;}
  264.           else x++;
  265.         }
  266.       }
  267.     }
  268.     fclose(killfile);
  269.   }
  270.   if (match==1) address[0]=0;
  271. }
  272.  
  273. /* find str1 in case-insensitive str2 */
  274. /* only used to check for remailer-* strings */
  275. int search(char str1[],char str2[]) {
  276.   int x=0;
  277.   int y=0;
  278.   int match=0;
  279.  
  280.   while(str2[x]!=0) {
  281.     y=0;
  282.     while ((str2[x+y]==str1[y]||str2[x+y]==(str1[y]-32))&&str2[x+y]!=0) {
  283.       y++;
  284.       if (str1[y]==0) match=1;
  285.     }
  286.     x++;
  287.   }
  288.   return(match);
  289. }
  290.  
  291. /* strncmp variant, case-insensitive, returns 1 for match else 0 */
  292. /* compares first strlen(str2) characters (not sure if this is
  293.    being efficient or just inviting bugs :-) but I want to prevent
  294.    the programmer from having to count characters, and if I just
  295.    check for the first end-of-string, it invites problems like
  296.    match("S","Subject:") 
  297. */
  298. int match(char *source, char *pattern)
  299. {
  300.     register char *s, *p;
  301.     s=source; p=pattern; 
  302.     while (*p && ((*s++)|32)==((*p++)|32)) ;
  303.     if (*p) return 0;
  304.     return 1;
  305. }
  306.  
  307.  
  308. /* Workhorse subroutine - scans header lines for remailer-related info */
  309. /* used to have lots of complex hand-built string compares;
  310.    replacing most with match */
  311. /* ASSERT: Bounds checking not needed because main() does it */
  312. void scanline(char input[],char resend_address[]) {
  313.   register int x,y,z;
  314.   int resend_flag=0;
  315.   int cutmarks_flag=0;
  316.   int post_flag=0;
  317.   int latent_plusflag;
  318.   int latent_randflag;
  319.   int latent_h;
  320.   int latent_m;
  321.   int latent_s;
  322.   int reply_check=0;
  323.  
  324.   /* Pass thru Subject, Content-Type, and In-Reply-To lines */
  325.   if (match(input,"Subject:")) {
  326.      /* if the subject line is blank, drop it */
  327.     if (input[8]!=0&&input[9]!=0) fprintf(outfile,"%s",input);
  328.     /* and handle special case subjects for help and stats */
  329.     /* but prevent loops (and denial-of-service) */
  330.     if (strncmp(input+9,"Re:",3)!=0) { 
  331.         if (search("remailer-stat",input)) {
  332.           latime=tp.tv_sec; /* No latency */
  333.           stat_flag=1;
  334.         }
  335.         if (search("remailer-help",input)||search("remailer-info",input) || search("help", input) ) {
  336.           latime=tp.tv_sec; /* No latency */
  337.           help_flag=1;
  338.         }
  339.     }
  340.   }
  341.   else if (match(input, "Content-")) {
  342.     fprintf(outfile,"%s",input);
  343.   }
  344.   else if (match(input, "In-Reply-To:")) {
  345.     fprintf(outfile,"%s",input);
  346.   }
  347.   
  348.   /* Save the From: line in case non-anonymous posting is requested */
  349.   /* (only From: and not From ) */
  350.   else if (match(input, "From:")) {
  351.     getfrom(input);block_addr(from_address,BLOCKFROM);
  352.     if(from_address[0]==0) blockflag=1; /* Source block */
  353.     block_addr(input,BLOCKTO);
  354.     strcpy(from,input);
  355.   }
  356.  
  357. /* Match headers */
  358.   else if (match(input,"Request-Remailing-To:")) { resend_flag=1; anon_flag=1; }
  359.   else if (match(input,"Remail-To:")) { resend_flag=1; anon_flag=1; }
  360.   else if (match(input,"Anon-To:")) { resend_flag=1; anon_flag=1; }
  361.   else if (match(input,"Anon-Send-To:")) { resend_flag=1; anon_flag=1; }
  362.   else if (match(input,"Post-To:")) { resend_flag=1; }
  363.   /* soda.berkeley style Send-To ? */
  364.   else if (match(input,"Send-To:")) { resend_flag=1; }
  365.  
  366. #define HEADERTOOLONG 100
  367. /* Check for PGP...   I got a little sloppy here...ohwell*/
  368.   else if (match(input,"Encrypted:")) { resend_flag=0; pgp_flag=1; }
  369.   else if (match(input,"Encrypt-")) {
  370.     x=7;y=0;
  371.     while(input[x++]!=':') {if (x>HEADERTOOLONG) goto hosed;}
  372.     while(input[x]==' '||input[x]=='\t'){x=x+1;}
  373.     z=x; /* what's this z for??? */
  374.     while(input[x]>' ') {replykey[y++]=input[x++];} /* ASSERT: input[1023]=0 */
  375.     replykey[y]=0;
  376.     hosed: ;
  377.   
  378.   }
  379.   else if (match(input,"Cutmarks:")||match(input,"Cutmark:")) {
  380. cutmarks_flag=1; }
  381.  
  382.   /* process input to get address */
  383.   if(resend_flag){
  384.     x=2;y=0; /* x=2 in case Extropians-style ::Header */
  385.     while(input[x]!=':'){x=x+1;}
  386.     x=x+1;
  387.     while(input[x]<=32){x=x+1;}
  388.     z=x;
  389.     if (post_flag==0) {
  390.       while(input[x]>32){
  391.         resend_address[y]=input[x];
  392.         x=x+1;y=y+1;
  393.       }
  394.       resend_address[y]=0;
  395.       x=0; /* look for <address> */
  396.       while(input[x]>31&&input[x]!='<'){x=x+1;}
  397.       if(input[x]=='<'){
  398.         y=0;x=x+1;
  399.         while(input[x]>32&&input[x]!='>'){
  400.           resend_address[y]=input[x];
  401.           x=x+1;y=y+1;
  402.         }
  403.         resend_address[y]=0;
  404.       }
  405.       /* Print out new To: line */
  406.       fprintf(outfile,"To: ");
  407.       while(input[z]>0){
  408.         fprintf(outfile,"%c",input[z]);
  409.         z=z+1;
  410.       }
  411.       block_addr(resend_address,BLOCKTO);
  412.     }
  413.     if (post_flag) {
  414.       fprintf(outfile,"Newsgroups: ");
  415.       while(input[z]>0){
  416.         fprintf(outfile,"%c",input[z]);
  417.         z=z+1;
  418.       }
  419.       resend_address[0]='p';
  420.       resend_address[1]='o';
  421.       resend_address[2]='s';
  422.       resend_address[3]='t';
  423.       resend_address[4]=0;
  424.       block_addr(input,BLOCKTO);if (input[0]==0) resend_address[0]=0;
  425.     }
  426.   }
  427.  
  428.   if(cutmarks_flag){
  429.     x=0;y=0;
  430.     while(input[x]!=':'){x=x+1;}
  431.     x=x+1;
  432.     if(input[x]==32){x=x+1;}
  433.     z=x;
  434.     while(input[x]>32){
  435.       cutmarks[y]=input[x];
  436.       x=x+1;y=y+1;
  437.     }
  438.     cutmarks[y]=0;
  439.   }
  440.  
  441.   if (match(input,"Latent-Time:")) {
  442.     x=12;
  443.     while (input[x]==' '||input[x]=='\t'){x++;}
  444.  
  445.     latent_plusflag=0;latent_randflag=0;
  446.     latent_h=0;latent_m=0;latent_s=0;
  447.  
  448.     while((input[x]<'0'||input[x]>'9')&&input[x]>=32) {
  449.       if (input[x]=='+') latent_plusflag=1;
  450.       if ((input[x]=='r')||(input[x]=='R')) latent_randflag=1;
  451.       x++;
  452.     }
  453.     while (input[x]>='0'&&input[x]<='9') {
  454.       latent_h=(latent_h*10)+(input[x]-48);
  455.       x++;
  456.     }
  457.     if(input[x]==':') {
  458.       x++;
  459.       while (input[x]>='0'&&input[x]<='9') {
  460.         latent_m=(latent_m*10)+(input[x]-48);
  461.         x++;
  462.       }
  463.       if(input[x]==':') {
  464.         x++;
  465.         while (input[x]>='0'&&input[x]<='9') {
  466.           latent_s=(latent_s*10)+(input[x]-48);
  467.           x++;
  468.         }
  469.       }
  470.     }
  471.     while(input[x]>=32) {
  472.       if (input[x]=='+') latent_plusflag=1;
  473.       if ((input[x]=='r')||(input[x]=='R')) latent_randflag=1;
  474.       x++;
  475.     }
  476.  
  477.     latime=(latent_h*3600+latent_m*60+latent_s);
  478.  
  479.     if(latent_plusflag==0) {
  480.       /* Not Supported - Is this really necessary? */
  481.     }
  482.  
  483.     if(latent_randflag&&(latime>1)) {
  484.       /* Simple randomizer */
  485.       latime=abs((tp.tv_sec^latime)+tp.tv_usec+(getpid()*latime))%(latime+1);
  486.     }
  487.  
  488.     latime+=tp.tv_sec;
  489.   }
  490. }
  491.  
  492. char* genid() { /* Generate ascii id from process id and time with shuffle */
  493.   unsigned long int id1,id2;
  494.   int x=0;
  495.   
  496.   id1=getpid()|(idcount<<16);
  497.   id2=tp.tv_sec;
  498.   idcount++;
  499.   
  500.   for(x=32;x--;){
  501.     id1+=1234567890;
  502.     id1^=0xABCDEF12;
  503.     id1=(id1<<1)|(id1>>31);
  504.     id2^=id1;
  505.     id2+=0x12345678;
  506.     id2^=0x9ABCDEF0;
  507.     id2=(id2<<31)|(id2>>1);
  508.     id1^=id2;
  509.   }
  510.   for(x=0;x<8;x++) {
  511.     idbuf[x]=65+(id1&15);
  512.     id1=id1>>4;
  513.   }
  514.   for(x=8;x<16;x++) {
  515.     idbuf[x]=65+(id2&15);
  516.     id2=id2>>4;
  517.   }
  518.   idbuf[16]=0;
  519.   return(idbuf);
  520. }
  521.  
  522. /* Re-encrypt messages for use with reply-blocks */
  523. void reencrypt(){
  524.   char input[MAXLEN];
  525.   int pipefd[2];
  526.   int pipe2fd[2];
  527.  
  528.   input[MAXLEN-1]=0;
  529.   pipe(pipefd);
  530.   pipe(pipe2fd);
  531.   if(!fork()) {
  532.     dup2(pipefd[0],0);
  533.     dup2(pipe2fd[1],1);
  534.     close(pipefd[1]);
  535.     close(pipe2fd[0]);
  536.     chdir(DIR);
  537.     execl(PGP,"pgp","-fcta","+BATCHMODE","+ARMORLINES=0","-z",replykey,(char
  538. *)0);
  539.   }
  540.   close(pipefd[0]);close(pipe2fd[1]);
  541.   file2=fdopen(pipefd[1],"w");
  542.   while(fgets(input,MAXLEN-1,infile)) {
  543.     fprintf(file2,"%s",input);
  544.   }
  545.   fclose(file2);
  546.   file2=fdopen(pipe2fd[0],"r");
  547.   while(fgets(input,MAXLEN-1,file2)) {
  548.     fprintf(outfile,"%s",input);
  549.   }
  550.   fclose(file2);
  551. }
  552.  
  553. void updatestats(int inccnt,int incpgp,int inclat,int incpost) {
  554.   int m[24];
  555.   int ccm=0;
  556.   int p[24];
  557.   int ccpgp=0;
  558.   int l[24];
  559.   int ccl=0;
  560.   int u[24];
  561.   int ccnews=0;
  562.   char month[24][5];
  563.   int date[24];
  564.   int hour=0;
  565.   int currenthour;
  566.   FILE *datafile;
  567.   int x;
  568.   int y;
  569.   struct tm *timestr;
  570.  
  571.   timestr=localtime(&(tp.tv_sec));
  572.  
  573.   if(datafile=fopen(STATSDATA,"r")){
  574.     fscanf(datafile,"%d",&hour);
  575.     fscanf(datafile,"%d %d %d %d",&ccm,&ccpgp,&ccl,&ccnews);
  576.     for(x=0;x<24;x++) {
  577.       fscanf(datafile,"%s %d %d %d %d %d",
  578.              month[x],&date[x],&m[x],&p[x],&l[x],&u[x]); }
  579.     fclose(datafile);
  580.   }else{
  581.     for(x=0;x<24;x++) {
  582.       strcpy(month[x],"---");
  583.       date[x]=0;m[x]=0;p[x]=0;l[x]=0;u[x]=0;
  584.     }
  585.   }
  586.   currenthour=(*timestr).tm_hour;
  587.   x=hour%24;
  588.   while (x!=currenthour) {
  589.     if (x>0) {
  590.       strcpy(month[x],month[x-1]);
  591.       date[x]=date[x-1];
  592.     }else{
  593.       if((*timestr).tm_mon==0) strcpy(month[0],"Jan");
  594.       if((*timestr).tm_mon==1) strcpy(month[0],"Feb");
  595.       if((*timestr).tm_mon==2) strcpy(month[0],"Mar");
  596.       if((*timestr).tm_mon==3) strcpy(month[0],"Apr");
  597.       if((*timestr).tm_mon==4) strcpy(month[0],"May");
  598.       if((*timestr).tm_mon==5) strcpy(month[0],"Jun");
  599.       if((*timestr).tm_mon==6) strcpy(month[0],"Jul");
  600.       if((*timestr).tm_mon==7) strcpy(month[0],"Aug");
  601.       if((*timestr).tm_mon==8) strcpy(month[0],"Sep");
  602.       if((*timestr).tm_mon==9) strcpy(month[0],"Oct");
  603.       if((*timestr).tm_mon==10) strcpy(month[0],"Nov");
  604.       if((*timestr).tm_mon==11) strcpy(month[0],"Dec");
  605.       date[0]=(*timestr).tm_mday;
  606.     }
  607.     m[x]=0;
  608.     p[x]=0;
  609.     l[x]=0;
  610.     u[x]=0;
  611.     x++;if (x>23) x=0;
  612.   }
  613.  
  614.   if (hour!=currenthour) {
  615.     m[hour]=ccm;
  616.     p[hour]=ccpgp;
  617.     l[hour]=ccl;
  618.     u[hour]=ccnews;
  619.     ccm=0;
  620.     ccpgp=0;
  621.     ccl=0;
  622.     ccnews=0;
  623.   }
  624.  
  625.   ccm+=inccnt;
  626.   ccpgp+=incpgp;
  627.   ccl+=inclat;
  628.   ccnews+=incpost;
  629.  
  630.   if(datafile=fopen(STATSDATA,"w")){
  631.     fprintf(datafile,"%d\n",currenthour);
  632.     fprintf(datafile,"%d %d %d %d\n",ccm,ccpgp,ccl,ccnews);
  633.     for(x=0;x<24;x++) {
  634.       fprintf(datafile,"%s %d %d %d %d %d\n",
  635.               month[x],date[x],m[x],p[x],l[x],u[x]);
  636.     }
  637.     fclose(datafile);
  638.   } else fprintf(stderr,"remailer: can't write file %s\n",STATSDATA);
  639. }
  640.  
  641. void viewstats() {
  642.   int m[24];
  643.   int ccm;
  644.   int p[24];
  645.   int ccpgp;
  646.   int l[24];
  647.   int ccl;
  648.   int u[24];
  649.   int ccnews;
  650.   char month[24][5];
  651.   int date[24];
  652.   int hour;
  653.   int currenthour;
  654.   FILE *datafile;
  655.   int x;
  656.   int y;
  657.   char buffer[1024];
  658.  
  659.   datafile=fopen(STATSDATA,"r");
  660.  
  661.   fscanf(datafile,"%d",&hour);
  662.   fscanf(datafile,"%d %d %d %d",&ccm,&ccpgp,&ccl,&ccnews);
  663.   for(x=0;x<24;x++) {
  664.     fscanf(datafile,"%s %d %d %d %d %d",
  665.            month[x],&date[x],&m[x],&p[x],&l[x],&u[x]); }
  666.   fclose(datafile);
  667.  
  668.   fprintf(outfile,"Subject: Re: Remailer Statistics\n");
  669.       /* Note - don't even *THINK* about leaving out the Re: ! */
  670.     /* Unless somebody's depending on it, I'd prefer to use
  671.         "Subject: Re: Remailer Statistics from %s\n", REMAILERADDRESS */
  672.   fprintf(outfile,"\n");
  673. #ifdef SPAM_THRESHOLD
  674.   if (access(SPAMWARNFILE,R_OK)==0) /* there's spam! spam! */
  675.   {
  676.     FILE *spamfile;
  677.     spamfile = fopen(SPAMWARNFILE,"rt");
  678.     while(fgets(buffer,1023,spamfile)>0) fputs(buffer,outfile);
  679.     fclose(spamfile);
  680.     fprintf(outfile,"\n");
  681.   }
  682.   else fprintf(outfile, "No Spam problems detected at this time\n\n");
  683. #endif
  684.   fprintf(outfile,"Statistics for last 24 hours from anonymous remailer at\n");
  685.   fprintf(outfile,"e-mail address: %s\n",REMAILERADDRESS);
  686.   fprintf(outfile,"\n");
  687.   fprintf(outfile,
  688.     "Number of messages per hour from %s %d %d:00 to %s %d %d:59\n",
  689.     month[23],date[23],hour,month[0],date[0],(hour+23)%24);
  690.   fprintf(outfile,"\n");
  691.   for(x=0;x<24;x++) {
  692.     fprintf(outfile," %2d:00 (%2d) ",x,m[x]);
  693.     if (m[x]>0) {
  694.       y=0;while((y<m[x])&&(y<66)) {
  695.         fprintf(outfile,"*");
  696.         y++;
  697.       }
  698.       ccm+=m[x];
  699.       ccpgp+=p[x];
  700.       ccl+=l[x];
  701.       ccnews+=u[x];
  702.     }
  703.     fprintf(outfile,"\n");
  704.   }
  705.   fprintf(outfile,"\n");
  706.   fprintf(outfile,"Total messages remailed in last 24 hours: %d\n",ccm);
  707. #ifdef PGP
  708.   fprintf(outfile,"Number of messages encrypted with PGP: %d\n",ccpgp);
  709. #endif
  710.   fprintf(outfile,"Number of messages queued with latency: %d\n",ccl);
  711. #ifdef INEWS
  712.   fprintf(outfile,"Number of posts to usenet: %d\n",ccnews);
  713. #endif
  714. }
  715.  
  716. void main(int argc,char **argv) {
  717.   char input[MAXLEN];
  718.   char resend_address[MAXLEN]="";
  719.   int stop;
  720.   int x;
  721.   pid_t mypid,otherpid;
  722.   char filename[MAXLEN];
  723.   char filename2[MAXLEN];
  724.   int pipefd[2];
  725.   int pipe2fd[2];
  726.   char envstr[MAXLEN];
  727.   int c;
  728.  
  729.   while ( (c = getopt(argc, argv, "s")) != EOF )
  730.   {
  731.     switch(c) {
  732.     case 's': nospamcheck_flag++; break ;
  733.     default: fprintf(stderr, "Bad Option  %c - ignored\n", c);
  734.     }
  735.   }
  736.  
  737.   /* bounds-checking insurance */
  738.   input[MAXLEN-1]='\0';        resend_address[MAXLEN-1]='\0';
  739.   filename[MAXLEN-1]='\0';    filename2[MAXLEN-1]='\0';
  740.   envstr[MAXLEN-1]='\0';
  741.   from[MAXLEN-1]='\0';        from_address[MAXLEN-1]='\0';
  742.   cutmarks[MAXLEN-1]='\0';
  743.  
  744.   gettimeofday(&tp,0);
  745.   if(chdir(DIR))
  746.    {fprintf(stderr,"remailer: Fatal Error: can't chdir to %s\n",DIR);exit(1);}
  747.   mkdir(INQUEUE,0700); /* Create it if it doesn't exist */
  748.   mkdir(TEMPDIR,0700); /* And the temp dir */  
  749.  
  750.   /* Create a randomly named temporary file in TEMPDIR */
  751.       /* note: creating random names and reading the lowest-named
  752.        file later on creates a slight bias toward LIFO */
  753.   strcpy(filename,TEMPDIR);
  754.   strcat(filename,"/");
  755.   strcat(filename,genid());
  756.   if((outfile=fopen(filename,"w"))==0){
  757.     fprintf(stderr,"remailer: Fatal Error: can't create temporary file\n");
  758.     exit(1);
  759.   }
  760.   while(fgets(input,MAXLEN-1,stdin)) fprintf(outfile,"%s",input);
  761.   fclose(outfile);
  762.   strcpy(filename2,INQUEUE);
  763.   strcat(filename2,"/");
  764.   strcat(filename2,genid());
  765.   if(rename(filename,filename2)){
  766.     fprintf(stderr,"remailer: Fatal Error: can't move %s to %s\n",
  767.       filename,filename2);
  768.     exit(1);
  769.   }
  770.  
  771.   mypid=getpid();otherpid=0;
  772.   if(infile=fopen("pid","rb")) {
  773.     fread(&otherpid,sizeof(pid_t),1,infile);
  774.     fclose(infile);
  775.   }
  776.   /* If there is a remailer process already running, leave the message
  777.      in in.queue and exit */
  778.   if(otherpid) {
  779.     if(kill(otherpid,SIGCONT)==0) exit(0); }
  780.   if(outfile=fopen("pid","wb")) {
  781.     fwrite(&mypid,sizeof(pid_t),1,outfile);
  782.     fclose(outfile);
  783.   } else fprintf(stderr,"remailer: can't write pid file\n");
  784.  
  785. in_loop:
  786.  
  787.   /* Open an input file from in.queue */
  788.   chdir(DIR);chdir(INQUEUE);
  789.   pipe(pipefd);
  790.   filename[0]=0;
  791.   if(!fork()) {
  792.     dup2(pipefd[1],1);
  793.     close(pipefd[0]);
  794.     execl(LS,"ls","-1",(char *)0);
  795.   }
  796.   x=0;close(pipefd[1]);
  797.   infile=fdopen(pipefd[0],"r");
  798.   while(fgets(filename,MAXLEN-1,infile)) x++;
  799.   fclose(infile);
  800.   if(filename[0]==0) exit(0);
  801. #ifdef SPAM_THRESHOLD
  802.   if(x>SPAM_THRESHOLD && stat_flag==0 || nospamcheck_flag >1)
  803.     /* original version quit without any notification */
  804.   {
  805.     if (access(SPAMWARNFILE,0)!=0) /* brand new spam! */
  806.     {
  807.         FILE *spamfile;
  808.         spamfile = fopen(SPAMWARNFILE,"wt");
  809.         fprintf(spamfile, "spam x %d filename %s\n", x, filename);
  810.         fclose(spamfile);
  811.     }
  812.     fprintf(stderr, "spam x %d filename %s\n", x, filename);
  813.       if (nospamcheck_flag!=1) exit(7);
  814.   }
  815. #endif
  816.   for(x=0;filename[x]>32;x++){} filename[x]=0;
  817.   if(!(infile=fopen(filename,"r"))){}
  818.   
  819.   /* Open the output file */
  820.   chdir(DIR);
  821.   mkdir(OUTQUEUE,0700); /* Create it if it doesn't exist */
  822.   if(chdir(OUTQUEUE))
  823.     {fprintf(stderr,"remailer: Error - can't chdir to %s\n",OUTQUEUE);exit(1);}
  824.   if(!(outfile=fopen(filename,"w")))
  825.     {fprintf(stderr,"remailer: can't write output file, message left in
  826. %s\n",INQUEUE);exit(1);}
  827.  
  828.   /* Create blank space for fields in output file */
  829.   latime=0;resend_address[0]=0;resend_address[MAXLEN-1]=0;
  830.   fwrite(&latime,sizeof(long),1,outfile);
  831.   fwrite(resend_address,MAXLEN,1,outfile);
  832.  
  833.   /* Initialize latency time & misc */
  834.   latime=tp.tv_sec;
  835.   from[0]=0;cutmarks[0]=0;replykey[0]=0;
  836.   anon_flag=0;help_flag=0;stat_flag=0;pgp_flag=0;blockflag=0;
  837.  
  838. #ifdef DEFAULT_LATENCY
  839.   /* Randomly reorder messages if DEFAULT_LATENCY is set */
  840.   if(DEFAULT_LATENCY>1) {
  841.     latime=tp.tv_sec+abs(tp.tv_sec+tp.tv_usec+getpid())%(DEFAULT_LATENCY+1);
  842.   }
  843. #endif
  844.  
  845.   /* Scan headers */
  846.   fgets(input,MAXLEN-1,infile);
  847.   while(input[0]!=10) {
  848.     scanline(input,resend_address);
  849.     input[0]=10;input[1]=0;
  850.     fgets(input,MAXLEN-1,infile);
  851.   }
  852.   fgets(input,MAXLEN-1,infile); /* end of headers, skip a line */
  853.   
  854.   /* if first line is blank, skip it and look for a :: on the next line */
  855.   if(resend_address[0]==0&&input[0]<32) fgets(input,MAXLEN-1,infile);
  856.   /* Also skip "blank" lines with a space in them: */
  857.   if(resend_address[0]==0){
  858.     for(x=0;(input[x]<=32)&&(input[x]);x++){}
  859.     if(input[x]==0) fgets(input,MAXLEN-1,infile);
  860.   }
  861.  
  862.   /* Scan :: headers, if applicable */
  863.   if(input[0]==':'&&input[1]==':') {
  864.     while(input[0]!=10) {
  865.       scanline(input,resend_address);
  866.       input[0]=10;input[1]=0;
  867.       fgets(input,MAXLEN-1,infile);
  868.     }
  869.     fgets(input,MAXLEN-1,infile);
  870.   }
  871.  
  872.   /* or scan for headers anyway for idiots who forget the double colon */
  873.   if(resend_address[0]==0) {
  874.     scanline(input,resend_address);
  875.     if(resend_address[0]!=0) {
  876.       fgets(input,MAXLEN-1,infile);
  877.       while(input[0]!=10) {
  878.         scanline(input,resend_address);
  879.         input[0]=10;input[1]=0;
  880.         fgets(input,MAXLEN-1,infile);
  881.       }
  882.     }
  883.     fgets(input,MAXLEN-1,infile);
  884.   }
  885.  
  886.   /* Exec PGP? */
  887.   if (pgp_flag) {
  888.     fclose(outfile);
  889.     chdir(DIR);chdir(OUTQUEUE);
  890.     unlink(filename);
  891.     pipe(pipefd);
  892.     pipe(pipe2fd);
  893.     if(!fork()) {
  894.       dup2(pipefd[0],0);
  895.       dup2(pipe2fd[1],1);
  896.       close(pipefd[1]);
  897.       close(pipe2fd[0]);
  898.       chdir(DIR);
  899. #ifdef PGPPATH
  900.       strcpy(envstr,"PGPPATH=");
  901.       strcat(envstr,PGPPATH);
  902.       putenv(envstr);
  903. #endif
  904.       execl(PGP,"pgp","-f","-z",PGPPASS,(char *)0);
  905.     }
  906.     close(pipefd[0]);close(pipe2fd[1]);
  907.     fseek(infile,0,0);
  908.     outfile=fdopen(pipefd[1],"w");
  909.     while((fgets(input,MAXLEN-1,infile)>0)
  910.          &&(strcmp(input,"-----BEGIN PGP MESSAGE-----\n")!=0)) {}
  911.     fprintf(outfile,"%s",input);
  912.     while(fgets(input,MAXLEN-1,infile)
  913.          &&(strcmp(input,"-----END PGP MESSAGE-----\n")!=0)) {
  914.       fprintf(outfile,"%s",input);
  915.     }
  916.     fprintf(outfile,"%s",input);
  917.     fclose(outfile);
  918.     file2=fdopen(pipe2fd[0],"r");
  919.     chdir(DIR);chdir(INQUEUE);
  920.     outfile=fopen(genid(),"w");
  921.     fprintf(outfile,"\n");
  922.     while(fgets(input,MAXLEN-1,file2)) {
  923.       fprintf(outfile,"%s",input);
  924.     }
  925.     fclose(file2);
  926.     /* Append rest of message to decrypted reply-block */
  927.     while(fgets(input,MAXLEN-1,infile)) {
  928.       fprintf(outfile,"%s",input);
  929.     }
  930.     fclose(infile);fclose(outfile);
  931.     unlink(filename);/* Remove the original message from in.queue */
  932.     chdir(DIR);
  933.     updatestats(0,1,0,0);
  934.     goto in_loop;
  935.   }
  936.  
  937.   if (from[0]==0) anon_flag=1;
  938.  
  939.   if (anon_flag) {
  940.     fprintf(outfile,ANONFROM);
  941. #ifdef ANONREPLYTO
  942.     fprintf(outfile,ANONREPLYTO);
  943. #endif
  944.     fprintf(outfile,DISCLAIMER);
  945.   }else{
  946.     fprintf(outfile,"%s",from);
  947.     fprintf(outfile,NONANONDISC);
  948.   }
  949.  
  950.   /* Paste in ## headers if present */
  951.   if(input[0]=='#'&&input[1]=='#') {
  952.    /* Kill Reply-To lines with blocked addresses to prevent
  953.       mailbombs via alt.test */
  954.     while(fgets(input,MAXLEN-1,infile)>0&&input[0]>31) {
  955.       if ((input[0]=='R'||input[0]=='r')&&input[1]=='e'&&input[2]=='p') {
  956.         block_addr(input,BLOCKTO);if (input[0]!=0) fprintf(outfile,"%s",input);
  957.       /* Block ## pasted Newsgroups: */
  958.       }else if((input[0]|32=='n')&&input[1]=='e'&&input[2]=='w'&&input[3]=='s')
  959.       {
  960.         block_addr(input,BLOCKTO);if (input[0]!=0) fprintf(outfile,"%s",input);
  961.       }else fprintf(outfile,"%s",input);
  962.     }
  963.     fprintf(outfile,"\n");
  964.   }else{
  965.     fprintf(outfile,"\n%s",input);
  966.     if(replykey[0]>0&&input[0]=='*'&&input[1]=='*') {
  967.       reencrypt();
  968.     }
  969.   }
  970.  
  971.   /* Copy message */
  972.   stop=0;
  973.   while(fgets(input,MAXLEN-1,infile)>0&&(!stop)) {
  974.     if (cutmarks[0]!=0) {
  975.       x=0;
  976.       while(cutmarks[x]==input[x]&&input[x]!=0&&cutmarks[x]!=0) {
  977.         x++;
  978.       }
  979.       if (cutmarks[x]==0) stop=1;
  980.     }
  981.     if (!stop) fprintf(outfile,"%s",input);
  982.     if(replykey[0]>0&&input[0]=='*'&&input[1]=='*') {
  983.       reencrypt();
  984.     }
  985.   }
  986.   
  987.   /* If help or stats were requested, set destination address to reply
  988.      to sender */
  989.   if((resend_address[0]==0)&&(help_flag||stat_flag)){
  990.     strcpy(resend_address,from_address);
  991.   } else {help_flag=0;stat_flag=0;}
  992.  
  993.   /* Save time and destination address in binary data table at
  994.      begining of file */
  995.   if (blockflag) resend_address[0]=0;
  996.   fseek(outfile,0,0);
  997.   fwrite(&latime,sizeof(long),1,outfile);
  998.   fwrite(resend_address,MAXLEN,1,outfile);
  999.   if(help_flag||stat_flag){
  1000.     chdir(DIR);
  1001.     fprintf(outfile,"%s",REMAILERFROM);
  1002.     if(help_flag) {
  1003.       if(file2=fopen(HELPFILE,"r")){
  1004.         while(fgets(input,MAXLEN-1,file2)){
  1005.       if (match(input,"Subject: remailer-")) /* prevent loops */
  1006.           {fprintf(outfile, "Subject: Re: remailer-%s",(input+18)); continue; }
  1007.           for(x=0;input[x];x++){
  1008.             if(input[x]=='['&&input[x+1]=='a'&&input[x+2]=='d'
  1009.                &&input[x+3]=='d'&&input[x+4]=='r'&&input[x+5]==']')
  1010.             {
  1011.               fprintf(outfile,"%s",REMAILERADDRESS);x=x+5;
  1012.             }
  1013.             else
  1014.             {
  1015.               putc(input[x],outfile);
  1016.             }   
  1017.           }
  1018.         }
  1019.         fclose(file2);
  1020.       } else resend_address[0]=0;
  1021.     }
  1022.     if(stat_flag) {viewstats();}
  1023.   }
  1024.   fclose(outfile);
  1025.  
  1026.   chdir(DIR);chdir(INQUEUE);
  1027.  
  1028.   /* Second message?  Put message following cutmarks into inqueue */
  1029.   if (stop==1&&input[0]==':'&&input[1]==':') {
  1030.     outfile=fopen(genid(),"w");
  1031.     fprintf(outfile,"\n::\n");
  1032.     while(fgets(input,MAXLEN-1,infile)>0) {
  1033.       fprintf(outfile,"%s",input);
  1034.     }
  1035.     fclose(outfile);
  1036.   }
  1037.  
  1038.   /* Write non-remailer messages into operator's mailbox */
  1039.   if (resend_address[0]==0&&from[0]!=0){
  1040.     fseek(infile,0,0);
  1041.     outfile=fopen(SPOOL,"a");
  1042.     while(fgets(input,MAXLEN-1,infile)) {
  1043.       fprintf(outfile,"%s",input);
  1044.     }
  1045.     fclose(infile);
  1046.     fprintf(outfile,"\n");
  1047.     fclose(outfile);
  1048.     unlink(filename);
  1049.     chdir(DIR);chdir(OUTQUEUE);
  1050.     unlink(filename);
  1051.   }else{
  1052.     fclose(infile);
  1053.     unlink(filename);
  1054.     if(strcmp(resend_address,"null")==0
  1055.      ||strcmp(resend_address,"/dev/null")==0) resend_address[0]=0;
  1056.     if(resend_address[0]==0){ /* drop empty messages */
  1057.       chdir(DIR);chdir(OUTQUEUE);
  1058.       unlink(filename);
  1059.     }else{
  1060.       chdir(DIR);
  1061.       if((latime-tp.tv_sec)>2) updatestats(0,0,1,0);
  1062.       updatestats(1,0,0,0); /* Add one remailed message to stats */
  1063.     }
  1064.   }
  1065.  
  1066.   /* Deliver messages in out.queue */
  1067.   gettimeofday(&tp,0);
  1068.   chdir(DIR);chdir(OUTQUEUE);
  1069.   pipe(pipefd);
  1070.   filename[0]=0;
  1071.   if(!fork()) {
  1072.     dup2(pipefd[1],1);
  1073.     close(pipefd[0]);
  1074.     execl(LS,"ls","-1",(char *)0);
  1075.   }
  1076.   x=0;close(pipefd[1]);
  1077.   file2=fdopen(pipefd[0],"r");
  1078.   while(fgets(filename,MAXLEN,file2)&&filename[0]!=0) {
  1079.     for(x=0;filename[x]>32;x++){} filename[x]=0;
  1080.     if(infile=fopen(filename,"r")){
  1081.       fread(&latime,sizeof(long),1,infile);
  1082.       fread(resend_address,MAXLEN,1,infile);
  1083.       if (latime<=tp.tv_sec) {
  1084.         pipe(pipe2fd);/*pipe(pipe3fd);*/
  1085.         if(!fork()) {
  1086.           /*Child*/
  1087.           dup2(pipe2fd[0],0);close(pipe2fd[1]);
  1088.           /*dup2(pipe3fd[1],1);close(pipe3fd[0]);*/
  1089.           if(strcmp(resend_address,"post")){
  1090.             execl(SENDMAIL,SENDMAIL,
  1091. #ifdef RETURN
  1092.                                     "-f",RETURN,
  1093. #endif
  1094.                                                 resend_address,(char *)0);
  1095.             exit(0);
  1096.           }else{
  1097. #ifdef INEWS
  1098. #ifdef NNTPSERVER
  1099.             strcpy(envstr,"NNTPSERVER=");
  1100.             strcat(envstr,NNTPSERVER);
  1101.             putenv(envstr);
  1102. #endif
  1103.             execl(INEWS,"inews","-h",(char *)0);
  1104. #endif
  1105.             exit(0);
  1106.           }
  1107.         }else{
  1108.           /*Parent*/
  1109.           close(pipe2fd[0]);/*close(pipe3fd[1]);*/
  1110.           outfile=fdopen(pipe2fd[1],"w");
  1111.           if(strcmp(resend_address,"post")){
  1112.             /* We are talking to sendmail */
  1113.             while(fgets(input,MAXLEN-1,infile)>0) {
  1114.               fprintf(outfile,"%s",input);
  1115.             }
  1116.             fclose(outfile);
  1117.             /* At this point, it's a safe bet that sendmail will deliver
  1118.                the message, so the remailer can delete its copy.  If
  1119.                sendmail execution had failed for some reason, this
  1120.                process would have been killed by a SIGPIPE */
  1121.             unlink(filename);
  1122.           }else{
  1123.             /* We are talking to inews */
  1124. #ifdef INEWS
  1125.             while(fgets(input,MAXLEN-1,infile)>0) {
  1126.               fprintf(outfile,"%s",input);
  1127.             }
  1128.             /* There should be a way to analyze the response from inews
  1129.                and requeue messages that could not be posted due to server
  1130.                failure.  Now, the messages just get deleted :( */
  1131.             unlink(filename);
  1132. #else
  1133.             /* If posting is not allowed, delete the failed message */
  1134.             unlink(filename);
  1135. #endif
  1136.           }
  1137.         }
  1138. #ifdef WAIT_SEC
  1139.         sleep(WAIT_SEC);
  1140. #endif
  1141.         gettimeofday(&tp,0);
  1142.       }
  1143.       fclose(infile);
  1144.     }
  1145.   }
  1146.   fclose(file2);
  1147.  
  1148.   goto in_loop;
  1149. }
  1150.