Back to index

courier  0.68.2
Functions
courier.c File Reference
#include "courier.h"
#include "localstatedir.h"
#include "datadir.h"
#include "comctlfile.h"
#include "comparseqid.h"
#include "comqueuename.h"
#include "comtrack.h"
#include <sys/types.h>
#include <string.h>
#include <signal.h>
#include <stdlib.h>
#include "waitlib/waitlib.h"
#include "liblock/config.h"
#include "liblock/liblock.h"
#include "numlib/numlib.h"

Go to the source code of this file.

Functions

void courier_clear_all ()
void courier_show_all ()
int main (int argc, char **argv)

Function Documentation

Here is the caller graph for this function:

void courier_show_all ( )

Here is the caller graph for this function:

int main ( int  argc,
char **  argv 
)

Definition at line 37 of file courier.c.

{
       if (argc > 1 && strcmp(argv[1], "--version") == 0)
       {
              printf("%s\n", COURIER_COPYRIGHT);
              exit(0);
       }

       if (chdir(courierdir()))
       {
              perror("chdir");
              return (1);
       }
       if (argc < 2) return (0);

       if (strcmp(argv[1], "stop") == 0)
       {
       int    fd;

              trigger(TRIGGER_STOP);

              /* Wait until the exclusive lock goes away: */

              signal(SIGHUP, SIG_DFL);
              if ((fd=open(TMPDIR "/courierd.lock", O_RDWR|O_CREAT, 0600))
                     < 0)   clog_msg_errno();

              alarm(15);    /* But abort after 15 seconds. */

              ll_lock_ex(fd);
              return (0);
       }

       if (strcmp(argv[1], "restart") == 0)
       {
              trigger(TRIGGER_RESTART);
              return (0);
       }

       if (strcmp(argv[1], "flush") == 0)
       {
       ino_t  n;
       struct ctlfile       ctf;

              if (getuid())
              {
              /*
              ** We'll fail trying to open the pipe anyway, but let's
              ** give a meaningful error message now.
              */
                     fprintf(stderr,
              "courier flush can be executed only by the superuser.\n");
                     exit(1);
              }

              if (argc < 3)
              {
                     trigger(TRIGGER_FLUSH);     /* Everything */
                     exit(0);
              }

              if (comparseqid(argv[2], &n) == 0 &&
                     ctlfile_openi(n, &ctf, 1) == 0)
              {
              int c=ctlfile_searchfirst(&ctf, COMCTLFILE_MSGID);

                     if (c >= 0 && strcmp(ctf.lines[c]+1, argv[2]) == 0)
                     {
                     char   *s=courier_malloc(sizeof(TRIGGER_FLUSHMSG)+1+
                            strlen(argv[2]));

                            strcat(strcat(strcpy(s, TRIGGER_FLUSHMSG),
                                   argv[2]), "\n");
                            trigger(s);
                            ctlfile_close(&ctf);
                            return (0);
                     }
                     ctlfile_close(&ctf);
              }
              fprintf(stderr, "No such message.\n");
              exit(1);
              return (1);
       }

       /* Might as well... */

       if (strcmp(argv[1], "start") == 0)
       {
       pid_t  p;
       int    waitstat;
       char   dummy;

       /*
       ** Ok, courierd will close file descriptor 3 when it starts, so we
       ** put a pipe on there, and wait for it to close.
       */
       int    pipefd[2];

              close(3);
              if (open("/dev/null", O_RDONLY) != 3 || pipe(pipefd))
              {
                     fprintf(stderr, "Cannot open pipe\n");
                     exit(1);
              }

              if (getuid())
              {
              /*
              ** We'll fail trying to execute courierd anyway, but let's
              ** give a meaningful error message now.
              */
                     fprintf(stderr, "courier start can be executed only by the superuser.\n");
                     return (1);
              }
              signal(SIGCHLD, SIG_DFL);
              while ((p=fork()) == -1)
              {
                     perror("fork");
                     sleep(10);
              }
              if (p == 0)
              {
                     dup2(pipefd[1], 3);
                     close(pipefd[1]);
                     close(pipefd[0]);
                     while ((p=fork()) == -1)
                     {
                            perror("fork");
                            sleep(10);
                     }
                     if (p == 0)
                     {
                            /*
                            ** stdin from the bitbucket.  stdout to
                            ** /dev/null, or the bitbucket.
                            */

                            signal(SIGHUP, SIG_IGN);
                            close(0);
                            open("/dev/null", O_RDWR);
                            dup2(0, 1);
                            dup2(0, 2);
                     /* See if we can disconnect from the terminal */

#ifdef TIOCNOTTY
                            {
                            int fd=open("/dev/tty", O_RDWR);

                                   if (fd >= 0)
                                   {
                                          ioctl(fd, TIOCNOTTY, 0);
                                          close(fd);
                                   }
                            }
#endif
                     /* Remove any process groups */

#if    HAVE_SETPGRP
#if    SETPGRP_VOID
                            setpgrp();
#else
                            setpgrp(0, 0);
#endif
#endif
                            execl( DATADIR "/courierctl.start",
                                   "courierctl.start", (char *)0);
                            perror("exec");
                            _exit(1);
                     }
                     _exit(0);
              }
              close(pipefd[1]);
              while (wait(&waitstat) != p)
                     ;
              if (read(pipefd[0], &dummy, 1) < 0)
                     ; /* ignore */
              close(pipefd[0]);
              close(3);
              return (0);
       }

       if (strcmp(argv[1], "clear") == 0 && argc > 2)
       {
              libmail_changeuidgid(MAILUID, MAILGID);

              if (strcmp(argv[2], "all") == 0)
              {
                     courier_clear_all();
              }
              else
              {
                     track_save(argv[2], TRACK_ADDRACCEPTED);
                     printf("%s cleared.\n", argv[2]);
              }
              return (0);
       }

       if (argc > 2 && strcmp(argv[1], "show") == 0 &&
           strcmp(argv[2], "all") == 0)
       {
              libmail_changeuidgid(MAILUID, MAILGID);
              courier_show_all();
       }

       return (0);
}

Here is the call graph for this function: