summaryrefslogtreecommitdiffstats
path: root/imap/mainloop.c
diff options
context:
space:
mode:
authorSam Varshavchik2013-08-19 16:39:41 -0400
committerSam Varshavchik2013-08-25 14:43:51 -0400
commit9c45d9ad13fdf439d44d7443ae75da15ea0223ed (patch)
tree7a81a04cb51efb078ee350859a64be2ebc6b8813 /imap/mainloop.c
parenta9520698b770168d1f33d6301463bb70a19655ec (diff)
downloadcourier-libs-9c45d9ad13fdf439d44d7443ae75da15ea0223ed.tar.bz2
Initial checkin
Imported from subversion report, converted to git. Updated all paths in scripts and makefiles, reflecting the new directory hierarchy.
Diffstat (limited to 'imap/mainloop.c')
-rw-r--r--imap/mainloop.c151
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();
+ }
+}