imapext-2007
diff 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 diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/mtest/mtest.c Mon Sep 14 15:17:45 2009 +0900 1.3 @@ -0,0 +1,813 @@ 1.4 +/* ======================================================================== 1.5 + * Copyright 1988-2007 University of Washington 1.6 + * 1.7 + * Licensed under the Apache License, Version 2.0 (the "License"); 1.8 + * you may not use this file except in compliance with the License. 1.9 + * You may obtain a copy of the License at 1.10 + * 1.11 + * http://www.apache.org/licenses/LICENSE-2.0 1.12 + * 1.13 + * 1.14 + * ======================================================================== 1.15 + */ 1.16 + 1.17 +/* 1.18 + * Program: Mail library test program 1.19 + * 1.20 + * Author: Mark Crispin 1.21 + * Networks and Distributed Computing 1.22 + * Computing & Communications 1.23 + * University of Washington 1.24 + * Administration Building, AG-44 1.25 + * Seattle, WA 98195 1.26 + * Internet: MRC@CAC.Washington.EDU 1.27 + * 1.28 + * Date: 8 July 1988 1.29 + * Last Edited: 5 November 2007 1.30 + * 1.31 + * This original version of this file is 1.32 + * Copyright 1988 Stanford University 1.33 + * and was developed in the Symbolic Systems Resources Group of the Knowledge 1.34 + * Systems Laboratory at Stanford University in 1987-88, and was funded by the 1.35 + * Biomedical Research Technology Program of the NationalInstitutes of Health 1.36 + * under grant number RR-00785. 1.37 + */ 1.38 + 1.39 +#include <stdio.h> 1.40 +#include <ctype.h> 1.41 +#include <signal.h> 1.42 +#include "c-client.h" 1.43 +#include "imap4r1.h" 1.44 + 1.45 +/* Excellent reasons to hate ifdefs, and why my real code never uses them */ 1.46 + 1.47 +#ifndef unix 1.48 +# define unix 0 1.49 +#endif 1.50 + 1.51 +#if unix 1.52 +# define UNIXLIKE 1 1.53 +# define MACOS 0 1.54 +# include <pwd.h> 1.55 +#else 1.56 +# define UNIXLIKE 0 1.57 +# ifdef noErr 1.58 +# define MACOS 1 1.59 +# include <Memory.h> 1.60 +# else 1.61 +# define MACOS 0 1.62 +# endif 1.63 +#endif 1.64 + 1.65 +char *curhst = NIL; /* currently connected host */ 1.66 +char *curusr = NIL; /* current login user */ 1.67 +char personalname[MAILTMPLEN]; /* user's personal name */ 1.68 + 1.69 +static char *hostlist[] = { /* SMTP server host list */ 1.70 + "mailhost", 1.71 + "localhost", 1.72 + NIL 1.73 +}; 1.74 + 1.75 +static char *newslist[] = { /* Netnews server host list */ 1.76 + "news", 1.77 + NIL 1.78 +}; 1.79 + 1.80 +int main (void); 1.81 +void mm (MAILSTREAM *stream,long debug); 1.82 +void overview_header (MAILSTREAM *stream,unsigned long uid,OVERVIEW *ov, 1.83 + unsigned long msgno); 1.84 +void header (MAILSTREAM *stream,long msgno); 1.85 +void display_body (BODY *body,char *pfx,long i); 1.86 +void status (MAILSTREAM *stream); 1.87 +void prompt (char *msg,char *txt); 1.88 +void smtptest (long debug); 1.89 + 1.90 +/* Main program - initialization */ 1.91 + 1.92 +int main () 1.93 +{ 1.94 + MAILSTREAM *stream = NIL; 1.95 + void *sdb = NIL; 1.96 + char *s,tmp[MAILTMPLEN]; 1.97 + long debug; 1.98 +#include "linkage.c" 1.99 +#if MACOS 1.100 + { 1.101 + size_t *base = (size_t *) 0x000908; 1.102 + /* increase stack size on a Mac */ 1.103 + SetApplLimit ((Ptr) (*base - (size_t) 65535L)); 1.104 + } 1.105 +#endif 1.106 + curusr = cpystr (((s = myusername ()) && *s) ? s : "somebody"); 1.107 +#if UNIXLIKE 1.108 + { 1.109 + char *suffix; 1.110 + struct passwd *pwd = getpwnam (curusr); 1.111 + if (pwd) { 1.112 + strcpy (tmp,pwd->pw_gecos); 1.113 + /* dyke out the office and phone poop */ 1.114 + if (suffix = strchr (tmp,',')) suffix[0] = '\0'; 1.115 + strcpy (personalname,tmp);/* make a permanent copy of it */ 1.116 + } 1.117 + else personalname[0] = '\0'; 1.118 + } 1.119 +#else 1.120 + personalname[0] = '\0'; 1.121 +#endif 1.122 + curhst = cpystr (mylocalhost ()); 1.123 + puts ("MTest -- C client test program"); 1.124 + if (!*personalname) prompt ("Personal name: ",personalname); 1.125 + /* user wants protocol telemetry? */ 1.126 + prompt ("Debug protocol (y/n)?",tmp); 1.127 + ucase (tmp); 1.128 + debug = (tmp[0] == 'Y') ? T : NIL; 1.129 + do { 1.130 + prompt ("Mailbox ('?' for help): ",tmp); 1.131 + if (!strcmp (tmp,"?")) { 1.132 + puts ("Enter INBOX, mailbox name, or IMAP mailbox as {host}mailbox"); 1.133 + puts ("Known local mailboxes:"); 1.134 + mail_list (NIL,NIL,"%"); 1.135 + if (s = sm_read (&sdb)) { 1.136 + puts ("Local subscribed mailboxes:"); 1.137 + do (mm_lsub (NIL,NIL,s,NIL)); 1.138 + while (s = sm_read (&sdb)); 1.139 + } 1.140 + puts ("or just hit return to quit"); 1.141 + } 1.142 + else if (tmp[0]) stream = mail_open (stream,tmp,debug ? OP_DEBUG : NIL); 1.143 + } while (!stream && tmp[0]); 1.144 + mm (stream,debug); /* run user interface if opened */ 1.145 +#if MACOS 1.146 + /* clean up resolver */ 1.147 + if (resolveropen) CloseResolver (); 1.148 +#endif 1.149 + return NIL; 1.150 +} 1.151 + 1.152 +/* MM command loop 1.153 + * Accepts: MAIL stream 1.154 + */ 1.155 + 1.156 +void mm (MAILSTREAM *stream,long debug) 1.157 +{ 1.158 + void *sdb = NIL; 1.159 + char cmd[MAILTMPLEN]; 1.160 + char *s,*arg; 1.161 + unsigned long i; 1.162 + unsigned long last = 0; 1.163 + BODY *body; 1.164 + status (stream); /* first report message status */ 1.165 + while (stream) { 1.166 + prompt ("MTest>",cmd); /* prompt user, get command */ 1.167 + /* get argument */ 1.168 + if (arg = strchr (cmd,' ')) *arg++ = '\0'; 1.169 + switch (*ucase (cmd)) { /* dispatch based on command */ 1.170 + case 'B': /* Body command */ 1.171 + if (arg) last = atoi (arg); 1.172 + else if (!last) { 1.173 + puts ("?Missing message number"); 1.174 + break; 1.175 + } 1.176 + if (last && (last <= stream->nmsgs)) { 1.177 + mail_fetchstructure (stream,last,&body); 1.178 + if (body) display_body (body,NIL,(long) 0); 1.179 + else puts ("%No body information available"); 1.180 + } 1.181 + else puts ("?Bad message number"); 1.182 + break; 1.183 + case 'C': /* Check command */ 1.184 + mail_check (stream); 1.185 + status (stream); 1.186 + break; 1.187 + case 'D': /* Delete command */ 1.188 + if (arg) last = atoi (arg); 1.189 + else { 1.190 + if (last == 0) { 1.191 + puts ("?Missing message number"); 1.192 + break; 1.193 + } 1.194 + arg = cmd; 1.195 + sprintf (arg,"%lu",last); 1.196 + } 1.197 + if (last && (last <= stream->nmsgs)) 1.198 + mail_setflag (stream,arg,"\\DELETED"); 1.199 + else puts ("?Bad message number"); 1.200 + break; 1.201 + case 'E': /* Expunge command */ 1.202 + mail_expunge (stream); 1.203 + last = 0; 1.204 + break; 1.205 + case 'F': /* Find command */ 1.206 + if (!arg) { 1.207 + arg = "%"; 1.208 + if (s = sm_read (&sdb)) { 1.209 + puts ("Local network subscribed mailboxes:"); 1.210 + do if (*s == '{') (mm_lsub (NIL,NIL,s,NIL)); 1.211 + while (s = sm_read (&sdb)); 1.212 + } 1.213 + } 1.214 + puts ("Subscribed mailboxes:"); 1.215 + mail_lsub (((arg[0] == '{') && (*stream->mailbox == '{')) ? stream : NIL, 1.216 + NIL,arg); 1.217 + puts ("Known mailboxes:"); 1.218 + mail_list (((arg[0] == '{') && (*stream->mailbox == '{')) ? stream : NIL, 1.219 + NIL,arg); 1.220 + break; 1.221 + case 'G': 1.222 + mail_gc (stream,GC_ENV|GC_TEXTS|GC_ELT); 1.223 + break; 1.224 + case 'H': /* Headers command */ 1.225 + if (arg) { 1.226 + if (!(last = atoi (arg))) { 1.227 + mail_search (stream,arg); 1.228 + for (i = 1; i <= stream->nmsgs; ++i) 1.229 + if (mail_elt (stream,i)->searched) header (stream,i); 1.230 + break; 1.231 + } 1.232 + } 1.233 + else if (last == 0) { 1.234 + puts ("?Missing message number"); 1.235 + break; 1.236 + } 1.237 + if (last && (last <= stream->nmsgs)) header (stream,last); 1.238 + else puts ("?Bad message number"); 1.239 + break; 1.240 + case 'L': /* Literal command */ 1.241 + if (arg) last = atoi (arg); 1.242 + else if (!last) { 1.243 + puts ("?Missing message number"); 1.244 + break; 1.245 + } 1.246 + if (last && (last <= stream->nmsgs)) 1.247 + puts (mail_fetch_message (stream,last,NIL,NIL)); 1.248 + else puts ("?Bad message number"); 1.249 + break; 1.250 + case 'M': 1.251 + mail_status (NIL,arg ? arg : stream->mailbox, 1.252 + SA_MESSAGES|SA_RECENT|SA_UNSEEN|SA_UIDNEXT|SA_UIDVALIDITY); 1.253 + break; 1.254 + case 'N': /* New mailbox command */ 1.255 + if (!arg) { 1.256 + puts ("?Missing mailbox"); 1.257 + break; 1.258 + } 1.259 + /* get the new mailbox */ 1.260 + while (!(stream = mail_open (stream,arg,debug))) { 1.261 + prompt ("Mailbox: ",arg); 1.262 + if (!arg[0]) break; 1.263 + } 1.264 + last = 0; 1.265 + status (stream); 1.266 + break; 1.267 + case 'O': /* Overview command */ 1.268 + if (!arg) { 1.269 + puts ("?Missing UID"); 1.270 + break; 1.271 + } 1.272 + mail_fetch_overview (stream,arg,overview_header); 1.273 + break; 1.274 + case 'P': /* Ping command */ 1.275 + mail_ping (stream); 1.276 + status (stream); 1.277 + break; 1.278 + case 'Q': /* Quit command */ 1.279 + mail_close (stream); 1.280 + stream = NIL; 1.281 + break; 1.282 + case 'S': /* Send command */ 1.283 + smtptest (debug); 1.284 + break; 1.285 + case '\0': /* null command (type next message) */ 1.286 + if (!last || (last++ >= stream->nmsgs)) { 1.287 + puts ("%No next message"); 1.288 + break; 1.289 + } 1.290 + case 'T': /* Type command */ 1.291 + if (arg) last = atoi (arg); 1.292 + else if (!last) { 1.293 + puts ("?Missing message number"); 1.294 + break; 1.295 + } 1.296 + if (last && (last <= stream->nmsgs)) { 1.297 + STRINGLIST *lines = mail_newstringlist (); 1.298 + STRINGLIST *cur = lines; 1.299 + cur->text.size = strlen ((char *) (cur->text.data = (unsigned char *) 1.300 + cpystr ("Date"))); 1.301 + cur = cur->next = mail_newstringlist (); 1.302 + cur->text.size = strlen ((char *) (cur->text.data = (unsigned char *) 1.303 + cpystr ("From"))); 1.304 + cur = cur->next = mail_newstringlist (); 1.305 + cur->text.size = strlen ((char *) (cur->text.data = (unsigned char *) 1.306 + cpystr (">From"))); 1.307 + cur = cur->next = mail_newstringlist (); 1.308 + cur->text.size = strlen ((char *) (cur->text.data = (unsigned char *) 1.309 + cpystr ("Subject"))); 1.310 + cur = cur->next = mail_newstringlist (); 1.311 + cur->text.size = strlen ((char *) (cur->text.data = (unsigned char *) 1.312 + cpystr ("To"))); 1.313 + cur = cur->next = mail_newstringlist (); 1.314 + cur->text.size = strlen ((char *) (cur->text.data = (unsigned char *) 1.315 + cpystr ("cc"))); 1.316 + cur = cur->next = mail_newstringlist (); 1.317 + cur->text.size = strlen ((char *) (cur->text.data = (unsigned char *) 1.318 + cpystr ("Newsgroups"))); 1.319 + printf ("%s",mail_fetchheader_full (stream,last,lines,NIL,NIL)); 1.320 + puts (mail_fetchtext (stream,last)); 1.321 + mail_free_stringlist (&lines); 1.322 + } 1.323 + else puts ("?Bad message number"); 1.324 + break; 1.325 + case 'U': /* Undelete command */ 1.326 + if (arg) last = atoi (arg); 1.327 + else { 1.328 + if (!last) { 1.329 + puts ("?Missing message number"); 1.330 + break; 1.331 + } 1.332 + arg = cmd; 1.333 + sprintf (arg,"%lu",last); 1.334 + } 1.335 + if (last > 0 && last <= stream->nmsgs) 1.336 + mail_clearflag (stream,arg,"\\DELETED"); 1.337 + else puts ("?Bad message number"); 1.338 + break; 1.339 + case 'X': /* Xit command */ 1.340 + mail_expunge (stream); 1.341 + mail_close (stream); 1.342 + stream = NIL; 1.343 + break; 1.344 + case '+': 1.345 + mail_debug (stream); debug = T; 1.346 + break; 1.347 + case '-': 1.348 + mail_nodebug (stream); debug = NIL; 1.349 + break; 1.350 + case '?': /* ? command */ 1.351 + puts ("Body, Check, Delete, Expunge, Find, GC, Headers, Literal,"); 1.352 + puts (" MailboxStatus, New Mailbox, Overview, Ping, Quit, Send, Type,"); 1.353 + puts ("Undelete, Xit, +, -, or <RETURN> for next message"); 1.354 + break; 1.355 + default: /* bogus command */ 1.356 + printf ("?Unrecognized command: %s\n",cmd); 1.357 + break; 1.358 + } 1.359 + } 1.360 +} 1.361 + 1.362 +/* MM display header 1.363 + * Accepts: IMAP2 stream 1.364 + * message number 1.365 + */ 1.366 + 1.367 +void overview_header (MAILSTREAM *stream,unsigned long uid,OVERVIEW *ov, 1.368 + unsigned long msgno) 1.369 +{ 1.370 + if (ov) { 1.371 + unsigned long i; 1.372 + char *t,tmp[MAILTMPLEN]; 1.373 + ADDRESS *adr; 1.374 + MESSAGECACHE *elt = mail_elt (stream,msgno); 1.375 + MESSAGECACHE selt; 1.376 + tmp[0] = elt->recent ? (elt->seen ? 'R': 'N') : ' '; 1.377 + tmp[1] = (elt->recent | elt->seen) ? ' ' : 'U'; 1.378 + tmp[2] = elt->flagged ? 'F' : ' '; 1.379 + tmp[3] = elt->answered ? 'A' : ' '; 1.380 + tmp[4] = elt->deleted ? 'D' : ' '; 1.381 + mail_parse_date (&selt,ov->date); 1.382 + sprintf (tmp+5,"%4lu) ",elt->msgno); 1.383 + mail_date (tmp+11,&selt); 1.384 + tmp[17] = ' '; 1.385 + tmp[18] = '\0'; 1.386 + memset (tmp+18,' ',(size_t) 20); 1.387 + tmp[38] = '\0'; /* tie off with null */ 1.388 + /* get first from address from envelope */ 1.389 + for (adr = ov->from; adr && !adr->host; adr = adr->next); 1.390 + if (adr) { /* if a personal name exists use it */ 1.391 + if (!(t = adr->personal)) 1.392 + sprintf (t = tmp+400,"%s@%s",adr->mailbox,adr->host); 1.393 + memcpy (tmp+18,t,(size_t) min (20,(long) strlen (t))); 1.394 + } 1.395 + strcat (tmp," "); 1.396 + if (i = elt->user_flags) { 1.397 + strcat (tmp,"{"); 1.398 + while (i) { 1.399 + strcat (tmp,stream->user_flags[find_rightmost_bit (&i)]); 1.400 + if (i) strcat (tmp," "); 1.401 + } 1.402 + strcat (tmp,"} "); 1.403 + } 1.404 + sprintf (tmp + strlen (tmp),"%.25s (%lu chars)", 1.405 + ov->subject ? ov->subject : " ",ov->optional.octets); 1.406 + puts (tmp); 1.407 + } 1.408 + else printf ("%%No overview for UID %lu\n",uid); 1.409 +} 1.410 + 1.411 +/* MM display header 1.412 + * Accepts: IMAP2 stream 1.413 + * message number 1.414 + */ 1.415 + 1.416 +void header (MAILSTREAM *stream,long msgno) 1.417 +{ 1.418 + unsigned long i; 1.419 + char tmp[MAILTMPLEN]; 1.420 + char *t; 1.421 + MESSAGECACHE *cache = mail_elt (stream,msgno); 1.422 + mail_fetchstructure (stream,msgno,NIL); 1.423 + tmp[0] = cache->recent ? (cache->seen ? 'R': 'N') : ' '; 1.424 + tmp[1] = (cache->recent | cache->seen) ? ' ' : 'U'; 1.425 + tmp[2] = cache->flagged ? 'F' : ' '; 1.426 + tmp[3] = cache->answered ? 'A' : ' '; 1.427 + tmp[4] = cache->deleted ? 'D' : ' '; 1.428 + sprintf (tmp+5,"%4lu) ",cache->msgno); 1.429 + mail_date (tmp+11,cache); 1.430 + tmp[17] = ' '; 1.431 + tmp[18] = '\0'; 1.432 + mail_fetchfrom (tmp+18,stream,msgno,(long) 20); 1.433 + strcat (tmp," "); 1.434 + if (i = cache->user_flags) { 1.435 + strcat (tmp,"{"); 1.436 + while (i) { 1.437 + strcat (tmp,stream->user_flags[find_rightmost_bit (&i)]); 1.438 + if (i) strcat (tmp," "); 1.439 + } 1.440 + strcat (tmp,"} "); 1.441 + } 1.442 + mail_fetchsubject (t = tmp + strlen (tmp),stream,msgno,(long) 25); 1.443 + sprintf (t += strlen (t)," (%lu chars)",cache->rfc822_size); 1.444 + puts (tmp); 1.445 +} 1.446 + 1.447 +/* MM display body 1.448 + * Accepts: BODY structure pointer 1.449 + * prefix string 1.450 + * index 1.451 + */ 1.452 + 1.453 +void display_body (BODY *body,char *pfx,long i) 1.454 +{ 1.455 + char tmp[MAILTMPLEN]; 1.456 + char *s = tmp; 1.457 + PARAMETER *par; 1.458 + PART *part; /* multipart doesn't have a row to itself */ 1.459 + if (body->type == TYPEMULTIPART) { 1.460 + /* if not first time, extend prefix */ 1.461 + if (pfx) sprintf (tmp,"%s%ld.",pfx,++i); 1.462 + else tmp[0] = '\0'; 1.463 + for (i = 0,part = body->nested.part; part; part = part->next) 1.464 + display_body (&part->body,tmp,i++); 1.465 + } 1.466 + else { /* non-multipart, output oneline descriptor */ 1.467 + if (!pfx) pfx = ""; /* dummy prefix if top level */ 1.468 + sprintf (s," %s%ld %s",pfx,++i,body_types[body->type]); 1.469 + if (body->subtype) sprintf (s += strlen (s),"/%s",body->subtype); 1.470 + if (body->description) sprintf (s += strlen (s)," (%s)",body->description); 1.471 + if (par = body->parameter) do 1.472 + sprintf (s += strlen (s),";%s=%s",par->attribute,par->value); 1.473 + while (par = par->next); 1.474 + if (body->id) sprintf (s += strlen (s),", id = %s",body->id); 1.475 + switch (body->type) { /* bytes or lines depending upon body type */ 1.476 + case TYPEMESSAGE: /* encapsulated message */ 1.477 + case TYPETEXT: /* plain text */ 1.478 + sprintf (s += strlen (s)," (%lu lines)",body->size.lines); 1.479 + break; 1.480 + default: 1.481 + sprintf (s += strlen (s)," (%lu bytes)",body->size.bytes); 1.482 + break; 1.483 + } 1.484 + puts (tmp); /* output this line */ 1.485 + /* encapsulated message? */ 1.486 + if ((body->type == TYPEMESSAGE) && !strcmp (body->subtype,"RFC822") && 1.487 + (body = body->nested.msg->body)) { 1.488 + if (body->type == TYPEMULTIPART) display_body (body,pfx,i-1); 1.489 + else { /* build encapsulation prefix */ 1.490 + sprintf (tmp,"%s%ld.",pfx,i); 1.491 + display_body (body,tmp,(long) 0); 1.492 + } 1.493 + } 1.494 + } 1.495 +} 1.496 + 1.497 +/* MM status report 1.498 + * Accepts: MAIL stream 1.499 + */ 1.500 + 1.501 +void status (MAILSTREAM *stream) 1.502 +{ 1.503 + unsigned long i; 1.504 + char *s,date[MAILTMPLEN]; 1.505 + THREADER *thr; 1.506 + AUTHENTICATOR *auth; 1.507 + rfc822_date (date); 1.508 + puts (date); 1.509 + if (stream) { 1.510 + if (stream->mailbox) 1.511 + printf (" %s mailbox: %s, %lu messages, %lu recent\n", 1.512 + stream->dtb->name,stream->mailbox,stream->nmsgs,stream->recent); 1.513 + else puts ("%No mailbox is open on this stream"); 1.514 + if (stream->user_flags[0]) { 1.515 + printf ("Keywords: %s",stream->user_flags[0]); 1.516 + for (i = 1; i < NUSERFLAGS && stream->user_flags[i]; ++i) 1.517 + printf (", %s",stream->user_flags[i]); 1.518 + puts (""); 1.519 + } 1.520 + if (!strcmp (stream->dtb->name,"imap")) { 1.521 + if (LEVELIMAP4rev1 (stream)) s = "IMAP4rev1 (RFC 3501)"; 1.522 + else if (LEVEL1730 (stream)) s = "IMAP4 (RFC 1730)"; 1.523 + else if (LEVELIMAP2bis (stream)) s = "IMAP2bis"; 1.524 + else if (LEVEL1176 (stream)) s = "IMAP2 (RFC 1176)"; 1.525 + else s = "IMAP2 (RFC 1064)"; 1.526 + printf ("%s server %s\n",s,imap_host (stream)); 1.527 + if (LEVELIMAP4 (stream)) { 1.528 + if (i = imap_cap (stream)->auth) { 1.529 + s = ""; 1.530 + printf ("Mutually-supported SASL mechanisms:"); 1.531 + while (auth = mail_lookup_auth (find_rightmost_bit (&i) + 1)) { 1.532 + printf (" %s",auth->name); 1.533 + if (!strcmp (auth->name,"PLAIN")) 1.534 + s = "\n [LOGIN will not be listed here if PLAIN is supported]"; 1.535 + } 1.536 + puts (s); 1.537 + } 1.538 + printf ("Supported standard extensions:\n"); 1.539 + if (LEVELACL (stream)) puts (" Access Control lists (RFC 2086)"); 1.540 + if (LEVELQUOTA (stream)) puts (" Quotas (RFC 2087)"); 1.541 + if (LEVELLITERALPLUS (stream)) 1.542 + puts (" Non-synchronizing literals (RFC 2088)"); 1.543 + if (LEVELIDLE (stream)) puts (" IDLE unsolicited update (RFC 2177)"); 1.544 + if (LEVELMBX_REF (stream)) puts (" Mailbox referrals (RFC 2193)"); 1.545 + if (LEVELLOG_REF (stream)) puts (" Login referrals (RFC 2221)"); 1.546 + if (LEVELANONYMOUS (stream)) puts (" Anonymous access (RFC 2245)"); 1.547 + if (LEVELNAMESPACE (stream)) puts (" Multiple namespaces (RFC 2342)"); 1.548 + if (LEVELUIDPLUS (stream)) puts (" Extended UID behavior (RFC 2359)"); 1.549 + if (LEVELSTARTTLS (stream)) 1.550 + puts (" Transport Layer Security (RFC 2595)"); 1.551 + if (LEVELLOGINDISABLED (stream)) 1.552 + puts (" LOGIN command disabled (RFC 2595)"); 1.553 + if (LEVELID (stream)) 1.554 + puts (" Implementation identity negotiation (RFC 2971)"); 1.555 + if (LEVELCHILDREN (stream)) 1.556 + puts (" LIST children announcement (RFC 3348)"); 1.557 + if (LEVELMULTIAPPEND (stream)) 1.558 + puts (" Atomic multiple APPEND (RFC 3502)"); 1.559 + if (LEVELBINARY (stream)) 1.560 + puts (" Binary body content (RFC 3516)"); 1.561 + if (LEVELUNSELECT (stream)) puts (" Mailbox unselect (RFC 3691)"); 1.562 + if (LEVELURLAUTH (stream)) 1.563 + puts (" URL authenticated fetch (RFC 4467)"); 1.564 + if (LEVELCATENATE (stream)) puts (" Catenation (RFC 4469)"); 1.565 + if (LEVELCONDSTORE (stream)) puts (" Conditional STORE (RFC 4551)"); 1.566 + if (LEVELESEARCH (stream)) puts (" Extended SEARCH (RFC 4731)"); 1.567 + puts ("Supported draft extensions:"); 1.568 + if (LEVELSASLIR (stream)) puts (" SASL initial client response"); 1.569 + if (LEVELSORT (stream)) puts (" Server-based sorting"); 1.570 + if (LEVELTHREAD (stream)) { 1.571 + printf (" Server-based threading:"); 1.572 + for (thr = imap_cap (stream)->threader; thr; thr = thr->next) 1.573 + printf (" %s",thr->name); 1.574 + putchar ('\n'); 1.575 + } 1.576 + if (LEVELSCAN (stream)) puts (" Mailbox text scan"); 1.577 + if (i = imap_cap (stream)->extlevel) { 1.578 + printf ("Supported BODYSTRUCTURE extensions:"); 1.579 + switch (i) { 1.580 + case BODYEXTLOC: printf (" location"); 1.581 + case BODYEXTLANG: printf (" language"); 1.582 + case BODYEXTDSP: printf (" disposition"); 1.583 + case BODYEXTMD5: printf (" MD5\n"); 1.584 + } 1.585 + } 1.586 + } 1.587 + else putchar ('\n'); 1.588 + } 1.589 + } 1.590 +} 1.591 + 1.592 + 1.593 +/* Prompt user for input 1.594 + * Accepts: pointer to prompt message 1.595 + * pointer to input buffer 1.596 + */ 1.597 + 1.598 +void prompt (char *msg,char *txt) 1.599 +{ 1.600 + printf ("%s",msg); 1.601 + gets (txt); 1.602 +} 1.603 + 1.604 +/* Interfaces to C-client */ 1.605 + 1.606 + 1.607 +void mm_searched (MAILSTREAM *stream,unsigned long number) 1.608 +{ 1.609 +} 1.610 + 1.611 + 1.612 +void mm_exists (MAILSTREAM *stream,unsigned long number) 1.613 +{ 1.614 +} 1.615 + 1.616 + 1.617 +void mm_expunged (MAILSTREAM *stream,unsigned long number) 1.618 +{ 1.619 +} 1.620 + 1.621 + 1.622 +void mm_flags (MAILSTREAM *stream,unsigned long number) 1.623 +{ 1.624 +} 1.625 + 1.626 + 1.627 +void mm_notify (MAILSTREAM *stream,char *string,long errflg) 1.628 +{ 1.629 + mm_log (string,errflg); 1.630 +} 1.631 + 1.632 + 1.633 +void mm_list (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes) 1.634 +{ 1.635 + putchar (' '); 1.636 + if (delimiter) putchar (delimiter); 1.637 + else fputs ("NIL",stdout); 1.638 + putchar (' '); 1.639 + fputs (mailbox,stdout); 1.640 + if (attributes & LATT_NOINFERIORS) fputs (", no inferiors",stdout); 1.641 + if (attributes & LATT_NOSELECT) fputs (", no select",stdout); 1.642 + if (attributes & LATT_MARKED) fputs (", marked",stdout); 1.643 + if (attributes & LATT_UNMARKED) fputs (", unmarked",stdout); 1.644 + putchar ('\n'); 1.645 +} 1.646 + 1.647 + 1.648 +void mm_lsub (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes) 1.649 +{ 1.650 + putchar (' '); 1.651 + if (delimiter) putchar (delimiter); 1.652 + else fputs ("NIL",stdout); 1.653 + putchar (' '); 1.654 + fputs (mailbox,stdout); 1.655 + if (attributes & LATT_NOINFERIORS) fputs (", no inferiors",stdout); 1.656 + if (attributes & LATT_NOSELECT) fputs (", no select",stdout); 1.657 + if (attributes & LATT_MARKED) fputs (", marked",stdout); 1.658 + if (attributes & LATT_UNMARKED) fputs (", unmarked",stdout); 1.659 + putchar ('\n'); 1.660 +} 1.661 + 1.662 + 1.663 +void mm_status (MAILSTREAM *stream,char *mailbox,MAILSTATUS *status) 1.664 +{ 1.665 + printf (" Mailbox %s",mailbox); 1.666 + if (status->flags & SA_MESSAGES) printf (", %lu messages",status->messages); 1.667 + if (status->flags & SA_RECENT) printf (", %lu recent",status->recent); 1.668 + if (status->flags & SA_UNSEEN) printf (", %lu unseen",status->unseen); 1.669 + if (status->flags & SA_UIDVALIDITY) printf (", %lu UID validity", 1.670 + status->uidvalidity); 1.671 + if (status->flags & SA_UIDNEXT) printf (", %lu next UID",status->uidnext); 1.672 + printf ("\n"); 1.673 +} 1.674 + 1.675 + 1.676 +void mm_log (char *string,long errflg) 1.677 +{ 1.678 + switch ((short) errflg) { 1.679 + case NIL: 1.680 + printf ("[%s]\n",string); 1.681 + break; 1.682 + case PARSE: 1.683 + case WARN: 1.684 + printf ("%%%s\n",string); 1.685 + break; 1.686 + case ERROR: 1.687 + printf ("?%s\n",string); 1.688 + break; 1.689 + } 1.690 +} 1.691 + 1.692 + 1.693 +void mm_dlog (char *string) 1.694 +{ 1.695 + puts (string); 1.696 +} 1.697 + 1.698 + 1.699 +void mm_login (NETMBX *mb,char *user,char *pwd,long trial) 1.700 +{ 1.701 + char *s,tmp[MAILTMPLEN]; 1.702 + if (curhst) fs_give ((void **) &curhst); 1.703 + curhst = (char *) fs_get (1+strlen (mb->host)); 1.704 + strcpy (curhst,mb->host); 1.705 + sprintf (s = tmp,"{%s/%s",mb->host,mb->service); 1.706 + if (*mb->user) sprintf (tmp+strlen (tmp),"/user=%s",strcpy (user,mb->user)); 1.707 + if (*mb->authuser) sprintf (tmp+strlen (tmp),"/authuser=%s",mb->authuser); 1.708 + if (*mb->user) strcat (s = tmp,"} password:"); 1.709 + else { 1.710 + printf ("%s} username: ",tmp); 1.711 + fgets (user,NETMAXUSER-1,stdin); 1.712 + user[NETMAXUSER-1] = '\0'; 1.713 + if (s = strchr (user,'\n')) *s = '\0'; 1.714 + s = "password: "; 1.715 + } 1.716 + if (curusr) fs_give ((void **) &curusr); 1.717 + curusr = cpystr (user); 1.718 + strcpy (pwd,getpass (s)); 1.719 +} 1.720 + 1.721 + 1.722 +void mm_critical (MAILSTREAM *stream) 1.723 +{ 1.724 +} 1.725 + 1.726 + 1.727 +void mm_nocritical (MAILSTREAM *stream) 1.728 +{ 1.729 +} 1.730 + 1.731 + 1.732 +long mm_diskerror (MAILSTREAM *stream,long errcode,long serious) 1.733 +{ 1.734 +#if UNIXLIKE 1.735 + kill (getpid (),SIGSTOP); 1.736 +#else 1.737 + abort (); 1.738 +#endif 1.739 + return NIL; 1.740 +} 1.741 + 1.742 + 1.743 +void mm_fatal (char *string) 1.744 +{ 1.745 + printf ("?%s\n",string); 1.746 +} 1.747 + 1.748 +/* SMTP tester */ 1.749 + 1.750 +void smtptest (long debug) 1.751 +{ 1.752 + SENDSTREAM *stream = NIL; 1.753 + char line[MAILTMPLEN]; 1.754 + char *text = (char *) fs_get (8*MAILTMPLEN); 1.755 + ENVELOPE *msg = mail_newenvelope (); 1.756 + BODY *body = mail_newbody (); 1.757 + msg->from = mail_newaddr (); 1.758 + msg->from->personal = cpystr (personalname); 1.759 + msg->from->mailbox = cpystr (curusr); 1.760 + msg->from->host = cpystr (curhst); 1.761 + msg->return_path = mail_newaddr (); 1.762 + msg->return_path->mailbox = cpystr (curusr); 1.763 + msg->return_path->host = cpystr (curhst); 1.764 + prompt ("To: ",line); 1.765 + rfc822_parse_adrlist (&msg->to,line,curhst); 1.766 + if (msg->to) { 1.767 + prompt ("cc: ",line); 1.768 + rfc822_parse_adrlist (&msg->cc,line,curhst); 1.769 + } 1.770 + else { 1.771 + prompt ("Newsgroups: ",line); 1.772 + if (*line) msg->newsgroups = cpystr (line); 1.773 + else { 1.774 + mail_free_body (&body); 1.775 + mail_free_envelope (&msg); 1.776 + fs_give ((void **) &text); 1.777 + return; 1.778 + } 1.779 + } 1.780 + prompt ("Subject: ",line); 1.781 + msg->subject = cpystr (line); 1.782 + puts (" Msg (end with a line with only a '.'):"); 1.783 + body->type = TYPETEXT; 1.784 + *text = '\0'; 1.785 + while (gets (line)) { 1.786 + if (line[0] == '.') { 1.787 + if (line[1] == '\0') break; 1.788 + else strcat (text,"."); 1.789 + } 1.790 + strcat (text,line); 1.791 + strcat (text,"\015\012"); 1.792 + } 1.793 + body->contents.text.data = (unsigned char *) text; 1.794 + body->contents.text.size = strlen (text); 1.795 + rfc822_date (line); 1.796 + msg->date = (char *) fs_get (1+strlen (line)); 1.797 + strcpy (msg->date,line); 1.798 + if (msg->to) { 1.799 + puts ("Sending..."); 1.800 + if (stream = smtp_open (hostlist,debug)) { 1.801 + if (smtp_mail (stream,"MAIL",msg,body)) puts ("[Ok]"); 1.802 + else printf ("[Failed - %s]\n",stream->reply); 1.803 + } 1.804 + } 1.805 + else { 1.806 + puts ("Posting..."); 1.807 + if (stream = nntp_open (newslist,debug)) { 1.808 + if (nntp_mail (stream,msg,body)) puts ("[Ok]"); 1.809 + else printf ("[Failed - %s]\n",stream->reply); 1.810 + } 1.811 + } 1.812 + if (stream) smtp_close (stream); 1.813 + else puts ("[Can't open connection to any server]"); 1.814 + mail_free_envelope (&msg); 1.815 + mail_free_body (&body); 1.816 +}