diff options
Diffstat (limited to 'imap/mainloop.c')
| -rw-r--r-- | imap/mainloop.c | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/imap/mainloop.c b/imap/mainloop.c new file mode 100644 index 0000000..b58ae6f --- /dev/null +++ b/imap/mainloop.c @@ -0,0 +1,151 @@ +/* +** Copyright 1998 - 2006 Double Precision, Inc. +** See COPYING for distribution information. +*/ + +#if HAVE_CONFIG_H +#include "config.h" +#endif +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <ctype.h> +#include <fcntl.h> +#include <signal.h> +#include <unistd.h> +#include "imaptoken.h" +#include "imapwrite.h" +#include "numlib/numlib.h" + + +extern int do_imap_command(const char *); + +extern unsigned long header_count, body_count; +extern unsigned long bytes_received_count, bytes_sent_count; +extern time_t start_time; + +static RETSIGTYPE sigexit(int n) +{ + static char byemsg[]="* BYE Courier-IMAP server shut down by signal.\r\n"; + const char *a=getenv("AUTHENTICATED"); + char buf[NUMBUFSIZE]; + char msg[1024]; + int l = 0; + const char *tls=getenv("IMAP_TLS"); + const char *ip=getenv("TCPREMOTEIP"); + + if (write(1, byemsg, sizeof(byemsg)-1) < 0) + exit(1); + + bytes_sent_count += sizeof(byemsg); + + libmail_str_time_t(time(NULL)-start_time, buf); + + if (tls && atoi(tls)) + tls=", starttls=1"; + else + tls=""; + + if (a && *a) + l = snprintf(msg, sizeof(msg) - 1, "NOTICE: Disconnected during shutdown by signal, user=%s, " + "ip=[%s], headers=%lu, body=%lu, rcvd=%lu, sent=%lu, time=%s%s\n", + a, ip, header_count, body_count, bytes_received_count, bytes_sent_count, + buf, tls); + else + l = snprintf(msg, sizeof(msg) - 1, "NOTICE: Disconnected during shutdown by signal, ip=[%s], time=%s%s\n", + getenv("TCPREMOTEIP"), + buf, tls); + + if (l > 0 && write(2, msg, l)) + ; /* Suppress gcc warning */ + + exit(0); +#if RETSIGTYPE != void + return (0); +#endif +} + + +void cmdfail(const char *tag, const char *msg) +{ +#if SMAP + const char *p=getenv("PROTOCOL"); + + if (p && strcmp(p, "SMAP1") == 0) + writes("-ERR "); + else +#endif + { + writes(tag); + writes(" NO "); + } + writes(msg); +} + +void cmdsuccess(const char *tag, const char *msg) +{ +#if SMAP + const char *p=getenv("PROTOCOL"); + + if (p && strcmp(p, "SMAP1") == 0) + writes("+OK "); + else +#endif + { + writes(tag); + writes(" OK "); + } + writes(msg); +} + +void mainloop(void) +{ + int noerril = 0; + + signal(SIGTERM, sigexit); + signal(SIGHUP, sigexit); + signal(SIGINT, sigexit); + + for (;;) + { + char tag[IT_MAX_ATOM_SIZE+1]; + struct imaptoken *curtoken; + + read_timeout(30 * 60); + curtoken=nexttoken_nouc(); + tag[0]=0; + if (curtoken->tokentype == IT_ATOM || + curtoken->tokentype == IT_NUMBER) + { + int rc; + + if (strlen(tag)+strlen(curtoken->tokenbuf) > IT_MAX_ATOM_SIZE) + write_error_exit("max atom size too small"); + + strncat(tag, curtoken->tokenbuf, IT_MAX_ATOM_SIZE); + rc=do_imap_command(tag); + + if (rc == 0) + { + noerril = 0; + writeflush(); + read_eol(); + continue; + } + if (rc == -2) + continue; + } + + noerril++; + if (noerril > 9) + { + errno = 0; + write_error_exit("TOO MANY CONSECUTIVE PROTOCOL VIOLATIONS"); + } + read_eol(); + cmdfail(tag[0] ? tag:"*", + "Error in IMAP command received by server.\r\n"); + writeflush(); + } +} |
