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

  1. /* Mail Command Line Interface -- Clients
  2.  * Copyright 1992 William Allen Simpson
  3.  *      partly based on a MAIL client design by Anders Klemets, SM0RGV
  4.  *
  5.  * Mods by PA0GRI
  6.  * Improved param cracking
  7.  */
  8. #include <ctype.h>
  9. #include <time.h>
  10. #include "global.h"
  11. #include "timer.h"
  12. #include "proc.h"
  13. #include "socket.h"
  14. #include "domain.h"
  15. #include "cmdparse.h"
  16. #include "files.h"
  17. #include "netuser.h"
  18. #include "mailcli.h"
  19. #include "mailutil.h"
  20. #include "smtp.h"
  21.   
  22.   
  23. /* Tracing levels:
  24.     0 - no tracing
  25.     1 - serious errors reported
  26.     2 - transient errors reported
  27.     3 - session progress reported
  28.  */
  29. unsigned short Mailtrace = 1;
  30.   
  31. #ifdef MAILCLIENT
  32.   
  33. int Mailquiet = FALSE;
  34. #ifdef LZW
  35. int poplzw = TRUE;
  36. #endif
  37.   
  38. struct mailservers *Mailservers = NULLMAIL;
  39.   
  40. static int domsquiet __ARGS((int argc,char *argv[],void *p));
  41. static int domstrace __ARGS((int argc,char *argv[],void *p));
  42. static int doadds __ARGS((int argc,char *argv[],void *p));
  43. static int dodrops __ARGS((int argc,char *argv[],void *p));
  44. static int dokicks __ARGS((int argc,char *argv[],void *p));
  45. static int dolists __ARGS((int argc,char *argv[],void *p));
  46. #ifdef LZW
  47. static int dopoplzw __ARGS((int argc,char *argv[],void *p));
  48. #endif
  49.   
  50. static void mailtick __ARGS((void *tp));
  51.   
  52. static char mreaderr[] = "popmail: Missing";
  53.   
  54. static struct cmds Mailcmds[] = {
  55.     "addserver",    doadds,         0, 2, "popmail addserver <mailserver>"
  56.     " [<seconds>] [hh:mm-hh:mm] "
  57. #ifdef POP2CLIENT
  58.     "pop2"
  59. #endif
  60. #ifdef POP3CLIENT
  61. #ifdef POP2CLIENT
  62.     "|"
  63. #endif
  64.     "pop3"
  65. #endif
  66.     " <mailbox> <username> <password>",
  67.     "dropserver",   dodrops,        0, 2, "popmail dropserver <mailserver>",
  68.     "kick",         dokicks,        0, 2, "popmail kick <mailserver>",
  69.     "list",         dolists,        0, 0, NULLCHAR,
  70. #ifdef LZW
  71.     "lzw",          dopoplzw,       0, 0, NULLCHAR,
  72. #endif
  73.     "quiet",        domsquiet,      0, 0, NULLCHAR,
  74.     "trace",        domstrace,      0, 0, NULLCHAR,
  75.     NULLCHAR,
  76. };
  77.   
  78.   
  79. #ifdef LZW
  80. static
  81. int dopoplzw(argc,argv,p)
  82. int argc;
  83. char *argv[];
  84. void *p;
  85. {
  86.     return setbool(&poplzw,"pop lzw",argc,argv);
  87. }
  88. #endif
  89.  
  90. int
  91. domsread(argc,argv,p)
  92. int argc;
  93. char *argv[];
  94. void *p;
  95. {
  96.     return subcmd(Mailcmds,argc,argv,p);
  97. }
  98.   
  99.   
  100. static int
  101. domsquiet(argc,argv,p)
  102. int argc;
  103. char *argv[];
  104. void *p;
  105. {
  106.     return setbool(&Mailquiet,"mail quiet",argc,argv);
  107. }
  108.   
  109. #endif
  110.   
  111. static int
  112. domstrace(argc, argv, p)
  113. int argc;
  114. char *argv[];
  115. void *p;
  116. {
  117.     return setshort(&Mailtrace,"mail tracing",argc,argv);
  118. }
  119.   
  120. #ifdef MAILCLIENT
  121.   
  122. static int
  123. doadds(argc,argv,p)
  124. int argc;
  125. char *argv[];
  126. void *p;
  127. {
  128.     struct mailservers *np;
  129.     char *fullname;
  130.     int i;
  131.     int32 addr;
  132.   
  133.     fullname = domainsuffix(argv[1]);
  134.     if((addr = resolve(fullname)) == 0L){
  135.         tprintf("Unknown host %s\n",fullname);
  136.         /* domainsuffix() ALLOCATED memory !, so free it - WG7J */
  137.         free(fullname);
  138.         return 1;
  139.     }
  140.   
  141.     i = 2;
  142.     np = (struct mailservers *) callocw(1,sizeof(struct mailservers));
  143.     np->hostname = fullname;
  144.     np->next = Mailservers;
  145.     Mailservers = np;
  146.     np->lowtime = np->hightime = -1;
  147.     np->timer.func = mailtick;  /* what to call on timeout */
  148.     np->timer.arg = (void *)np;
  149.   
  150.     if( argc > i && isdigit(*argv[i])){
  151.         if(strchr(argv[i],'-') == NULLCHAR )
  152.             /* set timer duration */
  153.             set_timer(&np->timer,atol(argv[i++])*1000L);
  154.     }
  155.   
  156.     if( argc > i && isdigit(*argv[i])){
  157.         int lh, ll, hh, hl;
  158.         sscanf(argv[i++], "%d:%d-%d:%d", &lh, &ll, &hh, &hl);
  159.         np->lowtime = lh * 100 + ll;
  160.         np->hightime = hh * 100 + hl;
  161.     }
  162.   
  163.     if ( argc > i ) {
  164.         struct daemon *dp = Mailreaders;
  165.   
  166.         for ( ; dp->name != NULLCHAR ; dp++ ) {
  167.             if ( stricmp(dp->name, argv[i]) == 0 ) {
  168.                 np->reader = dp;
  169.                 break;
  170.             }
  171.         }
  172.         if ( np->reader == NULLDAEMON ) {
  173.             tprintf("unrecognized protocol '%s'\n", argv[i] );
  174.             goto quit;
  175.         }
  176.         i++;
  177.     } else {
  178.         tprintf("%s protocol\n",mreaderr);
  179.         goto quit;
  180.     }
  181.   
  182.     if ( argc > i ) {
  183.         np->mailbox = strdup(argv[i++]);
  184.     } else {
  185.         tprintf("%s mailbox\n",mreaderr);
  186.         goto quit;
  187.     }
  188.   
  189.     if ( argc > i ) {
  190.         np->username = strdup(argv[i++]);
  191.     } else {
  192.         tprintf("%s username\n",mreaderr);
  193.         goto quit;
  194.     }
  195.   
  196.     if ( argc > i ) {
  197.         np->password = strdup(argv[i++]);
  198.     } else {
  199.         char poppass[20];
  200.  
  201.         tputs("Enter POP password: ");
  202.         usflush(Curproc->output);
  203.         if(recvline(Curproc->input, poppass, sizeof(poppass)) == -1)
  204.             goto quit;
  205.         rip(poppass);
  206.         np->password = strdup(poppass);
  207.     }
  208.   
  209.     start_timer(&np->timer);            /* and fire it up */
  210.     return 0;
  211.   
  212.     quit:
  213.     Mailservers = np->next;
  214.     free(np->hostname);
  215.     free(np->username);
  216.     free(np->password);
  217.     free(np->mailbox);
  218.     free((char *)np);
  219.     return -1;
  220. }
  221.   
  222.   
  223. static int
  224. dodrops(argc,argv,p)
  225. int argc;
  226. char *argv[];
  227. void *p;
  228. {
  229.     struct mailservers *np, *npprev = NULLMAIL;
  230.     char *fullname;
  231.   
  232.     fullname = domainsuffix(argv[1]);
  233.     for (np = Mailservers; np != NULLMAIL; npprev = np, np = np->next) {
  234.         if(strnicmp(np->hostname,fullname,strlen(fullname)) == 0) {
  235.             stop_timer(&np->timer);
  236.             free(np->hostname);
  237.             free(np->username);
  238.             free(np->password);
  239.             free(np->mailbox);
  240.   
  241.             if(npprev != NULLMAIL)
  242.                 npprev->next = np->next;
  243.             else
  244.                 Mailservers = np->next;
  245.             free((char *)np);
  246.             return 0;
  247.         }
  248.     }
  249.     tputs("No such server enabled.\n");
  250.     return -1;
  251. }
  252.   
  253.   
  254. static int
  255. dolists(argc,argv,p)
  256. int argc;
  257. char *argv[];
  258. void *p;
  259. {
  260.     struct mailservers *np;
  261.   
  262.     for (np = Mailservers; np != NULLMAIL; np = np->next) {
  263.         char tbuf[80];
  264.         if (np->lowtime != -1 && np->hightime != -1)
  265.             sprintf(tbuf, " %02d:%02d-%02d:%02d",
  266.             np->lowtime/100,
  267.             np->lowtime%100,
  268.             np->hightime/100,
  269.             np->hightime%100);
  270.         else
  271.             tbuf[0] = '\0';
  272.         tprintf("%-32s (%lu/%lu%s) %s %s\n",
  273.         np->hostname,
  274.         read_timer(&np->timer) /1000L,
  275.         dur_timer(&np->timer) /1000L,
  276.         tbuf,
  277.         np->reader->name,
  278.         np->username );
  279.     }
  280.     return 0;
  281. }
  282.   
  283.   
  284. static int
  285. dokicks(argc,argv,p)
  286. int argc;
  287. char *argv[];
  288. void *p;
  289. {
  290.     struct mailservers *np;
  291.     char *fullname;
  292.   
  293.     fullname = domainsuffix(argv[1]);
  294.     for (np = Mailservers; np != NULLMAIL; np = np->next) {
  295.         if(strnicmp(np->hostname,fullname,strlen(fullname)) == 0) {
  296.             if(availmem() - np->reader->stksize < Memthresh){
  297.                 tputs("insufficient memory\n");
  298.                 return 1;
  299.             }
  300.             /* If the timer is not running, the timeout function
  301.              * has already been called, and we don't want to call
  302.              * it again.
  303.              */
  304.             if ( np->timer.duration == 0
  305.             || run_timer(&np->timer) ) {
  306.                 stop_timer(&np->timer);
  307.                 newproc( np->reader->name,
  308.                 np->reader->stksize,
  309.                 np->reader->fp,
  310.                 0, np, NULL,0);
  311.             }
  312.             return 0;
  313.         }
  314.     }
  315.     tputs("No such server enabled.\n");
  316.     return -1;
  317. }
  318.   
  319.   
  320. static void
  321. mailtick(tp)
  322. void *tp;
  323. {
  324.     struct mailservers *np = tp;
  325.     struct tm *ltm;
  326.     time_t t;
  327.     int now;
  328.   
  329.     if(availmem() - np->reader->stksize < Memthresh){
  330.         /* Memory is tight, don't do anything */
  331.         if (Mailtrace >= 2)
  332.             log(-1,"%s tick exit -- low memory",
  333.             np->reader->name);
  334.         start_timer(&np->timer);
  335.         return;
  336.     }
  337.   
  338.     time(&t);
  339.     ltm = localtime(&t);
  340.     now = ltm->tm_hour * 100 + ltm->tm_min;
  341.     if (np->lowtime < np->hightime) {  /* doesn't cross midnight */
  342.         if (now < np->lowtime || now >= np->hightime) {
  343.             if (Mailtrace >= 2)
  344.                 log(-1,"%s window to '%s' not open",
  345.                 np->reader->name,
  346.                 np->hostname);
  347.             start_timer(&np->timer);
  348.             return;
  349.         }
  350.     } else {
  351.         if (now < np->lowtime && now >= np->hightime) {
  352.             if (Mailtrace >= 2)
  353.                 log(-1,"%s window to '%s' not open",
  354.                 np->reader->name,
  355.                 np->hostname);
  356.             start_timer(&np->timer);
  357.             return;
  358.         }
  359.     }
  360.   
  361.     newproc( np->reader->name, np->reader->stksize, np->reader->fp,
  362.     0, tp, NULL,0);
  363. }
  364.   
  365.   
  366. int
  367. mailresponse(s,buf,comment)
  368. int s;          /* Socket index */
  369. char *buf;      /* User buffer */
  370. char *comment;  /* comment for error message */
  371. {
  372.     if (recvline(s,buf,RLINELEN) != -1) {
  373.         if ( Mailtrace >= 3 ) {
  374.             rip(buf);
  375.             log(s,"%s <== %s", comment, buf);
  376.         }
  377.         return 0;
  378.     }
  379.     if ( Mailtrace >= 2 )
  380.         log(s,"receive error for %s response", comment);
  381.     return -1;
  382. }
  383.   
  384.   
  385. /* Check to see if mailbox is already busy (or perpetually locked) */
  386. int
  387. mailbusy( np )
  388. struct mailservers *np;
  389. {
  390.     int countdown = 10;
  391.   
  392.     while ( mlock( Mailspool, np->mailbox ) ) {
  393.         if ( --countdown > 0 ) {
  394.             pause( 60000L ); /* 60 seconds */
  395.         } else {
  396.             start_timer(&np->timer);
  397.             return TRUE;
  398.         }
  399.     }
  400.   
  401.     /* release while processing */
  402.     rmlock( Mailspool, np->mailbox );
  403.     return FALSE;
  404. }
  405.   
  406. #endif
  407.