summaryrefslogtreecommitdiffstats
path: root/pcp/pcpmksocket.c
diff options
context:
space:
mode:
Diffstat (limited to 'pcp/pcpmksocket.c')
-rw-r--r--pcp/pcpmksocket.c113
1 files changed, 113 insertions, 0 deletions
diff --git a/pcp/pcpmksocket.c b/pcp/pcpmksocket.c
new file mode 100644
index 0000000..f37795e
--- /dev/null
+++ b/pcp/pcpmksocket.c
@@ -0,0 +1,113 @@
+/*
+** Copyright 2001 Double Precision, Inc. See COPYING for
+** distribution information.
+*/
+
+
+#include "config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include "pcp.h"
+#if HAVE_DIRENT_H
+#include <dirent.h>
+#else
+#define dirent direct
+#if HAVE_SYS_NDIR_H
+#include <sys/ndir.h>
+#endif
+#if HAVE_SYS_DIR_H
+#include <sys/dir.h>
+#endif
+#if HAVE_NDIR_H
+#include <ndir.h>
+#endif
+#endif
+
+#ifndef SOMAXCONN
+#define SOMAXCONN 5
+#endif
+
+int pcp_mksocket(const char *dir, const char *sockname)
+{
+ int fd;
+ const char *priority;
+ DIR *dirp;
+ struct dirent *de;
+ char *p;
+ struct sockaddr_un skun;
+
+ p=malloc(strlen(sockname)+sizeof("_PRIORITY"));
+ if (!p)
+ {
+ perror("malloc");
+ return (-1);
+ }
+
+ strcat(strcpy(p, sockname), "_PRIORITY");
+
+ priority=getenv(p);
+ free(p);
+ if (!priority || !*priority)
+ priority="50";
+
+ /* Delete the previous socket */
+
+ dirp=opendir(dir);
+ while (dirp && (de=readdir(dirp)))
+ {
+ const char *n=de->d_name;
+
+ while (*n && isdigit((int)(unsigned char)*n))
+ ++n;
+
+ if (strcmp(n, sockname))
+ continue;
+
+ p=malloc(strlen(dir)+strlen(de->d_name)+2);
+ if (!p)
+ {
+ perror("malloc");
+ closedir(dirp);
+ return (-1);
+ }
+ strcat(strcat(strcpy(p, dir), "/"), de->d_name);
+ unlink(p);
+ free(p);
+ }
+ if (dirp)
+ closedir(dirp);
+
+ fd=socket(PF_UNIX, SOCK_STREAM, 0);
+
+ if (fd < 0)
+ {
+ fprintf(stderr, "ALERT: socket failed: %s\n", strerror(errno));
+ return (-1);
+ }
+
+ skun.sun_family=AF_UNIX;
+ strcpy(skun.sun_path, dir);
+ strcat(skun.sun_path, "/");
+ strcat(skun.sun_path, priority);
+ strcat(skun.sun_path, sockname);
+
+ if (bind(fd, (const struct sockaddr *)&skun, sizeof(skun)) ||
+ listen(fd, SOMAXCONN) ||
+ chmod(skun.sun_path, 0777) ||
+ fcntl(fd, F_SETFL, O_NONBLOCK) < 0)
+ {
+ fprintf(stderr, "ALERT: %s\n", skun.sun_path);
+ close(fd);
+ return (-1);
+ }
+ return (fd);
+}