imapext-2007

view src/mtest/mtest.c @ 0:ada5e610ab86

imap-2007e
author yuuji@gentei.org
date Mon, 14 Sep 2009 15:17:45 +0900
parents
children cd53ed0e4bb2
line source
1 /* ========================================================================
2 * Copyright 1988-2007 University of Washington
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 *
11 * ========================================================================
12 */
14 /*
15 * Program: Mail library test program
16 *
17 * Author: Mark Crispin
18 * Networks and Distributed Computing
19 * Computing & Communications
20 * University of Washington
21 * Administration Building, AG-44
22 * Seattle, WA 98195
23 * Internet: MRC@CAC.Washington.EDU
24 *
25 * Date: 8 July 1988
26 * Last Edited: 5 November 2007
27 *
28 * This original version of this file is
29 * Copyright 1988 Stanford University
30 * and was developed in the Symbolic Systems Resources Group of the Knowledge
31 * Systems Laboratory at Stanford University in 1987-88, and was funded by the
32 * Biomedical Research Technology Program of the NationalInstitutes of Health
33 * under grant number RR-00785.
34 */
36 #include <stdio.h>
37 #include <ctype.h>
38 #include <signal.h>
39 #include "c-client.h"
40 #include "imap4r1.h"
42 /* Excellent reasons to hate ifdefs, and why my real code never uses them */
44 #ifndef unix
45 # define unix 0
46 #endif
48 #if unix
49 # define UNIXLIKE 1
50 # define MACOS 0
51 # include <pwd.h>
52 #else
53 # define UNIXLIKE 0
54 # ifdef noErr
55 # define MACOS 1
56 # include <Memory.h>
57 # else
58 # define MACOS 0
59 # endif
60 #endif
62 char *curhst = NIL; /* currently connected host */
63 char *curusr = NIL; /* current login user */
64 char personalname[MAILTMPLEN]; /* user's personal name */
66 static char *hostlist[] = { /* SMTP server host list */
67 "mailhost",
68 "localhost",
69 NIL
70 };
72 static char *newslist[] = { /* Netnews server host list */
73 "news",
74 NIL
75 };
77 int main (void);
78 void mm (MAILSTREAM *stream,long debug);
79 void overview_header (MAILSTREAM *stream,unsigned long uid,OVERVIEW *ov,
80 unsigned long msgno);
81 void header (MAILSTREAM *stream,long msgno);
82 void display_body (BODY *body,char *pfx,long i);
83 void status (MAILSTREAM *stream);
84 void prompt (char *msg,char *txt);
85 void smtptest (long debug);
87 /* Main program - initialization */
89 int main ()
90 {
91 MAILSTREAM *stream = NIL;
92 void *sdb = NIL;
93 char *s,tmp[MAILTMPLEN];
94 long debug;
95 #include "linkage.c"
96 #if MACOS
97 {
98 size_t *base = (size_t *) 0x000908;
99 /* increase stack size on a Mac */
100 SetApplLimit ((Ptr) (*base - (size_t) 65535L));
101 }
102 #endif
103 curusr = cpystr (((s = myusername ()) && *s) ? s : "somebody");
104 #if UNIXLIKE
105 {
106 char *suffix;
107 struct passwd *pwd = getpwnam (curusr);
108 if (pwd) {
109 strcpy (tmp,pwd->pw_gecos);
110 /* dyke out the office and phone poop */
111 if (suffix = strchr (tmp,',')) suffix[0] = '\0';
112 strcpy (personalname,tmp);/* make a permanent copy of it */
113 }
114 else personalname[0] = '\0';
115 }
116 #else
117 personalname[0] = '\0';
118 #endif
119 curhst = cpystr (mylocalhost ());
120 puts ("MTest -- C client test program");
121 if (!*personalname) prompt ("Personal name: ",personalname);
122 /* user wants protocol telemetry? */
123 prompt ("Debug protocol (y/n)?",tmp);
124 ucase (tmp);
125 debug = (tmp[0] == 'Y') ? T : NIL;
126 do {
127 prompt ("Mailbox ('?' for help): ",tmp);
128 if (!strcmp (tmp,"?")) {
129 puts ("Enter INBOX, mailbox name, or IMAP mailbox as {host}mailbox");
130 puts ("Known local mailboxes:");
131 mail_list (NIL,NIL,"%");
132 if (s = sm_read (&sdb)) {
133 puts ("Local subscribed mailboxes:");
134 do (mm_lsub (NIL,NIL,s,NIL));
135 while (s = sm_read (&sdb));
136 }
137 puts ("or just hit return to quit");
138 }
139 else if (tmp[0]) stream = mail_open (stream,tmp,debug ? OP_DEBUG : NIL);
140 } while (!stream && tmp[0]);
141 mm (stream,debug); /* run user interface if opened */
142 #if MACOS
143 /* clean up resolver */
144 if (resolveropen) CloseResolver ();
145 #endif
146 return NIL;
147 }
149 /* MM command loop
150 * Accepts: MAIL stream
151 */
153 void mm (MAILSTREAM *stream,long debug)
154 {
155 void *sdb = NIL;
156 char cmd[MAILTMPLEN];
157 char *s,*arg;
158 unsigned long i;
159 unsigned long last = 0;
160 BODY *body;
161 status (stream); /* first report message status */
162 while (stream) {
163 prompt ("MTest>",cmd); /* prompt user, get command */
164 /* get argument */
165 if (arg = strchr (cmd,' ')) *arg++ = '\0';
166 switch (*ucase (cmd)) { /* dispatch based on command */
167 case 'B': /* Body command */
168 if (arg) last = atoi (arg);
169 else if (!last) {
170 puts ("?Missing message number");
171 break;
172 }
173 if (last && (last <= stream->nmsgs)) {
174 mail_fetchstructure (stream,last,&body);
175 if (body) display_body (body,NIL,(long) 0);
176 else puts ("%No body information available");
177 }
178 else puts ("?Bad message number");
179 break;
180 case 'C': /* Check command */
181 mail_check (stream);
182 status (stream);
183 break;
184 case 'D': /* Delete command */
185 if (arg) last = atoi (arg);
186 else {
187 if (last == 0) {
188 puts ("?Missing message number");
189 break;
190 }
191 arg = cmd;
192 sprintf (arg,"%lu",last);
193 }
194 if (last && (last <= stream->nmsgs))
195 mail_setflag (stream,arg,"\\DELETED");
196 else puts ("?Bad message number");
197 break;
198 case 'E': /* Expunge command */
199 mail_expunge (stream);
200 last = 0;
201 break;
202 case 'F': /* Find command */
203 if (!arg) {
204 arg = "%";
205 if (s = sm_read (&sdb)) {
206 puts ("Local network subscribed mailboxes:");
207 do if (*s == '{') (mm_lsub (NIL,NIL,s,NIL));
208 while (s = sm_read (&sdb));
209 }
210 }
211 puts ("Subscribed mailboxes:");
212 mail_lsub (((arg[0] == '{') && (*stream->mailbox == '{')) ? stream : NIL,
213 NIL,arg);
214 puts ("Known mailboxes:");
215 mail_list (((arg[0] == '{') && (*stream->mailbox == '{')) ? stream : NIL,
216 NIL,arg);
217 break;
218 case 'G':
219 mail_gc (stream,GC_ENV|GC_TEXTS|GC_ELT);
220 break;
221 case 'H': /* Headers command */
222 if (arg) {
223 if (!(last = atoi (arg))) {
224 mail_search (stream,arg);
225 for (i = 1; i <= stream->nmsgs; ++i)
226 if (mail_elt (stream,i)->searched) header (stream,i);
227 break;
228 }
229 }
230 else if (last == 0) {
231 puts ("?Missing message number");
232 break;
233 }
234 if (last && (last <= stream->nmsgs)) header (stream,last);
235 else puts ("?Bad message number");
236 break;
237 case 'L': /* Literal command */
238 if (arg) last = atoi (arg);
239 else if (!last) {
240 puts ("?Missing message number");
241 break;
242 }
243 if (last && (last <= stream->nmsgs))
244 puts (mail_fetch_message (stream,last,NIL,NIL));
245 else puts ("?Bad message number");
246 break;
247 case 'M':
248 mail_status (NIL,arg ? arg : stream->mailbox,
249 SA_MESSAGES|SA_RECENT|SA_UNSEEN|SA_UIDNEXT|SA_UIDVALIDITY);
250 break;
251 case 'N': /* New mailbox command */
252 if (!arg) {
253 puts ("?Missing mailbox");
254 break;
255 }
256 /* get the new mailbox */
257 while (!(stream = mail_open (stream,arg,debug))) {
258 prompt ("Mailbox: ",arg);
259 if (!arg[0]) break;
260 }
261 last = 0;
262 status (stream);
263 break;
264 case 'O': /* Overview command */
265 if (!arg) {
266 puts ("?Missing UID");
267 break;
268 }
269 mail_fetch_overview (stream,arg,overview_header);
270 break;
271 case 'P': /* Ping command */
272 mail_ping (stream);
273 status (stream);
274 break;
275 case 'Q': /* Quit command */
276 mail_close (stream);
277 stream = NIL;
278 break;
279 case 'S': /* Send command */
280 smtptest (debug);
281 break;
282 case '\0': /* null command (type next message) */
283 if (!last || (last++ >= stream->nmsgs)) {
284 puts ("%No next message");
285 break;
286 }
287 case 'T': /* Type command */
288 if (arg) last = atoi (arg);
289 else if (!last) {
290 puts ("?Missing message number");
291 break;
292 }
293 if (last && (last <= stream->nmsgs)) {
294 STRINGLIST *lines = mail_newstringlist ();
295 STRINGLIST *cur = lines;
296 cur->text.size = strlen ((char *) (cur->text.data = (unsigned char *)
297 cpystr ("Date")));
298 cur = cur->next = mail_newstringlist ();
299 cur->text.size = strlen ((char *) (cur->text.data = (unsigned char *)
300 cpystr ("From")));
301 cur = cur->next = mail_newstringlist ();
302 cur->text.size = strlen ((char *) (cur->text.data = (unsigned char *)
303 cpystr (">From")));
304 cur = cur->next = mail_newstringlist ();
305 cur->text.size = strlen ((char *) (cur->text.data = (unsigned char *)
306 cpystr ("Subject")));
307 cur = cur->next = mail_newstringlist ();
308 cur->text.size = strlen ((char *) (cur->text.data = (unsigned char *)
309 cpystr ("To")));
310 cur = cur->next = mail_newstringlist ();
311 cur->text.size = strlen ((char *) (cur->text.data = (unsigned char *)
312 cpystr ("cc")));
313 cur = cur->next = mail_newstringlist ();
314 cur->text.size = strlen ((char *) (cur->text.data = (unsigned char *)
315 cpystr ("Newsgroups")));
316 printf ("%s",mail_fetchheader_full (stream,last,lines,NIL,NIL));
317 puts (mail_fetchtext (stream,last));
318 mail_free_stringlist (&lines);
319 }
320 else puts ("?Bad message number");
321 break;
322 case 'U': /* Undelete command */
323 if (arg) last = atoi (arg);
324 else {
325 if (!last) {
326 puts ("?Missing message number");
327 break;
328 }
329 arg = cmd;
330 sprintf (arg,"%lu",last);
331 }
332 if (last > 0 && last <= stream->nmsgs)
333 mail_clearflag (stream,arg,"\\DELETED");
334 else puts ("?Bad message number");
335 break;
336 case 'X': /* Xit command */
337 mail_expunge (stream);
338 mail_close (stream);
339 stream = NIL;
340 break;
341 case '+':
342 mail_debug (stream); debug = T;
343 break;
344 case '-':
345 mail_nodebug (stream); debug = NIL;
346 break;
347 case '?': /* ? command */
348 puts ("Body, Check, Delete, Expunge, Find, GC, Headers, Literal,");
349 puts (" MailboxStatus, New Mailbox, Overview, Ping, Quit, Send, Type,");
350 puts ("Undelete, Xit, +, -, or <RETURN> for next message");
351 break;
352 default: /* bogus command */
353 printf ("?Unrecognized command: %s\n",cmd);
354 break;
355 }
356 }
357 }
359 /* MM display header
360 * Accepts: IMAP2 stream
361 * message number
362 */
364 void overview_header (MAILSTREAM *stream,unsigned long uid,OVERVIEW *ov,
365 unsigned long msgno)
366 {
367 if (ov) {
368 unsigned long i;
369 char *t,tmp[MAILTMPLEN];
370 ADDRESS *adr;
371 MESSAGECACHE *elt = mail_elt (stream,msgno);
372 MESSAGECACHE selt;
373 tmp[0] = elt->recent ? (elt->seen ? 'R': 'N') : ' ';
374 tmp[1] = (elt->recent | elt->seen) ? ' ' : 'U';
375 tmp[2] = elt->flagged ? 'F' : ' ';
376 tmp[3] = elt->answered ? 'A' : ' ';
377 tmp[4] = elt->deleted ? 'D' : ' ';
378 mail_parse_date (&selt,ov->date);
379 sprintf (tmp+5,"%4lu) ",elt->msgno);
380 mail_date (tmp+11,&selt);
381 tmp[17] = ' ';
382 tmp[18] = '\0';
383 memset (tmp+18,' ',(size_t) 20);
384 tmp[38] = '\0'; /* tie off with null */
385 /* get first from address from envelope */
386 for (adr = ov->from; adr && !adr->host; adr = adr->next);
387 if (adr) { /* if a personal name exists use it */
388 if (!(t = adr->personal))
389 sprintf (t = tmp+400,"%s@%s",adr->mailbox,adr->host);
390 memcpy (tmp+18,t,(size_t) min (20,(long) strlen (t)));
391 }
392 strcat (tmp," ");
393 if (i = elt->user_flags) {
394 strcat (tmp,"{");
395 while (i) {
396 strcat (tmp,stream->user_flags[find_rightmost_bit (&i)]);
397 if (i) strcat (tmp," ");
398 }
399 strcat (tmp,"} ");
400 }
401 sprintf (tmp + strlen (tmp),"%.25s (%lu chars)",
402 ov->subject ? ov->subject : " ",ov->optional.octets);
403 puts (tmp);
404 }
405 else printf ("%%No overview for UID %lu\n",uid);
406 }
408 /* MM display header
409 * Accepts: IMAP2 stream
410 * message number
411 */
413 void header (MAILSTREAM *stream,long msgno)
414 {
415 unsigned long i;
416 char tmp[MAILTMPLEN];
417 char *t;
418 MESSAGECACHE *cache = mail_elt (stream,msgno);
419 mail_fetchstructure (stream,msgno,NIL);
420 tmp[0] = cache->recent ? (cache->seen ? 'R': 'N') : ' ';
421 tmp[1] = (cache->recent | cache->seen) ? ' ' : 'U';
422 tmp[2] = cache->flagged ? 'F' : ' ';
423 tmp[3] = cache->answered ? 'A' : ' ';
424 tmp[4] = cache->deleted ? 'D' : ' ';
425 sprintf (tmp+5,"%4lu) ",cache->msgno);
426 mail_date (tmp+11,cache);
427 tmp[17] = ' ';
428 tmp[18] = '\0';
429 mail_fetchfrom (tmp+18,stream,msgno,(long) 20);
430 strcat (tmp," ");
431 if (i = cache->user_flags) {
432 strcat (tmp,"{");
433 while (i) {
434 strcat (tmp,stream->user_flags[find_rightmost_bit (&i)]);
435 if (i) strcat (tmp," ");
436 }
437 strcat (tmp,"} ");
438 }
439 mail_fetchsubject (t = tmp + strlen (tmp),stream,msgno,(long) 25);
440 sprintf (t += strlen (t)," (%lu chars)",cache->rfc822_size);
441 puts (tmp);
442 }
444 /* MM display body
445 * Accepts: BODY structure pointer
446 * prefix string
447 * index
448 */
450 void display_body (BODY *body,char *pfx,long i)
451 {
452 char tmp[MAILTMPLEN];
453 char *s = tmp;
454 PARAMETER *par;
455 PART *part; /* multipart doesn't have a row to itself */
456 if (body->type == TYPEMULTIPART) {
457 /* if not first time, extend prefix */
458 if (pfx) sprintf (tmp,"%s%ld.",pfx,++i);
459 else tmp[0] = '\0';
460 for (i = 0,part = body->nested.part; part; part = part->next)
461 display_body (&part->body,tmp,i++);
462 }
463 else { /* non-multipart, output oneline descriptor */
464 if (!pfx) pfx = ""; /* dummy prefix if top level */
465 sprintf (s," %s%ld %s",pfx,++i,body_types[body->type]);
466 if (body->subtype) sprintf (s += strlen (s),"/%s",body->subtype);
467 if (body->description) sprintf (s += strlen (s)," (%s)",body->description);
468 if (par = body->parameter) do
469 sprintf (s += strlen (s),";%s=%s",par->attribute,par->value);
470 while (par = par->next);
471 if (body->id) sprintf (s += strlen (s),", id = %s",body->id);
472 switch (body->type) { /* bytes or lines depending upon body type */
473 case TYPEMESSAGE: /* encapsulated message */
474 case TYPETEXT: /* plain text */
475 sprintf (s += strlen (s)," (%lu lines)",body->size.lines);
476 break;
477 default:
478 sprintf (s += strlen (s)," (%lu bytes)",body->size.bytes);
479 break;
480 }
481 puts (tmp); /* output this line */
482 /* encapsulated message? */
483 if ((body->type == TYPEMESSAGE) && !strcmp (body->subtype,"RFC822") &&
484 (body = body->nested.msg->body)) {
485 if (body->type == TYPEMULTIPART) display_body (body,pfx,i-1);
486 else { /* build encapsulation prefix */
487 sprintf (tmp,"%s%ld.",pfx,i);
488 display_body (body,tmp,(long) 0);
489 }
490 }
491 }
492 }
494 /* MM status report
495 * Accepts: MAIL stream
496 */
498 void status (MAILSTREAM *stream)
499 {
500 unsigned long i;
501 char *s,date[MAILTMPLEN];
502 THREADER *thr;
503 AUTHENTICATOR *auth;
504 rfc822_date (date);
505 puts (date);
506 if (stream) {
507 if (stream->mailbox)
508 printf (" %s mailbox: %s, %lu messages, %lu recent\n",
509 stream->dtb->name,stream->mailbox,stream->nmsgs,stream->recent);
510 else puts ("%No mailbox is open on this stream");
511 if (stream->user_flags[0]) {
512 printf ("Keywords: %s",stream->user_flags[0]);
513 for (i = 1; i < NUSERFLAGS && stream->user_flags[i]; ++i)
514 printf (", %s",stream->user_flags[i]);
515 puts ("");
516 }
517 if (!strcmp (stream->dtb->name,"imap")) {
518 if (LEVELIMAP4rev1 (stream)) s = "IMAP4rev1 (RFC 3501)";
519 else if (LEVEL1730 (stream)) s = "IMAP4 (RFC 1730)";
520 else if (LEVELIMAP2bis (stream)) s = "IMAP2bis";
521 else if (LEVEL1176 (stream)) s = "IMAP2 (RFC 1176)";
522 else s = "IMAP2 (RFC 1064)";
523 printf ("%s server %s\n",s,imap_host (stream));
524 if (LEVELIMAP4 (stream)) {
525 if (i = imap_cap (stream)->auth) {
526 s = "";
527 printf ("Mutually-supported SASL mechanisms:");
528 while (auth = mail_lookup_auth (find_rightmost_bit (&i) + 1)) {
529 printf (" %s",auth->name);
530 if (!strcmp (auth->name,"PLAIN"))
531 s = "\n [LOGIN will not be listed here if PLAIN is supported]";
532 }
533 puts (s);
534 }
535 printf ("Supported standard extensions:\n");
536 if (LEVELACL (stream)) puts (" Access Control lists (RFC 2086)");
537 if (LEVELQUOTA (stream)) puts (" Quotas (RFC 2087)");
538 if (LEVELLITERALPLUS (stream))
539 puts (" Non-synchronizing literals (RFC 2088)");
540 if (LEVELIDLE (stream)) puts (" IDLE unsolicited update (RFC 2177)");
541 if (LEVELMBX_REF (stream)) puts (" Mailbox referrals (RFC 2193)");
542 if (LEVELLOG_REF (stream)) puts (" Login referrals (RFC 2221)");
543 if (LEVELANONYMOUS (stream)) puts (" Anonymous access (RFC 2245)");
544 if (LEVELNAMESPACE (stream)) puts (" Multiple namespaces (RFC 2342)");
545 if (LEVELUIDPLUS (stream)) puts (" Extended UID behavior (RFC 2359)");
546 if (LEVELSTARTTLS (stream))
547 puts (" Transport Layer Security (RFC 2595)");
548 if (LEVELLOGINDISABLED (stream))
549 puts (" LOGIN command disabled (RFC 2595)");
550 if (LEVELID (stream))
551 puts (" Implementation identity negotiation (RFC 2971)");
552 if (LEVELCHILDREN (stream))
553 puts (" LIST children announcement (RFC 3348)");
554 if (LEVELMULTIAPPEND (stream))
555 puts (" Atomic multiple APPEND (RFC 3502)");
556 if (LEVELBINARY (stream))
557 puts (" Binary body content (RFC 3516)");
558 if (LEVELUNSELECT (stream)) puts (" Mailbox unselect (RFC 3691)");
559 if (LEVELURLAUTH (stream))
560 puts (" URL authenticated fetch (RFC 4467)");
561 if (LEVELCATENATE (stream)) puts (" Catenation (RFC 4469)");
562 if (LEVELCONDSTORE (stream)) puts (" Conditional STORE (RFC 4551)");
563 if (LEVELESEARCH (stream)) puts (" Extended SEARCH (RFC 4731)");
564 puts ("Supported draft extensions:");
565 if (LEVELSASLIR (stream)) puts (" SASL initial client response");
566 if (LEVELSORT (stream)) puts (" Server-based sorting");
567 if (LEVELTHREAD (stream)) {
568 printf (" Server-based threading:");
569 for (thr = imap_cap (stream)->threader; thr; thr = thr->next)
570 printf (" %s",thr->name);
571 putchar ('\n');
572 }
573 if (LEVELSCAN (stream)) puts (" Mailbox text scan");
574 if (i = imap_cap (stream)->extlevel) {
575 printf ("Supported BODYSTRUCTURE extensions:");
576 switch (i) {
577 case BODYEXTLOC: printf (" location");
578 case BODYEXTLANG: printf (" language");
579 case BODYEXTDSP: printf (" disposition");
580 case BODYEXTMD5: printf (" MD5\n");
581 }
582 }
583 }
584 else putchar ('\n');
585 }
586 }
587 }
590 /* Prompt user for input
591 * Accepts: pointer to prompt message
592 * pointer to input buffer
593 */
595 void prompt (char *msg,char *txt)
596 {
597 printf ("%s",msg);
598 gets (txt);
599 }
601 /* Interfaces to C-client */
604 void mm_searched (MAILSTREAM *stream,unsigned long number)
605 {
606 }
609 void mm_exists (MAILSTREAM *stream,unsigned long number)
610 {
611 }
614 void mm_expunged (MAILSTREAM *stream,unsigned long number)
615 {
616 }
619 void mm_flags (MAILSTREAM *stream,unsigned long number)
620 {
621 }
624 void mm_notify (MAILSTREAM *stream,char *string,long errflg)
625 {
626 mm_log (string,errflg);
627 }
630 void mm_list (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes)
631 {
632 putchar (' ');
633 if (delimiter) putchar (delimiter);
634 else fputs ("NIL",stdout);
635 putchar (' ');
636 fputs (mailbox,stdout);
637 if (attributes & LATT_NOINFERIORS) fputs (", no inferiors",stdout);
638 if (attributes & LATT_NOSELECT) fputs (", no select",stdout);
639 if (attributes & LATT_MARKED) fputs (", marked",stdout);
640 if (attributes & LATT_UNMARKED) fputs (", unmarked",stdout);
641 putchar ('\n');
642 }
645 void mm_lsub (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes)
646 {
647 putchar (' ');
648 if (delimiter) putchar (delimiter);
649 else fputs ("NIL",stdout);
650 putchar (' ');
651 fputs (mailbox,stdout);
652 if (attributes & LATT_NOINFERIORS) fputs (", no inferiors",stdout);
653 if (attributes & LATT_NOSELECT) fputs (", no select",stdout);
654 if (attributes & LATT_MARKED) fputs (", marked",stdout);
655 if (attributes & LATT_UNMARKED) fputs (", unmarked",stdout);
656 putchar ('\n');
657 }
660 void mm_status (MAILSTREAM *stream,char *mailbox,MAILSTATUS *status)
661 {
662 printf (" Mailbox %s",mailbox);
663 if (status->flags & SA_MESSAGES) printf (", %lu messages",status->messages);
664 if (status->flags & SA_RECENT) printf (", %lu recent",status->recent);
665 if (status->flags & SA_UNSEEN) printf (", %lu unseen",status->unseen);
666 if (status->flags & SA_UIDVALIDITY) printf (", %lu UID validity",
667 status->uidvalidity);
668 if (status->flags & SA_UIDNEXT) printf (", %lu next UID",status->uidnext);
669 printf ("\n");
670 }
673 void mm_log (char *string,long errflg)
674 {
675 switch ((short) errflg) {
676 case NIL:
677 printf ("[%s]\n",string);
678 break;
679 case PARSE:
680 case WARN:
681 printf ("%%%s\n",string);
682 break;
683 case ERROR:
684 printf ("?%s\n",string);
685 break;
686 }
687 }
690 void mm_dlog (char *string)
691 {
692 puts (string);
693 }
696 void mm_login (NETMBX *mb,char *user,char *pwd,long trial)
697 {
698 char *s,tmp[MAILTMPLEN];
699 if (curhst) fs_give ((void **) &curhst);
700 curhst = (char *) fs_get (1+strlen (mb->host));
701 strcpy (curhst,mb->host);
702 sprintf (s = tmp,"{%s/%s",mb->host,mb->service);
703 if (*mb->user) sprintf (tmp+strlen (tmp),"/user=%s",strcpy (user,mb->user));
704 if (*mb->authuser) sprintf (tmp+strlen (tmp),"/authuser=%s",mb->authuser);
705 if (*mb->user) strcat (s = tmp,"} password:");
706 else {
707 printf ("%s} username: ",tmp);
708 fgets (user,NETMAXUSER-1,stdin);
709 user[NETMAXUSER-1] = '\0';
710 if (s = strchr (user,'\n')) *s = '\0';
711 s = "password: ";
712 }
713 if (curusr) fs_give ((void **) &curusr);
714 curusr = cpystr (user);
715 strcpy (pwd,getpass (s));
716 }
719 void mm_critical (MAILSTREAM *stream)
720 {
721 }
724 void mm_nocritical (MAILSTREAM *stream)
725 {
726 }
729 long mm_diskerror (MAILSTREAM *stream,long errcode,long serious)
730 {
731 #if UNIXLIKE
732 kill (getpid (),SIGSTOP);
733 #else
734 abort ();
735 #endif
736 return NIL;
737 }
740 void mm_fatal (char *string)
741 {
742 printf ("?%s\n",string);
743 }
745 /* SMTP tester */
747 void smtptest (long debug)
748 {
749 SENDSTREAM *stream = NIL;
750 char line[MAILTMPLEN];
751 char *text = (char *) fs_get (8*MAILTMPLEN);
752 ENVELOPE *msg = mail_newenvelope ();
753 BODY *body = mail_newbody ();
754 msg->from = mail_newaddr ();
755 msg->from->personal = cpystr (personalname);
756 msg->from->mailbox = cpystr (curusr);
757 msg->from->host = cpystr (curhst);
758 msg->return_path = mail_newaddr ();
759 msg->return_path->mailbox = cpystr (curusr);
760 msg->return_path->host = cpystr (curhst);
761 prompt ("To: ",line);
762 rfc822_parse_adrlist (&msg->to,line,curhst);
763 if (msg->to) {
764 prompt ("cc: ",line);
765 rfc822_parse_adrlist (&msg->cc,line,curhst);
766 }
767 else {
768 prompt ("Newsgroups: ",line);
769 if (*line) msg->newsgroups = cpystr (line);
770 else {
771 mail_free_body (&body);
772 mail_free_envelope (&msg);
773 fs_give ((void **) &text);
774 return;
775 }
776 }
777 prompt ("Subject: ",line);
778 msg->subject = cpystr (line);
779 puts (" Msg (end with a line with only a '.'):");
780 body->type = TYPETEXT;
781 *text = '\0';
782 while (gets (line)) {
783 if (line[0] == '.') {
784 if (line[1] == '\0') break;
785 else strcat (text,".");
786 }
787 strcat (text,line);
788 strcat (text,"\015\012");
789 }
790 body->contents.text.data = (unsigned char *) text;
791 body->contents.text.size = strlen (text);
792 rfc822_date (line);
793 msg->date = (char *) fs_get (1+strlen (line));
794 strcpy (msg->date,line);
795 if (msg->to) {
796 puts ("Sending...");
797 if (stream = smtp_open (hostlist,debug)) {
798 if (smtp_mail (stream,"MAIL",msg,body)) puts ("[Ok]");
799 else printf ("[Failed - %s]\n",stream->reply);
800 }
801 }
802 else {
803 puts ("Posting...");
804 if (stream = nntp_open (newslist,debug)) {
805 if (nntp_mail (stream,msg,body)) puts ("[Ok]");
806 else printf ("[Failed - %s]\n",stream->reply);
807 }
808 }
809 if (stream) smtp_close (stream);
810 else puts ("[Can't open connection to any server]");
811 mail_free_envelope (&msg);
812 mail_free_body (&body);
813 }

UW-IMAP'd extensions by yuuji