Back to index

courier  0.68.2
libfilter.c
Go to the documentation of this file.
00001 /*
00002 ** Copyright 2000-2006 Double Precision, Inc.
00003 ** See COPYING for distribution information.
00004 */
00005 
00006 #include      "config.h"
00007 #include      "courier.h"
00008 #include      <stdio.h>
00009 #include      <string.h>
00010 #include      <stdlib.h>
00011 #if    HAVE_UNISTD_H
00012 #include      <unistd.h>
00013 #endif
00014 #include      <sys/types.h>
00015 #if    HAVE_SYS_STAT_H
00016 #include      <sys/stat.h>
00017 #endif
00018 #if TIME_WITH_SYS_TIME
00019 #include      <sys/time.h>
00020 #include      <time.h>
00021 #else
00022 #if HAVE_SYS_TIME_H
00023 #include      <sys/time.h>
00024 #else
00025 #include      <time.h>
00026 #endif
00027 #endif
00028 #if    HAVE_FCNTL_H
00029 #include      <fcntl.h>
00030 #endif
00031 #include      <sys/socket.h>
00032 #include      <sys/un.h>
00033 
00034 #include      "libfilter.h"
00035 
00036 
00037 int lf_init(const char *modfile,
00038               const char *allname,
00039               const char *alltmpname,
00040 
00041               const char *notallname,
00042               const char *notalltmpname)
00043 {
00044 int    all=0;
00045 const  char *sockname, *tmpsockname;
00046 struct sockaddr_un ssun;
00047 int    listensock;
00048 
00049        if (chdir(courierdir()))
00050        {
00051               perror(courierdir());
00052               return (-1);
00053        }
00054 
00055        {
00056        char   *fn=config_localfilename(modfile);
00057        char   *f;
00058 
00059               f=config_read1l(fn);
00060               free(fn);
00061               if (f)
00062               {
00063                      if (strcmp(f, "all") == 0)
00064                             all=1;
00065                      free(f);
00066               }
00067        }
00068 
00069        if (all)
00070        {
00071               sockname=allname;
00072               tmpsockname=alltmpname;
00073               unlink(notallname);
00074        }
00075        else
00076        {
00077               sockname=notallname;
00078               tmpsockname=notalltmpname;
00079               unlink(allname);
00080        }
00081 
00082        ssun.sun_family=AF_UNIX;
00083        strcpy(ssun.sun_path, tmpsockname);
00084        unlink(ssun.sun_path);
00085        if ((listensock=socket(PF_UNIX, SOCK_STREAM, 0)) < 0 ||
00086               bind(listensock, (struct sockaddr *)&ssun, sizeof(ssun)) < 0 ||
00087               listen(listensock, SOMAXCONN) < 0 ||
00088               chmod(ssun.sun_path, 0660) ||
00089               rename (tmpsockname, sockname) ||
00090               fcntl(listensock, F_SETFL, O_NDELAY) < 0
00091               )
00092        {
00093               perror("socket");
00094               return (-1);
00095        }
00096        return (listensock);
00097 }
00098 
00099 void lf_init_completed(int sockfd)
00100 {
00101        if (sockfd != 3)     close(3);
00102 }
00103 
00104 int lf_accept(int listensock)
00105 {
00106 struct sockaddr_un ssun;
00107 fd_set fd0;
00108 int    fd;
00109 socklen_t     sunlen;
00110 
00111        for (;;)
00112        {
00113               FD_ZERO(&fd0);
00114               FD_SET(0, &fd0);
00115               FD_SET(listensock, &fd0);
00116 
00117               if (select(listensock+1, &fd0, 0, 0, 0) < 0)
00118               {
00119                      perror("select");
00120                      return (-1);
00121               }
00122 
00123               if (FD_ISSET(0, &fd0))
00124               {
00125               char    buf[16];
00126 
00127                      if (read(0, buf, sizeof(buf)) <= 0)
00128                             return (-1);  /* Shutting down */
00129               }
00130 
00131               if (!FD_ISSET(listensock, &fd0))   continue;
00132 
00133               sunlen=sizeof(ssun);
00134               if ((fd=accept(listensock, (struct sockaddr *)&ssun, &sunlen))
00135                      < 0)
00136                         continue;
00137 
00138               fcntl(fd, F_SETFL, 0);      /* Take out of NDELAY mode */
00139               break;
00140        }
00141        return (fd);
00142 }