1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
|
/*
** 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 *, int *);
extern unsigned long header_count, body_count;
extern unsigned long bytes_received_count, bytes_sent_count;
extern time_t start_time;
static void 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");
const char *port=getenv("TCPREMOTEPORT");
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], port=[%s], headers=%lu, body=%lu, rcvd=%lu, sent=%lu, time=%s%s\n",
a, ip, port, 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], port=[%s], time=%s%s\n",
getenv("TCPREMOTEIP"),
getenv("TCPREMOTEPORT"),
buf, tls);
if (l > 0 && write(2, msg, l))
; /* Suppress gcc warning */
exit(0);
}
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;
int flushflag=0;
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, &flushflag);
if (rc == 0)
{
noerril = 0;
writeflush();
read_eol();
if (flushflag)
readflush();
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();
}
}
|