imapext-2007
diff src/ipopd/ipop2d.c @ 0:ada5e610ab86
imap-2007e
author | yuuji@gentei.org |
---|---|
date | Mon, 14 Sep 2009 15:17:45 +0900 |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/ipopd/ipop2d.c Mon Sep 14 15:17:45 2009 +0900 1.3 @@ -0,0 +1,711 @@ 1.4 +/* ======================================================================== 1.5 + * Copyright 1988-2008 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: IPOP2D - IMAP to POP2 conversion server 1.19 + * 1.20 + * Author: Mark Crispin 1.21 + * UW Technology 1.22 + * University of Washington 1.23 + * Seattle, WA 98195 1.24 + * Internet: MRC@Washington.EDU 1.25 + * 1.26 + * Date: 28 October 1990 1.27 + * Last Edited: 13 February 2008 1.28 + */ 1.29 + 1.30 + 1.31 +/* Parameter files */ 1.32 + 1.33 +#include <stdio.h> 1.34 +#include <ctype.h> 1.35 +#include <errno.h> 1.36 +extern int errno; /* just in case */ 1.37 +#include <signal.h> 1.38 +#include <time.h> 1.39 +#include "c-client.h" 1.40 + 1.41 + 1.42 +/* Autologout timer */ 1.43 +#define KODTIMEOUT 60*5 1.44 +#define LOGINTIMEOUT 60*3 1.45 +#define TIMEOUT 60*30 1.46 + 1.47 + 1.48 +/* Size of temporary buffers */ 1.49 +#define TMPLEN 1024 1.50 + 1.51 + 1.52 +/* Server states */ 1.53 + 1.54 +#define LISN 0 1.55 +#define AUTH 1 1.56 +#define MBOX 2 1.57 +#define ITEM 3 1.58 +#define NEXT 4 1.59 +#define DONE 5 1.60 + 1.61 +/* Global storage */ 1.62 + 1.63 +char *version = "75"; /* edit number of this server */ 1.64 +short state = LISN; /* server state */ 1.65 +short critical = NIL; /* non-zero if in critical code */ 1.66 +MAILSTREAM *stream = NIL; /* mailbox stream */ 1.67 +time_t idletime = 0; /* time we went idle */ 1.68 +unsigned long nmsgs = 0; /* number of messages */ 1.69 +unsigned long current = 1; /* current message number */ 1.70 +unsigned long size = 0; /* size of current message */ 1.71 +char status[MAILTMPLEN]; /* space for status string */ 1.72 +char *user = ""; /* user name */ 1.73 +char *pass = ""; /* password */ 1.74 +unsigned long *msg = NIL; /* message translation vector */ 1.75 +char *logout = "Logout"; 1.76 +char *goodbye = "+ Sayonara\015\012"; 1.77 + 1.78 + 1.79 +/* Function prototypes */ 1.80 + 1.81 +int main (int argc,char *argv[]); 1.82 +void sayonara (int status); 1.83 +void clkint (); 1.84 +void kodint (); 1.85 +void hupint (); 1.86 +void trmint (); 1.87 +short c_helo (char *t,int argc,char *argv[]); 1.88 +short c_fold (char *t); 1.89 +short c_read (char *t); 1.90 +short c_retr (char *t); 1.91 +short c_acks (char *t); 1.92 +short c_ackd (char *t); 1.93 +short c_nack (char *t); 1.94 + 1.95 +/* Main program */ 1.96 + 1.97 +int main (int argc,char *argv[]) 1.98 +{ 1.99 + char *s,*t; 1.100 + char cmdbuf[TMPLEN]; 1.101 + char *pgmname = (argc && argv[0]) ? 1.102 + (((s = strrchr (argv[0],'/')) || (s = strrchr (argv[0],'\\'))) ? 1.103 + s+1 : argv[0]) : "ipop2d"; 1.104 + /* set service name before linkage */ 1.105 + mail_parameters (NIL,SET_SERVICENAME,(void *) "pop"); 1.106 +#include "linkage.c" 1.107 + if (mail_parameters (NIL,GET_DISABLEPLAINTEXT,NIL)) { 1.108 + goodbye = "- POP2 server disabled on this system\015\012"; 1.109 + sayonara (1); 1.110 + } 1.111 + /* initialize server */ 1.112 + server_init (pgmname,"pop",NIL,clkint,kodint,hupint,trmint,NIL); 1.113 + /* There are reports of POP2 clients which get upset if anything appears 1.114 + * between the "+" and the "POP2" in the greeting. 1.115 + */ 1.116 + printf ("+ POP2 %s %s.%s server ready\015\012",tcp_serverhost (), 1.117 + CCLIENTVERSION,version); 1.118 + fflush (stdout); /* dump output buffer */ 1.119 + state = AUTH; /* initial server state */ 1.120 + while (state != DONE) { /* command processing loop */ 1.121 + idletime = time (0); /* get a command under timeout */ 1.122 + alarm ((state != AUTH) ? TIMEOUT : LOGINTIMEOUT); 1.123 + clearerr (stdin); /* clear stdin errors */ 1.124 + while (!fgets (cmdbuf,TMPLEN-1,stdin)) { 1.125 + if (ferror (stdin) && (errno == EINTR)) clearerr (stdin); 1.126 + else { 1.127 + char *e = ferror (stdin) ? 1.128 + strerror (errno) : "Unexpected client disconnect"; 1.129 + alarm (0); /* disable all interrupts */ 1.130 + server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN); 1.131 + sprintf (logout = cmdbuf,"%.80s while reading line",e); 1.132 + state = DONE; 1.133 + stream = mail_close (stream); 1.134 + goodbye = NIL; 1.135 + sayonara (1); 1.136 + } 1.137 + } 1.138 + alarm (0); /* make sure timeout disabled */ 1.139 + idletime = 0; /* no longer idle */ 1.140 + /* find end of line */ 1.141 + if (!strchr (cmdbuf,'\012')) { 1.142 + server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN); 1.143 + logout = "- Command line too long\015\012"; 1.144 + state = DONE; 1.145 + } 1.146 + else if (!(s = strtok (cmdbuf," \015\012"))) { 1.147 + server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN); 1.148 + goodbye = "- Missing or null command\015\012"; 1.149 + state = DONE; 1.150 + } 1.151 + else { /* dispatch based on command */ 1.152 + ucase (s); /* canonicalize case */ 1.153 + /* snarf argument */ 1.154 + t = strtok (NIL,"\015\012"); 1.155 + if ((state == AUTH) && !strcmp (s,"HELO")) state = c_helo (t,argc,argv); 1.156 + else if ((state == MBOX || state == ITEM) && !strcmp (s,"FOLD")) 1.157 + state = c_fold (t); 1.158 + else if ((state == MBOX || state == ITEM) && !strcmp (s,"READ")) 1.159 + state = c_read (t); 1.160 + else if ((state == ITEM) && !strcmp (s,"RETR")) state = c_retr (t); 1.161 + else if ((state == NEXT) && !strcmp (s,"ACKS")) state = c_acks (t); 1.162 + else if ((state == NEXT) && !strcmp (s,"ACKD")) state = c_ackd (t); 1.163 + else if ((state == NEXT) && !strcmp (s,"NACK")) state = c_nack (t); 1.164 + else if ((state == AUTH || state == MBOX || state == ITEM) && 1.165 + !strcmp (s,"QUIT")) { 1.166 + server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN); 1.167 + state = DONE; /* done in either case */ 1.168 + if (t) goodbye = "- Bogus argument given to QUIT\015\012"; 1.169 + else { /* expunge the stream */ 1.170 + if (stream && nmsgs) stream = mail_close_full (stream,CL_EXPUNGE); 1.171 + stream = NIL; /* don't repeat it */ 1.172 + } 1.173 + } 1.174 + else { /* some other or inappropriate command */ 1.175 + server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN); 1.176 + goodbye = "- Bogus or out of sequence command\015\012"; 1.177 + state = DONE; 1.178 + } 1.179 + } 1.180 + fflush (stdout); /* make sure output blatted */ 1.181 + } 1.182 + /* clean up the stream */ 1.183 + if (stream) mail_close (stream); 1.184 + sayonara (0); 1.185 + return 0; /* stupid compilers */ 1.186 +} 1.187 + 1.188 + 1.189 +/* Say goodbye 1.190 + * Accepts: exit status 1.191 + * 1.192 + * Does not return 1.193 + */ 1.194 + 1.195 +void sayonara (int status) 1.196 +{ 1.197 + logouthook_t lgoh = (logouthook_t) mail_parameters (NIL,GET_LOGOUTHOOK,NIL); 1.198 + if (goodbye) { /* have a goodbye message? */ 1.199 + fputs (goodbye,stdout); 1.200 + fflush (stdout); /* make sure blatted */ 1.201 + } 1.202 + syslog (LOG_INFO,"%s user=%.80s host=%.80s",logout, 1.203 + user ? (char *) user : "???",tcp_clienthost ()); 1.204 + /* do logout hook if needed */ 1.205 + if (lgoh) (*lgoh) (mail_parameters (NIL,GET_LOGOUTDATA,NIL)); 1.206 + _exit (status); /* all done */ 1.207 +} 1.208 + 1.209 +/* Clock interrupt 1.210 + */ 1.211 + 1.212 +void clkint () 1.213 +{ 1.214 + alarm (0); /* disable all interrupts */ 1.215 + server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN); 1.216 + goodbye = "- Autologout; idle for too long\015\012"; 1.217 + logout = "Autologout"; 1.218 + state = DONE; /* mark state done in either case */ 1.219 + if (!critical) { /* badly host if in critical code */ 1.220 + if (stream && !stream->lock) mail_close (stream); 1.221 + stream = NIL; 1.222 + sayonara (1); /* die die die */ 1.223 + } 1.224 +} 1.225 + 1.226 + 1.227 +/* Kiss Of Death interrupt 1.228 + */ 1.229 + 1.230 +void kodint () 1.231 +{ 1.232 + /* only if in command wait */ 1.233 + if (idletime && ((time (0) - idletime) > KODTIMEOUT)) { 1.234 + alarm (0); /* disable all interrupts */ 1.235 + server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN); 1.236 + goodbye = "- Killed (lost mailbox lock)\015\012"; 1.237 + logout = "Killed (lost mailbox lock)"; 1.238 + state = DONE; /* mark state done in either case */ 1.239 + if (!critical) { /* badly host if in critical code */ 1.240 + if (stream && !stream->lock) mail_close (stream); 1.241 + stream = NIL; 1.242 + sayonara (1); /* die die die */ 1.243 + } 1.244 + } 1.245 +} 1.246 + 1.247 + 1.248 +/* Hangup interrupt 1.249 + */ 1.250 + 1.251 +void hupint () 1.252 +{ 1.253 + alarm (0); /* disable all interrupts */ 1.254 + server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN); 1.255 + goodbye = NIL; 1.256 + logout = "Hangup"; 1.257 + state = DONE; /* mark state done in either case */ 1.258 + if (!critical) { /* badly host if in critical code */ 1.259 + if (stream && !stream->lock) mail_close (stream); 1.260 + stream = NIL; 1.261 + sayonara (1); /* die die die */ 1.262 + } 1.263 +} 1.264 + 1.265 + 1.266 +/* Termination interrupt 1.267 + */ 1.268 + 1.269 +void trmint () 1.270 +{ 1.271 + alarm (0); /* disable all interrupts */ 1.272 + server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN); 1.273 + goodbye = "- Killed (terminated)\015\012"; 1.274 + logout = "Killed (terminated)"; 1.275 + if (critical) state = DONE; /* mark state done in either case */ 1.276 + /* Make no attempt at graceful closure since a shutdown may be in 1.277 + * progress, and we won't have any time to do mail_close() actions. 1.278 + */ 1.279 + else sayonara (1); /* die die die */ 1.280 +} 1.281 + 1.282 +/* Parse HELO command 1.283 + * Accepts: pointer to command argument 1.284 + * Returns: new state 1.285 + */ 1.286 + 1.287 +short c_helo (char *t,int argc,char *argv[]) 1.288 +{ 1.289 + char *s,*u,*p; 1.290 + char tmp[TMPLEN]; 1.291 + if ((!(t && *t && (u = strtok (t," ")) && (p = strtok (NIL,"\015\012")))) || 1.292 + (strlen (p) >= TMPLEN)) { /* get user name and password */ 1.293 + fputs ("- Missing user or password\015\012",stdout); 1.294 + return DONE; 1.295 + } 1.296 + /* copy password, handle quoting */ 1.297 + for (s = tmp; *p; p++) *s++ = (*p == '\\') ? *++p : *p; 1.298 + *s = '\0'; /* tie off string */ 1.299 + pass = cpystr (tmp); 1.300 + if (!(s = strchr (u,':'))) { /* want remote mailbox? */ 1.301 + /* no, delimit user from possible admin */ 1.302 + if (s = strchr (u,'*')) *s++ = '\0'; 1.303 + if (server_login (user = cpystr (u),pass,s,argc,argv)) { 1.304 + syslog (LOG_INFO,"%sLogin user=%.80s host=%.80s",s ? "Admin " : "", 1.305 + user,tcp_clienthost ()); 1.306 + return c_fold ("INBOX"); /* local; select INBOX */ 1.307 + } 1.308 + } 1.309 +#ifndef DISABLE_POP_PROXY 1.310 + /* can't do if can't log in as anonymous */ 1.311 + else if (anonymous_login (argc,argv)) { 1.312 + *s++ = '\0'; /* separate host name from user name */ 1.313 + user = cpystr (s); /* note user name */ 1.314 + syslog (LOG_INFO,"IMAP login to host=%.80s user=%.80s host=%.80s",u,user, 1.315 + tcp_clienthost ()); 1.316 + /* initially remote INBOX */ 1.317 + sprintf (tmp,"{%.128s/user=%.128s}INBOX",u,user); 1.318 + /* disable rimap just in case */ 1.319 + mail_parameters (NIL,SET_RSHTIMEOUT,0); 1.320 + return c_fold (tmp); 1.321 + } 1.322 +#endif 1.323 + fputs ("- Bad login\015\012",stdout); 1.324 + return DONE; 1.325 +} 1.326 + 1.327 +/* Parse FOLD command 1.328 + * Accepts: pointer to command argument 1.329 + * Returns: new state 1.330 + */ 1.331 + 1.332 +short c_fold (char *t) 1.333 +{ 1.334 + unsigned long i,j,flags; 1.335 + char *s = NIL,tmp[2*TMPLEN]; 1.336 + NETMBX mb; 1.337 + if (!(t && *t)) { /* make sure there's an argument */ 1.338 + fputs ("- Missing mailbox name\015\012",stdout); 1.339 + return DONE; 1.340 + } 1.341 + myusername_full (&flags); /* get user type flags */ 1.342 + /* expunge old stream */ 1.343 + if (stream && nmsgs) mail_expunge (stream); 1.344 + nmsgs = 0; /* no more messages */ 1.345 + if (msg) fs_give ((void **) &msg); 1.346 +#ifndef DISABLE_POP_PROXY 1.347 + if (flags == MU_ANONYMOUS) { /* don't permit proxy to leave IMAP */ 1.348 + if (stream) { /* not first time */ 1.349 + if (!(stream->mailbox && (s = strchr (stream->mailbox,'}')))) 1.350 + fatal ("bad previous mailbox name"); 1.351 + strncpy (tmp,stream->mailbox,i = (++s - stream->mailbox)); 1.352 + if (i >= TMPLEN) fatal ("ridiculous network prefix"); 1.353 + strcpy (tmp+i,t); /* append mailbox to initial spec */ 1.354 + t = tmp; 1.355 + } 1.356 + /* must be net name first time */ 1.357 + else if (!mail_valid_net_parse (t,&mb)) fatal ("anonymous folder bogon"); 1.358 + } 1.359 +#endif 1.360 + /* open mailbox, note # of messages */ 1.361 + if (j = (stream = mail_open (stream,t,NIL)) ? stream->nmsgs : 0) { 1.362 + sprintf (tmp,"1:%lu",j); /* fetch fast information for all messages */ 1.363 + mail_fetch_fast (stream,tmp,NIL); 1.364 + msg = (unsigned long *) fs_get ((stream->nmsgs + 1) * 1.365 + sizeof (unsigned long)); 1.366 + for (i = 1; i <= j; i++) /* find undeleted messages, add to vector */ 1.367 + if (!mail_elt (stream,i)->deleted) msg[++nmsgs] = i; 1.368 + } 1.369 +#ifndef DISABLE_POP_PROXY 1.370 + if (!stream && (flags == MU_ANONYMOUS)) { 1.371 + fputs ("- Bad login\015\012",stdout); 1.372 + return DONE; 1.373 + } 1.374 +#endif 1.375 + printf ("#%lu messages in %s\015\012",nmsgs,stream ? stream->mailbox : 1.376 + "<none>"); 1.377 + return MBOX; 1.378 +} 1.379 + 1.380 +/* Parse READ command 1.381 + * Accepts: pointer to command argument 1.382 + * Returns: new state 1.383 + */ 1.384 + 1.385 +short c_read (char *t) 1.386 +{ 1.387 + MESSAGECACHE *elt = NIL; 1.388 + if (t && *t) { /* have a message number argument? */ 1.389 + /* validity check message number */ 1.390 + if (((current = strtoul (t,NIL,10)) < 1) || (current > nmsgs)) { 1.391 + fputs ("- Invalid message number given to READ\015\012",stdout); 1.392 + return DONE; 1.393 + } 1.394 + } 1.395 + else if (current > nmsgs) { /* at end of mailbox? */ 1.396 + fputs ("=0 No more messages\015\012",stdout); 1.397 + return MBOX; 1.398 + } 1.399 + /* set size if message valid and exists */ 1.400 + size = msg[current] ? (elt = mail_elt(stream,msg[current]))->rfc822_size : 0; 1.401 + if (elt) sprintf (status,"Status: %s%s\015\012", 1.402 + elt->seen ? "R" : " ",elt->recent ? " " : "O"); 1.403 + else status[0] = '\0'; /* no status */ 1.404 + size += strlen (status); /* update size to reflect status */ 1.405 + /* display results */ 1.406 + printf ("=%lu characters in message %lu\015\012",size + 2,current); 1.407 + return ITEM; 1.408 +} 1.409 + 1.410 + 1.411 +/* Parse RETR command 1.412 + * Accepts: pointer to command argument 1.413 + * Returns: new state 1.414 + */ 1.415 + 1.416 +short c_retr (char *t) 1.417 +{ 1.418 + unsigned long i,j; 1.419 + STRING *bs; 1.420 + if (t) { /* disallow argument */ 1.421 + fputs ("- Bogus argument given to RETR\015\012",stdout); 1.422 + return DONE; 1.423 + } 1.424 + if (size) { /* message size valid? */ 1.425 + t = mail_fetch_header (stream,msg[current],NIL,NIL,&i,FT_PEEK); 1.426 + if (i > 2) { /* only if there is something */ 1.427 + i -= 2; /* lop off last two octets */ 1.428 + while (i) { /* blat the header */ 1.429 + if (!(j = fwrite (t,sizeof (char),i,stdout))) return DONE; 1.430 + if (i -= j) t += j; /* advance to incomplete data */ 1.431 + } 1.432 + } 1.433 + fputs (status,stdout); /* yes, output message */ 1.434 + fputs ("\015\012",stdout); /* delimit header from text */ 1.435 + if (t = mail_fetch_text (stream,msg[current],NIL,&i,FT_RETURNSTRINGSTRUCT)) 1.436 + while (i) { /* blat the text */ 1.437 + if (!(j = fwrite (t,sizeof (char),i,stdout))) return DONE; 1.438 + if (i -= j) t += j; /* advance to incomplete data */ 1.439 + } 1.440 + else for (bs = &stream->private.string; i--; ) 1.441 + if (putc (SNX (bs),stdout) == EOF) return DONE; 1.442 + fputs ("\015\012",stdout); /* trailer to coddle PCNFS' NFSMAIL */ 1.443 + } 1.444 + else return DONE; /* otherwise go away */ 1.445 + return NEXT; 1.446 +} 1.447 + 1.448 +/* Parse ACKS command 1.449 + * Accepts: pointer to command argument 1.450 + * Returns: new state 1.451 + */ 1.452 + 1.453 +short c_acks (char *t) 1.454 +{ 1.455 + char tmp[TMPLEN]; 1.456 + if (t) { /* disallow argument */ 1.457 + fputs ("- Bogus argument given to ACKS\015\012",stdout); 1.458 + return DONE; 1.459 + } 1.460 + /* mark message as seen */ 1.461 + sprintf (tmp,"%lu",msg[current++]); 1.462 + mail_setflag (stream,tmp,"\\Seen"); 1.463 + return c_read (NIL); /* end message reading transaction */ 1.464 +} 1.465 + 1.466 + 1.467 +/* Parse ACKD command 1.468 + * Accepts: pointer to command argument 1.469 + * Returns: new state 1.470 + */ 1.471 + 1.472 +short c_ackd (char *t) 1.473 +{ 1.474 + char tmp[TMPLEN]; 1.475 + if (t) { /* disallow argument */ 1.476 + fputs ("- Bogus argument given to ACKD\015\012",stdout); 1.477 + return DONE; 1.478 + } 1.479 + /* mark message as seen and deleted */ 1.480 + sprintf (tmp,"%lu",msg[current]); 1.481 + mail_setflag (stream,tmp,"\\Seen \\Deleted"); 1.482 + msg[current++] = 0; /* mark message as deleted */ 1.483 + return c_read (NIL); /* end message reading transaction */ 1.484 +} 1.485 + 1.486 + 1.487 +/* Parse NACK command 1.488 + * Accepts: pointer to command argument 1.489 + * Returns: new state 1.490 + */ 1.491 + 1.492 +short c_nack (char *t) 1.493 +{ 1.494 + if (t) { /* disallow argument */ 1.495 + fputs ("- Bogus argument given to NACK\015\012",stdout); 1.496 + return DONE; 1.497 + } 1.498 + return c_read (NIL); /* end message reading transaction */ 1.499 +} 1.500 + 1.501 +/* Co-routines from MAIL library */ 1.502 + 1.503 + 1.504 +/* Message matches a search 1.505 + * Accepts: MAIL stream 1.506 + * message number 1.507 + */ 1.508 + 1.509 +void mm_searched (MAILSTREAM *stream,unsigned long msgno) 1.510 +{ 1.511 + /* Never called */ 1.512 +} 1.513 + 1.514 + 1.515 +/* Message exists (i.e. there are that many messages in the mailbox) 1.516 + * Accepts: MAIL stream 1.517 + * message number 1.518 + */ 1.519 + 1.520 +void mm_exists (MAILSTREAM *stream,unsigned long number) 1.521 +{ 1.522 + /* Can't use this mechanism. POP has no means of notifying the client of 1.523 + new mail during the session. */ 1.524 +} 1.525 + 1.526 + 1.527 +/* Message expunged 1.528 + * Accepts: MAIL stream 1.529 + * message number 1.530 + */ 1.531 + 1.532 +void mm_expunged (MAILSTREAM *stream,unsigned long number) 1.533 +{ 1.534 + if (state != DONE) { /* ignore if closing */ 1.535 + /* someone else screwed us */ 1.536 + goodbye = "- Mailbox expunged from under me!\015\012"; 1.537 + if (stream && !stream->lock) mail_close (stream); 1.538 + stream = NIL; 1.539 + sayonara (1); 1.540 + } 1.541 +} 1.542 + 1.543 + 1.544 +/* Message status changed 1.545 + * Accepts: MAIL stream 1.546 + * message number 1.547 + */ 1.548 + 1.549 +void mm_flags (MAILSTREAM *stream,unsigned long number) 1.550 +{ 1.551 + /* This isn't used */ 1.552 +} 1.553 + 1.554 + 1.555 +/* Mailbox found 1.556 + * Accepts: MAIL stream 1.557 + * hierarchy delimiter 1.558 + * mailbox name 1.559 + * mailbox attributes 1.560 + */ 1.561 + 1.562 +void mm_list (MAILSTREAM *stream,int delimiter,char *name,long attributes) 1.563 +{ 1.564 + /* This isn't used */ 1.565 +} 1.566 + 1.567 + 1.568 +/* Subscribe mailbox found 1.569 + * Accepts: MAIL stream 1.570 + * hierarchy delimiter 1.571 + * mailbox name 1.572 + * mailbox attributes 1.573 + */ 1.574 + 1.575 +void mm_lsub (MAILSTREAM *stream,int delimiter,char *name,long attributes) 1.576 +{ 1.577 + /* This isn't used */ 1.578 +} 1.579 + 1.580 + 1.581 +/* Mailbox status 1.582 + * Accepts: MAIL stream 1.583 + * mailbox name 1.584 + * mailbox status 1.585 + */ 1.586 + 1.587 +void mm_status (MAILSTREAM *stream,char *mailbox,MAILSTATUS *status) 1.588 +{ 1.589 + /* This isn't used */ 1.590 +} 1.591 + 1.592 +/* Notification event 1.593 + * Accepts: MAIL stream 1.594 + * string to log 1.595 + * error flag 1.596 + */ 1.597 + 1.598 +void mm_notify (MAILSTREAM *stream,char *string,long errflg) 1.599 +{ 1.600 + mm_log (string,errflg); /* just do mm_log action */ 1.601 +} 1.602 + 1.603 + 1.604 +/* Log an event for the user to see 1.605 + * Accepts: string to log 1.606 + * error flag 1.607 + */ 1.608 + 1.609 +void mm_log (char *string,long errflg) 1.610 +{ 1.611 + switch (errflg) { 1.612 + case NIL: /* information message */ 1.613 + case PARSE: /* parse glitch */ 1.614 + break; /* too many of these to log */ 1.615 + case WARN: /* warning */ 1.616 + syslog (LOG_DEBUG,"%s",string); 1.617 + break; 1.618 + case BYE: /* driver broke connection */ 1.619 + if (state != DONE) { 1.620 + char tmp[MAILTMPLEN]; 1.621 + alarm (0); /* disable all interrupts */ 1.622 + server_init (NIL,NIL,NIL,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN,SIG_IGN); 1.623 + sprintf (logout = tmp,"Mailbox closed (%.80s)",string); 1.624 + sayonara (1); 1.625 + } 1.626 + break; 1.627 + case ERROR: /* error that broke command */ 1.628 + default: /* default should never happen */ 1.629 + syslog (LOG_NOTICE,"%s",string); 1.630 + break; 1.631 + } 1.632 +} 1.633 + 1.634 + 1.635 +/* Log an event to debugging telemetry 1.636 + * Accepts: string to log 1.637 + */ 1.638 + 1.639 +void mm_dlog (char *string) 1.640 +{ 1.641 + /* Not doing anything here for now */ 1.642 +} 1.643 + 1.644 + 1.645 +/* Get user name and password for this host 1.646 + * Accepts: parse of network mailbox name 1.647 + * where to return user name 1.648 + * where to return password 1.649 + * trial count 1.650 + */ 1.651 + 1.652 +void mm_login (NETMBX *mb,char *username,char *password,long trial) 1.653 +{ 1.654 + /* set user name */ 1.655 + strncpy (username,*mb->user ? mb->user : user,NETMAXUSER-1); 1.656 + strncpy (password,pass,255); /* and password */ 1.657 + username[NETMAXUSER] = password[255] = '\0'; 1.658 +} 1.659 + 1.660 +/* About to enter critical code 1.661 + * Accepts: stream 1.662 + */ 1.663 + 1.664 +void mm_critical (MAILSTREAM *stream) 1.665 +{ 1.666 + ++critical; 1.667 +} 1.668 + 1.669 + 1.670 +/* About to exit critical code 1.671 + * Accepts: stream 1.672 + */ 1.673 + 1.674 +void mm_nocritical (MAILSTREAM *stream) 1.675 +{ 1.676 + --critical; 1.677 +} 1.678 + 1.679 + 1.680 +/* Disk error found 1.681 + * Accepts: stream 1.682 + * system error code 1.683 + * flag indicating that mailbox may be clobbered 1.684 + * Returns: abort flag 1.685 + */ 1.686 + 1.687 +long mm_diskerror (MAILSTREAM *stream,long errcode,long serious) 1.688 +{ 1.689 + if (serious) { /* try your damnest if clobberage likely */ 1.690 + syslog (LOG_ALERT, 1.691 + "Retrying after disk error user=%.80s host=%.80s mbx=%.80s: %.80s", 1.692 + user,tcp_clienthost (), 1.693 + (stream && stream->mailbox) ? stream->mailbox : "???", 1.694 + strerror (errcode)); 1.695 + alarm (0); /* make damn sure timeout disabled */ 1.696 + sleep (60); /* give it some time to clear up */ 1.697 + return NIL; 1.698 + } 1.699 + syslog (LOG_ALERT,"Fatal disk error user=%.80s host=%.80s mbx=%.80s: %.80s", 1.700 + user,tcp_clienthost (), 1.701 + (stream && stream->mailbox) ? stream->mailbox : "???", 1.702 + strerror (errcode)); 1.703 + return T; 1.704 +} 1.705 + 1.706 + 1.707 +/* Log a fatal error event 1.708 + * Accepts: string to log 1.709 + */ 1.710 + 1.711 +void mm_fatal (char *string) 1.712 +{ 1.713 + mm_log (string,ERROR); /* shouldn't happen normally */ 1.714 +}