Back to index

courier  0.68.2
mainloop.c
Go to the documentation of this file.
00001 /*
00002 ** Copyright 1998 - 2006 Double Precision, Inc.
00003 ** See COPYING for distribution information.
00004 */
00005 
00006 #if    HAVE_CONFIG_H
00007 #include      "config.h"
00008 #endif
00009 #include      <stdio.h>
00010 #include      <stdlib.h>
00011 #include      <string.h>
00012 #include      <errno.h>
00013 #include      <ctype.h>
00014 #include      <fcntl.h>
00015 #include      <signal.h>
00016 #include      <unistd.h>
00017 #include      "imaptoken.h"
00018 #include      "imapwrite.h"
00019 #include      "numlib/numlib.h"
00020 
00021 
00022 extern int do_imap_command(const char *);
00023 
00024 extern unsigned long header_count, body_count;
00025 extern unsigned long bytes_received_count, bytes_sent_count;
00026 extern time_t start_time;
00027 
00028 static RETSIGTYPE sigexit(int n)
00029 {
00030        static char byemsg[]="* BYE Courier-IMAP server shut down by signal.\r\n";
00031        const char *a=getenv("AUTHENTICATED");
00032        char buf[NUMBUFSIZE];
00033        char msg[1024];
00034        int l = 0;
00035        const char *tls=getenv("IMAP_TLS");
00036        const char *ip=getenv("TCPREMOTEIP");
00037 
00038        if (write(1, byemsg, sizeof(byemsg)-1) < 0)
00039               exit(1);
00040 
00041        bytes_sent_count += sizeof(byemsg);
00042 
00043        libmail_str_time_t(time(NULL)-start_time, buf);
00044 
00045        if (tls && atoi(tls))
00046               tls=", starttls=1";
00047        else
00048               tls="";
00049 
00050        if (a && *a)
00051               l = snprintf(msg, sizeof(msg) - 1, "NOTICE: Disconnected during shutdown by signal, user=%s, "
00052                      "ip=[%s], headers=%lu, body=%lu, rcvd=%lu, sent=%lu, time=%s%s\n",
00053                      a, ip, header_count, body_count, bytes_received_count, bytes_sent_count,
00054                      buf, tls);
00055        else
00056               l = snprintf(msg, sizeof(msg) - 1, "NOTICE: Disconnected during shutdown by signal, ip=[%s], time=%s%s\n",
00057                      getenv("TCPREMOTEIP"),
00058                      buf, tls);
00059 
00060        if (l > 0 && write(2, msg, l))
00061               ; /* Suppress gcc warning */
00062 
00063        exit(0);
00064 #if    RETSIGTYPE != void
00065        return (0);
00066 #endif
00067 }
00068 
00069 
00070 void cmdfail(const char *tag, const char *msg)
00071 {
00072 #if SMAP
00073        const char *p=getenv("PROTOCOL");
00074 
00075        if (p && strcmp(p, "SMAP1") == 0)
00076               writes("-ERR ");
00077        else
00078 #endif
00079        {
00080               writes(tag);
00081               writes(" NO ");
00082        }
00083        writes(msg);
00084 }
00085 
00086 void cmdsuccess(const char *tag, const char *msg)
00087 {
00088 #if SMAP
00089        const char *p=getenv("PROTOCOL");
00090 
00091        if (p && strcmp(p, "SMAP1") == 0)
00092               writes("+OK ");
00093        else
00094 #endif
00095        {
00096               writes(tag);
00097               writes(" OK ");
00098        }
00099        writes(msg);
00100 }
00101 
00102 void mainloop(void)
00103 {
00104        int noerril = 0;
00105 
00106        signal(SIGTERM, sigexit);
00107        signal(SIGHUP, sigexit);
00108        signal(SIGINT, sigexit);
00109 
00110        for (;;)
00111        {
00112        char   tag[IT_MAX_ATOM_SIZE+1];
00113        struct imaptoken *curtoken;
00114 
00115               read_timeout(30 * 60);
00116               curtoken=nexttoken_nouc();
00117               tag[0]=0;
00118               if (curtoken->tokentype == IT_ATOM ||
00119                      curtoken->tokentype == IT_NUMBER)
00120               {
00121               int    rc;
00122 
00123                      if (strlen(tag)+strlen(curtoken->tokenbuf) > IT_MAX_ATOM_SIZE)
00124                             write_error_exit("max atom size too small");
00125                             
00126                      strncat(tag, curtoken->tokenbuf, IT_MAX_ATOM_SIZE);
00127                      rc=do_imap_command(tag);
00128 
00129                      if (rc == 0)
00130                      {
00131                             noerril = 0;
00132                             writeflush();
00133                             read_eol();
00134                             continue;
00135                      }
00136                      if (rc == -2)
00137                             continue;
00138               }
00139 
00140               noerril++;
00141               if (noerril > 9)
00142               {
00143                      errno = 0;
00144                      write_error_exit("TOO MANY CONSECUTIVE PROTOCOL VIOLATIONS");
00145               }
00146               read_eol();
00147               cmdfail(tag[0] ? tag:"*",
00148                      "Error in IMAP command received by server.\r\n");
00149               writeflush();
00150        }
00151 }