home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 459.lha / AnyMail_v1.0 / src / AnyMail.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-27  |  10.1 KB  |  525 lines

  1. /*
  2.  *  AnyMail -x MailReadyFileName -c Command -e user -i user ...
  3.  *
  4.  *  (C) Copyright 1990 by Chris Hind Genly, chris@genly.uucp
  5.  *
  6.  *  See AnyMail.doc for legal terms.
  7.  *
  8.  */
  9.  
  10. #include <exec/types.h>
  11. #include <exec/lists.h>
  12. #include <exec/ports.h>
  13. #include <proto/exec.h>
  14. #include <proto/dos.h>
  15. #include <libraries/dos.h>
  16. #include <intuition/intuition.h>
  17. #include <graphics/gfxbase.h>
  18.  
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22.  
  23. #include "protos.h"
  24. #include "config.h"
  25. #include "version.h"
  26.  
  27. typedef struct line_tag {
  28.     struct line_tag *Next;
  29.     char             Msg[255];
  30. } *LINE, LINE_STRUCT;
  31.  
  32. LINE Lines, LastLine;
  33.  
  34. struct Window    *Window;
  35. struct MsgPort    *Port;
  36. int              Count;
  37.  
  38. struct IntuitionBase *IntuitionBase;
  39. struct GfxBase         *GfxBase;
  40.  
  41. typedef struct MailNode {
  42.     struct MailNode *Next;
  43.     struct MailNode *Prev;
  44.     char             Name[1];
  45. } *MAILNODE, MAILNODE_STRUCT;
  46.  
  47. int
  48. OkToScan(
  49.     struct FileInfoBlock *fib
  50. );
  51.  
  52. void
  53. MakeNode(
  54.     struct List *List,
  55.     char *Name
  56. );
  57.  
  58. struct NewWindow Nw = {
  59.     40, 10, 560, 180, -1, -1,
  60.     CLOSEWINDOW|REFRESHWINDOW|MOUSEBUTTONS,
  61.     WINDOWCLOSE|WINDOWDRAG|WINDOWSIZING|SIMPLE_REFRESH|WINDOWDEPTH,
  62.     NULL, NULL, 
  63.     "AnyMail Version 1.0     You have mail", 
  64.     NULL, /* Screen */
  65.     NULL, /* BitMap */
  66.     30, 30, 640, 200, WBENCHSCREEN
  67. };
  68.  
  69.  
  70. #define PORTNAME "AnyMail-Port"
  71.  
  72. int
  73. Init(
  74.     void
  75. );
  76.  
  77. int
  78. AnotherAnyMail(
  79.     void
  80. );
  81.  
  82. void
  83. AnyMail(
  84.     char *User
  85. );
  86.  
  87. void
  88. Display(
  89.     void
  90. );
  91.  
  92. int
  93. TimeToRepeat(
  94.     int *DoCommand
  95. );
  96.  
  97. char *
  98. ExtractPersonalName(
  99.     char *str
  100. );
  101.  
  102. void
  103. Terminate(
  104.     void
  105. );
  106.  
  107. LINE 
  108. AppendNewLine(
  109.     void
  110. );
  111.  
  112. void
  113. DeleteList(
  114.     void
  115. );
  116.  
  117. char *
  118. FromName(
  119.      char *FromLine
  120. );
  121.  
  122. struct List Excludes;
  123. struct List Includes;
  124.  
  125. struct FileInfoBlock fib;
  126. char *MailRdyName;
  127.  
  128. void
  129. main(
  130.     int argc,
  131.     char **argv
  132. )
  133. {
  134.     int i;
  135.     BPTR uumail;
  136.     char *Command = 0;
  137.     int DoCommand = FALSE;
  138.     
  139.     NewList(&Excludes);
  140.     NewList(&Includes);
  141.  
  142.     for(i=1; i<argc; ++i) {
  143.         if (stricmp(argv[i], "-x") == 0) {
  144.             MailRdyName = argv[++i];
  145.         } else 
  146.         if (stricmp(argv[i], "-e") == 0) {
  147.             MakeNode(&Excludes, argv[++i]);
  148.         } else
  149.         if (stricmp(argv[i], "-i") == 0) {
  150.             MakeNode(&Includes, argv[++i]);
  151.         } else
  152.         if (stricmp(argv[i], "-c") == 0) {
  153.             Command = argv[++i];
  154.         } else {
  155.             fprintf(stderr, "AnyMail: Unknown keyword %s\n", argv[i]);
  156.         }
  157.     }
  158.     
  159.     if (MailRdyName)
  160.         unlink(MailRdyName);
  161.     
  162.     if (AnotherAnyMail())
  163.         exit(0);
  164.         
  165.     if (Init()) {
  166.         
  167.         while(TimeToRepeat(&DoCommand)) {
  168.  
  169.             DeleteList();
  170.             
  171.             uumail = Lock("uumail:", ACCESS_READ);
  172.             if (Examine(uumail, &fib)) {
  173.                 while(ExNext(uumail, &fib)) {
  174.                     if (!OkToScan(&fib)) continue;
  175.                     
  176.                     AnyMail(fib.fib_FileName);
  177.                 }
  178.             }
  179.             UnLock(uumail);
  180.             
  181.             Display();
  182.         }
  183.     }
  184.     
  185.     Terminate();
  186.     
  187.     if (DoCommand && Command) {
  188.         Execute(Command, 0, 0);
  189.     }
  190. }
  191.  
  192. int
  193. OkToScan(
  194.     struct FileInfoBlock *fib
  195. )
  196. {
  197.     MAILNODE n;
  198.     char *FileName;
  199.     
  200.     if (fib->fib_DirEntryType >= 0) return FALSE;
  201.                     
  202.     for(n=(MAILNODE)Includes.lh_Head; n->Next; n = n->Next) {
  203.         FileName = fib->fib_FileName;
  204.         strlwr(FileName);
  205.         if (astcsma(FileName, n->Name) == strlen(FileName)) {
  206.             return TRUE;
  207.         }
  208.     }
  209.                     
  210.     for(n=(MAILNODE)Excludes.lh_Head; n->Next; n = n->Next) {
  211.         FileName = fib->fib_FileName;
  212.         strlwr(FileName);
  213.         if (astcsma(FileName, n->Name) == strlen(FileName)) {
  214.             return FALSE;
  215.         }
  216.     }
  217.     
  218.     return TRUE;
  219. }
  220.  
  221. int
  222. Init(
  223.     void
  224. )
  225. {
  226.     IntuitionBase = OpenLibrary("intuition.library", 0);
  227.     if (IntuitionBase == 0) {
  228.         fprintf(stderr, "AnyMail: Unable to open intuition.library\n");
  229.         return 0;
  230.     }
  231.     
  232.     GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 0);
  233.     if (GfxBase == 0) {
  234.         fprintf(stderr, ": Unable to open graphics.library\n");
  235.         return 0;
  236.     }
  237.     
  238.     return 1;
  239. }
  240.  
  241. int
  242. AnotherAnyMail(
  243.     void
  244. )
  245. {
  246.     struct MsgPort *OtherPort;
  247.     
  248.     /*
  249.      * Check for another port.  If none, create one.  Prevent races.
  250.      */
  251.     Forbid();
  252.     OtherPort = FindPort(PORTNAME);
  253.     if (OtherPort == NULL)
  254.         Port = CreatePort(PORTNAME, 0);
  255.     Permit();
  256.     
  257.     /*
  258.      * Signal the other AnyMail to scan uumail: again.
  259.      */
  260.     if (OtherPort) {
  261.         Signal(OtherPort->mp_SigTask, 1<<OtherPort->mp_SigBit);
  262.     }
  263.     
  264.     return OtherPort != 0;
  265. }   
  266.  
  267. int
  268. TimeToRepeat(
  269.     int *DoCommand
  270. )
  271. {
  272.     int Done   = FALSE;
  273.     int Repeat = FALSE;
  274.     struct IntuiMessage *im;
  275.     int WindowMask;
  276.     int PortMask;
  277.     int Signals;
  278.     
  279.     if (Window == 0) return TRUE;
  280.     
  281.     WindowMask = 1<<Window->UserPort->mp_SigBit;
  282.     PortMask   = 1<<Port->mp_SigBit;
  283.     
  284.     while(!Done && !Repeat) {
  285.     
  286.         Signals = Wait(WindowMask|PortMask);
  287.         
  288.         if (Signals & WindowMask) {
  289.             while (im = (struct IntuiMessage *)GetMsg(Window->UserPort)) {
  290.                 switch(im->Class) {
  291.                 case MOUSEBUTTONS:
  292.                     if (im->Code == SELECTDOWN) {
  293.                         *DoCommand = TRUE;
  294.                         Done = TRUE;
  295.                     }
  296.                     break;
  297.                 case REFRESHWINDOW:
  298.                     Display();
  299.                     break;
  300.                 case CLOSEWINDOW:
  301.                     Done = TRUE;
  302.                     break;
  303.                 }
  304.                 ReplyMsg((struct Message *)im);
  305.             }
  306.         }
  307.         if (Signals & PortMask) {
  308.             Repeat = TRUE;
  309.         }
  310.     }
  311.     
  312.     return Repeat;
  313. }
  314.  
  315. void
  316. AnyMail(
  317.     char *User
  318. )
  319. {
  320.     static char Buf[256];
  321.     static char FromLine[256];
  322.     static char SubjLine[256];
  323.     char *file = malloc(strlen(User) + 32);
  324.     FILE *fi;
  325.     long msgno = 0;
  326.     LINE Line;
  327.     int  NewUser = TRUE;
  328.  
  329.     if ('a' <= User[0] && User[0] <= 'z')
  330.         User[0] = User[0] - 'a' + 'A';
  331.         
  332.     strcpy(file, MakeConfigPath(UUMAIL, User));
  333.     if (fi = fopen(file, "r")) {
  334.         while (fgets(Buf, 256, fi)) {
  335.  
  336.             /*
  337.              *    Start of message
  338.              */
  339.  
  340.             if (strncmp(Buf, "From ", 5) != 0)
  341.                 continue;
  342.  
  343.             ++msgno;
  344.  
  345.             /*
  346.              *    Scan headers for From: and Subject:
  347.              *    Headers end with a blank line.
  348.              */
  349.  
  350.             FromLine[0] = 0;
  351.             SubjLine[0] = 0;
  352.  
  353.             while (fgets(Buf, 256, fi) && Buf[0] != '\n') {
  354.                 if (strncmp(Buf, "From:", 5) == 0)
  355.                     strcpy(FromLine, Buf + 5);
  356.                 if (strncmp(Buf, "Subject:", 8) == 0)
  357.                     strcpy(SubjLine, Buf + 8);
  358.             }
  359.  
  360.             /* Remove the trailing new line from the subject */
  361.             if (SubjLine[0])  SubjLine[strlen(SubjLine)-1] = 0;
  362.             
  363.             if (NewUser) {
  364.                 NewUser = FALSE;
  365.                 if (Lines != 0) {
  366.                     Line = AppendNewLine();
  367.                     Line->Msg[0] = 0;
  368.                 }
  369.                 Line = AppendNewLine();
  370.                 strcpy(Line->Msg, "To ");
  371.                 strcat(Line->Msg, User);
  372.             }
  373.             
  374.             Line = AppendNewLine();
  375.             sprintf(Line->Msg,
  376.                 "%-2d %-20.20s  %s",
  377.                 msgno,
  378.                 FromName(FromLine),
  379.                 SubjLine
  380.             );
  381.             ++Count;
  382.         }
  383.         
  384.         fclose(fi);
  385.     }
  386. }
  387.  
  388. void
  389. Display(
  390.     void
  391. )
  392. {
  393.     int xmin, xmax, ymin, ymax, x, y;
  394.     int len, lenmax;
  395.     LINE Line;
  396.     char Buff[200];
  397.  
  398.     if (Window == 0) {
  399.         Window = OpenWindow(&Nw);
  400.         if (Window == 0) 
  401.             return;
  402.             
  403.         ScreenToFront(Window->WScreen);
  404.     }
  405.     
  406.     xmin = Window->BorderLeft;             
  407.     ymin = Window->BorderTop;
  408.     xmax = Window->Width  - Window->BorderRight  - 1;
  409.     ymax = Window->Height - Window->BorderBottom - 1;
  410.     
  411.     if (xmin < xmax && ymin < ymax) {
  412.         SetAPen(Window->RPort, 0);
  413.         RectFill(Window->RPort, xmin, ymin, xmax, ymax);
  414.     }
  415.     
  416.     x = xmin + 2;
  417.     y = ymin + 4;
  418.     lenmax = (xmax-xmin+1)/GfxBase->DefaultFont->tf_XSize;
  419.             
  420.     SetAPen(Window->RPort, 1);
  421.     SetBPen(Window->RPort, 0);
  422.     
  423.     for(Line=Lines; Line; Line = Line->Next) {
  424.         if (y + GfxBase->DefaultFont->tf_YSize > ymax) break;
  425.         len = strlen(Line->Msg);
  426.         if (len > lenmax) len = lenmax;
  427.         Move(Window->RPort, x, y+GfxBase->DefaultFont->tf_Baseline);
  428.         Text(Window->RPort, Line->Msg, len);
  429.         y += GfxBase->DefaultFont->tf_YSize;
  430.     }
  431.     
  432.     sprintf(Buff, "AnyMail Version 1.0    You have %d message%s waiting.",
  433.         Count, Count==1?"":"s");
  434.     SetWindowTitles(Window, Buff, 0);
  435. }
  436.  
  437. void
  438. Terminate(
  439.     void
  440. )
  441. {
  442.     if (Window)        CloseWindow(Window);
  443.     
  444.     if (GfxBase)       CloseLibrary(GfxBase);
  445.     if (IntuitionBase) CloseLibrary(IntuitionBase);
  446.     
  447.     if (Port)          DeletePort(Port);
  448. }
  449.  
  450. void
  451. DeleteList(
  452.     void
  453. )
  454. {
  455.     LINE Line, Next;
  456.     
  457.     for(Line = Lines; Line; Line = Next) {
  458.         Next = Line->Next;
  459.         free(Line);
  460.     }
  461.     Lines = 0;
  462.     LastLine = 0;
  463.     Count = 0;
  464. }
  465.  
  466.             
  467. LINE 
  468. AppendNewLine(
  469.     void
  470. )
  471. {
  472.     LINE Line;
  473.     
  474.     Line = malloc(sizeof(LINE_STRUCT));
  475.     Line->Next = 0;
  476.     if (Lines == 0)
  477.         Lines = Line;
  478.     else 
  479.         LastLine->Next = Line;
  480.     LastLine = Line;
  481.             
  482.     return Line;
  483. }
  484.  
  485. /*
  486.  * The real name is between parens.  If it can't be found, use the
  487.  * whole from line
  488.  */
  489. char *
  490. FromName(
  491.      char *FromLine
  492. )
  493. {
  494.     char *Start;
  495.     char *End;
  496.     
  497.     Start = strchr(FromLine, '(');
  498.     if (Start) {
  499.         Start++;
  500.         End = strchr(Start, ')');
  501.         if (End) {
  502.             *End = 0;
  503.             return Start;
  504.         }
  505.     }
  506.     End = strchr(FromLine, '\n');
  507.     if (End) *End = 0;
  508.     
  509.     return FromLine;
  510. }
  511.  
  512. void
  513. MakeNode(
  514.     struct List *List,
  515.     char *Name
  516. )
  517. {
  518.     MAILNODE n;
  519.     
  520.     n = malloc(sizeof(MAILNODE_STRUCT) + strlen(Name));
  521.     strcpy(n->Name, Name);
  522.     
  523.     AddTail(List, (struct Node *)n);
  524. }
  525.