/[mailutils]/mailutils/imap4d/imap4d.c
ViewVC logotype

Diff of /mailutils/imap4d/imap4d.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.31 by gray, Fri Dec 27 19:31:06 2002 UTC revision 1.32 by polak, Fri Jan 17 19:07:15 2003 UTC
# Line 1  Line 1 
1  /* GNU Mailutils -- a suite of utilities for electronic mail  /* GNU Mailutils -- a suite of utilities for electronic mail
2     Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc.     Copyright (C) 1999, 2001, 2002, 2003 Free Software Foundation, Inc.
3    
4     GNU Mailutils is free software; you can redistribute it and/or modify     GNU Mailutils is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by     it under the terms of the GNU General Public License as published by
# Line 13  Line 13 
13    
14     You should have received a copy of the GNU General Public License     You should have received a copy of the GNU General Public License
15     along with GNU Mailutils; if not, write to the Free Software     along with GNU Mailutils; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA  */
17    
18  #include "imap4d.h"  #include "imap4d.h"
19    
 FILE *ifile;  
 FILE *ofile;  
20  mailbox_t mbox;  mailbox_t mbox;
21  char *homedir;  char *homedir;
22  int state = STATE_NONAUTH;  int state = STATE_NONAUTH;
23  int debug_mode = 0;  int debug_mode = 0;
24  struct mu_auth_data *auth_data;  struct mu_auth_data *auth_data;
25    
26  struct daemon_param daemon_param = {  struct daemon_param daemon_param = {
27    MODE_INTERACTIVE,     /* Start in interactive (inetd) mode */    MODE_INTERACTIVE,             /* Start in interactive (inetd) mode */
28    20,                   /* Default maximum number of children */    20,                           /* Default maximum number of children */
29    143,                  /* Standard IMAP4 port */    143,                          /* Standard IMAP4 port */
30    1800,                 /* RFC2060: 30 minutes. */    1800,                         /* RFC2060: 30 minutes. */
31    0                     /* No transcript by default */    0                             /* No transcript by default */
32  };  };
33    
34    #ifdef WITH_TLS
35    int tls_available;
36    int tls_done;
37    #endif /* WITH_TLS */
38    
39  /* Number of child processes.  */  /* Number of child processes.  */
40  volatile size_t children;  volatile size_t children;
41    
42  const char *argp_program_version = "imap4d (" PACKAGE_STRING ")";  const char *argp_program_version = "imap4d (" PACKAGE_STRING ")";
43  static char doc[] = N_("GNU imap4d -- the IMAP4D daemon");  static char doc[] = N_("GNU imap4d -- the IMAP4D daemon");
44    
45  static struct argp_option options[] =  static struct argp_option options[] = {
 {  
46    {"other-namespace", 'O', N_("PATHLIST"), 0,    {"other-namespace", 'O', N_("PATHLIST"), 0,
47     N_("set the `other' namespace"), 0},     N_("set the `other' namespace"), 0},
48    {"shared-namespace", 'S', N_("PATHLIST"), 0,    {"shared-namespace", 'S', N_("PATHLIST"), 0,
49     N_("set the `shared' namespace"), 0},     N_("set the `shared' namespace"), 0},
50    { NULL,      0, NULL, 0, NULL, 0 }    {NULL, 0, NULL, 0, NULL, 0}
51  };  };
52    
53  static error_t imap4d_parse_opt (int key, char *arg, struct argp_state *state);  static error_t imap4d_parse_opt (int key, char *arg,
54                                     struct argp_state *state);
55    
56  static struct argp argp = {  static struct argp argp = {
57    options,    options,
58    imap4d_parse_opt,    imap4d_parse_opt,
59    NULL,    NULL,
60    doc,    doc,
61    NULL,    NULL,
62    NULL, NULL    NULL, NULL
# Line 62  static struct argp argp = { Line 65  static struct argp argp = {
65  static const char *imap4d_capa[] = {  static const char *imap4d_capa[] = {
66    "daemon",    "daemon",
67    "auth",    "auth",
68    #ifdef WITH_TLS
69      "tls",
70    #endif /* WITH_TLS */
71    "common",    "common",
72    "mailbox",    "mailbox",
73    "logging",    "logging",
# Line 69  static const char *imap4d_capa[] = { Line 75  static const char *imap4d_capa[] = {
75    NULL    NULL
76  };  };
77    
78  static int imap4d_mainloop      __P ((int, int));  static int imap4d_mainloop __P ((int, int));
79  static void imap4d_daemon_init  __P ((void));  static void imap4d_daemon_init __P ((void));
80  static void imap4d_daemon       __P ((unsigned int, unsigned int));  static void imap4d_daemon __P ((unsigned int, unsigned int));
81  static int imap4d_mainloop      __P ((int, int));  static int imap4d_mainloop __P ((int, int));
82    
83  static error_t  static error_t
84  imap4d_parse_opt (int key, char *arg, struct argp_state *state)  imap4d_parse_opt (int key, char *arg, struct argp_state *state)
# Line 82  imap4d_parse_opt (int key, char *arg, st Line 88  imap4d_parse_opt (int key, char *arg, st
88      case ARGP_KEY_INIT:      case ARGP_KEY_INIT:
89        state->child_inputs[0] = state->input;        state->child_inputs[0] = state->input;
90        break;        break;
91          
92      case 'O':      case 'O':
93        set_namespace (NS_OTHER, arg);        set_namespace (NS_OTHER, arg);
94        break;        break;
95          
96      case 'S':      case 'S':
97        set_namespace (NS_SHARED, arg);        set_namespace (NS_SHARED, arg);
98        break;        break;
99          
100      default:      default:
101        return ARGP_ERR_UNKNOWN;        return ARGP_ERR_UNKNOWN;
102      }      }
# Line 106  main (int argc, char **argv) Line 112  main (int argc, char **argv)
112    /* Native Language Support */    /* Native Language Support */
113    mu_init_nls ();    mu_init_nls ();
114    
115    state = STATE_NONAUTH; /* Starting state in non-auth.  */    state = STATE_NONAUTH;        /* Starting state in non-auth.  */
116    
117    MU_AUTH_REGISTER_ALL_MODULES();    MU_AUTH_REGISTER_ALL_MODULES ();
118    #ifdef WITH_TLS
119      mu_tls_init_argp ();
120    #endif /* WITH_TLS */
121    mu_argp_parse (&argp, &argc, &argv, 0, imap4d_capa, NULL, &daemon_param);    mu_argp_parse (&argp, &argc, &argv, 0, imap4d_capa, NULL, &daemon_param);
122    
123  #ifdef USE_LIBPAM  #ifdef USE_LIBPAM
# Line 131  main (int argc, char **argv) Line 140  main (int argc, char **argv)
140            perror (_("Error getting mail group"));            perror (_("Error getting mail group"));
141            exit (1);            exit (1);
142          }          }
143          
144        if (setgid (gr->gr_gid) == -1)        if (setgid (gr->gr_gid) == -1)
145          {          {
146            perror (_("Error setting mail group"));            perror (_("Error setting mail group"));
# Line 143  main (int argc, char **argv) Line 152  main (int argc, char **argv)
152    {    {
153      list_t bookie;      list_t bookie;
154      registrar_get_list (&bookie);      registrar_get_list (&bookie);
155      list_append (bookie, mbox_record);      list_append (bookie, mbox_record);
156      list_append (bookie, path_record);      list_append (bookie, path_record);
157    }    }
158    
# Line 174  main (int argc, char **argv) Line 183  main (int argc, char **argv)
183    /* Redirect any stdout error from the library to syslog, they    /* Redirect any stdout error from the library to syslog, they
184       should not go to the client.  */       should not go to the client.  */
185    mu_error_set_print (mu_syslog_error_printer);    mu_error_set_print (mu_syslog_error_printer);
186      
187    umask (S_IROTH | S_IWOTH | S_IXOTH);  /* 007 */    umask (S_IROTH | S_IWOTH | S_IXOTH);  /* 007 */
188    
189      /* Check TLS environment, i.e. cert and key files */
190    #ifdef WITH_TLS
191      tls_available = mu_check_tls_environment ();
192      if (tls_available)
193        tls_available = mu_init_tls_libs ();
194    #endif /* WITH_TLS */
195    
196    /* Actually run the daemon.  */    /* Actually run the daemon.  */
197    if (daemon_param.mode == MODE_DAEMON)    if (daemon_param.mode == MODE_DAEMON)
# Line 194  static int Line 210  static int
210  imap4d_mainloop (int infile, int outfile)  imap4d_mainloop (int infile, int outfile)
211  {  {
212    char *text;    char *text;
213      
214    /* Reset hup to exit.  */    /* Reset hup to exit.  */
215    signal (SIGHUP, imap4d_signal);    signal (SIGHUP, imap4d_signal);
216    /* Timeout alarm.  */    /* Timeout alarm.  */
217    signal (SIGALRM, imap4d_signal);    signal (SIGALRM, imap4d_signal);
218    
219    ifile = fdopen (infile, "r");    util_setio (infile, outfile);
   ofile = fdopen (outfile, "w");  
   if (!ofile || !ifile)  
     imap4d_bye (ERR_NO_OFILE);  
   
   setvbuf(ofile, NULL, _IOLBF, 0);  
220    
221    /* log information on the connecting client */    /* log information on the connecting client */
222    if (!debug_mode)    if (!debug_mode)
# Line 214  imap4d_mainloop (int infile, int outfile Line 225  imap4d_mainloop (int infile, int outfile
225        int len = sizeof cs;        int len = sizeof cs;
226    
227        syslog (LOG_INFO, _("Incoming connection opened"));        syslog (LOG_INFO, _("Incoming connection opened"));
228        if (getpeername (infile, (struct sockaddr*)&cs, &len) < 0)        if (getpeername (infile, (struct sockaddr *) &cs, &len) < 0)
229          syslog (LOG_ERR, _("can't obtain IP address of client: %s"),          syslog (LOG_ERR, _("can't obtain IP address of client: %s"),
230                  strerror (errno));                  strerror (errno));
231        else        else
232          syslog (LOG_INFO, _("connect from %s"), inet_ntoa(cs.sin_addr));          syslog (LOG_INFO, _("connect from %s"), inet_ntoa (cs.sin_addr));
233        text = "IMAP4rev1";        text = "IMAP4rev1";
234      }      }
235    else    else
# Line 226  imap4d_mainloop (int infile, int outfile Line 237  imap4d_mainloop (int infile, int outfile
237        syslog (LOG_INFO, _("Started in debugging mode"));        syslog (LOG_INFO, _("Started in debugging mode"));
238        text = "IMAP4rev1 Debugging mode";        text = "IMAP4rev1 Debugging mode";
239      }      }
240      
241    /* Greetings.  */    /* Greetings.  */
242    util_out (RESP_OK, text);    util_out (RESP_OK, text);
243    fflush (ofile);    util_flush_output ();
244    
245    while (1)    while (1)
246      {      {
247        char *cmd = imap4d_readline (ifile);        char *cmd = imap4d_readline ();
248        /* check for updates */        /* check for updates */
249        imap4d_sync ();        imap4d_sync ();
250        util_do_command (cmd);        util_do_command (cmd);
251        imap4d_sync ();        imap4d_sync ();
252        free (cmd);        free (cmd);
253        fflush (ofile);        util_flush_output ();
254      }      }
255    
   closelog ();  
256    return EXIT_SUCCESS;    return EXIT_SUCCESS;
257  }  }
258    
# Line 256  imap4d_daemon_init (void) Line 266  imap4d_daemon_init (void)
266       first three one, in, out, err   */       first three one, in, out, err   */
267    if (daemon (0, 0) < 0)    if (daemon (0, 0) < 0)
268      {      {
269        perror(_("fork failed:"));        perror (_("fork failed:"));
270        exit (1);        exit (1);
271      }      }
272    
# Line 289  imap4d_daemon (unsigned int maxchildren, Line 299  imap4d_daemon (unsigned int maxchildren,
299    listenfd = socket (AF_INET, SOCK_STREAM, 0);    listenfd = socket (AF_INET, SOCK_STREAM, 0);
300    if (listenfd == -1)    if (listenfd == -1)
301      {      {
302        syslog (LOG_ERR, "socket: %s", strerror(errno));        syslog (LOG_ERR, "socket: %s", strerror (errno));
303        exit (1);        exit (1);
304      }      }
305    size = 1; /* Use size here to avoid making a new variable.  */    size = 1;                     /* Use size here to avoid making a new variable.  */
306    setsockopt (listenfd, SOL_SOCKET, SO_REUSEADDR, &size, sizeof(size));    setsockopt (listenfd, SOL_SOCKET, SO_REUSEADDR, &size, sizeof (size));
307    size = sizeof (server);    size = sizeof (server);
308    memset (&server, 0, size);    memset (&server, 0, size);
309    server.sin_family = AF_INET;    server.sin_family = AF_INET;
310    server.sin_addr.s_addr = htonl (INADDR_ANY);    server.sin_addr.s_addr = htonl (INADDR_ANY);
311    server.sin_port = htons (port);    server.sin_port = htons (port);
312    
313    if (bind (listenfd, (struct sockaddr *)&server, size) == -1)    if (bind (listenfd, (struct sockaddr *) &server, size) == -1)
314      {      {
315        syslog (LOG_ERR, "bind: %s", strerror (errno));        syslog (LOG_ERR, "bind: %s", strerror (errno));
316        exit (1);        exit (1);
# Line 315  imap4d_daemon (unsigned int maxchildren, Line 325  imap4d_daemon (unsigned int maxchildren,
325    for (;;)    for (;;)
326      {      {
327        if (children > maxchildren)        if (children > maxchildren)
328          {          {
329            syslog (LOG_ERR, _("too many children (%lu)"),            syslog (LOG_ERR, _("too many children (%lu)"),
330                    (unsigned long) children);                    (unsigned long) children);
331            pause ();            pause ();
332            continue;            continue;
333          }          }
334        connfd = accept (listenfd, (struct sockaddr *)&client,        connfd = accept (listenfd, (struct sockaddr *) &client,
335                         (socklen_t*) &size);                         (socklen_t *) & size);
336        if (connfd == -1)        if (connfd == -1)
337          {          {
338            if (errno == EINTR)            if (errno == EINTR)
339              continue;              continue;
340            syslog (LOG_ERR, "accept: %s", strerror (errno));            syslog (LOG_ERR, "accept: %s", strerror (errno));
341            exit (1);            exit (1);
342          }          }
343    
344        pid = fork ();        pid = fork ();
345        if (pid == -1)        if (pid == -1)
346          syslog(LOG_ERR, "fork: %s", strerror (errno));          syslog (LOG_ERR, "fork: %s", strerror (errno));
347        else if (pid == 0) /* Child.  */        else if (pid == 0)        /* Child.  */
348          {          {
349            int status;            int status;
350            close (listenfd);            close (listenfd);
351            status = imap4d_mainloop (connfd, connfd);            status = imap4d_mainloop (connfd, connfd);
352            closelog ();            closelog ();
353            exit (status);            exit (status);
354          }          }
355        else        else
356          {          {
357            ++children;            ++children;
358          }          }
359        close (connfd);        close (connfd);
360      }      }
361  }  }
   

Legend:
Removed from v.1.31  
changed lines
  Added in v.1.32

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26