mtest.c
上传用户:ycwykj01
上传日期:2007-01-04
资源大小:1819k
文件大小:20k
源码类别:

网络编程

开发平台:

Unix_Linux

  1. /*
  2.  * Program: Mail library test program
  3.  *
  4.  * Author: Mark Crispin
  5.  * Networks and Distributed Computing
  6.  * Computing & Communications
  7.  * University of Washington
  8.  * Administration Building, AG-44
  9.  * Seattle, WA  98195
  10.  * Internet: MRC@CAC.Washington.EDU
  11.  *
  12.  * Date: 8 July 1988
  13.  * Last Edited: 28 May 1999
  14.  *
  15.  * Sponsorship: The original version of this work was developed in the
  16.  * Symbolic Systems Resources Group of the Knowledge Systems
  17.  * Laboratory at Stanford University in 1987-88, and was funded
  18.  * by the Biomedical Research Technology Program of the National
  19.  * Institutes of Health under grant number RR-00785.
  20.  *
  21.  * Original version Copyright 1988 by The Leland Stanford Junior University
  22.  * Copyright 1999 by the University of Washington
  23.  *
  24.  *  Permission to use, copy, modify, and distribute this software and its
  25.  * documentation for any purpose and without fee is hereby granted, provided
  26.  * that the above copyright notices appear in all copies and that both the
  27.  * above copyright notices and this permission notice appear in supporting
  28.  * documentation, and that the name of the University of Washington or The
  29.  * Leland Stanford Junior University not be used in advertising or publicity
  30.  * pertaining to distribution of the software without specific, written prior
  31.  * permission.  This software is made available "as is", and
  32.  * THE UNIVERSITY OF WASHINGTON AND THE LELAND STANFORD JUNIOR UNIVERSITY
  33.  * DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO THIS SOFTWARE,
  34.  * INCLUDING WITHOUT LIMITATION ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  35.  * FITNESS FOR A PARTICULAR PURPOSE, AND IN NO EVENT SHALL THE UNIVERSITY OF
  36.  * WASHINGTON OR THE LELAND STANFORD JUNIOR UNIVERSITY BE LIABLE FOR ANY
  37.  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
  38.  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
  39.  * CONTRACT, TORT (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF
  40.  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  41.  *
  42.  */
  43. #include <stdio.h>
  44. #include <ctype.h>
  45. #include <signal.h>
  46. #include "mail.h"
  47. #include "osdep.h"
  48. #include "rfc822.h"
  49. #include "smtp.h"
  50. #include "nntp.h"
  51. /* Excellent reasons to hate ifdefs, and why my real code never uses them */
  52. #ifndef unix
  53. # define unix 0
  54. #endif
  55. #if unix
  56. # define UNIXLIKE 1
  57. # define MACOS 0
  58. # include <pwd.h>
  59. char *getpass ();
  60. #else
  61. # define UNIXLIKE 0
  62. # ifdef noErr
  63. #  define MACOS 1
  64. #  include <Memory.h>
  65. # else
  66. #  define MACOS 0
  67. # endif
  68. #endif
  69. #include "misc.h"
  70. char *curhst = NIL; /* currently connected host */
  71. char *curusr = NIL; /* current login user */
  72. char personalname[MAILTMPLEN]; /* user's personal name */
  73. static char *hostlist[] = { /* SMTP server host list */
  74.   "mailhost",
  75.   "localhost",
  76.   NIL
  77. };
  78. static char *newslist[] = { /* Netnews server host list */
  79.   "news",
  80.   NIL
  81. };
  82. int main (void);
  83. void mm (MAILSTREAM *stream,long debug);
  84. void overview_header (MAILSTREAM *stream,unsigned long uid,OVERVIEW *ov);
  85. void header (MAILSTREAM *stream,long msgno);
  86. void display_body (BODY *body,char *pfx,long i);
  87. void status (MAILSTREAM *stream);
  88. void prompt (char *msg,char *txt);
  89. void smtptest (long debug);
  90. /* Main program - initialization */
  91. int main ()
  92. {
  93.   MAILSTREAM *stream = NIL;
  94.   void *sdb = NIL;
  95.   char *s,tmp[MAILTMPLEN];
  96.   long debug;
  97. #include "linkage.c"
  98. #if MACOS
  99.   {
  100.     size_t *base = (size_t *) 0x000908;
  101. /* increase stack size on a Mac */
  102.     SetApplLimit ((Ptr) (*base - (size_t) 65535L));
  103.   }
  104. #endif
  105. #if UNIXLIKE
  106.   curusr = cpystr(myusername());/* current user is this name */
  107.   {
  108.     char *suffix;
  109.     struct passwd *pwd = getpwnam (curusr);
  110.     if (pwd) {
  111.       strcpy (tmp,pwd->pw_gecos);
  112. /* dyke out the office and phone poop */
  113.       if (suffix = strchr (tmp,',')) suffix[0] = '';
  114.       strcpy (personalname,tmp);/* make a permanent copy of it */
  115.     }
  116.     else personalname[0] = '';
  117.   }
  118. #else
  119.   curusr = cpystr ("somebody");
  120.   personalname[0] = '';
  121. #endif
  122.   curhst = cpystr (mylocalhost ());
  123.   puts ("MTest -- C client test program");
  124.   if (!*personalname) prompt ("Personal name: ",personalname);
  125. /* user wants protocol telemetry? */
  126.   prompt ("Debug protocol (y/n)?",tmp);
  127.   ucase (tmp);
  128.   debug = (tmp[0] == 'Y') ? T : NIL;
  129.   do {
  130.     prompt ("Mailbox ('?' for help): ",tmp);
  131.     if (!strcmp (tmp,"?")) {
  132.       puts ("Enter INBOX, mailbox name, or IMAP mailbox as {host}mailbox");
  133.       puts ("Known local mailboxes:");
  134.       mail_list (NIL,NIL,"%");
  135.       if (s = sm_read (&sdb)) {
  136. puts ("Local subscribed mailboxes:");
  137. do (mm_lsub (NIL,NIL,s,NIL));
  138. while (s = sm_read (&sdb));
  139.       }
  140.       puts ("or just hit return to quit");
  141.     }
  142.     else if (tmp[0]) stream = mail_open (stream,tmp,debug ? OP_DEBUG : NIL);
  143.   } while (!stream && tmp[0]);
  144.   mm (stream,debug); /* run user interface if opened */
  145. #if MACOS
  146. /* clean up resolver */
  147.   if (resolveropen) CloseResolver ();
  148. #endif
  149.   return NIL;
  150. }
  151. /* MM command loop
  152.  * Accepts: MAIL stream
  153.  */
  154. void mm (MAILSTREAM *stream,long debug)
  155. {
  156.   void *sdb = NIL;
  157.   char cmd[MAILTMPLEN];
  158.   char *s,*arg;
  159.   unsigned long i;
  160.   unsigned long last = 0;
  161.   BODY *body;
  162.   status (stream); /* first report message status */
  163.   while (stream) {
  164.     prompt ("MTest>",cmd); /* prompt user, get command */
  165. /* get argument */
  166.     if (arg = strchr (cmd,' ')) *arg++ = '';
  167.     switch (*ucase (cmd)) { /* dispatch based on command */
  168.     case 'B': /* Body command */
  169.       if (arg) last = atoi (arg);
  170.       else if (!last) {
  171. puts ("?Missing message number");
  172. break;
  173.       }
  174.       if (last && (last <= stream->nmsgs)) {
  175. mail_fetchstructure (stream,last,&body);
  176. if (body) display_body (body,NIL,(long) 0);
  177. else puts ("%No body information available");
  178.       }
  179.       else puts ("?Bad message number");
  180.       break;
  181.     case 'C': /* Check command */
  182.       mail_check (stream);
  183.       status (stream);
  184.       break;
  185.     case 'D': /* Delete command */
  186.       if (arg) last = atoi (arg);
  187.       else {
  188. if (last == 0) {
  189.   puts ("?Missing message number");
  190.   break;
  191. }
  192. arg = cmd;
  193. sprintf (arg,"%lu",last);
  194.       }
  195.       if (last && (last <= stream->nmsgs))
  196. mail_setflag (stream,arg,"\DELETED");
  197.       else puts ("?Bad message number");
  198.       break;
  199.     case 'E': /* Expunge command */
  200.       mail_expunge (stream);
  201.       last = 0;
  202.       break;
  203.     case 'F': /* Find command */
  204.       if (!arg) {
  205. arg = "%";
  206. if (s = sm_read (&sdb)) {
  207.   puts ("Local network subscribed mailboxes:");
  208.   do if (*s == '{') (mm_lsub (NIL,NIL,s,NIL));
  209.   while (s = sm_read (&sdb));
  210. }
  211.       }
  212.       puts ("Subscribed mailboxes:");
  213.       mail_lsub (((arg[0] == '{') && (*stream->mailbox == '{')) ? stream : NIL,
  214.  NIL,arg);
  215.       puts ("Known mailboxes:");
  216.       mail_list (((arg[0] == '{') && (*stream->mailbox == '{')) ? stream : NIL,
  217.  NIL,arg);
  218.       break;
  219.     case 'G':
  220.       mail_gc (stream,GC_ENV|GC_TEXTS|GC_ELT);
  221.       break;
  222.     case 'H': /* Headers command */
  223.       if (arg) {
  224. if (!(last = atoi (arg))) {
  225.   mail_search (stream,arg);
  226.   for (i = 1; i <= stream->nmsgs; ++i)
  227.     if (mail_elt (stream,i)->searched) header (stream,i);
  228.   break;
  229. }
  230.       }
  231.       else if (last == 0) {
  232. puts ("?Missing message number");
  233. break;
  234.       }
  235.       if (last && (last <= stream->nmsgs)) header (stream,last);
  236.       else puts ("?Bad message number");
  237.       break;
  238.     case 'L': /* Literal command */
  239.       if (arg) last = atoi (arg);
  240.       else if (!last) {
  241. puts ("?Missing message number");
  242. break;
  243.       }
  244.       if (last && (last <= stream->nmsgs))
  245. puts (mail_fetch_message (stream,last,NIL,NIL));
  246.       else puts ("?Bad message number");
  247.       break;
  248.     case 'M':
  249.       mail_status (NIL,arg ? arg : stream->mailbox,
  250.    SA_MESSAGES|SA_RECENT|SA_UNSEEN|SA_UIDNEXT|SA_UIDVALIDITY);
  251.       break;
  252.     case 'N': /* New mailbox command */
  253.       if (!arg) {
  254. puts ("?Missing mailbox");
  255. break;
  256.       }
  257. /* get the new mailbox */
  258.       while (!(stream = mail_open (stream,arg,debug)))
  259. prompt ("Mailbox: ",arg);
  260.       last = 0;
  261.       status (stream);
  262.       break;
  263.     case 'O': /* Overview command */
  264.       if (!arg) {
  265. puts ("?Missing UID");
  266. break;
  267.       }
  268.       mail_fetch_overview (stream,arg,overview_header);
  269.       break;
  270.     case 'Q': /* Quit command */
  271.       mail_close (stream);
  272.       stream = NIL;
  273.       break;
  274.     case 'S': /* Send command */
  275.       smtptest (debug);
  276.       break;
  277.     case '': /* null command (type next message) */
  278.       if (!last || (last++ >= stream->nmsgs)) {
  279. puts ("%No next message");
  280. break;
  281.       }
  282.     case 'T': /* Type command */
  283.       if (arg) last = atoi (arg);
  284.       else if (!last) {
  285. puts ("?Missing message number");
  286. break;
  287.       }
  288.       if (last && (last <= stream->nmsgs)) {
  289. STRINGLIST *lines = mail_newstringlist ();
  290. STRINGLIST *cur = lines;
  291. cur->text.size = strlen ((char *) (cur->text.data = (unsigned char *)
  292.    cpystr ("Date")));
  293. cur = cur->next = mail_newstringlist ();
  294. cur->text.size = strlen ((char *) (cur->text.data = (unsigned char *)
  295.    cpystr ("From")));
  296. cur = cur->next = mail_newstringlist ();
  297. cur->text.size = strlen ((char *) (cur->text.data = (unsigned char *)
  298.    cpystr (">From")));
  299. cur = cur->next = mail_newstringlist ();
  300. cur->text.size = strlen ((char *) (cur->text.data = (unsigned char *)
  301.    cpystr ("Subject")));
  302. cur = cur->next = mail_newstringlist ();
  303. cur->text.size = strlen ((char *) (cur->text.data = (unsigned char *)
  304.    cpystr ("To")));
  305. cur = cur->next = mail_newstringlist ();
  306. cur->text.size = strlen ((char *) (cur->text.data = (unsigned char *)
  307.    cpystr ("cc")));
  308. cur = cur->next = mail_newstringlist ();
  309. cur->text.size = strlen ((char *) (cur->text.data = (unsigned char *)
  310.    cpystr ("Newsgroups")));
  311. printf ("%s",mail_fetchheader_full (stream,last,lines,NIL,NIL));
  312. puts (mail_fetchtext (stream,last));
  313. mail_free_stringlist (&lines);
  314.       }
  315.       else puts ("?Bad message number");
  316.       break;
  317.     case 'U': /* Undelete command */
  318.       if (arg) last = atoi (arg);
  319.       else {
  320. if (!last) {
  321.   puts ("?Missing message number");
  322.   break;
  323. }
  324. arg = cmd;
  325. sprintf (arg,"%lu",last);
  326.       }
  327.       if (last > 0 && last <= stream->nmsgs)
  328. mail_clearflag (stream,arg,"\DELETED");
  329.       else puts ("?Bad message number");
  330.       break;
  331.     case 'X': /* Xit command */
  332.       mail_expunge (stream);
  333.       mail_close (stream);
  334.       stream = NIL;
  335.       break;
  336.     case '+':
  337.       mail_debug (stream); debug = T;
  338.       break;
  339.     case '-':
  340.       mail_nodebug (stream); debug = NIL;
  341.       break;
  342.     case '?': /* ? command */
  343.       puts ("Body, Check, Delete, Expunge, Find, GC, Headers, Literal,");
  344.       puts (" MailboxStatus, New Mailbox, Overview, Quit, Send, Type,");
  345.       puts ("Undelete, Xit, +, -, or <RETURN> for next message");
  346.       break;
  347.     default: /* bogus command */
  348.       printf ("?Unrecognized command: %sn",cmd);
  349.       break;
  350.     }
  351.   }
  352. }
  353. /* MM display header
  354.  * Accepts: IMAP2 stream
  355.  *     message number
  356.  */
  357. void overview_header (MAILSTREAM *stream,unsigned long uid,OVERVIEW *ov)
  358. {
  359.   unsigned long i;
  360.   char *t,tmp[MAILTMPLEN];
  361.   ADDRESS *adr;
  362.   unsigned long msgno = mail_msgno (stream,uid);
  363.   MESSAGECACHE *elt = mail_elt (stream,msgno);
  364.   MESSAGECACHE selt;
  365.   tmp[0] = elt->recent ? (elt->seen ? 'R': 'N') : ' ';
  366.   tmp[1] = (elt->recent | elt->seen) ? ' ' : 'U';
  367.   tmp[2] = elt->flagged ? 'F' : ' ';
  368.   tmp[3] = elt->answered ? 'A' : ' ';
  369.   tmp[4] = elt->deleted ? 'D' : ' ';
  370.   mail_parse_date (&selt,ov->date);
  371.   sprintf (tmp+5,"%4lu) ",elt->msgno);
  372.   mail_date (tmp+11,&selt);
  373.   tmp[17] = ' ';
  374.   tmp[18] = '';
  375.   memset (tmp+18,' ',(size_t) 20);
  376.   tmp[38] = ''; /* tie off with null */
  377. /* get first from address from envelope */
  378.   for (adr = ov->from; adr && !adr->host; adr = adr->next);
  379.   if (adr) { /* if a personal name exists use it */
  380.     if (!(t = adr->personal))
  381.       sprintf (t = tmp+400,"%s@%s",adr->mailbox,adr->host);
  382.     memcpy (tmp+18,t,(size_t) min (20,(long) strlen (t)));
  383.   }
  384.   strcat (tmp," ");
  385.   if (i = elt->user_flags) {
  386.     strcat (tmp,"{");
  387.     while (i) {
  388.       strcat (tmp,stream->user_flags[find_rightmost_bit (&i)]);
  389.       if (i) strcat (tmp," ");
  390.     }
  391.     strcat (tmp,"} ");
  392.   }
  393.   sprintf (tmp + strlen (tmp),"%.25s (%lu chars)",
  394.    ov->subject ? ov->subject : " ",ov->optional.octets);
  395.   puts (tmp);
  396. }
  397. /* MM display header
  398.  * Accepts: IMAP2 stream
  399.  *     message number
  400.  */
  401. void header (MAILSTREAM *stream,long msgno)
  402. {
  403.   unsigned long i;
  404.   char tmp[MAILTMPLEN];
  405.   char *t;
  406.   MESSAGECACHE *cache = mail_elt (stream,msgno);
  407.   mail_fetchstructure (stream,msgno,NIL);
  408.   tmp[0] = cache->recent ? (cache->seen ? 'R': 'N') : ' ';
  409.   tmp[1] = (cache->recent | cache->seen) ? ' ' : 'U';
  410.   tmp[2] = cache->flagged ? 'F' : ' ';
  411.   tmp[3] = cache->answered ? 'A' : ' ';
  412.   tmp[4] = cache->deleted ? 'D' : ' ';
  413.   sprintf (tmp+5,"%4lu) ",cache->msgno);
  414.   mail_date (tmp+11,cache);
  415.   tmp[17] = ' ';
  416.   tmp[18] = '';
  417.   mail_fetchfrom (tmp+18,stream,msgno,(long) 20);
  418.   strcat (tmp," ");
  419.   if (i = cache->user_flags) {
  420.     strcat (tmp,"{");
  421.     while (i) {
  422.       strcat (tmp,stream->user_flags[find_rightmost_bit (&i)]);
  423.       if (i) strcat (tmp," ");
  424.     }
  425.     strcat (tmp,"} ");
  426.   }
  427.   mail_fetchsubject (t = tmp + strlen (tmp),stream,msgno,(long) 25);
  428.   sprintf (t += strlen (t)," (%lu chars)",cache->rfc822_size);
  429.   puts (tmp);
  430. }
  431. /* MM display body
  432.  * Accepts: BODY structure pointer
  433.  *     prefix string
  434.  *     index
  435.  */
  436. void display_body (BODY *body,char *pfx,long i)
  437. {
  438.   char tmp[MAILTMPLEN];
  439.   char *s = tmp;
  440.   PARAMETER *par;
  441.   PART *part; /* multipart doesn't have a row to itself */
  442.   if (body->type == TYPEMULTIPART) {
  443. /* if not first time, extend prefix */
  444.     if (pfx) sprintf (tmp,"%s%ld.",pfx,++i);
  445.     else tmp[0] = '';
  446.     for (i = 0,part = body->nested.part; part; part = part->next)
  447.       display_body (&part->body,tmp,i++);
  448.   }
  449.   else { /* non-multipart, output oneline descriptor */
  450.     if (!pfx) pfx = ""; /* dummy prefix if top level */
  451.     sprintf (s," %s%ld %s",pfx,++i,body_types[body->type]);
  452.     if (body->subtype) sprintf (s += strlen (s),"/%s",body->subtype);
  453.     if (body->description) sprintf (s += strlen (s)," (%s)",body->description);
  454.     if (par = body->parameter) do
  455.       sprintf (s += strlen (s),";%s=%s",par->attribute,par->value);
  456.     while (par = par->next);
  457.     if (body->id) sprintf (s += strlen (s),", id = %s",body->id);
  458.     switch (body->type) { /* bytes or lines depending upon body type */
  459.     case TYPEMESSAGE: /* encapsulated message */
  460.     case TYPETEXT: /* plain text */
  461.       sprintf (s += strlen (s)," (%lu lines)",body->size.lines);
  462.       break;
  463.     default:
  464.       sprintf (s += strlen (s)," (%lu bytes)",body->size.bytes);
  465.       break;
  466.     }
  467.     puts (tmp); /* output this line */
  468. /* encapsulated message? */
  469.     if ((body->type == TYPEMESSAGE) && !strcmp (body->subtype,"RFC822") &&
  470. (body = body->nested.msg->body)) {
  471.       if (body->type == TYPEMULTIPART) display_body (body,pfx,i-1);
  472.       else { /* build encapsulation prefix */
  473. sprintf (tmp,"%s%ld.",pfx,i);
  474. display_body (body,tmp,(long) 0);
  475.       }
  476.     }
  477.   }
  478. }
  479. /* MM status report
  480.  * Accepts: MAIL stream
  481.  */
  482. void status (MAILSTREAM *stream)
  483. {
  484.   long i;
  485.   char date[MAILTMPLEN];
  486.   rfc822_date (date);
  487.   puts (date);
  488.   if (stream) {
  489.     if (stream->mailbox)
  490.       printf (" %s mailbox: %s, %lu messages, %lu recentn",
  491.       stream->dtb->name,stream->mailbox,stream->nmsgs,stream->recent);
  492.     else puts ("%No mailbox is open on this stream");
  493.     if (stream->user_flags[0]) {
  494.       printf ("Keywords: %s",stream->user_flags[0]);
  495.       for (i = 1; i < NUSERFLAGS && stream->user_flags[i]; ++i)
  496. printf (", %s",stream->user_flags[i]);
  497.       puts ("");
  498.     }
  499.   }
  500. }
  501. /* Prompt user for input
  502.  * Accepts: pointer to prompt message
  503.  *          pointer to input buffer
  504.  */
  505. void prompt (char *msg,char *txt)
  506. {
  507.   printf ("%s",msg);
  508.   gets (txt);
  509. }
  510. /* Interfaces to C-client */
  511. void mm_searched (MAILSTREAM *stream,unsigned long number)
  512. {
  513. }
  514. void mm_exists (MAILSTREAM *stream,unsigned long number)
  515. {
  516. }
  517. void mm_expunged (MAILSTREAM *stream,unsigned long number)
  518. {
  519. }
  520. void mm_flags (MAILSTREAM *stream,unsigned long number)
  521. {
  522. }
  523. void mm_notify (MAILSTREAM *stream,char *string,long errflg)
  524. {
  525.   mm_log (string,errflg);
  526. }
  527. void mm_list (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes)
  528. {
  529.   putchar (' ');
  530.   if (delimiter) putchar (delimiter);
  531.   else fputs ("NIL",stdout);
  532.   putchar (' ');
  533.   fputs (mailbox,stdout);
  534.   if (attributes & LATT_NOINFERIORS) fputs (", no inferiors",stdout);
  535.   if (attributes & LATT_NOSELECT) fputs (", no select",stdout);
  536.   if (attributes & LATT_MARKED) fputs (", marked",stdout);
  537.   if (attributes & LATT_UNMARKED) fputs (", unmarked",stdout);
  538.   putchar ('n');
  539. }
  540. void mm_lsub (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes)
  541. {
  542.   putchar (' ');
  543.   if (delimiter) putchar (delimiter);
  544.   else fputs ("NIL",stdout);
  545.   putchar (' ');
  546.   fputs (mailbox,stdout);
  547.   if (attributes & LATT_NOINFERIORS) fputs (", no inferiors",stdout);
  548.   if (attributes & LATT_NOSELECT) fputs (", no select",stdout);
  549.   if (attributes & LATT_MARKED) fputs (", marked",stdout);
  550.   if (attributes & LATT_UNMARKED) fputs (", unmarked",stdout);
  551.   putchar ('n');
  552. }
  553. void mm_status (MAILSTREAM *stream,char *mailbox,MAILSTATUS *status)
  554. {
  555.   printf (" Mailbox %s",mailbox);
  556.   if (status->flags & SA_MESSAGES) printf (", %lu messages",status->messages);
  557.   if (status->flags & SA_RECENT) printf (", %lu recent",status->recent);
  558.   if (status->flags & SA_UNSEEN) printf (", %lu unseen",status->unseen);
  559.   if (status->flags & SA_UIDVALIDITY) printf (", %lu UID validity",
  560.       status->uidvalidity);
  561.   if (status->flags & SA_UIDNEXT) printf (", %lu next UID",status->uidnext);
  562.   printf ("n");
  563. }
  564. void mm_log (char *string,long errflg)
  565. {
  566.   switch ((short) errflg) {
  567.   case NIL:
  568.     printf ("[%s]n",string);
  569.     break;
  570.   case PARSE:
  571.   case WARN:
  572.     printf ("%%%sn",string);
  573.     break;
  574.   case ERROR:
  575.     printf ("?%sn",string);
  576.     break;
  577.   }
  578. }
  579. void mm_dlog (char *string)
  580. {
  581.   puts (string);
  582. }
  583. void mm_login (NETMBX *mb,char *user,char *pwd,long trial)
  584. {
  585.   char tmp[MAILTMPLEN];
  586.   if (curhst) fs_give ((void **) &curhst);
  587.   curhst = (char *) fs_get (1+strlen (mb->host));
  588.   strcpy (curhst,mb->host);
  589.   if (*mb->user) {
  590.     strcpy (user,mb->user);
  591.     sprintf (tmp,"{%s/%s/user="%s"} password: ",mb->host,mb->service,mb->user);
  592.   }
  593.   else {
  594.     sprintf (tmp,"{%s/%s} username: ",mb->host,mb->service);
  595.     prompt (tmp,user);
  596.     strcpy (tmp,"Password: ");
  597.   }
  598.   if (curusr) fs_give ((void **) &curusr);
  599.   curusr = cpystr (user);
  600. #if UNIXLIKE
  601.   strcpy (pwd,getpass (tmp));
  602. #else
  603.   prompt (tmp,pwd);
  604. #endif
  605. }
  606. void mm_critical (MAILSTREAM *stream)
  607. {
  608. }
  609. void mm_nocritical (MAILSTREAM *stream)
  610. {
  611. }
  612. long mm_diskerror (MAILSTREAM *stream,long errcode,long serious)
  613. {
  614. #if UNIXLIKE
  615.   kill (getpid (),SIGSTOP);
  616. #else
  617.   abort ();
  618. #endif
  619.   return NIL;
  620. }
  621. void mm_fatal (char *string)
  622. {
  623.   printf ("?%sn",string);
  624. }
  625. /* SMTP tester */
  626. void smtptest (long debug)
  627. {
  628.   SENDSTREAM *stream = NIL;
  629.   char line[MAILTMPLEN];
  630.   char *text = (char *) fs_get (8*MAILTMPLEN);
  631.   ENVELOPE *msg = mail_newenvelope ();
  632.   BODY *body = mail_newbody ();
  633.   msg->from = mail_newaddr ();
  634.   msg->from->personal = cpystr (personalname);
  635.   msg->from->mailbox = cpystr (curusr);
  636.   msg->from->host = cpystr (curhst);
  637.   msg->return_path = mail_newaddr ();
  638.   msg->return_path->mailbox = cpystr (curusr);
  639.   msg->return_path->host = cpystr (curhst);
  640.   prompt ("To: ",line);
  641.   rfc822_parse_adrlist (&msg->to,line,curhst);
  642.   if (msg->to) {
  643.     prompt ("cc: ",line);
  644.     rfc822_parse_adrlist (&msg->cc,line,curhst);
  645.   }
  646.   else {
  647.     prompt ("Newsgroups: ",line);
  648.     if (*line) msg->newsgroups = cpystr (line);
  649.     else {
  650.       mail_free_body (&body);
  651.       mail_free_envelope (&msg);
  652.       fs_give ((void **) &text);
  653.     }
  654.   }
  655.   prompt ("Subject: ",line);
  656.   msg->subject = cpystr (line);
  657.   puts (" Msg (end with a line with only a '.'):");
  658.   body->type = TYPETEXT;
  659.   *text = '';
  660.   while (gets (line)) {
  661.     if (line[0] == '.') {
  662.       if (line[1] == '') break;
  663.       else strcat (text,".");
  664.     }
  665.     strcat (text,line);
  666.     strcat (text,"1512");
  667.   }
  668.   body->contents.text.data = (unsigned char *) text;
  669.   body->contents.text.size = strlen (text);
  670.   rfc822_date (line);
  671.   msg->date = (char *) fs_get (1+strlen (line));
  672.   strcpy (msg->date,line);
  673.   if (msg->to) {
  674.     puts ("Sending...");
  675.     if (stream = smtp_open (hostlist,debug)) {
  676.       if (smtp_mail (stream,"MAIL",msg,body)) puts ("[Ok]");
  677.       else printf ("[Failed - %s]n",stream->reply);
  678.     }
  679.   }
  680.   else {
  681.     puts ("Posting...");
  682.     if (stream = nntp_open (newslist,debug)) {
  683.       if (nntp_mail (stream,msg,body)) puts ("[Ok]");
  684.       else printf ("[Failed - %s]n",stream->reply);
  685.     }
  686.   }
  687.   if (stream) smtp_close (stream);
  688.   else puts ("[Can't open connection to any server]");
  689.   mail_free_envelope (&msg);
  690.   mail_free_body (&body);
  691. }