imapext-2007

annotate src/mailutil/mailutil.c @ 0:ada5e610ab86

imap-2007e
author yuuji@gentei.org
date Mon, 14 Sep 2009 15:17:45 +0900
parents
children
rev   line source
yuuji@0 1 /* ========================================================================
yuuji@0 2 * Copyright 1988-2008 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 utility
yuuji@0 16 *
yuuji@0 17 * Author: Mark Crispin
yuuji@0 18 * UW Technology
yuuji@0 19 * University of Washington
yuuji@0 20 * Seattle, WA 98195
yuuji@0 21 * Internet: MRC@Washington.EDU
yuuji@0 22 *
yuuji@0 23 * Date: 2 February 1994
yuuji@0 24 * Last Edited: 19 February 2008
yuuji@0 25 */
yuuji@0 26
yuuji@0 27
yuuji@0 28 #include <stdio.h>
yuuji@0 29 #include <errno.h>
yuuji@0 30 extern int errno; /* just in case */
yuuji@0 31 #include "c-client.h"
yuuji@0 32 #ifdef SYSCONFIG /* defined in env_unix.h */
yuuji@0 33 #include <pwd.h>
yuuji@0 34 #endif
yuuji@0 35
yuuji@0 36 /* Globals */
yuuji@0 37
yuuji@0 38 char *version = "13"; /* edit number */
yuuji@0 39 int debugp = NIL; /* flag saying debug */
yuuji@0 40 int verbosep = NIL; /* flag saying verbose */
yuuji@0 41 int rwcopyp = NIL; /* flag saying readwrite copy (for POP) */
yuuji@0 42 int kwcopyp = NIL; /* flag saying keyword copy */
yuuji@0 43 int ignorep = NIL; /* flag saying ignore keywords */
yuuji@0 44 int critical = NIL; /* flag saying in critical code */
yuuji@0 45 int trycreate = NIL; /* [TRYCREATE] seen */
yuuji@0 46 char *suffix = NIL; /* suffer merge mode suffix text */
yuuji@0 47 int ddelim = -1; /* destination delimiter */
yuuji@0 48 FILE *f = NIL;
yuuji@0 49
yuuji@0 50 /* Usage strings */
yuuji@0 51
yuuji@0 52 char *usage2 = "usage: %s %s\n\n%s\n";
yuuji@0 53 char *usage3 = "usage: %s %s %s\n\n%s\n";
yuuji@0 54 char *usgchk = "check [MAILBOX]";
yuuji@0 55 char *usgcre = "create MAILBOX";
yuuji@0 56 char *usgdel = "delete MAILBOX";
yuuji@0 57 char *usgren = "rename SOURCE DESTINATION";
yuuji@0 58 char *usgcpymov = "[-rw[copy]] [-kw[copy]] [-ig[nore]] SOURCE DESTINATION";
yuuji@0 59 char *usgappdel = "[-rw[copy]] [-kw[copy]] [-ig[nore]] SOURCE DESTINATION";
yuuji@0 60 char *usgprn = "prune mailbox SEARCH_CRITERIA";
yuuji@0 61 char *usgxfr = "transfer [-rw[copy]] [-kw[copy]] [-ig[nore]] [-m[erge] m] SOURCE DEST";
yuuji@0 62 #ifdef SYSCONFIG
yuuji@0 63 char *stdsw = "Standard switches valid with any command:\n\t[-d[ebug]] [-v[erbose]] [-u[ser] userid] [--]";
yuuji@0 64 #else
yuuji@0 65 char *stdsw = "Standard switches valid with any command:\n\t[-d[ebug]] [-v[erbose]]";
yuuji@0 66 #endif
yuuji@0 67
yuuji@0 68 /* Merge modes */
yuuji@0 69
yuuji@0 70 #define mPROMPT 1
yuuji@0 71 #define mAPPEND 2
yuuji@0 72 #define mSUFFIX 3
yuuji@0 73
yuuji@0 74
yuuji@0 75 /* Function prototypes */
yuuji@0 76
yuuji@0 77 void ms_init (STRING *s,void *data,unsigned long size);
yuuji@0 78 char ms_next (STRING *s);
yuuji@0 79 void ms_setpos (STRING *s,unsigned long i);
yuuji@0 80 int main (int argc,char *argv[]);
yuuji@0 81 SEARCHPGM *prune_criteria (char *criteria);
yuuji@0 82 int prune_criteria_number (unsigned long *number,char **r);
yuuji@0 83 int mbxcopy (MAILSTREAM *source,MAILSTREAM *dest,char *dst,int create,int del,
yuuji@0 84 int mode);
yuuji@0 85 long mm_append (MAILSTREAM *stream,void *data,char **flags,char **date,
yuuji@0 86 STRING **message);
yuuji@0 87
yuuji@0 88
yuuji@0 89 /* Append package */
yuuji@0 90
yuuji@0 91 typedef struct append_package {
yuuji@0 92 MAILSTREAM *stream; /* source stream */
yuuji@0 93 unsigned long msgno; /* current message number */
yuuji@0 94 unsigned long msgmax; /* maximum message number */
yuuji@0 95 char *flags; /* current flags */
yuuji@0 96 char *date; /* message internal date */
yuuji@0 97 STRING *message; /* stringstruct of message */
yuuji@0 98 } APPENDPACKAGE;
yuuji@0 99
yuuji@0 100
yuuji@0 101 /* Message string driver for message stringstructs */
yuuji@0 102
yuuji@0 103 STRINGDRIVER mstring = {
yuuji@0 104 ms_init, /* initialize string structure */
yuuji@0 105 ms_next, /* get next byte in string structure */
yuuji@0 106 ms_setpos /* set position in string structure */
yuuji@0 107 };
yuuji@0 108
yuuji@0 109 /* Initialize file string structure for file stringstruct
yuuji@0 110 * Accepts: string structure
yuuji@0 111 * pointer to message data structure
yuuji@0 112 * size of string
yuuji@0 113 */
yuuji@0 114
yuuji@0 115 void ms_init (STRING *s,void *data,unsigned long size)
yuuji@0 116 {
yuuji@0 117 APPENDPACKAGE *md = (APPENDPACKAGE *) data;
yuuji@0 118 s->data = data; /* note stream/msgno and header length */
yuuji@0 119 mail_fetch_header (md->stream,md->msgno,NIL,NIL,&s->data1,
yuuji@0 120 FT_PREFETCHTEXT|FT_PEEK);
yuuji@0 121 #if 0
yuuji@0 122 s->size = size; /* message size */
yuuji@0 123 #else /* This kludge is necessary because of broken IMAP servers (sigh!) */
yuuji@0 124 mail_fetch_text (md->stream,md->msgno,NIL,&s->size,FT_PEEK);
yuuji@0 125 s->size += s->data1; /* header + body size */
yuuji@0 126 #endif
yuuji@0 127 SETPOS (s,0);
yuuji@0 128 }
yuuji@0 129
yuuji@0 130
yuuji@0 131 /* Get next character from file stringstruct
yuuji@0 132 * Accepts: string structure
yuuji@0 133 * Returns: character, string structure chunk refreshed
yuuji@0 134 */
yuuji@0 135
yuuji@0 136 char ms_next (STRING *s)
yuuji@0 137 {
yuuji@0 138 char c = *s->curpos++; /* get next byte */
yuuji@0 139 SETPOS (s,GETPOS (s)); /* move to next chunk */
yuuji@0 140 return c; /* return the byte */
yuuji@0 141 }
yuuji@0 142
yuuji@0 143
yuuji@0 144 /* Set string pointer position for file stringstruct
yuuji@0 145 * Accepts: string structure
yuuji@0 146 * new position
yuuji@0 147 */
yuuji@0 148
yuuji@0 149 void ms_setpos (STRING *s,unsigned long i)
yuuji@0 150 {
yuuji@0 151 APPENDPACKAGE *md = (APPENDPACKAGE *) s->data;
yuuji@0 152 if (i < s->data1) { /* want header? */
yuuji@0 153 s->chunk = mail_fetch_header (md->stream,md->msgno,NIL,NIL,NIL,FT_PEEK);
yuuji@0 154 s->chunksize = s->data1; /* header length */
yuuji@0 155 s->offset = 0; /* offset is start of message */
yuuji@0 156 }
yuuji@0 157 else if (i < s->size) { /* want body */
yuuji@0 158 s->chunk = mail_fetch_text (md->stream,md->msgno,NIL,NIL,FT_PEEK);
yuuji@0 159 s->chunksize = s->size - s->data1;
yuuji@0 160 s->offset = s->data1; /* offset is end of header */
yuuji@0 161 }
yuuji@0 162 else { /* off end of message */
yuuji@0 163 s->chunk = NIL; /* make sure that we crack on this then */
yuuji@0 164 s->chunksize = 1; /* make sure SNX cracks the right way... */
yuuji@0 165 s->offset = i;
yuuji@0 166 }
yuuji@0 167 /* initial position and size */
yuuji@0 168 s->curpos = s->chunk + (i -= s->offset);
yuuji@0 169 s->cursize = s->chunksize - i;
yuuji@0 170 }
yuuji@0 171
yuuji@0 172 /* Main program */
yuuji@0 173
yuuji@0 174 int main (int argc,char *argv[])
yuuji@0 175 {
yuuji@0 176 MAILSTREAM *source = NIL;
yuuji@0 177 MAILSTREAM *dest = NIL;
yuuji@0 178 SEARCHPGM *criteria;
yuuji@0 179 char c,*s,*dp,*t,*t1,tmp[MAILTMPLEN],mbx[MAILTMPLEN];
yuuji@0 180 unsigned long m,len,curlen,start,last;
yuuji@0 181 int i;
yuuji@0 182 int merge = NIL;
yuuji@0 183 int retcode = 1;
yuuji@0 184 int moreswitchp = T;
yuuji@0 185 char *cmd = NIL;
yuuji@0 186 char *src = NIL;
yuuji@0 187 char *dst = NIL;
yuuji@0 188 char *pgm = argc ? argv[0] : "mailutil";
yuuji@0 189 #include "linkage.c"
yuuji@0 190 for (i = 1; i < argc; i++) {
yuuji@0 191 s = argv[i]; /* pick up argument */
yuuji@0 192 /* parse switches */
yuuji@0 193 if (moreswitchp && (*s == '-')) {
yuuji@0 194 if (!strcmp (s,"-debug") || !strcmp (s,"-d")) debugp = T;
yuuji@0 195 else if (!strcmp (s,"-verbose") || !strcmp (s,"-v")) verbosep = T;
yuuji@0 196 else if (!strcmp (s,"-rwcopy") || !strcmp (s,"-rw")) rwcopyp = T;
yuuji@0 197 else if (!strcmp (s,"-kwcopy") || !strcmp (s,"-kw")) kwcopyp = T;
yuuji@0 198 else if (!strcmp (s,"-ignore") || !strcmp (s,"-ig")) ignorep = T;
yuuji@0 199 else if ((!strcmp (s,"-merge") || !strcmp (s,"-m")) && (++i < argc)) {
yuuji@0 200 if (!strcmp (s = argv[i],"prompt")) merge = mPROMPT;
yuuji@0 201 else if (!strcmp (s,"append")) merge = mAPPEND;
yuuji@0 202 else if (!strncmp (s,"suffix=",7) && s[7]) {
yuuji@0 203 merge = mSUFFIX;
yuuji@0 204 suffix = cpystr (s+7);
yuuji@0 205 }
yuuji@0 206 else {
yuuji@0 207 printf ("unknown merge option: %s\n",s);
yuuji@0 208 exit (retcode);
yuuji@0 209 }
yuuji@0 210 }
yuuji@0 211
yuuji@0 212 #ifdef SYSCONFIG
yuuji@0 213 else if ((!strcmp (s,"-user") || !strcmp (s,"-u")) && (++i < argc)) {
yuuji@0 214 struct passwd *pw = getpwnam (s = argv[i]);
yuuji@0 215 if (!pw) {
yuuji@0 216 printf ("unknown user id: %s\n",argv[i]);
yuuji@0 217 exit (retcode);
yuuji@0 218 }
yuuji@0 219 else if (setuid (pw->pw_uid)) {
yuuji@0 220 perror ("unable to change user id");
yuuji@0 221 exit (retcode);
yuuji@0 222 }
yuuji@0 223 }
yuuji@0 224 #endif
yuuji@0 225 /* -- means no more switches, so mailbox
yuuji@0 226 name can start with "-" */
yuuji@0 227 else if ((s[1] == '-') && !s[2]) moreswitchp = NIL;
yuuji@0 228 else {
yuuji@0 229 printf ("unknown switch: %s\n",s);
yuuji@0 230 exit (retcode);
yuuji@0 231 }
yuuji@0 232 }
yuuji@0 233 else if (!cmd) cmd = s; /* first non-switch is command */
yuuji@0 234 else if (!src) src = s; /* second non-switch is source */
yuuji@0 235 else if (!dst) dst = s; /* third non-switch is destination */
yuuji@0 236 else {
yuuji@0 237 printf ("unknown argument: %s\n",s);
yuuji@0 238 exit (retcode);
yuuji@0 239 }
yuuji@0 240 }
yuuji@0 241 if (kwcopyp && ignorep) {
yuuji@0 242 puts ("-kwcopy and -ignore are mutually exclusive");
yuuji@0 243 exit (retcode);
yuuji@0 244 }
yuuji@0 245 if (!cmd) cmd = ""; /* prevent SEGV */
yuuji@0 246
yuuji@0 247 if (!strcmp (cmd,"check")) { /* check for new messages */
yuuji@0 248 if (!src) src = "INBOX";
yuuji@0 249 if (dst || merge || rwcopyp || kwcopyp || ignorep)
yuuji@0 250 printf (usage2,pgm,usgchk,stdsw);
yuuji@0 251 else if (mail_status (source = (*src == '{') ?
yuuji@0 252 mail_open (NIL,src,OP_HALFOPEN |
yuuji@0 253 (debugp ? OP_DEBUG : NIL)) : NIL,
yuuji@0 254 src,SA_MESSAGES | SA_RECENT | SA_UNSEEN))
yuuji@0 255 retcode = 0;
yuuji@0 256 }
yuuji@0 257 else if (!strcmp (cmd,"create")) {
yuuji@0 258 if (!src || dst || merge || rwcopyp || kwcopyp || ignorep)
yuuji@0 259 printf (usage2,pgm,usgcre,stdsw);
yuuji@0 260 else if (mail_create (source = (*src == '{') ?
yuuji@0 261 mail_open (NIL,src,OP_HALFOPEN |
yuuji@0 262 (debugp ? OP_DEBUG : NIL)) : NIL,src))
yuuji@0 263 retcode = 0;
yuuji@0 264 }
yuuji@0 265 else if (!strcmp (cmd,"delete")) {
yuuji@0 266 if (!src || dst || merge || rwcopyp || kwcopyp || ignorep)
yuuji@0 267 printf (usage2,pgm,usgdel,stdsw);
yuuji@0 268 else if (mail_delete (source = (*src == '{') ?
yuuji@0 269 mail_open (NIL,src,OP_HALFOPEN |
yuuji@0 270 (debugp ? OP_DEBUG : NIL)) : NIL,src))
yuuji@0 271 retcode = 0;
yuuji@0 272 }
yuuji@0 273 else if (!strcmp (cmd,"rename")) {
yuuji@0 274 if (!src || !dst || merge || rwcopyp || kwcopyp || ignorep)
yuuji@0 275 printf (usage2,pgm,usgren,stdsw);
yuuji@0 276 else if (mail_rename (source = (*src == '{') ?
yuuji@0 277 mail_open (NIL,src,OP_HALFOPEN |
yuuji@0 278 (debugp ? OP_DEBUG : NIL)) : NIL,src,dst))
yuuji@0 279 retcode = 0;
yuuji@0 280 }
yuuji@0 281
yuuji@0 282 else if ((i = !strcmp (cmd,"move")) || !strcmp (cmd,"copy")) {
yuuji@0 283 if (!src || !dst || merge) printf (usage3,pgm,cmd,usgcpymov,stdsw);
yuuji@0 284 else if (source = mail_open (NIL,src,((i || rwcopyp) ? NIL : OP_READONLY) |
yuuji@0 285 (debugp ? OP_DEBUG : NIL))) {
yuuji@0 286 dest = NIL; /* open destination stream if network */
yuuji@0 287 if ((*dst != '{') || (dest = mail_open (NIL,dst,OP_HALFOPEN |
yuuji@0 288 (debugp ? OP_DEBUG : NIL)))) {
yuuji@0 289 if (mbxcopy (source,dest,dst,T,i,merge)) retcode = 0;
yuuji@0 290 }
yuuji@0 291 }
yuuji@0 292 }
yuuji@0 293 else if ((i = !strcmp (cmd,"appenddelete")) || !strcmp (cmd,"append")) {
yuuji@0 294 if (!src || !dst || merge) printf (usage3,pgm,cmd,usgappdel,stdsw);
yuuji@0 295 else if (source = mail_open (NIL,src,((i || rwcopyp) ? NIL : OP_READONLY) |
yuuji@0 296 (debugp ? OP_DEBUG : NIL))) {
yuuji@0 297 dest = NIL; /* open destination stream if network */
yuuji@0 298 if ((*dst != '{') || (dest = mail_open (NIL,dst,OP_HALFOPEN |
yuuji@0 299 (debugp ? OP_DEBUG : NIL)))) {
yuuji@0 300 if (mbxcopy (source,dest,dst,NIL,i,merge)) retcode = 0;
yuuji@0 301 }
yuuji@0 302 }
yuuji@0 303 }
yuuji@0 304
yuuji@0 305 else if (!strcmp (cmd,"prune")) {
yuuji@0 306 if (!src || !dst || merge || rwcopyp || kwcopyp || ignorep ||
yuuji@0 307 !(criteria = prune_criteria (dst))) printf (usage2,pgm,usgprn,stdsw);
yuuji@0 308 else if ((source = mail_open (NIL,src,(debugp ? OP_DEBUG : NIL))) &&
yuuji@0 309 mail_search_full (source,NIL,criteria,SE_FREE)) {
yuuji@0 310 for (m = 1, s = t = NIL, len = start = last = 0; m <= source->nmsgs; m++)
yuuji@0 311 if (mail_elt (source,m)->searched) {
yuuji@0 312 if (s) { /* continuing a range? */
yuuji@0 313 if (m == last + 1) last = m;
yuuji@0 314 else { /* no, end of previous range? */
yuuji@0 315 if (last != start) sprintf (t,":%lu,%lu",last,m);
yuuji@0 316 /* no, just this message */
yuuji@0 317 else sprintf (t,",%lu",m);
yuuji@0 318 start = last = m; /* either way, start new range */
yuuji@0 319 /* running out of space? */
yuuji@0 320 if ((len - (curlen = (t += strlen (t)) - s)) < 20) {
yuuji@0 321 fs_resize ((void **) &s,len += MAILTMPLEN);
yuuji@0 322 t = s + curlen; /* relocate current pointer */
yuuji@0 323 }
yuuji@0 324 }
yuuji@0 325 }
yuuji@0 326 else { /* first time, start new buffer */
yuuji@0 327 s = (char *) fs_get (len = MAILTMPLEN);
yuuji@0 328 sprintf (s,"%lu",start = last = m);
yuuji@0 329 t = s + strlen (s); /* end of buffer */
yuuji@0 330 }
yuuji@0 331 }
yuuji@0 332 /* finish last range if necessary */
yuuji@0 333 if (last != start) sprintf (t,":%lu",last);
yuuji@0 334 if (s) { /* delete/expunge any matching messages */
yuuji@0 335 mail_flag (source,s,"\\Deleted",ST_SET);
yuuji@0 336 m = source->nmsgs; /* get number of messages before purge */
yuuji@0 337 mail_expunge (source);
yuuji@0 338 printf ("%lu message(s) purged\n",m - source->nmsgs);
yuuji@0 339 fs_give ((void **) &s); /* flush buffer */
yuuji@0 340 }
yuuji@0 341 else puts ("No matching messages, so nothing purged");
yuuji@0 342 source = mail_close (source);
yuuji@0 343 }
yuuji@0 344 }
yuuji@0 345
yuuji@0 346 else if (!strcmp (cmd,"transfer")) {
yuuji@0 347 if (!src || !dst) printf (usage2,pgm,usgxfr,stdsw);
yuuji@0 348 else if ((*src == '{') && /* open source mailbox */
yuuji@0 349 !(source = mail_open (NIL,src,OP_HALFOPEN |
yuuji@0 350 (debugp ? OP_DEBUG : NIL))));
yuuji@0 351 else if ((*dst == '{') && /* open destination server */
yuuji@0 352 !(dest = mail_open (NIL,dst,OP_HALFOPEN |
yuuji@0 353 (debugp ? OP_DEBUG : NIL))));
yuuji@0 354 else if (!(f = tmpfile ())) puts ("can't open temporary file");
yuuji@0 355 else {
yuuji@0 356 if (verbosep) puts ("Listing mailboxes...");
yuuji@0 357 if (dest) strcpy (strchr (strcpy (tmp,dest->mailbox),'}') + 1,
yuuji@0 358 dp = strchr (dst,'}') + 1);
yuuji@0 359 else {
yuuji@0 360 dp = dst;
yuuji@0 361 tmp[0] = '\0';
yuuji@0 362 }
yuuji@0 363 mail_list (dest,tmp,"");
yuuji@0 364 rewind (f); /* list all mailboxes matching prefix */
yuuji@0 365 if (ddelim < 0) { /* if server failed to give delimiter */
yuuji@0 366 puts ("warning: unable to get destination hierarchy delimiter!");
yuuji@0 367 ddelim = 0; /* default to none */
yuuji@0 368 }
yuuji@0 369 if (source) strcpy (strchr (strcpy (tmp,source->mailbox),'}') + 1,
yuuji@0 370 strchr (src,'}') + 1);
yuuji@0 371 else strcpy (tmp,src);
yuuji@0 372 mail_list (source,tmp,"*");
yuuji@0 373 rewind (f);
yuuji@0 374 /* read back mailbox names */
yuuji@0 375 for (retcode = 0; !retcode && (fgets (tmp,MAILTMPLEN-1,f)); ) {
yuuji@0 376 if (t = strchr (tmp+1,'\n')) *t = '\0';
yuuji@0 377 for (t = mbx,t1 = dest ? dest->mailbox : "",c = NIL; (c != '}') && *t1;
yuuji@0 378 *t++ = c= *t1++);
yuuji@0 379 for (t1 = dp; *t1; *t++ = *t1++);
yuuji@0 380 /* point to name without delim or netspec */
yuuji@0 381 t1 = source ? (strchr (tmp+1,'}') + 1) : tmp + 1;
yuuji@0 382 /* src and mbx have different delimiters? */
yuuji@0 383 if (ddelim && (ddelim != tmp[0]))
yuuji@0 384 while (c = *t1++) { /* swap delimiters then */
yuuji@0 385 if (c == ddelim) c = tmp[0] ? tmp[0] : 'x';
yuuji@0 386 else if (c == tmp[0]) c = ddelim;
yuuji@0 387 *t++ = c;
yuuji@0 388 }
yuuji@0 389 /* easy case */
yuuji@0 390 else while (*t1) *t++ = *t1++;
yuuji@0 391 *t++ = '\0';
yuuji@0 392 if (verbosep) {
yuuji@0 393 printf ("Copying %s\n => %s\n",tmp+1,mbx);
yuuji@0 394 fflush (stdout);
yuuji@0 395 }
yuuji@0 396 if (source = mail_open (source,tmp+1,(debugp ? OP_DEBUG : NIL) |
yuuji@0 397 (rwcopyp ? NIL : OP_READONLY))) {
yuuji@0 398 if (!mbxcopy (source,dest,mbx,T,NIL,merge)) retcode = 1;
yuuji@0 399 if (source->dtb->flags & DR_LOCAL) source = mail_close (source);
yuuji@0 400 }
yuuji@0 401 else printf ("can't open source mailbox %s\n",tmp+1);
yuuji@0 402 }
yuuji@0 403 }
yuuji@0 404 }
yuuji@0 405
yuuji@0 406 else {
yuuji@0 407 printf ("%s version %s.%s\n\n",pgm,CCLIENTVERSION,version);
yuuji@0 408 printf (usage2,pgm,"command [switches] arguments",stdsw);
yuuji@0 409 printf ("\nCommands:\n %s\n",usgchk);
yuuji@0 410 puts (" ;; report number of messages and new messages");
yuuji@0 411 printf (" %s\n",usgcre);
yuuji@0 412 puts (" ;; create new mailbox");
yuuji@0 413 printf (" %s\n",usgdel);
yuuji@0 414 puts (" ;; delete existing mailbox");
yuuji@0 415 printf (" %s\n",usgren);
yuuji@0 416 puts (" ;; rename mailbox to a new name");
yuuji@0 417 printf (" copy %s\n",usgcpymov);
yuuji@0 418 printf (" move %s\n",usgcpymov);
yuuji@0 419 puts (" ;; create new mailbox and copy/move messages");
yuuji@0 420 printf (" append %s\n",usgappdel);
yuuji@0 421 printf (" appenddelete %s\n",usgappdel);
yuuji@0 422 puts (" ;; copy/move messages to existing mailbox");
yuuji@0 423 printf (" %s\n",usgprn);
yuuji@0 424 puts (" ;; prune mailbox of messages matching criteria");
yuuji@0 425 printf (" %s\n",usgxfr);
yuuji@0 426 puts (" ;; copy source hierarchy to destination");
yuuji@0 427 puts (" ;; -merge modes are prompt, append, or suffix=xxxx");
yuuji@0 428 }
yuuji@0 429 /* close streams */
yuuji@0 430 if (source) mail_close (source);
yuuji@0 431 if (dest) mail_close (dest);
yuuji@0 432 exit (retcode);
yuuji@0 433 return retcode; /* stupid compilers */
yuuji@0 434 }
yuuji@0 435
yuuji@0 436 /* Pruning criteria, somewhat extended from mail_criteria()
yuuji@0 437 * Accepts: criteria
yuuji@0 438 * Returns: search program if parse successful, else NIL
yuuji@0 439 */
yuuji@0 440
yuuji@0 441 SEARCHPGM *prune_criteria (char *criteria)
yuuji@0 442 {
yuuji@0 443 SEARCHPGM *pgm = NIL;
yuuji@0 444 char *criterion,*r,tmp[MAILTMPLEN];
yuuji@0 445 int f;
yuuji@0 446 if (criteria) { /* only if criteria defined */
yuuji@0 447 /* make writeable copy of criteria */
yuuji@0 448 criteria = cpystr (criteria);
yuuji@0 449 /* for each criterion */
yuuji@0 450 for (pgm = mail_newsearchpgm (), criterion = strtok_r (criteria," ",&r);
yuuji@0 451 criterion; (criterion = strtok_r (NIL," ",&r))) {
yuuji@0 452 f = NIL; /* init then scan the criterion */
yuuji@0 453 switch (*ucase (criterion)) {
yuuji@0 454 case 'A': /* possible ALL, ANSWERED */
yuuji@0 455 if (!strcmp (criterion+1,"LL")) f = T;
yuuji@0 456 else if (!strcmp (criterion+1,"NSWERED")) f = pgm->answered = T;
yuuji@0 457 break;
yuuji@0 458 case 'B': /* possible BCC, BEFORE, BODY */
yuuji@0 459 if (!strcmp (criterion+1,"CC"))
yuuji@0 460 f = mail_criteria_string (&pgm->bcc,&r);
yuuji@0 461 else if (!strcmp (criterion+1,"EFORE"))
yuuji@0 462 f = mail_criteria_date (&pgm->before,&r);
yuuji@0 463 else if (!strcmp (criterion+1,"ODY"))
yuuji@0 464 f = mail_criteria_string (&pgm->body,&r);
yuuji@0 465 break;
yuuji@0 466 case 'C': /* possible CC */
yuuji@0 467 if (!strcmp (criterion+1,"C")) f = mail_criteria_string (&pgm->cc,&r);
yuuji@0 468 break;
yuuji@0 469 case 'D': /* possible DELETED, DRAFT */
yuuji@0 470 if (!strcmp (criterion+1,"ELETED")) f = pgm->deleted = T;
yuuji@0 471 else if (!strcmp (criterion+1,"RAFT")) f = pgm->draft = T;
yuuji@0 472 break;
yuuji@0 473 case 'F': /* possible FLAGGED, FROM */
yuuji@0 474 if (!strcmp (criterion+1,"LAGGED")) f = pgm->flagged = T;
yuuji@0 475 else if (!strcmp (criterion+1,"ROM"))
yuuji@0 476 f = mail_criteria_string (&pgm->from,&r);
yuuji@0 477 break;
yuuji@0 478 case 'K': /* possible KEYWORD */
yuuji@0 479 if (!strcmp (criterion+1,"EYWORD"))
yuuji@0 480 f = mail_criteria_string (&pgm->keyword,&r);
yuuji@0 481 break;
yuuji@0 482 case 'L': /* possible LARGER */
yuuji@0 483 if (!strcmp (criterion+1,"ARGER"))
yuuji@0 484 f = prune_criteria_number (&pgm->larger,&r);
yuuji@0 485
yuuji@0 486 case 'N': /* possible NEW */
yuuji@0 487 if (!strcmp (criterion+1,"EW")) f = pgm->recent = pgm->unseen = T;
yuuji@0 488 break;
yuuji@0 489 case 'O': /* possible OLD, ON */
yuuji@0 490 if (!strcmp (criterion+1,"LD")) f = pgm->old = T;
yuuji@0 491 else if (!strcmp (criterion+1,"N"))
yuuji@0 492 f = mail_criteria_date (&pgm->on,&r);
yuuji@0 493 break;
yuuji@0 494 case 'R': /* possible RECENT */
yuuji@0 495 if (!strcmp (criterion+1,"ECENT")) f = pgm->recent = T;
yuuji@0 496 break;
yuuji@0 497 case 'S': /* possible SEEN, SENT*, SINCE, SMALLER,
yuuji@0 498 SUBJECT */
yuuji@0 499 if (!strcmp (criterion+1,"EEN")) f = pgm->seen = T;
yuuji@0 500 else if (!strncmp (criterion+1,"ENT",3)) {
yuuji@0 501 if (!strcmp (criterion+4,"BEFORE"))
yuuji@0 502 f = mail_criteria_date (&pgm->sentbefore,&r);
yuuji@0 503 else if (!strcmp (criterion+4,"ON"))
yuuji@0 504 f = mail_criteria_date (&pgm->senton,&r);
yuuji@0 505 else if (!strcmp (criterion+4,"SINCE"))
yuuji@0 506 f = mail_criteria_date (&pgm->sentsince,&r);
yuuji@0 507 }
yuuji@0 508 else if (!strcmp (criterion+1,"INCE"))
yuuji@0 509 f = mail_criteria_date (&pgm->since,&r);
yuuji@0 510 else if (!strcmp (criterion+1,"MALLER"))
yuuji@0 511 f = prune_criteria_number (&pgm->smaller,&r);
yuuji@0 512 else if (!strcmp (criterion+1,"UBJECT"))
yuuji@0 513 f = mail_criteria_string (&pgm->subject,&r);
yuuji@0 514 break;
yuuji@0 515 case 'T': /* possible TEXT, TO */
yuuji@0 516 if (!strcmp (criterion+1,"EXT"))
yuuji@0 517 f = mail_criteria_string (&pgm->text,&r);
yuuji@0 518 else if (!strcmp (criterion+1,"O"))
yuuji@0 519 f = mail_criteria_string (&pgm->to,&r);
yuuji@0 520 break;
yuuji@0 521 case 'U': /* possible UN* */
yuuji@0 522 if (criterion[1] == 'N') {
yuuji@0 523 if (!strcmp (criterion+2,"ANSWERED")) f = pgm->unanswered = T;
yuuji@0 524 else if (!strcmp (criterion+2,"DELETED")) f = pgm->undeleted = T;
yuuji@0 525 else if (!strcmp (criterion+2,"DRAFT")) f = pgm->undraft = T;
yuuji@0 526 else if (!strcmp (criterion+2,"FLAGGED")) f = pgm->unflagged = T;
yuuji@0 527 else if (!strcmp (criterion+2,"KEYWORD"))
yuuji@0 528 f = mail_criteria_string (&pgm->unkeyword,&r);
yuuji@0 529 else if (!strcmp (criterion+2,"SEEN")) f = pgm->unseen = T;
yuuji@0 530 }
yuuji@0 531 break;
yuuji@0 532 default: /* we will barf below */
yuuji@0 533 break;
yuuji@0 534 }
yuuji@0 535
yuuji@0 536 if (!f) { /* if can't identify criterion */
yuuji@0 537 sprintf (tmp,"Unknown search criterion: %.30s",criterion);
yuuji@0 538 MM_LOG (tmp,ERROR);
yuuji@0 539 mail_free_searchpgm (&pgm);
yuuji@0 540 break;
yuuji@0 541 }
yuuji@0 542 }
yuuji@0 543 /* no longer need copy of criteria */
yuuji@0 544 fs_give ((void **) &criteria);
yuuji@0 545 }
yuuji@0 546 return pgm;
yuuji@0 547 }
yuuji@0 548
yuuji@0 549
yuuji@0 550 /* Parse a number
yuuji@0 551 * Accepts: pointer to integer to return
yuuji@0 552 * pointer to strtok state
yuuji@0 553 * Returns: T if successful, else NIL
yuuji@0 554 */
yuuji@0 555
yuuji@0 556 int prune_criteria_number (unsigned long *number,char **r)
yuuji@0 557 {
yuuji@0 558 char *t;
yuuji@0 559 STRINGLIST *s = NIL;
yuuji@0 560 /* parse the date and return fn if OK */
yuuji@0 561 int ret = (mail_criteria_string (&s,r) &&
yuuji@0 562 (*number = strtoul ((char *) s->text.data,&t,10)) && !*t) ?
yuuji@0 563 T : NIL;
yuuji@0 564 if (s) mail_free_stringlist (&s);
yuuji@0 565 return ret;
yuuji@0 566 }
yuuji@0 567
yuuji@0 568 /* Copy mailbox
yuuji@0 569 * Accepts: stream open on source
yuuji@0 570 * halfopen stream for destination or NIL
yuuji@0 571 * destination mailbox name
yuuji@0 572 * non-zero to create destination mailbox
yuuji@0 573 * non-zero to delete messages from source after copying
yuuji@0 574 * merge mode
yuuji@0 575 * Returns: T if success, NIL if error
yuuji@0 576 */
yuuji@0 577
yuuji@0 578 int mbxcopy (MAILSTREAM *source,MAILSTREAM *dest,char *dst,int create,int del,
yuuji@0 579 int mode)
yuuji@0 580 {
yuuji@0 581 char *s,tmp[MAILTMPLEN];
yuuji@0 582 APPENDPACKAGE ap;
yuuji@0 583 STRING st;
yuuji@0 584 char *ndst = NIL;
yuuji@0 585 int ret = NIL;
yuuji@0 586 trycreate = NIL; /* no TRYCREATE yet */
yuuji@0 587 if (create) while (!mail_create (dest,dst) && (mode != mAPPEND)) {
yuuji@0 588 switch (mode) {
yuuji@0 589 case mPROMPT: /* prompt user for new name */
yuuji@0 590 tmp[0] = '\0';
yuuji@0 591 while (!tmp[0]) { /* read name */
yuuji@0 592 fputs ("alternative name: ",stdout);
yuuji@0 593 fflush (stdout);
yuuji@0 594 fgets (tmp,MAILTMPLEN-1,stdin);
yuuji@0 595 if (s = strchr (tmp,'\n')) *s = '\0';
yuuji@0 596 }
yuuji@0 597 if (ndst) fs_give ((void **) &ndst);
yuuji@0 598 ndst = cpystr (tmp);
yuuji@0 599 break;
yuuji@0 600 case mSUFFIX: /* try again with new suffix */
yuuji@0 601 if (ndst) fs_give ((void **) &ndst);
yuuji@0 602 sprintf (ndst = (char *) fs_get (strlen (dst) + strlen (suffix) + 1),
yuuji@0 603 "%s%s",dst,suffix);
yuuji@0 604 printf ("retry to create %s\n",ndst);
yuuji@0 605 mode = mPROMPT; /* switch to prompt mode if name fails */
yuuji@0 606 break;
yuuji@0 607 case NIL: /* not merging */
yuuji@0 608 return NIL;
yuuji@0 609 }
yuuji@0 610 if (ndst) dst = ndst; /* if alternative name given, use it */
yuuji@0 611 }
yuuji@0 612
yuuji@0 613 if (kwcopyp) {
yuuji@0 614 int i;
yuuji@0 615 size_t len;
yuuji@0 616 char *dummymsg = "Date: Thu, 18 May 2006 00:00 -0700\r\nFrom: dummy@example.com\r\nSubject: dummy\r\n\r\ndummy\r\n";
yuuji@0 617 for (i = 0,len = 0; i < NUSERFLAGS; ++i)
yuuji@0 618 if (source->user_flags[i]) len += strlen (source->user_flags[i]) + 1;
yuuji@0 619 if (len) { /* easy if no user flags to copy... */
yuuji@0 620 char *t;
yuuji@0 621 char *tail = "\\Deleted)";
yuuji@0 622 char *flags = (char *) fs_get (1 + len + strlen (tail) + 1);
yuuji@0 623 s = flags; *s++ = '(';
yuuji@0 624 for (i = 0; i < NUSERFLAGS; ++i) if (t = source->user_flags[i]) {
yuuji@0 625 while (*t) *s++ = *t++;
yuuji@0 626 *s++ = ' ';
yuuji@0 627 }
yuuji@0 628 strcpy (s,tail); /* terminate flags list */
yuuji@0 629 if ((dst[0] == '#') && ((dst[1] == 'D') || (dst[1] == 'd')) &&
yuuji@0 630 ((dst[2] == 'R') || (dst[2] == 'r')) &&
yuuji@0 631 ((dst[3] == 'I') || (dst[3] == 'i')) &&
yuuji@0 632 ((dst[4] == 'V') || (dst[4] == 'v')) &&
yuuji@0 633 ((dst[5] == 'E') || (dst[5] == 'e')) &&
yuuji@0 634 ((dst[6] == 'R') || (dst[6] == 'r')) && (dst[7] == '.') &&
yuuji@0 635 (t = strchr (dst+8,'/'))) ++t;
yuuji@0 636 else t = dst;
yuuji@0 637 INIT (&st,mail_string,dummymsg,strlen (dummymsg));
yuuji@0 638 if (!(mail_append (dest,dst,&st) &&
yuuji@0 639 (dest = mail_open (dest,t,debugp ? OP_DEBUG : NIL)))) {
yuuji@0 640 fs_give ((void **) &flags);
yuuji@0 641 return NIL;
yuuji@0 642 }
yuuji@0 643 mail_setflag (dest,"*",flags);
yuuji@0 644 mail_expunge (dest);
yuuji@0 645 fs_give ((void **) &flags);
yuuji@0 646 }
yuuji@0 647 }
yuuji@0 648
yuuji@0 649 if (source->nmsgs) { /* non-empty source */
yuuji@0 650 if (verbosep) printf ("%s [%lu message(s)] => %s\n",
yuuji@0 651 source->mailbox,source->nmsgs,dst);
yuuji@0 652 ap.stream = source; /* prepare append package */
yuuji@0 653 ap.msgno = 0;
yuuji@0 654 ap.msgmax = source->nmsgs;
yuuji@0 655 ap.flags = ap.date = NIL;
yuuji@0 656 ap.message = &st;
yuuji@0 657 /* make sure we have all messages */
yuuji@0 658 sprintf (tmp,"1:%lu",ap.msgmax);
yuuji@0 659 mail_fetchfast (source,tmp);
yuuji@0 660 if (mail_append_multiple (dest,dst,mm_append,(void *) &ap)) {
yuuji@0 661 --ap.msgno; /* make sure user knows it won */
yuuji@0 662 if (verbosep) printf ("[Ok %lu messages(s)]\n",ap.msgno);
yuuji@0 663 if (del && ap.msgno) { /* delete source messages */
yuuji@0 664 sprintf (tmp,"1:%lu",ap.msgno);
yuuji@0 665 mail_flag (source,tmp,"\\Deleted",ST_SET);
yuuji@0 666 /* flush moved messages */
yuuji@0 667 mail_expunge (source);
yuuji@0 668 }
yuuji@0 669 ret = T;
yuuji@0 670 }
yuuji@0 671 else if ((mode == mAPPEND) && trycreate)
yuuji@0 672 ret = mbxcopy (source,dest,dst,create,del,mPROMPT);
yuuji@0 673 else if (verbosep) puts ("[Failed]");
yuuji@0 674 }
yuuji@0 675 else { /* empty source */
yuuji@0 676 if (verbosep) printf ("%s [empty] => %s\n",source->mailbox,dst);
yuuji@0 677 ret = T;
yuuji@0 678 }
yuuji@0 679 if (ndst) fs_give ((void **) &ndst);
yuuji@0 680 return ret;
yuuji@0 681 }
yuuji@0 682
yuuji@0 683 /* Append callback
yuuji@0 684 * Accepts: mail stream
yuuji@0 685 * append package
yuuji@0 686 * pointer to return flags
yuuji@0 687 * pointer to return date
yuuji@0 688 * pointer to return message stringstruct
yuuji@0 689 * Returns: T on success
yuuji@0 690 */
yuuji@0 691
yuuji@0 692 long mm_append (MAILSTREAM *stream,void *data,char **flags,char **date,
yuuji@0 693 STRING **message)
yuuji@0 694 {
yuuji@0 695 char *t,*t1,tmp[MAILTMPLEN];
yuuji@0 696 unsigned long u;
yuuji@0 697 MESSAGECACHE *elt;
yuuji@0 698 APPENDPACKAGE *ap = (APPENDPACKAGE *) data;
yuuji@0 699 *flags = *date = NIL; /* assume no flags or date */
yuuji@0 700 if (ap->flags) fs_give ((void **) &ap->flags);
yuuji@0 701 if (ap->date) fs_give ((void **) &ap->date);
yuuji@0 702 mail_gc (ap->stream,GC_TEXTS);
yuuji@0 703 if (++ap->msgno <= ap->msgmax) {
yuuji@0 704 /* initialize flag string */
yuuji@0 705 memset (t = tmp,0,MAILTMPLEN);
yuuji@0 706 /* output system flags */
yuuji@0 707 if ((elt = mail_elt (ap->stream,ap->msgno))->seen) strcat (t," \\Seen");
yuuji@0 708 if (elt->deleted) strcat (t," \\Deleted");
yuuji@0 709 if (elt->flagged) strcat (t," \\Flagged");
yuuji@0 710 if (elt->answered) strcat (t," \\Answered");
yuuji@0 711 if (elt->draft) strcat (t," \\Draft");
yuuji@0 712 /* any user flags? */
yuuji@0 713 if (!ignorep && (u = elt->user_flags)) do
yuuji@0 714 if ((t1 = ap->stream->user_flags[find_rightmost_bit (&u)]) &&
yuuji@0 715 (MAILTMPLEN - ((t += strlen (t)) - tmp)) > (long) (2 + strlen (t1))){
yuuji@0 716 *t++ = ' '; /* space delimiter */
yuuji@0 717 strcpy (t,t1); /* copy the user flag */
yuuji@0 718 }
yuuji@0 719 while (u); /* until no more user flags */
yuuji@0 720 *flags = ap->flags = cpystr (tmp + 1);
yuuji@0 721 *date = ap->date = cpystr (mail_date (tmp,elt));
yuuji@0 722 *message = ap->message; /* message stringstruct */
yuuji@0 723 INIT (ap->message,mstring,(void *) ap,elt->rfc822_size);
yuuji@0 724 }
yuuji@0 725 else *message = NIL; /* all done */
yuuji@0 726 return LONGT;
yuuji@0 727 }
yuuji@0 728
yuuji@0 729 /* Co-routines from MAIL library */
yuuji@0 730
yuuji@0 731
yuuji@0 732 /* Message matches a search
yuuji@0 733 * Accepts: MAIL stream
yuuji@0 734 * message number
yuuji@0 735 */
yuuji@0 736
yuuji@0 737 void mm_searched (MAILSTREAM *stream,unsigned long msgno)
yuuji@0 738 {
yuuji@0 739 /* dummy routine */
yuuji@0 740 }
yuuji@0 741
yuuji@0 742
yuuji@0 743 /* Message exists (i.e. there are that many messages in the mailbox)
yuuji@0 744 * Accepts: MAIL stream
yuuji@0 745 * message number
yuuji@0 746 */
yuuji@0 747
yuuji@0 748 void mm_exists (MAILSTREAM *stream,unsigned long number)
yuuji@0 749 {
yuuji@0 750 /* dummy routine */
yuuji@0 751 }
yuuji@0 752
yuuji@0 753
yuuji@0 754 /* Message expunged
yuuji@0 755 * Accepts: MAIL stream
yuuji@0 756 * message number
yuuji@0 757 */
yuuji@0 758
yuuji@0 759 void mm_expunged (MAILSTREAM *stream,unsigned long number)
yuuji@0 760 {
yuuji@0 761 /* dummy routine */
yuuji@0 762 }
yuuji@0 763
yuuji@0 764
yuuji@0 765 /* Message flags update seen
yuuji@0 766 * Accepts: MAIL stream
yuuji@0 767 * message number
yuuji@0 768 */
yuuji@0 769
yuuji@0 770 void mm_flags (MAILSTREAM *stream,unsigned long number)
yuuji@0 771 {
yuuji@0 772 /* dummy routine */
yuuji@0 773 }
yuuji@0 774
yuuji@0 775 /* Mailbox found
yuuji@0 776 * Accepts: MAIL stream
yuuji@0 777 * hierarchy delimiter
yuuji@0 778 * mailbox name
yuuji@0 779 * mailbox attributes
yuuji@0 780 */
yuuji@0 781
yuuji@0 782 void mm_list (MAILSTREAM *stream,int delimiter,char *name,long attributes)
yuuji@0 783 {
yuuji@0 784 /* note destination delimiter */
yuuji@0 785 if (ddelim < 0) ddelim = delimiter;
yuuji@0 786 /* if got a selectable name */
yuuji@0 787 else if (!(attributes & LATT_NOSELECT) && *name)
yuuji@0 788 fprintf (f,"%c%s\n",delimiter,name);
yuuji@0 789 }
yuuji@0 790
yuuji@0 791
yuuji@0 792 /* Subscribe mailbox found
yuuji@0 793 * Accepts: MAIL stream
yuuji@0 794 * hierarchy delimiter
yuuji@0 795 * mailbox name
yuuji@0 796 * mailbox attributes
yuuji@0 797 */
yuuji@0 798
yuuji@0 799 void mm_lsub (MAILSTREAM *stream,int delimiter,char *name,long attributes)
yuuji@0 800 {
yuuji@0 801 /* dummy routine */
yuuji@0 802 }
yuuji@0 803
yuuji@0 804
yuuji@0 805 /* Mailbox status
yuuji@0 806 * Accepts: MAIL stream
yuuji@0 807 * mailbox name
yuuji@0 808 * mailbox status
yuuji@0 809 */
yuuji@0 810
yuuji@0 811 void mm_status (MAILSTREAM *stream,char *mailbox,MAILSTATUS *status)
yuuji@0 812 {
yuuji@0 813 if (status->recent || status->unseen)
yuuji@0 814 printf ("%lu new message(s) (%lu unseen),",status->recent,status->unseen);
yuuji@0 815 else fputs ("No new messages,",stdout);
yuuji@0 816 printf (" %lu total in %s\n",status->messages,mailbox);
yuuji@0 817 }
yuuji@0 818
yuuji@0 819 /* Notification event
yuuji@0 820 * Accepts: MAIL stream
yuuji@0 821 * string to log
yuuji@0 822 * error flag
yuuji@0 823 */
yuuji@0 824
yuuji@0 825 void mm_notify (MAILSTREAM *stream,char *string,long errflg)
yuuji@0 826 {
yuuji@0 827 if (!errflg && (string[0] == '[') &&
yuuji@0 828 ((string[1] == 'T') || (string[1] == 't')) &&
yuuji@0 829 ((string[2] == 'R') || (string[2] == 'r')) &&
yuuji@0 830 ((string[3] == 'Y') || (string[3] == 'y')) &&
yuuji@0 831 ((string[4] == 'C') || (string[4] == 'c')) &&
yuuji@0 832 ((string[5] == 'R') || (string[5] == 'r')) &&
yuuji@0 833 ((string[6] == 'E') || (string[6] == 'e')) &&
yuuji@0 834 ((string[7] == 'A') || (string[7] == 'a')) &&
yuuji@0 835 ((string[8] == 'T') || (string[8] == 't')) &&
yuuji@0 836 ((string[9] == 'E') || (string[9] == 'e')) &&
yuuji@0 837 (string[10] == ']'))
yuuji@0 838 trycreate = T;
yuuji@0 839 mm_log (string,errflg); /* just do mm_log action */
yuuji@0 840 }
yuuji@0 841
yuuji@0 842
yuuji@0 843 /* Log an event for the user to see
yuuji@0 844 * Accepts: string to log
yuuji@0 845 * error flag
yuuji@0 846 */
yuuji@0 847
yuuji@0 848 void mm_log (char *string,long errflg)
yuuji@0 849 {
yuuji@0 850 switch (errflg) {
yuuji@0 851 case BYE:
yuuji@0 852 case NIL: /* no error */
yuuji@0 853 if (verbosep) fprintf (stderr,"[%s]\n",string);
yuuji@0 854 break;
yuuji@0 855 case PARSE: /* parsing problem */
yuuji@0 856 case WARN: /* warning */
yuuji@0 857 fprintf (stderr,"warning: %s\n",string);
yuuji@0 858 break;
yuuji@0 859 case ERROR: /* error */
yuuji@0 860 default:
yuuji@0 861 fprintf (stderr,"%s\n",string);
yuuji@0 862 break;
yuuji@0 863 }
yuuji@0 864 }
yuuji@0 865
yuuji@0 866
yuuji@0 867 /* Log an event to debugging telemetry
yuuji@0 868 * Accepts: string to log
yuuji@0 869 */
yuuji@0 870
yuuji@0 871 void mm_dlog (char *string)
yuuji@0 872 {
yuuji@0 873 fprintf (stderr,"%s\n",string);
yuuji@0 874 }
yuuji@0 875
yuuji@0 876 /* Get user name and password for this host
yuuji@0 877 * Accepts: parse of network mailbox name
yuuji@0 878 * where to return user name
yuuji@0 879 * where to return password
yuuji@0 880 * trial count
yuuji@0 881 */
yuuji@0 882
yuuji@0 883 void mm_login (NETMBX *mb,char *username,char *password,long trial)
yuuji@0 884 {
yuuji@0 885 char *s,tmp[MAILTMPLEN];
yuuji@0 886 sprintf (s = tmp,"{%s/%s",mb->host,mb->service);
yuuji@0 887 if (*mb->user) sprintf (tmp+strlen (tmp),"/user=%s",
yuuji@0 888 strcpy (username,mb->user));
yuuji@0 889 if (*mb->authuser) sprintf (tmp+strlen (tmp),"/authuser=%s",mb->authuser);
yuuji@0 890 if (*mb->user) strcat (s = tmp,"} password:");
yuuji@0 891 else {
yuuji@0 892 printf ("%s} username: ",tmp);
yuuji@0 893 fgets (username,NETMAXUSER-1,stdin);
yuuji@0 894 username[NETMAXUSER-1] = '\0';
yuuji@0 895 if (s = strchr (username,'\n')) *s = '\0';
yuuji@0 896 s = "password: ";
yuuji@0 897 }
yuuji@0 898 strcpy (password,getpass (s));
yuuji@0 899 }
yuuji@0 900
yuuji@0 901
yuuji@0 902 /* About to enter critical code
yuuji@0 903 * Accepts: stream
yuuji@0 904 */
yuuji@0 905
yuuji@0 906 void mm_critical (MAILSTREAM *stream)
yuuji@0 907 {
yuuji@0 908 critical = T; /* note in critical code */
yuuji@0 909 }
yuuji@0 910
yuuji@0 911
yuuji@0 912 /* About to exit critical code
yuuji@0 913 * Accepts: stream
yuuji@0 914 */
yuuji@0 915
yuuji@0 916 void mm_nocritical (MAILSTREAM *stream)
yuuji@0 917 {
yuuji@0 918 critical = NIL; /* note not in critical code */
yuuji@0 919 }
yuuji@0 920
yuuji@0 921
yuuji@0 922 /* Disk error found
yuuji@0 923 * Accepts: stream
yuuji@0 924 * system error code
yuuji@0 925 * flag indicating that mailbox may be clobbered
yuuji@0 926 * Returns: T if user wants to abort
yuuji@0 927 */
yuuji@0 928
yuuji@0 929 long mm_diskerror (MAILSTREAM *stream,long errcode,long serious)
yuuji@0 930 {
yuuji@0 931 return T;
yuuji@0 932 }
yuuji@0 933
yuuji@0 934
yuuji@0 935 /* Log a fatal error event
yuuji@0 936 * Accepts: string to log
yuuji@0 937 */
yuuji@0 938
yuuji@0 939 void mm_fatal (char *string)
yuuji@0 940 {
yuuji@0 941 fprintf (stderr,"FATAL: %s\n",string);
yuuji@0 942 }

UW-IMAP'd extensions by yuuji