home *** CD-ROM | disk | FTP | other *** search
/ Gold Fish 2 / goldfish_vol2_cd1.bin / files / comm / net / amipop / source / pop_dopop.c < prev    next >
C/C++ Source or Header  |  1994-11-10  |  9KB  |  604 lines

  1. #include "pop.h"
  2.  
  3. /* Stuff for "From " Header */
  4. /* Courtesy Michael B. Smith */
  5.  
  6.  
  7. struct mytm    {
  8.                 int year;
  9.                 int month;
  10.                 int day;
  11.                 int dow;
  12.                 int hour;
  13.                 int min;
  14.                 int sec;
  15.             };
  16.  
  17. /* DaysInMonth */
  18. static const int    dim [] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
  19. static const char    *months [] = {    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  20.                                        "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
  21. static const char    *days [] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
  22.  
  23. static void DateStampToMyTm (struct DateStamp *date, struct mytm *da)
  24. {
  25.     int days, years, leap  = 0, month = 0;
  26.  
  27.     days = date->ds_Days + 731;        /*  1976    */
  28.     years = days / (365*3+366);        /*  #quad yrs    */
  29.     days -= years * (365*3+366);
  30.     years = 1976 + 4 * years;
  31.  
  32.     if (days <= 365)
  33.     {
  34.         leap = 1;
  35.     }
  36.     else
  37.     {
  38.         days -= 366;
  39.         ++years;
  40.         years += days / 365;
  41.         days %= 365;
  42.     }
  43.  
  44.     month = 0;
  45.     while (1)
  46.     {
  47.         if (month == 1)
  48.         {
  49.             if (days < (28 + leap)) break;
  50.             days -= 28 + leap;
  51.         }
  52.         else
  53.         {
  54.             if (days < dim [month]) break;
  55.             days -= dim [month];
  56.         }
  57.         ++month;
  58.     }
  59.  
  60.     da->hour   = date->ds_Minute / 60;
  61.     da->min    = date->ds_Minute % 60;
  62.     da->sec    = date->ds_Tick / 50;
  63.  
  64.     da->day    = days + 1;
  65.     da->month  = month + 1;
  66.     da->dow    = date->ds_Days % 7;    /*  0 = sunday   */
  67.     da->year   = years;
  68.  
  69.     return;
  70. }
  71.  
  72. char * datestr (char *buf)
  73. {
  74.     /*
  75.     **  datestr
  76.     **
  77.     **    Build ARPA date-time as specified in RFC-822:
  78.     **
  79.     **        Wed, 13 Oct 93 18:52:04 EST
  80.     **        123456789012345678901234567890
  81.     **
  82.     **    buf must be 24 characters, plus space for TimeZone and NUL.
  83.     **
  84.     **    As TimeZone may be "(+23:30)" or similar, 33 chars should
  85.     **    do it.
  86.     */
  87.     struct mytm da;
  88.     struct DateStamp ds;
  89.  
  90.     DateStampToMyTm (DateStamp (&ds), &da);
  91.  
  92.     DoFmt (buf, "%s, %ld %s %ld %02ld:%02ld:%02ld",
  93.                 days [da.dow], da.day,
  94.                 months [da.month - 1], da.year % 100,
  95.                 da.hour, da.min, da.sec);
  96.  
  97.     return buf;
  98. }
  99.  
  100. char * time_stamp (char *buf)
  101. {
  102.     /*
  103.     **  time_stamp
  104.     **
  105.     **    Put a time/date stamp into buf (for logging)
  106.     **
  107.     **    13 Nov 93 13:14:45
  108.     */
  109.     struct DateStamp ds;
  110.     struct mytm da;
  111.  
  112.     DateStampToMyTm (DateStamp (&ds), &da);
  113.  
  114.     DoFmt (buf, "%ld %s %ld %02ld:%02ld:%02ld",
  115.                 da.day,
  116.                 months [da.month - 1], da.year % 100,
  117.                 da.hour, da.min, da.sec);
  118.  
  119.     return buf;
  120. }
  121.  
  122. /*  End stuff for "From " header */
  123.  
  124.  
  125. #define ASYNCBUFSIZE 8192
  126.  
  127. BOOL needfrom ( char * , struct AsyncFile *);
  128.  
  129. /* Variables global to this file */
  130.  
  131. struct Library *SockBase ;
  132. int havemail;
  133.  
  134. /* Functions */
  135.  
  136. int dopop(void)
  137. {
  138.     int s;
  139.     int count=1;
  140.     int okay=1;
  141.     struct hostent *hp;
  142.     struct sockaddr_in sa;
  143.  
  144.     DoFmt(title,"Connecting to %s",pophost);
  145.     settitle(title);
  146.  
  147.     if((SockBase = OpenLibrary( SOCKLIBNAME, SOCKLIBVERSION )) == NULL)
  148.     {
  149.         doreq("Error opening "SOCKLIBNAME"\n",bum);
  150.         return(1);
  151.     }
  152. #ifdef AMITCP
  153.     SetErrnoPtr(&errno, sizeof errno);
  154. #else
  155.     setup_sockets( MAXSOCKS, &errno );
  156. #endif
  157.  
  158.     if((hp=gethostbyname(pophost))==NULL)
  159.     {
  160. #ifndef AMITCP
  161.         cleanup_sockets();
  162. #endif
  163.         CloseLibrary( SockBase ) ;
  164.         doreq("Connection Refused.",bum);
  165.         return(1);
  166.     }
  167.  
  168.     bzero(&sa, sizeof(sa));
  169.     bcopy(hp->h_addr, (char *)&sa.sin_addr, hp->h_length);
  170.     sa.sin_family = hp->h_addrtype;
  171.     sa.sin_port = htons((u_short)port);
  172.     if ((s=socket(hp->h_addrtype,SOCK_STREAM,0)) < 0)
  173.     {
  174. #ifndef AMITCP
  175.         cleanup_sockets();
  176. #endif
  177.         CloseLibrary( SockBase ) ;
  178.         doreq("Something bad\nhas happened.",bum);
  179.         return(1);
  180.     }
  181.  
  182.     if (connect(s,(struct sockaddr *) &sa,sizeof(sa))< 0)
  183.     {
  184.         doreq("No POP3 daemon\nrunning on this\nmachine or port.",bum);
  185.         s_close(s);
  186. #ifndef AMITCP
  187.         cleanup_sockets();
  188. #endif
  189.         CloseLibrary( SockBase ) ;
  190.         return(1);
  191.     }
  192.  
  193. /* Put actual code here */
  194.  
  195.     recv(s,buf,BUFSIZE-1,0);
  196.     settitle("Got Connection");
  197.  
  198. /*    sendgreet(s);*/
  199.  
  200.     if (senduser(s))
  201.     {
  202. #ifndef AMITCP
  203.         cleanup_sockets();
  204. #endif
  205.         CloseLibrary( SockBase ) ;
  206.         return(1);
  207.     }
  208.  
  209.     havemail=sendstat(s);
  210.  
  211.     while ((okay) && ((havemail > count) || (havemail == count)))
  212.     {
  213.         DoFmt(title,"Retrieving %lu",count);
  214.         settitle(title);
  215.  
  216.         okay=retrieve(s,count);
  217.  
  218.         if (delmail && okay)
  219.         {
  220.             DoFmt(title,"Deleting %lu",count);
  221.             settitle(title);
  222.  
  223.             okay=delmessage(s,count);
  224.         }
  225.         ++count;
  226.     }
  227.  
  228.     if(sendquit(s))
  229.     {
  230. #ifndef AMITCP
  231.         cleanup_sockets();
  232. #endif
  233.         CloseLibrary( SockBase ) ;
  234.         return(1);
  235.     }
  236.  
  237.     if (Project0Wnd)
  238.     {
  239.         SetWindowTitles(Project0Wnd,Project0Wdt, (UBYTE *) ~0);
  240.     }
  241.  
  242.     if (havemail && notify) /* removed sendstat() after Nofify */
  243.     {
  244.         doreq("You have new mail.","Cool");
  245.     }
  246.  
  247. /* End actual code */
  248.  
  249.     s_close(s);
  250. #ifndef AMITCP
  251.     cleanup_sockets();
  252. #endif
  253.     CloseLibrary( SockBase ) ;
  254.     return(0);
  255. }
  256.  
  257. /*int sendgreet(int s)
  258. {
  259.     DoFmt(buf,"HELLO\r\n");
  260.     trans(s,buf);
  261.  
  262.     return(0);
  263. }*/
  264.  
  265. int senduser(int s)
  266. {
  267.     int t;
  268.  
  269.     settitle("Sending Username");
  270.  
  271.     DoFmt(buf,"USER %s\r\n",username);
  272.  
  273.     if ( !trans(s,buf) ) return(1);
  274.  
  275.     t=sscanf(buf,"%s",temp);
  276.     if ( valcheck(t,temp) ) return(1);
  277.  
  278. /* Password */
  279.  
  280.     settitle("Sending Password");
  281.  
  282.     DoFmt(buf,"PASS %s\r\n",password);
  283.  
  284.     if ( !trans(s,buf) ) return(1);
  285.  
  286.     t=sscanf(buf,"%s",temp);
  287.  
  288.     if ( valcheck(t,temp) ) return(1);
  289.  
  290.     return(0);
  291. }
  292.  
  293. int sendquit(int s)
  294. {
  295.     int t;
  296.  
  297.     settitle("Sending QUIT");
  298.  
  299.     DoFmt(buf,"QUIT\r\n");
  300.  
  301.     if ( !trans(s,buf) ) return(1);
  302.  
  303.     t=sscanf(buf,"%s",temp);
  304.  
  305.     if ( valcheck(t,temp) ) return(1);
  306.  
  307.     settitle("Quit Acknowledged");
  308.  
  309.     return(0);
  310. }
  311.  
  312. int sendstat( int s )
  313. {
  314.     int t;
  315.     int count=0;
  316.  
  317.     DoFmt(buf,"STAT\r\n");
  318.  
  319.     if ( !trans(s,buf) ) return(0);
  320.  
  321.     t=sscanf(buf,"%s %lu",temp,&count);
  322.  
  323.     if ( valcheck(t,temp) ) return(0);
  324.  
  325.     return(count);
  326. }
  327.  
  328. int retrieve(int s,int count)
  329. {
  330.     int foo;
  331.     int c;
  332.     int goon=1;
  333.  
  334.     char *havefrom;
  335.     char *buf2;
  336.     char *buf3;
  337.  
  338.     BOOL begin=TRUE;
  339.     struct AsyncFile *ofp;
  340.  
  341.     if (havefrom=AllocVec(512,MEMF_CLEAR))
  342.     {
  343.         if ( (count == 1) && (!appfile) )
  344.         {
  345.             ofp = OpenAsync(maildir, MODE_WRITE,ASYNCBUFSIZE);
  346.         }
  347.         else
  348.         {
  349.             ofp = OpenAsync(maildir, MODE_APPEND,ASYNCBUFSIZE);
  350.         }
  351.  
  352.         if ( ofp == NULL)
  353.         {
  354.             doreq("Unable to lock mailbox.\n",bum);
  355.             FreeVec(havefrom);
  356.             return(0);
  357.         }
  358.  
  359.         DoFmt(buf,"RETR %lu\r\n",count);
  360.  
  361.         if ( !trans(s,buf) )
  362.         {
  363.             CloseAsync(ofp);
  364.             FreeVec(havefrom);
  365.             return(0);
  366.         }
  367.  
  368.         if ( valcheck(1,buf) )
  369.         {
  370.             CloseAsync(ofp);
  371.             FreeVec(havefrom);
  372.             return(0);
  373.         }
  374.  
  375.         /*buf3=strstr(buf,".\r\n");
  376.  
  377.         if ( (buf3) && (buf3+3) )
  378.         {
  379.             char *buf4;
  380.  
  381.             if (needfrom(buf3,ofp))
  382.             {
  383.                 begin=FALSE;
  384.             }
  385.  
  386.             buf4=strip(buf3);
  387.             buf3=stpchrn(buf4,0x20);
  388.             if (buf3)
  389.             {
  390.                 WriteAsync(ofp,buf3,strlen(buf3));
  391.             }
  392.         }*/
  393.  
  394.         /* Hack this up once more 11/5/94 */
  395.  
  396.         {
  397.             buf3=strstr(buf,".\r\n");
  398.  
  399.             if ( (buf3) && (buf3+3) )
  400.             {
  401.                 char *buf4;
  402.  
  403.                 if (needfrom(buf3+2,ofp))
  404.                 {
  405.                     begin=FALSE;
  406.                 }
  407.  
  408.                 buf4=strip(buf3+2);
  409.                 /*buf3=stpchrn(buf4,0x20);*/
  410.  
  411.                 if (buf4)
  412.                 {
  413.                     WriteAsync(ofp,buf4,strlen(buf4));
  414.                 }
  415.             }
  416.  
  417.         }
  418.  
  419.         while ( goon )
  420.         {
  421.             foo=recv(s,buf,BUFSIZE-1,0);
  422.  
  423.             if (foo < 1)
  424.             {
  425.                 goon=0;
  426.             }
  427.  
  428.             buf[foo]='\0';
  429.  
  430.             goon=lastblock(buf);
  431.  
  432.             /* Magic to add "From " header */
  433.  
  434.             if (begin && goon)
  435.             {
  436.                 needfrom(buf,ofp);
  437.             }
  438.  
  439.             begin=FALSE;
  440.  
  441.             buf2=strip(buf);
  442.  
  443.             c=WriteAsync(ofp,buf2,strlen(buf2));
  444.  
  445.             if (c == -1)
  446.             {
  447.                 doreq("Error during write to mailbox.",bum);
  448.                 goon=0;
  449.             }
  450.         }
  451.  
  452.         WriteAsync(ofp,"\n",1);
  453.         CloseAsync(ofp);
  454.  
  455.         FreeVec(havefrom);
  456.         return(1);
  457.     }
  458.     else
  459.     {
  460.         return(0);
  461.     }
  462.  
  463. }
  464.  
  465. int delmessage( int s, int count )
  466. {
  467.     DoFmt(buf,"DELE %lu\r\n",count);
  468.     trans(s,buf);
  469.  
  470.     if ( valcheck(1,buf) ) return(0);
  471.  
  472.     return(1);
  473. }
  474.  
  475. int valcheck(int t, char *localtemp)
  476. {
  477.     if (t == 0)
  478.     {
  479.         doreq("Got a bogus return string.\n",bum);
  480.         return(1);
  481.     }
  482.  
  483.     if ( !strstr(localtemp,"+OK") )
  484.     {
  485.         doreq("Didn't get +OK",bum);
  486.  
  487.         if (localtemp[0] != '\0')
  488.         {
  489.             doreq(localtemp,bum);
  490.         }
  491.         return(1);
  492.     }
  493.     return(0);
  494. }
  495.  
  496. int trans( int s, char *mybuf )
  497. {
  498.     int foo;
  499.  
  500.     send(s,mybuf,strlen(mybuf),0);
  501.  
  502.     foo=recv(s,buf,BUFSIZE-1,0);
  503.  
  504.     if ( foo < 1 )
  505.     {
  506.         return(0);
  507.     }
  508.  
  509.     buf[foo]='\0';
  510.  
  511.     return (1);
  512. }
  513.  
  514. void settitle( char *newtitle )
  515. {
  516.     if (winop)
  517.     {
  518.         SetWindowTitles(Project0Wnd,newtitle, (UBYTE *) ~0);
  519.     }
  520. }
  521.  
  522. char *strip( char *mybuf )
  523. {
  524.     char out[BUFSIZE]="";
  525.     ULONG x1=0;
  526.     ULONG x2=0;
  527.     ULONG len;
  528.  
  529.     len=strlen(mybuf);
  530.  
  531.     while (mybuf[x1] != '\0' )
  532.     {
  533.         while (mybuf[x1] == '\r')
  534.         {
  535.             ++x1;
  536.         }
  537.         out[x2]=mybuf[x1];
  538.         ++x2;
  539.         if (x1 < len)
  540.         {
  541.             ++x1;
  542.         }
  543.     }
  544.     out[x2]='\0';
  545.  
  546.     strcpy(mybuf,out);
  547.  
  548.     return(mybuf);
  549. }
  550.  
  551. int lastblock (char *segment)
  552. {
  553.     char *found;
  554.     int len = strlen(segment);
  555.  
  556.     if ( (found=strstr(segment,"\r\n.\r\n")))
  557.     {
  558.         /*buf[found-segment]='\n';*/
  559.         buf[found-segment]='\0'; /* used to be found-segment+2 */
  560.         return(0);
  561.     }
  562.  
  563.     if ( (len==2) && (found=strstr(segment,"\r\n")) )
  564.     {
  565.         buf[found-segment]='\0'; /* Added recently */
  566.         return(0);
  567.     }
  568.  
  569.     if ( len==1 ) /* Kludge of the century */
  570.     {
  571.         return(0);
  572.     }
  573.  
  574.     if ( (len <= 4) && (found=strstr(segment,".\r\n")) )
  575.     {
  576.         /*buf[found-segment]='\n';*/
  577.         buf[found-segment]='\0';
  578.         return(0);
  579.     }
  580.  
  581.     return(1);
  582. }
  583.  
  584. BOOL needfrom(char *mybuf,struct AsyncFile *ofp)
  585. {
  586.     if ( !strstr(mybuf,"From ") )
  587.     {
  588.         char *newtemp;
  589.  
  590.         if (newtemp=AllocVec(BIGSTRING,MEMF_CLEAR))
  591.         {
  592.             int tempsize=0;
  593.  
  594.             DoFmt(newtemp,"From %s@%s ", username,pophost);
  595.             tempsize=strlen(newtemp);
  596.             DoFmt((newtemp+tempsize),"%s\n",datestr((newtemp+tempsize)));
  597.             WriteAsync(ofp,newtemp,strlen(newtemp));
  598.             FreeVec(newtemp);
  599.         }
  600.  
  601.         return(TRUE);
  602.     }
  603.     return(FALSE);
  604. }