home *** CD-ROM | disk | FTP | other *** search
/ The Pier Shareware 6 / The_Pier_Shareware_Number_6_(The_Pier_Exchange)_(1995).iso / 024 / psi110g.zip / MAILFOR.C < prev    next >
C/C++ Source or Header  |  1994-08-26  |  10KB  |  381 lines

  1. /* The following code will broadcast 'Mail for:' beacons
  2.  * for private users with unread mail on a regular interval
  3.  *
  4.  * Also contains the commands to set the R: header read options
  5.  * with the 'bulletin' command.
  6.  *
  7.  * original: 920306
  8.  * rewritten: 920326
  9.  * Copyright 1992, Johan. K. Reinalda, WG7J/PA3DIS
  10.  * Permission granted for non-commercial use only!
  11.  *
  12.  * Modified to use the new mailbox index file - 930624 WG7J
  13.  * mailfor watch added by PE1DGZ/N5KNX
  14.  */
  15. #ifdef MSDOS
  16. #include <dir.h>
  17. #include <dos.h>
  18. #endif
  19. #include "global.h"
  20. #include "files.h"
  21. #include "dirutil.h"
  22. #include "bm.h"
  23. #include "cmdparse.h"
  24. #include "timer.h"
  25. #include "pktdrvr.h"
  26. #include "ax25.h"
  27. #include "mailfor.h"
  28. #include "socket.h"
  29. #include "index.h"
  30.   
  31. #ifdef MAILFOR
  32. #ifdef AX25
  33.   
  34. static int mf_member __ARGS((char *name, struct no_mf *head));
  35. static int checknewmail __ARGS((char *area));
  36. static int setmailfor __ARGS((void));
  37. static void ax_mf __ARGS((struct iface *ifp));
  38. static void Mftick __ARGS((void *v));
  39.   
  40. #define MAXMFLEN 256
  41. static struct timer Mftimer;
  42. static char ax_mftext[MAXMFLEN+1] = "Mail for:";
  43. #define DEFMFLEN 9
  44. int mflen = DEFMFLEN; /*Initial lenght of mail-for string*/
  45.   
  46. /* List of area names to exclude from mail-for beacon */
  47. struct no_mf {
  48.     struct no_mf *next;
  49.     char area[9];
  50. };
  51. #define NULLMF (struct no_mf *)0
  52. struct no_mf *No_mf = NULLMF;
  53.  
  54. #ifdef STATUSWIN
  55. int Mail_Received = 0;    /* accessed by StatusLine1() */
  56. struct no_mf *watch_list = NULLMF;
  57. #endif
  58.   
  59. /* Read a private message area, searching for unread mail
  60.  * this is indicated by the status character in the index file.
  61.  */
  62. static int
  63. checknewmail(area)
  64. char *area;
  65. {
  66.     int idx,i,len,unread = 0;
  67.     struct indexhdr hdr;
  68.     char buf[128];
  69.   
  70.     /* Open area index file */
  71.     sprintf(buf,"%s/%s.ind",Mailspool,area);
  72.     if((idx = open(buf,READBINARY)) != -1) {
  73.         /* Read header */
  74.         read_header(idx,&hdr);
  75.         close(idx);
  76.         return hdr.unread;
  77.     }
  78.     return 0;
  79. }
  80.   
  81. /* Check name with exclude/watch list;
  82.  * returns 1 if found, 0 if not
  83.  */
  84. static int
  85. mf_member(name, head)
  86. char *name;
  87. struct no_mf *head;
  88. {
  89.     struct no_mf *nm;
  90.   
  91.     /*Now check the 'exclude' list*/
  92.     for(nm=head;nm!=NULLMF;nm=nm->next) {
  93.         if(!stricmp(nm->area,name))
  94.             return 1;
  95.     }
  96.     return 0;
  97. }
  98.   
  99. static int
  100. setmailfor(void)
  101. {
  102.     char buf[80];
  103.     struct ffblk ff;
  104.   
  105.     sprintf(buf,"%s/*.txt",Mailspool);
  106.     if (findfirst(buf, &ff, 0) == 0) {
  107.         do {
  108.             pwait(NULL);    /* Let others run */
  109.             *(strchr(ff.ff_name,'.')) = '\0';
  110.             /*must be private mail area, and not on exclude list !*/
  111.             if(!isarea(ff.ff_name)) {
  112.               if(!mf_member(ff.ff_name, No_mf)) {
  113.                 if((strlen(ax_mftext) + strlen(ff.ff_name)) > MAXMFLEN - 1)
  114. #ifdef STATUSWIN
  115.                     ; else  /*checknewmail if room left, then test watch list, below */
  116. #else
  117.                     break; /* That's all folks */
  118. #endif
  119.                 if(checknewmail(ff.ff_name)) {
  120.                     strcat(ax_mftext," ");
  121.                     strcat(ax_mftext,ff.ff_name);
  122.                 }
  123.               }
  124. #ifdef STATUSWIN
  125.               if(mf_member(ff.ff_name, watch_list)) {  /* on watch list? */
  126.                   if(checknewmail(ff.ff_name)) Mail_Received++;
  127.               }
  128. #endif
  129.             }
  130.         } while (findnext(&ff) == 0);
  131.     }
  132.     return strlen(ax_mftext);
  133. }
  134.   
  135. /*This is the low-level broadcast function.*/
  136. static void
  137. ax_mf(ifp)
  138. struct iface *ifp;
  139. {
  140.     struct mbuf *bp;
  141.   
  142.     /* prepare the header */
  143.     if((bp = alloc_mbuf(mflen)) == NULLBUF)
  144.         return;
  145.   
  146.     /*copy the data into the packet*/
  147.     bp->cnt = mflen;
  148.     memcpy(bp->data,ax_mftext,mflen);
  149.   
  150.     /* send it */
  151.     (*ifp->output)(ifp, Ax25multi[MAILCALL], ifp->ax25->bbscall,PID_NO_L3, bp);
  152. }
  153.   
  154. static void
  155. Mftick(v)
  156. void *v;
  157. {
  158.     struct iface *ifp = Ifaces;
  159.   
  160.     stop_timer(&Mftimer); /* in case this was 'kicked' with a 'mailfor now'*/
  161. #ifdef STATUSWIN
  162.     Mail_Received = 0;  /* reset flag, tested in StatusLine1() */
  163. #endif
  164.  
  165.     /*Now find private mail areas with unread mail.
  166.      *add these to the info-line
  167.      */
  168.     ax_mftext[DEFMFLEN] = '\0'; /* Back to only 'Mail for:' again*/
  169.     if((mflen=setmailfor()) < DEFMFLEN+1) {
  170.         start_timer(&Mftimer);
  171.         return; /* No unread mail */
  172.     }
  173.   
  174.     /*broadcast it on all condifured interfaces*/
  175.     for(ifp=Ifaces;ifp != NULL;ifp=ifp->next)
  176.         if(ifp->flags & MAIL_BEACON)
  177.             ax_mf(ifp);
  178.   
  179.     /* Restart timer */
  180.     start_timer(&Mftimer) ;
  181. }
  182.   
  183. int
  184. dombmailfor(argc,argv,p)
  185. int argc;
  186. char *argv[];
  187. void *p;
  188. {
  189.     register int i;
  190.     struct no_mf *nm, **hp;
  191.   
  192.     if(argc < 2){
  193.         tprintf("Mail-for timer: %lu/%lu\n",
  194.         read_timer(&Mftimer)/1000L,
  195.         dur_timer(&Mftimer)/1000L);
  196.         if(mflen > DEFMFLEN)
  197.             tprintf("%s\n",ax_mftext);
  198.         return 0;
  199.     }
  200.   
  201.     if(*argv[1] == 'n') { /*send mailfor 'now' !!*/
  202.         Mftick(NULL);
  203.         return 0;
  204.     }
  205.   
  206.     if(*argv[1] == 'e'
  207. #ifdef STATUSWIN
  208.        || *argv[1] == 'w'
  209. #endif
  210.       ) { /* exclude or watch list */
  211.         if (*argv[1] == 'e')        /*the exclude subcommand*/
  212.             hp = &No_mf;
  213. #ifdef STATUSWIN
  214.         else hp = &watch_list;    /* the watch subcommand */
  215. #endif
  216.         if(argc == 2) { /*just list them*/
  217.             for(nm=*hp;nm!=NULLMF;nm=nm->next)
  218.                 tprintf("%s ",nm->area);
  219.             tputc('\n');
  220.         } else { /*add some call(s)*/
  221.             for(i=0;i<argc-2;i++) {
  222.                 if(strlen(argv[i+2]) > 8) {
  223.                     tprintf("Invalid: %s\n",argv[i+2]);
  224.                     continue;
  225.                 }
  226.                 nm = callocw(1,sizeof(struct no_mf));
  227.                 strcpy(nm->area,argv[i+2]);
  228.                 /* add to list */
  229.                 nm->next = *hp;
  230.                 *hp = nm;
  231.             }
  232.         }
  233.         return 0;
  234.     }
  235.   
  236.     /* set the timer */
  237.     Mftimer.func = (void (*) __ARGS((void *)))Mftick;/* what to call on timeout */
  238.     Mftimer.arg = NULL;        /* dummy value */
  239.     set_timer(&Mftimer,atol(argv[1])*1000L); /* set timer duration */
  240.     Mftick(NULL); /* Do one now and start it all!*/
  241.     return 0;
  242. }
  243. #endif /* AX25 */
  244. #endif /* MAILFOR */
  245.   
  246. /*************************************************************************/
  247.   
  248. #ifdef RLINE
  249.   
  250. /* Depending on the flag set, the mailbox will
  251.  * read the message's original date,
  252.  * the correct 'from' address (instead of the user%forwardbbs@myhost),
  253.  * and for buls set the X-Forwarded options to prevent
  254.  * unneccesary forward attemps
  255.  * all from the R: lines supplied by the bbs system
  256.  * 920311 - WG7J
  257.  */
  258. static int dordate __ARGS((int argc,char *argv[],void *p));
  259. static int dorreturn __ARGS((int argc,char *argv[],void *p));
  260. static int dofwdcheck __ARGS((int argc,char *argv[],void *p));
  261. static int dombloophold __ARGS((int argc,char *argv[],void *p));
  262. static void ReadFwdBbs(void);
  263.   
  264. char MyFwds[NUMFWDBBS][FWDBBSLEN+1];
  265. int Numfwds = 0;
  266. int Checklock = 0;   /* get increased to lock list of forward bbses */
  267. int Rdate = 0;
  268. int Rreturn = 0;
  269. int Rfwdcheck = 0;
  270.   
  271. static struct cmds Rlinetab[] = {
  272.     "check",    dofwdcheck,0, 0, NULLCHAR,
  273.     "date",     dordate,   0, 0, NULLCHAR,
  274.     "loophold", dombloophold,0,0, NULLCHAR,
  275.     "return",   dorreturn, 0, 0, NULLCHAR,
  276.     NULLCHAR,
  277. };
  278.   
  279. static int
  280. dordate(argc,argv,p)
  281. int argc;
  282. char *argv[];
  283. void *p;
  284. {
  285.     return setbool(&Rdate,"Use R: for orig. date",argc,argv);
  286. }
  287.   
  288. int Mbloophold = 2;
  289.   
  290. /* set loop detection threshold - WG7J */
  291. static int
  292. dombloophold(int argc,char *argv[],void *p)
  293. {
  294.     return setint(&Mbloophold,"Loop hold after",argc,argv);
  295. }
  296.   
  297. static int
  298. dorreturn(argc,argv,p)
  299. int argc;
  300. char *argv[];
  301. void *p;
  302. {
  303.     return setbool(&Rreturn,"Use R: for ret. addr.",argc,argv);
  304. }
  305.   
  306.   
  307. static int
  308. dofwdcheck(argc,argv,p)
  309. int argc;
  310. char *argv[];
  311. void *p;
  312. {
  313.     register int i;
  314.   
  315.     setbool(&Rfwdcheck,"Use R: to check buls",argc,argv);
  316.     if((argc == 1) && Rfwdcheck && Numfwds) { /*list the bbses we check*/
  317.         tputs("Checking for:");
  318.         for(i=0;i<Numfwds;i++)
  319.             tprintf(" %s",MyFwds[i]);
  320.         tputc('\n');
  321.     } else {
  322.         if(Rfwdcheck)
  323.             ReadFwdBbs();
  324.     }
  325.     return 0;
  326. }
  327.   
  328. int
  329. dombrline(argc,argv,p)
  330. int argc;
  331. char *argv[];
  332. void *p;
  333. {
  334.     return subcmd(Rlinetab,argc,argv,p);
  335. }
  336.   
  337. static void
  338. ReadFwdBbs() {
  339.     FILE *fp;
  340.     int start = 1;
  341.     char *cp;
  342.     char line[80];
  343.   
  344.     if(Checklock) {
  345.         tputs("Bbs-list locked, forward.bbs not re-read\n");
  346.         return;
  347.     }
  348.     Numfwds = 0;    /* reset */
  349.     if((fp=fopen(Forwardfile,READ_TEXT)) == NULLFILE) {
  350.         tputs("forward.bbs not found\n");
  351.         return;
  352.     }
  353.     /*Now scan the forward.bbs file to find bbs's*/
  354.     while(fgets(line,sizeof(line),fp) != NULLCHAR && (Numfwds < NUMFWDBBS)) {
  355.         if(*line == '\n')
  356.             continue;
  357.     /* lines starting with '-' separate the forwarding records */
  358.         if(*line == '-') {
  359.             start = 1;
  360.             continue;
  361.         }
  362.         if(start) {
  363.             start = 0;
  364.         /* get the name of this forwarding record */
  365.             if((cp=strchr(line,'\n')) != NULLCHAR)
  366.                 *cp = '\0';
  367.             if((cp=strchr(line,' ')) != NULLCHAR)
  368.                 *cp = '\0';
  369.             if((cp=strchr(line,'\t')) != NULLCHAR)
  370.                 *cp = '\0';
  371.             if(strlen(line) > FWDBBSLEN)
  372.                 continue;   /*What kind of bbs-call is this ?*/
  373.             strcpy(MyFwds[Numfwds++],strupr(line));
  374.         }
  375.     }
  376.     fclose(fp);
  377.     return;
  378. }
  379.   
  380. #endif /* RLINE */
  381.