home *** CD-ROM | disk | FTP | other *** search
/ The Pier Shareware 6 / The_Pier_Shareware_Number_6_(The_Pier_Exchange)_(1995).iso / 024 / psi110g.zip / MAILUTIL.C < prev    next >
C/C++ Source or Header  |  1994-07-05  |  7KB  |  261 lines

  1. /*  General Mail Utilities
  2.  *  culled from other files to reduce unnecessary cross references.
  3.  *  This material is believed to be in the public domain.
  4.  */
  5. #ifdef MSDOS
  6. #include <io.h>
  7. #endif
  8. #include <fcntl.h>
  9. #include <ctype.h>
  10. #include "global.h"
  11. #include "socket.h"
  12. #include "mailutil.h"
  13. #include "mailbox.h"
  14. #include "smtp.h"
  15. #include "files.h"
  16. #include "bm.h"
  17. #include "index.h"
  18.   
  19. #ifdef linux
  20. extern int close __ARGS((int)); /* this should be in fcntl.h... */
  21. extern int unlink __ARGS((char *)); /* can't include unistd.h, collisions */
  22. #endif
  23.   
  24. /*  Jan 92  Bill Simpson
  25.  *      The following routines were combined from smtpserv.c,
  26.  *      pop3cli.c and nntpcli.c
  27.  */
  28.   
  29. /* June 93 - Johan. K. Reinalda, WG7J
  30.  * Mail file indexing added.
  31.  */
  32.   
  33. #ifdef POP3CLIENT
  34.   
  35. /* Receive message from socket, copying to file.
  36.  * Returns number of lines received, -1 indicates error
  37.  */
  38. int
  39. recvmail(s,buf,len,fp,trace)
  40. int s;      /* Socket index */
  41. char *buf;  /* Line buffer */
  42. unsigned len;   /* Length of buffer */
  43. FILE *fp;   /* File to copy into */
  44. int trace;  /* to trace or not to trace */
  45. {
  46.     int lines = 0;
  47.   
  48.     while (recvline(s,buf,len) != -1) {
  49.         register char *p = buf;
  50.   
  51.         if (trace >= 4)
  52.             log(s,"<==%s", buf);
  53.   
  54.         /* check for end of message . or escaped .. */
  55.         if (*p == '.') {
  56.             if (*++p == '\n') {
  57.                 if (trace >= 3)
  58.                     log(s,"received %d lines", lines);
  59.                 return lines;
  60.             } else if ( *p != '.' ) {
  61.                 p--;
  62.             }
  63.         } else if (strncmp(p,"From ",5) == 0) {
  64.             /* for UNIX mail compatiblity */
  65.             (void) putc('>',fp);
  66.         }
  67.         /* Append to data file */
  68.         fputs(p,fp);
  69.         ++lines;
  70.     }
  71.     if ( trace >= 1 )
  72.         log(s,"receive error after %d lines", lines);
  73.     return -1;
  74. }
  75. #endif
  76.   
  77. #if (defined(POP2CLIENT) || defined(POP3CLIENT))
  78.   
  79. /* Copy from the work file into the mailbox.
  80.  * -1 indicates error
  81.  */
  82. int
  83. copymail(filename,buf,len,wfp,trace)
  84. char *filename; /* Target Filename */
  85. char *buf;  /* Line buffer */
  86. unsigned len;   /* Length of buffer */
  87. FILE *wfp;  /* File to copy from */
  88. int trace;      /* to trace or not to trace */
  89. {
  90.     FILE *mfp = NULLFILE;
  91.   
  92.     while (mlock(Mailspool,filename)) {
  93.         pause(10000L);  /* 10 seconds */
  94.     }
  95.   
  96.     sprintf(buf,"%s/%s.txt",Mailspool,filename);
  97.     if ((mfp = fopen(buf,"a+")) == NULL) {
  98.         if ( trace >= 1 )
  99.             log(-1,"*** Unable to open %s!!!\n", buf);
  100.         tprintf("\n*** Unable to open %s!!!\n", buf);
  101.         rmlock(Mailspool,filename);
  102.         return -1;
  103.     }
  104.   
  105.     rewind(wfp);            /* start of new mail, just to be safe ! */
  106.     fseek(mfp,0,SEEK_END);  /* End of mailbox file */
  107.   
  108.     /* loop for all lines in file */
  109.     while(fgets(buf,len,wfp) != NULL) {
  110.         pwait(NULL);    /* give other processes time in long copy */
  111.         fputs(buf,mfp); /* Write to the mailbox */
  112.     }
  113.     fclose(mfp);
  114.   
  115.     /* Update the index */
  116.     IndexFile(filename,0);
  117.   
  118.     rmlock(Mailspool,filename);
  119.     return 0;
  120. }
  121. #endif
  122.   
  123.   
  124. /*  Jan 92  Bill Simpson
  125.  *      The following routines were extracted from smtpserv.c
  126.  *      and smtpcli.c, since they are used from several places.
  127.  */
  128.   
  129. static void mklockname(char *lockname,char *dir,char *id) {
  130.   
  131.     if (id == NULLCHAR || !*id) strcpy(lockname, dir);
  132.     else sprintf(lockname,"%s/%s",dir,id);
  133.     dirformat(lockname);
  134.     strcat(lockname,".lck");
  135. }
  136.   
  137. /* create mail lockfile */
  138. int
  139. mlock(dir,id)
  140. char *dir,*id;
  141. {
  142.     int fd;
  143.     char lockname[FILE_PATH_SIZE];
  144.   
  145.     /* Try to create the lock file in an atomic operation */
  146.     mklockname(lockname,dir,id);
  147.   
  148. #ifdef        AMIGA
  149.     /* don't ask, really, just don't ask... I'd do file locking on
  150.      * an Amiga much more differently than this.
  151.      */
  152.     if(access(lockname, 0) == 0)
  153.         return -1;
  154. #endif
  155.     if((fd = open(lockname, O_WRONLY|O_EXCL|O_CREAT,0600)) == -1)
  156.         return -1;
  157.     close(fd);
  158.     return 0;
  159. }
  160.   
  161.   
  162. /* remove mail lockfile */
  163. int
  164. rmlock(dir,id)
  165. char *dir,*id;
  166. {
  167.     char lockname[FILE_PATH_SIZE];
  168.   
  169.     mklockname(lockname,dir,id);
  170.     return(unlink(lockname));
  171. }
  172.   
  173.   
  174. /*      Jan 92  Bill Simpson
  175.  *      The following routines were extracted from mailbox.c,
  176.  *      since they are used from several places.
  177.  */
  178.   
  179.   
  180. /* Read the rewrite file for lines where the first word is a regular
  181.  * expression and the second word are rewriting rules. The special
  182.  * character '$' followed by a digit denotes the string that matched
  183.  * a '*' character. The '*' characters are numbered from 1 to 9.
  184.  * Example: the line "*@*.* $2@$1.ampr.org" would rewrite the address
  185.  * "foo@bar.xxx" to "bar@foo.ampr.org".
  186.  * $H is replaced by our hostname, and $$ is an escaped $ character.
  187.  * If the third word on the line has an 'r' character in it, the function
  188.  * will recurse with the new address.
  189.  */
  190. char *
  191. rewrite_address(addr)
  192. char *addr;
  193. {
  194.     char *argv[10], buf[PLINELEN], *cp, *cp2, *retstr;
  195.     int cnt;
  196.     FILE *fp;
  197.   
  198.     if ((fp = fopen(Rewritefile,READ_TEXT)) == NULLFILE)
  199.         return NULLCHAR;
  200.   
  201.     memset((char *)argv,0,10*sizeof(char *));
  202.     while(fgets(buf,sizeof(buf),fp) != NULLCHAR) {
  203.         if(*buf == '#')     /* skip commented lines */
  204.             continue;
  205.   
  206.         if((cp = strchr(buf,' ')) == NULLCHAR) /* get the first word */
  207.             if((cp = strchr(buf,'\t')) == NULLCHAR)
  208.                 continue;
  209.         *cp = '\0';
  210.         if((cp2 = strchr(buf,'\t')) != NULLCHAR){
  211.             *cp = ' ';
  212.             cp = cp2;
  213.             *cp = '\0';
  214.         }
  215.         if(!wildmat(addr,buf,argv))
  216.             continue;       /* no match */
  217.         rip(++cp);
  218.         /* scan past additional whitespaces */
  219.         while (*cp == ' ' || *cp == '\t') ++cp;
  220.         cp2 = retstr = (char *) callocw(1,PLINELEN);
  221.         while(*cp != '\0' && *cp != ' ' && *cp != '\t')
  222.             if(*cp == '$') {
  223.                 if(isdigit(*(++cp)))
  224.                     if(argv[*cp - '0'-1] != '\0')
  225.                         strcat(cp2,argv[*cp - '0'-1]);
  226.                 if(*cp == 'h' || *cp == 'H') /* Our hostname */
  227.                     strcat(cp2,Hostname);
  228.                 if(*cp == '$')  /* Escaped $ character */
  229.                     strcat(cp2,"$");
  230.                 cp2 = retstr + strlen(retstr);
  231.                 cp++;
  232.             }
  233.             else
  234.                 *cp2++ = *cp++;
  235.         for(cnt=0; argv[cnt] != NULLCHAR; ++cnt)
  236.             free(argv[cnt]);
  237.         fclose(fp);
  238.         /* If there remains an 'r' character on the line, repeat
  239.          * everything by recursing.
  240.          */
  241.         if(strchr(cp,'r') != NULLCHAR || strchr(cp,'R') != NULLCHAR) {
  242.             if((cp2 = rewrite_address(retstr)) != NULLCHAR) {
  243.                 free(retstr);
  244.                 return cp2;
  245.             }
  246.         }
  247.         return retstr;
  248.     }
  249.     fclose(fp);
  250.     return NULLCHAR;
  251. }
  252.   
  253. int dorewrite(int argc, char *argv[], void *p) {
  254.     char *address = rewrite_address(argv[1]);
  255.     tprintf("to: %s\n", address ? address : argv[1]);
  256.     if(address)
  257.         free(address);
  258.     return 0;
  259. }
  260.   
  261.