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