Back to index

courier  0.68.2
pcpmksocket.c
Go to the documentation of this file.
00001 /*
00002 ** Copyright 2001 Double Precision, Inc.  See COPYING for
00003 ** distribution information.
00004 */
00005 
00006 
00007 #include "config.h"
00008 #include <stdio.h>
00009 #include <stdlib.h>
00010 #include <string.h>
00011 #include <errno.h>
00012 #include <signal.h>
00013 #include <fcntl.h>
00014 #include <ctype.h>
00015 #include <unistd.h>
00016 #include <sys/stat.h>
00017 #include <sys/socket.h>
00018 #include <sys/un.h>
00019 #include "pcp.h"
00020 #if HAVE_DIRENT_H
00021 #include <dirent.h>
00022 #else
00023 #define dirent direct
00024 #if HAVE_SYS_NDIR_H
00025 #include <sys/ndir.h>
00026 #endif
00027 #if HAVE_SYS_DIR_H
00028 #include <sys/dir.h>
00029 #endif
00030 #if HAVE_NDIR_H
00031 #include <ndir.h>
00032 #endif
00033 #endif
00034 
00035 #ifndef SOMAXCONN
00036 #define SOMAXCONN 5
00037 #endif
00038 
00039 int pcp_mksocket(const char *dir, const char *sockname)
00040 {
00041        int fd;
00042        const char *priority;
00043        DIR *dirp;
00044        struct dirent *de;
00045        char *p;
00046        struct  sockaddr_un skun;
00047 
00048        p=malloc(strlen(sockname)+sizeof("_PRIORITY"));
00049        if (!p)
00050        {
00051               perror("malloc");
00052               return (-1);
00053        }
00054 
00055        strcat(strcpy(p, sockname), "_PRIORITY");
00056 
00057        priority=getenv(p);
00058        free(p);
00059        if (!priority || !*priority)
00060               priority="50";
00061 
00062        /* Delete the previous socket */
00063 
00064        dirp=opendir(dir);
00065        while (dirp && (de=readdir(dirp)))
00066        {
00067               const char *n=de->d_name;
00068 
00069               while (*n && isdigit((int)(unsigned char)*n))
00070                      ++n;
00071 
00072               if (strcmp(n, sockname))
00073                      continue;
00074 
00075               p=malloc(strlen(dir)+strlen(de->d_name)+2);
00076               if (!p)
00077               {
00078                      perror("malloc");
00079                      closedir(dirp);
00080                      return (-1);
00081               }
00082               strcat(strcat(strcpy(p, dir), "/"), de->d_name);
00083               unlink(p);
00084               free(p);
00085        }
00086        if (dirp)
00087               closedir(dirp);
00088 
00089        fd=socket(PF_UNIX, SOCK_STREAM, 0);
00090 
00091         if (fd < 0)
00092        {
00093               fprintf(stderr, "ALERT: socket failed: %s\n", strerror(errno));
00094               return (-1);
00095        }
00096 
00097         skun.sun_family=AF_UNIX;
00098         strcpy(skun.sun_path, dir);
00099         strcat(skun.sun_path, "/");
00100         strcat(skun.sun_path, priority);
00101         strcat(skun.sun_path, sockname);
00102 
00103         if (bind(fd, (const struct sockaddr *)&skun, sizeof(skun)) ||
00104            listen(fd, SOMAXCONN) ||
00105            chmod(skun.sun_path, 0777) ||
00106            fcntl(fd, F_SETFL, O_NONBLOCK) < 0)
00107         {
00108               fprintf(stderr, "ALERT: %s\n", skun.sun_path);
00109                 close(fd);
00110                 return (-1);
00111         }
00112         return (fd);
00113 }