aboutsummaryrefslogtreecommitdiff
path: root/dpid
diff options
context:
space:
mode:
Diffstat (limited to 'dpid')
-rw-r--r--dpid/Makefile.am24
-rw-r--r--dpid/dpi.c4
-rw-r--r--dpid/dpi.h17
-rw-r--r--dpid/dpi_service.c114
-rw-r--r--dpid/dpi_service.h20
-rw-r--r--dpid/dpi_socket_dir.c3
-rw-r--r--dpid/dpid.c547
-rw-r--r--dpid/dpid.h46
-rw-r--r--dpid/dpid_common.c32
-rw-r--r--dpid/dpid_common.h9
-rw-r--r--dpid/dpidc31
-rw-r--r--dpid/dpidc.c121
-rw-r--r--dpid/dpidrc.in6
-rw-r--r--dpid/main.c118
-rw-r--r--dpid/misc_new.c55
-rw-r--r--dpid/misc_new.h3
16 files changed, 580 insertions, 570 deletions
diff --git a/dpid/Makefile.am b/dpid/Makefile.am
index 938a6244..2b81a98a 100644
--- a/dpid/Makefile.am
+++ b/dpid/Makefile.am
@@ -1,31 +1,29 @@
AM_CPPFLAGS=-DDPIDRC_SYS='"$(sysconfdir)/dpidrc"'
-bin_PROGRAMS = dpid
+bin_PROGRAMS = dpid dpidc
dpid_LDADD = ../dpip/libDpip.a ../dlib/libDlib.a
+dpidc_LDADD = ../dpip/libDpip.a ../dlib/libDlib.a
-EXTRA_DIST = dpidc
-bin_SCRIPTS = dpidc
+EXTRA_DIST = dpidrc.in
dpid_SOURCES = \
dpi.h \
- dpi_service.h \
dpi_socket_dir.h \
dpid.h \
dpid_common.h \
misc_new.h \
dpi.c \
- dpi_service.c \
dpi_socket_dir.c \
dpid.c \
dpid_common.c \
main.c \
misc_new.c
-install-data-local :
- $(mkinstalldirs) $(DESTDIR)$(sysconfdir)
- echo dpi_dir=$(libdir)/dillo/dpi > $(DESTDIR)$(sysconfdir)/dpidrc
- echo >> $(DESTDIR)$(sysconfdir)/dpidrc
- echo "proto.file=file/file.dpi" >> $(DESTDIR)$(sysconfdir)/dpidrc
- echo "proto.ftp=ftp/ftp.filter.dpi" >> $(DESTDIR)$(sysconfdir)/dpidrc
- echo "proto.https=https/https.filter.dpi" >> $(DESTDIR)$(sysconfdir)/dpidrc
- echo "proto.data=datauri/datauri.filter.dpi" >> $(DESTDIR)$(sysconfdir)/dpidrc
+dpidc_SOURCES = dpidc.c
+
+sysconf_DATA = dpidrc
+CLEANFILES = $(sysconf_DATA)
+
+dpidrc: $(srcdir)/dpidrc.in Makefile
+ sed -e 's|[@]libdir[@]|$(libdir)|' $(srcdir)/dpidrc.in > dpidrc
+
diff --git a/dpid/dpi.c b/dpid/dpi.c
index 45e5b49d..32bc628b 100644
--- a/dpid/dpi.c
+++ b/dpid/dpi.c
@@ -12,8 +12,7 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*! \file
@@ -23,6 +22,7 @@
*/
#include <errno.h>
+#include <stdlib.h> /* for exit */
#include "dpid_common.h"
#include "dpi.h"
#include "misc_new.h"
diff --git a/dpid/dpi.h b/dpid/dpi.h
index d97fdc6d..4ae33375 100644
--- a/dpid/dpi.h
+++ b/dpid/dpi.h
@@ -7,18 +7,8 @@
#ifndef DPI_H
#define DPI_H
-#include <config.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-
-/* Check the Unix98 goodie */
-#ifndef socklen_t
- #define socklen_t uint32_t
-#endif
+#include <unistd.h> /* for socklen_t */
+#include <sys/socket.h> /* for socklen_t and AF_LOCAL */
/* Some systems may not have this one... */
#ifndef AF_LOCAL
@@ -38,7 +28,8 @@
*/
enum {
UNKNOWN_CMD,
- BYE_CMD, /* "DpiBye" */
+ AUTH_CMD, /* authentication */
+ BYE_CMD, /* "DpiBye" */
CHECK_SERVER_CMD, /* "check_server" */
REGISTER_ALL_CMD, /* "register_all" */
REGISTER_SERVICE_CMD /* "register_service" */
diff --git a/dpid/dpi_service.c b/dpid/dpi_service.c
deleted file mode 100644
index 07cdad8e..00000000
--- a/dpid/dpi_service.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- Copyright (C) 2003 Ferdi Franceschini <ferdif@optusnet.com.au>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*! \file
- * \todo
- * This module should be removed because its original functions
- * have been removed or modified.
- * Put these functions in dpid.c
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include "dpid_common.h"
-#include "dpid.h"
-#include "../dpip/dpip.h"
-
-#ifdef TEST
-#include "testdat.h"
-#endif
-
-/* exported functions */
-char *get_dpi_dir(char *dpidrc);
-
-
-/*! Get dpi directory path from dpidrc
- * \Return
- * dpi directory on success, NULL on failure
- * \Important
- * The dpi_dir definition in dpidrc must have no leading white space.
- */
-char *get_dpi_dir(char *dpidrc)
-{
- FILE *In;
- int len;
- char *rcline = NULL, *value = NULL, *p;
-
- if ((In = fopen(dpidrc, "r")) == NULL) {
- ERRMSG("dpi_dir", "fopen", errno);
- MSG_ERR(" - %s\n", dpidrc);
- return (NULL);
- }
-
- while ((rcline = dGetline(In)) != NULL) {
- if (strncmp(rcline, "dpi_dir", 7) == 0)
- break;
- dFree(rcline);
- }
- fclose(In);
-
- if (!rcline) {
- ERRMSG("dpi_dir", "Failed to find a dpi_dir entry in dpidrc", 0);
- MSG_ERR("Put your dillo plugins path in %s\n", dpidrc);
- MSG_ERR("eg. dpi_dir=/usr/local/lib/dillo/dpi ");
- MSG_ERR("with no leading spaces.\n");
- value = NULL;
- } else {
- len = (int) strlen(rcline);
- if (len && rcline[len - 1] == '\n')
- rcline[len - 1] = 0;
-
- if ((p = strchr(rcline, '='))) {
- while (*++p == ' ');
- value = dStrdup(p);
- } else {
- ERRMSG("dpi_dir", "strchr", 0);
- MSG_ERR(" - '=' not found in %s\n", rcline);
- value = NULL;
- }
- }
-
- dFree(rcline);
- return (value);
-}
-
-/*! Send the list of available dpi IDs to a client
- * \Return
- * 1 on success, -1 on failure.
- *
-static int send_service_list(int sock, struct dp *dpi_attr_list, int srv_num)
-{
- int i;
- char *buf;
- ssize_t wlen = 0;
-
- for (i = 0; i < srv_num && wlen != -1; i++) {
- d_cmd = a_Dpip_build_cmd("cmd=%s msg=%s",
- "send_data", dpi_attr_list[i].id);
- wlen = write(sock, d_cmd, strlen(d_cmd));
- dFree(d_cmd);
- }
- if (wlen == -1) {
- ERRMSG("send_service_list", "write", errno);
- return (-1);
- }
- return (1);
-}
- */
diff --git a/dpid/dpi_service.h b/dpid/dpi_service.h
deleted file mode 100644
index af7679b3..00000000
--- a/dpid/dpi_service.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*! \file
- * \todo
- * This module should be removed because its original functions
- * have been removed or modified.
- * Put these functions in dpid.c
- */
-
-#ifndef DPI_SERVICE_H
-#define DPI_SERVICE_H
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include "dpid.h"
-
-char *get_dpi_dir(char *dpidrc);
-
-int send_service_list(int sock, struct dp *dpi_attr_list, int srv_num);
-
-#endif
diff --git a/dpid/dpi_socket_dir.c b/dpid/dpi_socket_dir.c
index 333ccf6a..09a24e2f 100644
--- a/dpid/dpi_socket_dir.c
+++ b/dpid/dpi_socket_dir.c
@@ -12,8 +12,7 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*! \file
diff --git a/dpid/dpid.c b/dpid/dpid.c
index 97e6414d..d8bfeb96 100644
--- a/dpid/dpid.c
+++ b/dpid/dpid.c
@@ -12,22 +12,26 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*! \file
* Main functions to set-up dpi information and to initialise sockets
*/
#include <errno.h>
+#include <stdlib.h> /* for exit */
+#include <fcntl.h> /* for F_SETFD, F_GETFD, FD_CLOEXEC */
+
#include <sys/stat.h>
#include <sys/wait.h>
+#include <sys/socket.h>
+#include <netinet/tcp.h>
+
#include <unistd.h>
#include "dpid_common.h"
#include "dpid.h"
#include "dpi.h"
#include "dpi_socket_dir.h"
-#include "dpi_service.h"
#include "misc_new.h"
#include "../dpip/dpip.h"
@@ -35,71 +39,18 @@
#define QUEUE 5
volatile sig_atomic_t caught_sigchld = 0;
+char *SharedKey = NULL;
-/*! Return the basename of a filename
- */
-static char *get_basename(char *filename)
-{
- char *p;
-
- if (filename && (p = strrchr(filename, '/'))) {
- filename = p + 1;
- }
- return filename;
-}
-
-/*! Close and remove the sockets in the
- * given dpi attribute list
+/*! Remove dpid_comm_keys file.
+ * This avoids that dillo instances connect to a stale port after dpid
+ * has exited (e.g. after a reboot).
*/
-void rm_dpi_sockets(struct dp *dpi_attr_list, int numdpis)
+void cleanup()
{
- int i;
-
- for (i = 0; i < numdpis; i++) {
- a_Misc_close_fd(dpi_attr_list[i].socket);
- (void) unlink(dpi_attr_list[i].sockpath);
- }
-}
-
-/*! Close and remove inactive dpi sockets
- * \Return
- * Number of active dpis.
- */
-int rm_inactive_dpi_sockets(struct dp *dpi_attr_list, int numdpis)
-{
- int i, active = 0;
-
- for (i = 0; i < numdpis; i++) {
- if (dpi_attr_list[i].pid == 1) {
- a_Misc_close_fd(dpi_attr_list[i].socket);
- (void) unlink(dpi_attr_list[i].sockpath);
- } else
- active++;
- }
- return (active);
-}
-
-/*! Remove sockets
- */
-void cleanup(char *socket_dir)
-{
- DIR *dir;
- struct dirent *dir_entry = NULL;
- char *sockpath;
-
- dir = opendir(socket_dir);
- if (dir == NULL) {
- ERRMSG("cleanup", "opendir", errno);
- return;
- }
- while ( (dir_entry = readdir(dir)) != NULL ) {
- if (dir_entry->d_name[0] == '.')
- continue;
- sockpath = dStrconcat(socket_dir, "/", dir_entry->d_name, NULL);
- unlink(sockpath);
- dFree(sockpath);
- }
- closedir(dir);
+ char *fname;
+ fname = dStrconcat(dGethomedir(), "/", dotDILLO_DPID_COMM_KEYS, NULL);
+ unlink(fname);
+ dFree(fname);
}
/*! Free memory used to describe
@@ -115,10 +66,6 @@ void free_dpi_attr(struct dp *dpi_attr)
dFree(dpi_attr->path);
dpi_attr->path = NULL;
}
- if (dpi_attr->sockpath != NULL) {
- dFree(dpi_attr->sockpath);
- dpi_attr->sockpath = NULL;
- }
}
/*! Free memory used by the plugin list
@@ -152,53 +99,46 @@ void free_services_list(Dlist *s_list)
dList_free(s_list);
}
-/*! \todo
- * Remove terminator and est_terminator unless we really want to clean up
- * on abnormal exit.
- */
-#if 0
/*! Signal handler for SIGINT, SIGQUIT, and SIGTERM. Calls cleanup
*/
-void terminator(int sig)
+static void terminator(int sig)
{
- (void) signal(SIGCHLD, SIG_DFL);
+ (void) sig; /* suppress unused parameter warning */
cleanup();
- (void) signal(sig, SIG_DFL);
- (void) raise(sig);
_exit(0);
}
/*! Establish handler for termination signals
* and register cleanup with atexit */
-void est_terminator(void)
+void est_dpi_terminator()
{
struct sigaction act;
sigset_t block;
- (void) sigemptyset(&block);
- (void) sigaddset(&block, SIGINT);
- (void) sigaddset(&block, SIGQUIT);
- (void) sigaddset(&block, SIGTERM);
- (void) sigaddset(&block, SIGSEGV);
+ sigemptyset(&block);
+ sigaddset(&block, SIGHUP);
+ sigaddset(&block, SIGINT);
+ sigaddset(&block, SIGQUIT);
+ sigaddset(&block, SIGTERM);
act.sa_handler = terminator;
act.sa_mask = block;
act.sa_flags = 0;
- if (sigaction(SIGINT, &act, NULL) ||
+ if (sigaction(SIGHUP, &act, NULL) ||
+ sigaction(SIGINT, &act, NULL) ||
sigaction(SIGQUIT, &act, NULL) ||
- sigaction(SIGTERM, &act, NULL) || sigaction(SIGSEGV, &act, NULL)) {
- ERRMSG("est_terminator", "sigaction", errno);
+ sigaction(SIGTERM, &act, NULL)) {
+ ERRMSG("est_dpi_terminator", "sigaction", errno);
exit(1);
}
if (atexit(cleanup) != 0) {
- ERRMSG("est_terminator", "atexit", 0);
+ ERRMSG("est_dpi_terminator", "atexit", 0);
MSG_ERR("Hey! atexit failed, how did that happen?\n");
exit(1);
}
}
-#endif
/*! Identify a given file
* Currently there is only one file type associated with dpis.
@@ -216,6 +156,56 @@ enum file_type get_file_type(char *file_name)
}
}
+/*! Get dpi directory path from dpidrc
+ * \Return
+ * dpi directory on success, NULL on failure
+ * \Important
+ * The dpi_dir definition in dpidrc must have no leading white space.
+ */
+char *get_dpi_dir(char *dpidrc)
+{
+ FILE *In;
+ int len;
+ char *rcline = NULL, *value = NULL, *p;
+
+ if ((In = fopen(dpidrc, "r")) == NULL) {
+ ERRMSG("dpi_dir", "fopen", errno);
+ MSG_ERR(" - %s\n", dpidrc);
+ return (NULL);
+ }
+
+ while ((rcline = dGetline(In)) != NULL) {
+ if (strncmp(rcline, "dpi_dir", 7) == 0)
+ break;
+ dFree(rcline);
+ }
+ fclose(In);
+
+ if (!rcline) {
+ ERRMSG("dpi_dir", "Failed to find a dpi_dir entry in dpidrc", 0);
+ MSG_ERR("Put your dillo plugins path in %s\n", dpidrc);
+ MSG_ERR("e.g. dpi_dir=/usr/local/lib/dillo/dpi\n");
+ MSG_ERR("with no leading spaces.\n");
+ value = NULL;
+ } else {
+ len = (int) strlen(rcline);
+ if (len && rcline[len - 1] == '\n')
+ rcline[len - 1] = 0;
+
+ if ((p = strchr(rcline, '='))) {
+ while (*++p == ' ');
+ value = dStrdup(p);
+ } else {
+ ERRMSG("dpi_dir", "strchr", 0);
+ MSG_ERR(" - '=' not found in %s\n", rcline);
+ value = NULL;
+ }
+ }
+
+ dFree(rcline);
+ return (value);
+}
+
/*! Scans a service directory in dpi_dir and fills dpi_attr
* \Note
* Caller must allocate memory for dpi_attr.
@@ -231,7 +221,7 @@ int get_dpi_attr(char *dpi_dir, char *service, struct dp *dpi_attr)
char *service_dir = NULL;
struct stat statinfo;
enum file_type ftype;
- int retval = -1;
+ int ret = -1;
DIR *dir_stream;
struct dirent *dir_entry = NULL;
@@ -255,13 +245,13 @@ int get_dpi_attr(char *dpi_dir, char *service, struct dp *dpi_attr)
dpi_attr->path =
dStrconcat(service_dir, "/", dir_entry->d_name, NULL);
dpi_attr->id = dStrdup(service);
- dpi_attr->sockpath = NULL;
+ dpi_attr->port = 0;
dpi_attr->pid = 1;
if (strstr(dpi_attr->path, ".filter") != NULL)
dpi_attr->filter = 1;
else
dpi_attr->filter = 0;
- retval = 0;
+ ret = 0;
break;
default:
break;
@@ -269,12 +259,12 @@ int get_dpi_attr(char *dpi_dir, char *service, struct dp *dpi_attr)
}
closedir(dir_stream);
- if (retval != 0)
+ if (ret != 0)
MSG_ERR("get_dpi_attr: No dpi plug-in in %s/%s\n",
dpi_dir, service);
}
dFree(service_dir);
- return retval;
+ return ret;
}
/*! Register a service
@@ -289,7 +279,7 @@ int get_dpi_attr(char *dpi_dir, char *service, struct dp *dpi_attr)
int register_service(struct dp *dpi_attr, char *service)
{
char *user_dpi_dir, *dpidrc, *user_service_dir, *dir = NULL;
- int retval = -1;
+ int ret = -1;
user_dpi_dir = dStrconcat(dGethomedir(), "/", dotDILLO_DPI, NULL);
user_service_dir =
@@ -313,12 +303,12 @@ int register_service(struct dp *dpi_attr, char *service)
/* Check home dir for dpis */
if (access(user_service_dir, F_OK) == 0) {
get_dpi_attr(user_dpi_dir, service, dpi_attr);
- retval = 0;
+ ret = 0;
} else { /* Check system wide dpis */
if ((dir = get_dpi_dir(dpidrc)) != NULL) {
if (access(dir, F_OK) == 0) {
get_dpi_attr(dir, service, dpi_attr);
- retval = 0;
+ ret = 0;
} else {
ERRMSG("register_service", "get_dpi_attr failed", 0);
}
@@ -330,7 +320,7 @@ int register_service(struct dp *dpi_attr, char *service)
dFree(user_service_dir);
dFree(dpidrc);
dFree(dir);
- return (retval);
+ return ret;
}
/*!
@@ -424,19 +414,18 @@ static int services_alpha_comp(const struct service *s1,
return -strcmp(s1->name, s2->name);
}
-/*! Add services reading a dpidrc file
- * each non empty or commented line has the form
- * service = path_relative_to_dpidir
- * \Return:
- * \li Returns number of available services on success
- * \li -1 on failure
- */
+/*! Add services reading a dpidrc file
+ * each non empty or commented line has the form
+ * service = path_relative_to_dpidir
+ * \Return:
+ * \li Returns number of available services on success
+ * \li -1 on failure
+ */
int fill_services_list(struct dp *attlist, int numdpis, Dlist **services_list)
{
FILE *dpidrc_stream;
- char *p, *line = NULL;
- char *service, *path;
- int i;
+ char *p, *line = NULL, *service, *path;
+ int i, st;
struct service *s;
char *user_dpidir = NULL, *sys_dpidir = NULL, *dpidrc = NULL;
@@ -479,16 +468,18 @@ int fill_services_list(struct dp *attlist, int numdpis, Dlist **services_list)
*services_list = dList_new(8);
/* dpidrc parser loop */
- while ((line = dGetline(dpidrc_stream)) != NULL) {
-
- if (dParser_get_rc_pair(&line, &service, &path) == -1) {
- if (line[0] && line[0] != '#' && (!service || !path)) {
- MSG_ERR("Syntax error in %s: service=\"%s\" path=\"%s\"\n",
- dpidrc, service, path);
- }
+ for (;(line = dGetline(dpidrc_stream)) != NULL; dFree(line)) {
+ st = dParser_parse_rc_line(&line, &service, &path);
+ if (st < 0) {
+ MSG_ERR("dpid: Syntax error in %s: service=\"%s\" path=\"%s\"\n",
+ dpidrc, service, path);
+ continue;
+ } else if (st != 0) {
continue;
}
+ _MSG("dpid: service=%s, path=%s\n", service, path);
+
/* ignore dpi_dir silently */
if (strcmp(service, "dpi_dir") == 0)
continue;
@@ -507,9 +498,8 @@ int fill_services_list(struct dp *attlist, int numdpis, Dlist **services_list)
/* if the dpi exist bind service and dpi */
if (i < numdpis)
s->dp_index = i;
- dFree(line);
}
- fclose(dpidrc_stream);
+ fclose(dpidrc_stream);
dList_sort(*services_list, (dCompareFunc)services_alpha_comp);
@@ -520,127 +510,142 @@ int fill_services_list(struct dp *attlist, int numdpis, Dlist **services_list)
return (dList_length(*services_list));
}
-/*! Initialise the service request socket
- * \Return:
- * \li Number of sockets (1 == success)
- * \li -1 on failure
+/*
+ * Return a socket file descriptor
+ * (useful to set socket options in a uniform way)
*/
-int init_srs_socket(char *sockdir)
+static int make_socket_fd()
{
- int retval = -1;
- struct sockaddr_un srs_sa;
- size_t sun_path_len;
- socklen_t addr_sz;
+ int ret, one = 1;
- srs_name = dStrconcat(sockdir, "/", SRS_NAME, NULL);
- FD_ZERO(&sock_set);
-
- /* Initialise srs, service request socket on startup */
- if ((srs = socket(AF_LOCAL, SOCK_STREAM, 0)) == -1) {
- ERRMSG("init_srs_socket", "socket", errno);
- return (retval); /* avoids nesting ifs too deeply */
+ if ((ret = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
+ ERRMSG("make_socket_fd", "socket", errno);
+ } else {
+ /* avoid delays when sending small pieces of data */
+ setsockopt(ret, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one));
}
- /* Set srs to close on exec */
- fcntl(srs, F_SETFD, FD_CLOEXEC | fcntl(srs, F_GETFD));
- srs_sa.sun_family = AF_LOCAL;
+ /* set some buffering to increase the transfer's speed */
+ //setsockopt(sock_fd, SOL_SOCKET, SO_SNDBUF,
+ // &sock_buflen, (socklen_t)sizeof(sock_buflen));
+
+ return ret;
+}
- sun_path_len = sizeof(srs_sa.sun_path);
- if (strlen(srs_name) > sun_path_len) {
- ERRMSG("init_srs_socket", "srs_name is too long", 0);
- MSG_ERR("\n - it should be <= %lu chars", (ulong_t)sun_path_len);
- MSG_ERR("\n - srs_name = %s\n", srs_name);
- return(retval);
+/*! Bind a socket port on localhost. Try to be close to base_port.
+ * \Return
+ * \li listening socket file descriptor on success
+ * \li -1 on failure
+ */
+int bind_socket_fd(int base_port, int *p_port)
+{
+ int sock_fd, port;
+ struct sockaddr_in sin;
+ int ok = 0, last_port = base_port + 50;
+
+ if ((sock_fd = make_socket_fd()) == -1) {
+ return (-1); /* avoids nested ifs */
}
- strncpy(srs_sa.sun_path, srs_name, sun_path_len);
- addr_sz = (socklen_t) D_SUN_LEN(&srs_sa);
+ /* Set the socket FD to close on exec */
+ fcntl(sock_fd, F_SETFD, FD_CLOEXEC | fcntl(sock_fd, F_GETFD));
- if ((bind(srs, (struct sockaddr *) &srs_sa, addr_sz)) == -1) {
- if (errno == EADDRINUSE) {
- ERRMSG("init_srs_socket", "bind", errno);
- MSG_ERR("srs_sa.sun_path = %s\n", srs_sa.sun_path);
- dpi_errno = dpid_srs_addrinuse;
+
+ memset(&sin, 0, sizeof(sin));
+ sin.sin_family = AF_INET;
+ sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+
+ /* Try to bind a port on localhost */
+ for (port = base_port; port <= last_port; ++port) {
+ sin.sin_port = htons(port);
+ if ((bind(sock_fd, (struct sockaddr *)&sin, sizeof(sin))) == -1) {
+ if (errno == EADDRINUSE || errno == EADDRNOTAVAIL)
+ continue;
+ ERRMSG("bind_socket_fd", "bind", errno);
+ } else if (listen(sock_fd, QUEUE) == -1) {
+ ERRMSG("bind_socket_fd", "listen", errno);
} else {
- ERRMSG("init_srs_socket", "bind", errno);
- MSG_ERR("srs_sa.sun_path = %s\n", srs_sa.sun_path);
+ *p_port = port;
+ ok = 1;
+ break;
}
- } else if (chmod(srs_sa.sun_path, S_IRUSR | S_IWUSR) == -1) {
- ERRMSG("init_srs_socket", "chmod", errno);
- MSG_ERR("srs_sa.sun_path = %s\n", srs_sa.sun_path);
- } else if (listen(srs, QUEUE) == -1) {
- ERRMSG("init_srs_socket", "listen", errno);
+ }
+ if (port > last_port) {
+ MSG_ERR("Hey! Can't find an available port from %d to %d\n",
+ base_port, last_port);
+ }
+
+ return ok ? sock_fd : -1;
+}
+
+/*! Save the current port and a shared secret in a file so dillo can find it.
+ * \Return:
+ * \li -1 on failure
+ */
+int save_comm_keys(int srs_port)
+{
+ int fd, ret = -1;
+ char *fname, port_str[32];
+
+ fname = dStrconcat(dGethomedir(), "/", dotDILLO_DPID_COMM_KEYS, NULL);
+ fd = open(fname, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
+ dFree(fname);
+ if (fd == -1) {
+ MSG("save_comm_keys: open %s\n", dStrerror(errno));
} else {
- retval = 1;
+ snprintf(port_str, 16, "%d %s\n", srs_port, SharedKey);
+ if (CKD_WRITE(fd, port_str) != -1 && CKD_CLOSE(fd) != -1) {
+ ret = 1;
+ }
+ }
+
+ return ret;
+}
+
+/*! Initialise the service request socket (IDS)
+ * \Return:
+ * \li Number of sockets (1 == success)
+ * \li -1 on failure
+ */
+int init_ids_srs_socket()
+{
+ int srs_port, ret = -1;
+
+ FD_ZERO(&sock_set);
+
+ if ((srs_fd = bind_socket_fd(DPID_BASE_PORT, &srs_port)) != -1) {
+ /* create the shared secret */
+ SharedKey = a_Misc_mksecret(8);
+ /* save port number and SharedKey */
+ if (save_comm_keys(srs_port) != -1) {
+ FD_SET(srs_fd, &sock_set);
+ ret = 1;
+ }
}
- FD_SET(srs, &sock_set);
- return (retval);
+ return ret;
}
-/*! Initialise a single dpi socket
+/*! Initialize a single dpi socket
* \Return
* \li 1 on success
* \li -1 on failure
*/
-int init_dpi_socket(struct dp *dpi_attr, char *sockdir)
+int init_dpi_socket(struct dp *dpi_attr)
{
- int caught_error = 0, s;
- char *dpi_nm; /* pointer to basename in dpi_attr->path */
- struct sockaddr_un sa;
- size_t sp_len;
- socklen_t addr_sz;
- size_t sock_buflen = 8192;
-
- sp_len = sizeof(sa.sun_path);
- if ((s = socket(AF_LOCAL, SOCK_STREAM, 0)) == -1) {
- ERRMSG("init_all_dpi_sockets", "socket", errno);
- return (-1); /* avoids nested ifs */
- }
- /* Set the socket FD to close on exec */
- fcntl(s, F_SETFD, FD_CLOEXEC | fcntl(s, F_GETFD));
+ int s_fd, port, ret = -1;
- /* set some buffering to increase the transfer's speed */
- setsockopt(s, SOL_SOCKET, SO_SNDBUF,
- &sock_buflen, (socklen_t)sizeof(sock_buflen));
-
- dpi_attr->socket = s;
- dpi_attr->sa.sun_family = AF_LOCAL;
- dpi_nm = get_basename(dpi_attr->path);
-
- dpi_attr->sockpath = dStrconcat(sockdir, "/", dpi_nm, "-XXXXXX", NULL);
- a_Misc_mkfname(dpi_attr->sockpath);
- if (strlen(dpi_attr->sockpath) > sp_len) {
- ERRMSG("init_all_dpi_sockets", "socket path is too long", 0);
- MSG_ERR("\n - it should be <= %lu chars", (ulong_t)sp_len);
- MSG_ERR("\n - socket path = %s\n", dpi_attr->sockpath);
- return(-1);
- }
- strncpy(dpi_attr->sa.sun_path, dpi_attr->sockpath, sp_len);
- addr_sz = (socklen_t) D_SUN_LEN(&dpi_attr->sa);
-
- if ((bind(s, (struct sockaddr *) &dpi_attr->sa, addr_sz)) == -1) {
- ERRMSG("init_all_dpi_sockets", "bind", errno);
- MSG_ERR("%s\n", dpi_attr->sa.sun_path);
- caught_error = 1;
- } else if (chmod(dpi_attr->sa.sun_path, S_IRUSR | S_IWUSR) == -1) {
- ERRMSG("init_all_dpi_sockets", "chmod", errno);
- MSG_ERR("%s\n", dpi_attr->sa.sun_path);
- caught_error = 1;
- } else if (listen(s, QUEUE) == -1) {
- ERRMSG("init_all_dpi_sockets", "listen", errno);
- caught_error = 1;
- }
-
- if (caught_error) {
- return (-1);
- } else {
- FD_SET(s, &sock_set);
- return (1);
+ if ((s_fd = bind_socket_fd(DPID_BASE_PORT, &port)) != -1) {
+ dpi_attr->sock_fd = s_fd;
+ dpi_attr->port = port;
+ FD_SET(s_fd, &sock_set);
+ ret = 1;
}
+
+ return ret;
}
/*! Setup sockets for the plugins and add them to
- * to the set of sockets (sock_set) watched by select.
+ * the set of sockets (sock_set) watched by select.
* \Return
* \li Number of sockets on success
* \li -1 on failure
@@ -649,17 +654,13 @@ int init_dpi_socket(struct dp *dpi_attr, char *sockdir)
* \Uses
* numdpis, srs, srs_name
*/
-int init_all_dpi_sockets(struct dp *dpi_attr_list, char *sockdir)
+int init_all_dpi_sockets(struct dp *dpi_attr_list)
{
int i;
- struct sockaddr_un sa;
- size_t sp_len;
-
- sp_len = sizeof(sa.sun_path);
/* Initialise sockets for each dpi */
for (i = 0; i < numdpis; i++) {
- if (init_dpi_socket(dpi_attr_list + i, sockdir) == -1)
+ if (init_dpi_socket(dpi_attr_list + i) == -1)
return (-1);
numsocks++;
}
@@ -688,7 +689,7 @@ void handle_sigchld(void)
for (i = 0; i < numdpis; i++) {
if (waitpid(dpi_attr_list[i].pid, &status, WNOHANG) > 0) {
dpi_attr_list[i].pid = 1;
- FD_SET(dpi_attr_list[i].socket, &sock_set);
+ FD_SET(dpi_attr_list[i].sock_fd, &sock_set);
numsocks++;
}
}
@@ -714,45 +715,62 @@ void est_dpi_sigchld(void)
}
}
+/*! EINTR aware connect() call */
+int ckd_connect (int sock_fd, struct sockaddr *addr, socklen_t len)
+{
+ ssize_t ret;
+
+ do {
+ ret = connect(sock_fd, addr, len);
+ } while (ret == -1 && errno == EINTR);
+ if (ret == -1) {
+ ERRMSG("dpid.c", "connect", errno);
+ }
+ return ret;
+}
+
/*! Send DpiBye command to all active non-filter dpis
*/
void stop_active_dpis(struct dp *dpi_attr_list, int numdpis)
{
- static char *DpiBye_cmd = NULL;
- int i, dpi_socket;
- struct sockaddr_un dpi_addr;
- struct sockaddr_un sa;
- size_t sun_path_len, addr_len;
+ char *bye_cmd, *auth_cmd;
+ int i, sock_fd;
+ struct sockaddr_in sin;
- if (!DpiBye_cmd)
- DpiBye_cmd = a_Dpip_build_cmd("cmd=%s", "DpiBye");
+ bye_cmd = a_Dpip_build_cmd("cmd=%s", "DpiBye");
+ auth_cmd = a_Dpip_build_cmd("cmd=%s msg=%s", "auth", SharedKey);
- sun_path_len = sizeof(sa.sun_path);
- addr_len = sizeof(dpi_addr);
-
- dpi_addr.sun_family = AF_LOCAL;
+ memset(&sin, 0, sizeof(sin));
+ sin.sin_family = AF_INET;
+ sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
for (i = 0; i < numdpis; i++) {
/* Skip inactive dpis and filters */
if (dpi_attr_list[i].pid == 1 || dpi_attr_list[i].filter)
continue;
- if ((dpi_socket = socket(AF_LOCAL, SOCK_STREAM, 0)) == -1) {
+ if ((sock_fd = make_socket_fd()) == -1) {
ERRMSG("stop_active_dpis", "socket", errno);
+ continue;
}
- if (strlen(dpi_attr_list[i].sockpath) > sun_path_len) {
- ERRMSG("stop_active_dpis", "socket path is too long", 0);
- MSG_ERR("\n - it should be <= %lu chars",(ulong_t)sun_path_len);
- MSG_ERR("\n - socket path = %s\n", dpi_attr_list[i].sockpath);
- }
- strncpy(dpi_addr.sun_path, dpi_attr_list[i].sockpath, sun_path_len);
- if (connect(dpi_socket, (struct sockaddr *) &dpi_addr, addr_len) == -1) {
+
+ sin.sin_port = htons(dpi_attr_list[i].port);
+ if (ckd_connect(sock_fd, (struct sockaddr *)&sin, sizeof(sin)) == -1) {
ERRMSG("stop_active_dpis", "connect", errno);
- MSG_ERR("%s\n", dpi_addr.sun_path);
+ MSG_ERR("%s\n", dpi_attr_list[i].path);
+ } else if (CKD_WRITE(sock_fd, auth_cmd) == -1) {
+ ERRMSG("stop_active_dpis", "write", errno);
+ } else if (CKD_WRITE(sock_fd, bye_cmd) == -1) {
+ ERRMSG("stop_active_dpis", "write", errno);
}
- (void) write(dpi_socket, DpiBye_cmd, strlen(DpiBye_cmd));
- a_Misc_close_fd(dpi_socket);
+ a_Misc_close_fd(sock_fd);
}
+
+ dFree(auth_cmd);
+ dFree(bye_cmd);
+
+ /* Allow child dpis some time to read dpid_comm_keys before erasing it */
+ sleep (1);
}
/*! Removes dpis in dpi_attr_list from the
@@ -764,8 +782,8 @@ void ignore_dpi_sockets(struct dp *dpi_attr_list, int numdpis)
int i;
for (i = 0; i < numdpis; i++) {
- FD_CLR(dpi_attr_list[i].socket, &sock_set);
- a_Misc_close_fd(dpi_attr_list[i].socket);
+ FD_CLR(dpi_attr_list[i].sock_fd, &sock_set);
+ a_Misc_close_fd(dpi_attr_list[i].sock_fd);
}
}
@@ -776,20 +794,19 @@ void ignore_dpi_sockets(struct dp *dpi_attr_list, int numdpis)
* \Return
* Number of available dpis
*/
-int register_all_cmd(char *sockdir)
+int register_all_cmd()
{
stop_active_dpis(dpi_attr_list, numdpis);
- rm_dpi_sockets(dpi_attr_list, numdpis);
free_plugin_list(&dpi_attr_list, numdpis);
free_services_list(services_list);
services_list = NULL;
numdpis = 0;
numsocks = 1; /* the srs socket */
FD_ZERO(&sock_set);
- FD_SET(srs, &sock_set);
+ FD_SET(srs_fd, &sock_set);
numdpis = register_all(&dpi_attr_list);
fill_services_list(dpi_attr_list, numdpis, &services_list);
- numsocks = init_all_dpi_sockets(dpi_attr_list, sockdir);
+ numsocks = init_all_dpi_sockets(dpi_attr_list);
return (numdpis);
}
@@ -798,16 +815,16 @@ int register_all_cmd(char *sockdir)
* \Return
* message on success, NULL on failure
*/
-char *get_message(int sock, char *dpi_tag)
+char *get_message(int sock_fd, char *dpi_tag)
{
char *msg, *d_cmd;
- msg = a_Dpip_get_attr(dpi_tag, strlen(dpi_tag), "msg");
+ msg = a_Dpip_get_attr(dpi_tag, "msg");
if (msg == NULL) {
ERRMSG("get_message", "failed to parse msg", 0);
d_cmd = a_Dpip_build_cmd("cmd=%s msg=%s",
"DpiError", "Failed to parse request");
- (void) CKD_WRITE(sock, d_cmd);
+ (void) CKD_WRITE(sock_fd, d_cmd);
dFree(d_cmd);
}
return (msg);
@@ -832,40 +849,30 @@ int service_match(const struct service *A, const char *B)
}
/*!
- * Send socket path that matches dpi_id to client
+ * Send socket port that matches dpi_id to client
*/
-void send_sockpath(int sock, char *dpi_tag, struct dp *dpi_attr_list)
+void send_sockport(int sock_fd, char *dpi_tag, struct dp *dpi_attr_list)
{
int i;
- char *dpi_id;
- char *d_cmd;
+ char *dpi_id, *d_cmd, port_str[16];
struct service *serv;
- dReturn_if_fail((dpi_id = get_message(sock, dpi_tag)) != NULL);
+ dReturn_if_fail((dpi_id = get_message(sock_fd, dpi_tag)) != NULL);
serv = dList_find_custom(services_list,dpi_id,(dCompareFunc)service_match);
if (serv == NULL || (i = serv->dp_index) == -1)
for (i = 0; i < numdpis; i++)
if (!strncmp(dpi_attr_list[i].id, dpi_id,
- dpi_attr_list[i].id - strchr(dpi_attr_list[i].id, '.')))
+ dpi_attr_list[i].id - strchr(dpi_attr_list[i].id, '.')))
break;
if (i < numdpis) {
/* found */
- if (access(dpi_attr_list[i].path, F_OK) == -1) {
- ERRMSG("send_sockpath", "access", errno);
- MSG_ERR(" - %s\n", dpi_attr_list[i].sockpath);
- d_cmd = a_Dpip_build_cmd("cmd=%s msg=%s",
- "DpiError", "Plugin currently unavailable");
- (void) CKD_WRITE(sock, d_cmd);
- dFree(d_cmd);
- } else {
- d_cmd = a_Dpip_build_cmd("cmd=%s msg=%s",
- "send_data", dpi_attr_list[i].sockpath);
- (void) CKD_WRITE(sock, d_cmd);
- dFree(d_cmd);
- }
+ snprintf(port_str, 8, "%d", dpi_attr_list[i].port);
+ d_cmd = a_Dpip_build_cmd("cmd=%s msg=%s", "send_data", port_str);
+ (void) CKD_WRITE(sock_fd, d_cmd);
+ dFree(d_cmd);
}
dFree(dpi_id);
diff --git a/dpid/dpid.h b/dpid/dpid.h
index 74686087..8ef67dd5 100644
--- a/dpid/dpid.h
+++ b/dpid/dpid.h
@@ -5,42 +5,38 @@
#ifndef DPID_H
#define DPID_H
-#include <assert.h>
-#include <signal.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <string.h>
#include <sys/socket.h>
-#include <sys/time.h>
+#include <sys/select.h> /* for fd_set */
#include <sys/un.h>
-#include <errno.h>
+#include <signal.h> /* for sig_atomic_t */
+#include <netinet/in.h> /* for ntohl, IPPORT_USERRESERVED and stuff */
#include "d_size.h"
+/* FreeBSD 6.4 doesn't have it */
+#ifndef IPPORT_USERRESERVED
+ #define IPPORT_USERRESERVED 5000
+#endif
#define PATH_LEN 50
#define CMDLEN 20
#define MSGLEN 50
+#define DPID_BASE_PORT (IPPORT_USERRESERVED + 20)
+
/*! \TODO: Should read this from dillorc */
#define SRS_NAME "dpid.srs"
char *srs_name;
-/*! dpid service request socket */
-int srs;
+/*! dpid's service request socket file descriptor */
+int srs_fd;
/*! plugin state information
*/
struct dp {
char *id;
char *path;
- char *sockpath;
- int socket;
- struct sockaddr_un sa;
+ int sock_fd;
+ int port;
pid_t pid;
int filter;
};
@@ -72,9 +68,7 @@ extern volatile sig_atomic_t caught_sigchld;
void rm_dpi_sockets(struct dp *dpi_attr_list, int numdpis);
-int rm_inactive_dpi_sockets(struct dp *dpi_attr_list, int numdpis);
-
-void cleanup(char *socket_dir);
+void cleanup();
void free_dpi_attr(struct dp *dpi_attr);
@@ -92,11 +86,11 @@ int register_all(struct dp **attlist);
int fill_services_list(struct dp *attlist, int numdpis, Dlist **services_list);
-int init_srs_socket(char *sockdir);
+int init_ids_srs_socket();
-int init_dpi_socket(struct dp *dpi_attr, char *sockdir);
+int init_dpi_socket(struct dp *dpi_attr);
-int init_all_dpi_sockets(struct dp *dpi_attr_list, char *sockdir);
+int init_all_dpi_sockets(struct dp *dpi_attr_list);
void dpi_sigchld(int sig);
@@ -104,16 +98,18 @@ void handle_sigchld(void);
void est_dpi_sigchld(void);
+void est_dpi_terminator(void);
+
void stop_active_dpis(struct dp *dpi_attr_list, int numdpis);
void ignore_dpi_sockets(struct dp *dpi_attr_list, int numdpis);
-int register_all_cmd(char *sockdir);
+int register_all_cmd();
char *get_message(int sock, char *dpi_tag);
int service_match(const struct service *A, const char *B);
-void send_sockpath(int sock, char * dpi_tag, struct dp *dpi_attr_list);
+void send_sockport(int sock_fd, char * dpi_tag, struct dp *dpi_attr_list);
#endif
diff --git a/dpid/dpid_common.c b/dpid/dpid_common.c
index a04d9c4f..a903db95 100644
--- a/dpid/dpid_common.c
+++ b/dpid/dpid_common.c
@@ -1,5 +1,16 @@
+/*
+ * File: dpid_common.c
+ *
+ * Copyright 2008 Jorge Arellano Cid <jcid@dillo.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <errno.h>
#include <stdio.h>
-#include <string.h>
#include <unistd.h>
#include "dpid_common.h"
@@ -41,3 +52,22 @@ ssize_t ckd_write(int fd, char *msg, char *file, int line)
}
return (ret);
}
+
+/*!
+ * Provides an error checked close() call.
+ * Call this via the CKD_CLOSE macro
+ * \return close return value
+ */
+ssize_t ckd_close(int fd, char *file, int line)
+{
+ ssize_t ret;
+
+ do {
+ ret = close(fd);
+ } while (ret == -1 && errno == EINTR);
+ if (ret == -1) {
+ MSG_ERR("%s:%d: close: %s\n", file, line, dStrerror(errno));
+ }
+ return (ret);
+}
+
diff --git a/dpid/dpid_common.h b/dpid/dpid_common.h
index 4311a8a8..ed886e19 100644
--- a/dpid/dpid_common.h
+++ b/dpid/dpid_common.h
@@ -9,9 +9,6 @@
* the next patch
*/
-#include <stdio.h>
-#include <errno.h>
-#include <sys/types.h>
#include <dirent.h>
#include "../dlib/dlib.h"
@@ -26,15 +23,18 @@
#define dotDILLO_DPI ".dillo/dpi"
#define dotDILLO_DPIDRC ".dillo/dpidrc"
+#define dotDILLO_DPID_COMM_KEYS ".dillo/dpid_comm_keys"
+
#define ERRMSG(CALLER, CALLED, ERR)\
errmsg(CALLER, CALLED, ERR, __FILE__, __LINE__)
#define _ERRMSG(CALLER, CALLED, ERR)
/*!
- * Macro for calling the ckd_write function
+ * Macros for calling ckd_write and ckd_close functions
*/
#define CKD_WRITE(fd, msg) ckd_write(fd, msg, __FILE__, __LINE__)
+#define CKD_CLOSE(fd) ckd_close(fd, __FILE__, __LINE__)
/*! Error codes for dpid */
@@ -57,5 +57,6 @@ void errmsg(char *caller, char *called, int errornum, char *file, int line);
int no_dotfiles(const struct dirent *filedat);
ssize_t ckd_write(int fd, char *msg, char *file, int line);
+ssize_t ckd_close(int fd, char *file, int line);
#endif
diff --git a/dpid/dpidc b/dpid/dpidc
deleted file mode 100644
index 88b887cb..00000000
--- a/dpid/dpidc
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/usr/bin/perl -w
-# Author: Ferdi Franceschini
-#
-# dpid control program
-# Currently allows
-# register: Tells dpid to register all available dpis
-# stop: Stops dpid.
-
-use strict;
-use IO::Socket::UNIX;
-
-# Get socket directory name
-open(DSD, "<$ENV{HOME}/.dillo/dpi_socket_dir");
-my $dir = <DSD>;
-close(DSD);
-
-my $socket = IO::Socket::UNIX->new(Peer => "$dir/dpid.srs", Type => SOCK_STREAM, Timeout => 1000 ) or die "new: $@";
-
-$socket->autoflush(1);
-
-my %dpi_command = (
- "register" => "<dpi cmd='register_all' '>",
- "stop" => "<dpi cmd='DpiBye' '>",
- );
-
-if ( exists($dpi_command{$ARGV[0]}) ) {
- print $socket $dpi_command{$ARGV[0]};
-} else {
- close($socket);
- print "Usage: dpidc register|stop\n";
-}
diff --git a/dpid/dpidc.c b/dpid/dpidc.c
new file mode 100644
index 00000000..61a91275
--- /dev/null
+++ b/dpid/dpidc.c
@@ -0,0 +1,121 @@
+#include <stdio.h>
+#include <stdlib.h> /* for exit */
+#include <string.h> /* for bzero */
+#include <unistd.h> /* for read and write */
+#include <ctype.h> /* for isxdigit */
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <errno.h>
+
+#include "../dpip/dpip.h"
+
+#define MSG_ERR(...) printf("** ERROR **: " __VA_ARGS__);
+
+char *CMD_REGISTER = "<cmd='register_all' '>";
+char *CMD_STOP = "<cmd='DpiBye' '>";
+
+static char SharedKey[32];
+
+static void print_usage(const char *prgname)
+{
+ fprintf(stderr,"Control program for the Dillo plugin daemon\n"
+ "Usage: %s {stop|register|chat}\n\n", prgname);
+}
+
+static void error(char *msg)
+{
+ perror(msg);
+ exit(1);
+}
+
+/*
+ * Read dpid's communication keys from its saved file.
+ * Return value: 1 on success, -1 on error.
+ */
+static int Dpi_read_comm_keys(int *port)
+{
+ FILE *In;
+ char *fname, *rcline = NULL, *tail;
+ int i, ret = -1;
+
+ fname = dStrconcat(dGethomedir(), "/.dillo/dpid_comm_keys", NULL);
+ if ((In = fopen(fname, "r")) == NULL) {
+ MSG_ERR("[Dpi_read_comm_keys] %s\n", dStrerror(errno));
+ } else if ((rcline = dGetline(In)) == NULL) {
+ MSG_ERR("[Dpi_read_comm_keys] empty file: %s\n", fname);
+ } else {
+ *port = strtol(rcline, &tail, 10);
+ for (i = 0; *tail && isxdigit(tail[i+1]); ++i)
+ SharedKey[i] = tail[i+1];
+ SharedKey[i] = 0;
+ ret = 1;
+ }
+ dFree(rcline);
+ dFree(fname);
+
+ return ret;
+}
+
+int main(int argc, char *argv[])
+{
+ int sockfd, portno, n;
+ struct sockaddr_in serv_addr;
+ char buffer[256];
+
+ if (argc != 2) {
+ print_usage(argv[0]);
+ exit(1);
+ }
+
+ /* Read dpid's port number from saved file */
+ if (Dpi_read_comm_keys(&portno) == -1) {
+ MSG_ERR("main: Can't read dpid's port number\n");
+ exit(1);
+ }
+
+ sockfd = socket(AF_INET, SOCK_STREAM, 0);
+ if (sockfd < 0)
+ error("ERROR opening socket");
+ bzero((char *) &serv_addr, sizeof(serv_addr));
+ serv_addr.sin_family = AF_INET;
+ serv_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+
+ serv_addr.sin_port = htons(portno);
+ if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
+ error("ERROR connecting");
+
+ snprintf(buffer, sizeof(buffer), "<cmd='auth' msg='%s' '>", SharedKey);
+ n = write(sockfd, buffer, strlen(buffer));
+ if (n < 0)
+ error("ERROR writing to socket");
+
+ if (strcmp(argv[1], "stop") == 0) {
+ strcpy(buffer, CMD_STOP);
+ } else if (strcmp(argv[1], "register") == 0) {
+ strcpy(buffer, CMD_REGISTER);
+ } else if (strcmp(argv[1], "chat") == 0) {
+ printf("Please enter the message: ");
+ bzero(buffer,256);
+ if (fgets(buffer,255,stdin) == NULL)
+ MSG_ERR("dpidc: Can't read the message\n");
+ } else {
+ MSG_ERR("main: Unknown operation '%s'\n", argv[1]);
+ print_usage(argv[0]);
+ exit(1);
+ }
+
+ n = write(sockfd,buffer,strlen(buffer));
+ if (n < 0)
+ error("ERROR writing to socket");
+/*
+ bzero(buffer,256);
+ n = read(sockfd,buffer,255);
+ if (n < 0)
+ error("ERROR reading from socket");
+ printf("%s\n",buffer);
+*/
+ close(sockfd);
+ return 0;
+}
diff --git a/dpid/dpidrc.in b/dpid/dpidrc.in
new file mode 100644
index 00000000..23374d96
--- /dev/null
+++ b/dpid/dpidrc.in
@@ -0,0 +1,6 @@
+dpi_dir=@libdir@/dillo/dpi
+
+proto.file=file/file.dpi
+proto.ftp=ftp/ftp.filter.dpi
+proto.https=https/https.filter.dpi
+proto.data=datauri/datauri.filter.dpi
diff --git a/dpid/main.c b/dpid/main.c
index b47ca627..5f512245 100644
--- a/dpid/main.c
+++ b/dpid/main.c
@@ -12,16 +12,15 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <errno.h>
-#include <unistd.h>
-#include <limits.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <assert.h>
+#include <errno.h> /* for ckd_write */
+#include <unistd.h> /* for ckd_write */
+#include <stdlib.h> /* for exit */
+#include <assert.h> /* for assert */
+#include <sys/stat.h> /* for umask */
+
#include "dpid_common.h"
#include "dpid.h"
#include "dpi.h"
@@ -46,7 +45,7 @@ static int start_filter_plugin(struct dp dpi_attr)
csz = (socklen_t) sizeof(clnt_addr);
- newsock = accept(dpi_attr.socket, (struct sockaddr *) &clnt_addr, &csz);
+ newsock = accept(dpi_attr.sock_fd, (struct sockaddr *) &clnt_addr, &csz);
if (newsock == -1)
ERRMSG("start_plugin", "accept", errno);
@@ -69,7 +68,7 @@ static int start_filter_plugin(struct dp dpi_attr)
}
if (pid == 0) {
/* Child, start plugin */
- if (execl(dpi_attr.path, dpi_attr.path, NULL) == -1) {
+ if (execl(dpi_attr.path, dpi_attr.path, (char*)NULL) == -1) {
ERRMSG("start_plugin", "execl", errno);
MSG_ERR("ERROR in child proc for %s\n", dpi_attr.path);
exit(1);
@@ -91,17 +90,17 @@ static int start_filter_plugin(struct dp dpi_attr)
static void start_server_plugin(struct dp dpi_attr)
{
- if (dup2(dpi_attr.socket, STDIN_FILENO) == -1) {
+ if (dup2(dpi_attr.sock_fd, STDIN_FILENO) == -1) {
ERRMSG("start_plugin", "dup2", errno);
MSG_ERR("ERROR in child proc for %s\n", dpi_attr.path);
exit(1);
}
- if (a_Misc_close_fd(dpi_attr.socket) == -1) {
+ if (a_Misc_close_fd(dpi_attr.sock_fd) == -1) {
ERRMSG("start_plugin", "close", errno);
MSG_ERR("ERROR in child proc for %s\n", dpi_attr.path);
exit(1);
}
- if (execl(dpi_attr.path, dpi_attr.path, NULL) == -1) {
+ if (execl(dpi_attr.path, dpi_attr.path, (char*)NULL) == -1) {
ERRMSG("start_plugin", "execl", errno);
MSG_ERR("ERROR in child proc for %s\n", dpi_attr.path);
exit(1);
@@ -113,32 +112,15 @@ static void start_server_plugin(struct dp dpi_attr)
* \Return
* pointer to dynamically allocated request tag
*/
-static char *get_request(int sock)
+static char *get_request(Dsh *sh)
{
- char *req, buf[10];
- size_t buflen;
- size_t rqsz;
- ssize_t rdln;
-
- req = NULL;
- buf[0] = '\0';
- buflen = sizeof(buf) / sizeof(buf[0]);
+ char *dpip_tag;
(void) sigprocmask(SIG_BLOCK, &mask_sigchld, NULL);
- for (rqsz = 0; (rdln = read(sock, buf, buflen)) != 0; rqsz += rdln) {
- if (rdln == -1)
- break;
- req = (char *) realloc(req, rqsz + rdln + 1);
- if (rqsz == 0)
- req[0] = '\0';
- strncat(req, buf, (size_t) rdln);
- }
+ dpip_tag = a_Dpip_dsh_read_token(sh, 1);
(void) sigprocmask(SIG_UNBLOCK, &mask_sigchld, NULL);
- if (rdln == -1) {
- ERRMSG("get_request", "read", errno);
- }
- return (req);
+ return dpip_tag;
}
/*!
@@ -146,7 +128,7 @@ static char *get_request(int sock)
* \Return
* command code on success, -1 on failure
*/
-static int get_command(int sock, char *dpi_tag)
+static int get_command(Dsh *sh, char *dpi_tag)
{
char *cmd, *d_cmd;
int COMMAND;
@@ -156,16 +138,18 @@ static int get_command(int sock, char *dpi_tag)
return (-1);
}
- cmd = a_Dpip_get_attr(dpi_tag, strlen(dpi_tag), "cmd");
+ cmd = a_Dpip_get_attr(dpi_tag, "cmd");
if (cmd == NULL) {
ERRMSG("get_command", "a_Dpip_get_attr", 0);
MSG_ERR(": dpid failed to parse cmd in %s\n", dpi_tag);
d_cmd = a_Dpip_build_cmd("cmd=%s msg=%s",
"DpiError", "Failed to parse request");
- (void) CKD_WRITE(sock, d_cmd);
+ a_Dpip_dsh_write_str(sh, 1, d_cmd);
dFree(d_cmd);
COMMAND = -1;
+ } else if (strcmp("auth", cmd) == 0) {
+ COMMAND = AUTH_CMD;
} else if (strcmp("DpiBye", cmd) == 0) {
COMMAND = BYE_CMD;
} else if (strcmp("check_server", cmd) == 0) {
@@ -221,7 +205,6 @@ static int get_open_max(void)
int main(void)
{
int i, n = 0, open_max;
- char *dirname = NULL, *sockdir = NULL;
int dpid_idle_timeout = 60 * 60; /* default, in seconds */
struct timeval select_timeout;
sigset_t mask_none;
@@ -251,6 +234,7 @@ int main(void)
/* Get list of available dpis */
numdpis = register_all(&dpi_attr_list);
+#if 0
/* Get name of socket directory */
dirname = a_Dpi_sockdir_file();
if ((sockdir = init_sockdir(dirname)) == NULL) {
@@ -258,14 +242,16 @@ int main(void)
MSG_ERR("Failed to create socket directory\n");
exit(1);
}
+#endif
/* Init and get services list */
fill_services_list(dpi_attr_list, numdpis, &services_list);
/* Remove any sockets that may have been leftover from a crash */
- cleanup(sockdir);
+ //cleanup();
+
/* Initialise sockets */
- if ((numsocks = init_srs_socket(sockdir)) == -1) {
+ if ((numsocks = init_ids_srs_socket()) == -1) {
switch (dpi_errno) {
case dpid_srs_addrinuse:
MSG_ERR("dpid refuses to start, possibly because:\n");
@@ -273,12 +259,13 @@ int main(void)
MSG_ERR("\t2) A previous dpid didn't clean up on exit.\n");
exit(1);
default:
- ERRMSG("main", "init_srs_sockets failed", 0);
+ //ERRMSG("main", "init_srs_socket failed", 0);
+ ERRMSG("main", "init_ids_srs_socket failed", 0);
exit(1);
}
}
- numsocks = init_all_dpi_sockets(dpi_attr_list, sockdir);
- //est_terminator(); /* Do we still want to clean up on an abnormal exit? */
+ numsocks = init_all_dpi_sockets(dpi_attr_list);
+ est_dpi_terminator();
est_dpi_sigchld();
(void) sigemptyset(&mask_sigchld);
@@ -309,7 +296,7 @@ int main(void)
continue;
stop_active_dpis(dpi_attr_list, numdpis);
- cleanup(sockdir);
+ //cleanup();
exit(0);
}
} while (n == -1 && errno == EINTR);
@@ -319,42 +306,51 @@ int main(void)
exit(1);
}
/* If the service req socket is selected then service the req. */
- if (FD_ISSET(srs, &selected_set)) {
- int sock;
- socklen_t csz;
- struct sockaddr_un clnt_addr;
+ if (FD_ISSET(srs_fd, &selected_set)) {
+ int sock_fd;
+ socklen_t sin_sz;
+ struct sockaddr_in sin;
char *req = NULL;
--n;
assert(n >= 0);
- csz = (socklen_t) sizeof(clnt_addr);
- sock = accept(srs, (struct sockaddr *) &clnt_addr, &csz);
- if (sock == -1) {
+ sin_sz = (socklen_t) sizeof(sin);
+ sock_fd = accept(srs_fd, (struct sockaddr *)&sin, &sin_sz);
+ if (sock_fd == -1) {
ERRMSG("main", "accept", errno);
MSG_ERR("accept on srs socket failed\n");
MSG_ERR("service pending connections, and continue\n");
} else {
int command;
+ Dsh *sh;
- req = get_request(sock);
- command = get_command(sock, req);
+ sh = a_Dpip_dsh_new(sock_fd, sock_fd, 1024);
+read_next:
+ req = get_request(sh);
+ command = get_command(sh, req);
switch (command) {
+ case AUTH_CMD:
+ if (a_Dpip_check_auth(req) != -1) {
+ dFree(req);
+ goto read_next;
+ }
+ break;
case BYE_CMD:
stop_active_dpis(dpi_attr_list, numdpis);
- cleanup(sockdir);
+ //cleanup();
exit(0);
break;
case CHECK_SERVER_CMD:
- send_sockpath(sock, req, dpi_attr_list);
+ send_sockport(sock_fd, req, dpi_attr_list);
break;
case REGISTER_ALL_CMD:
- register_all_cmd(sockdir);
+ register_all_cmd();
break;
case UNKNOWN_CMD:
{
char *d_cmd = a_Dpip_build_cmd("cmd=%s msg=%s",
"DpiError", "Unknown command");
- (void) CKD_WRITE(sock, d_cmd);
+ (void) CKD_WRITE(sock_fd, d_cmd);
dFree(d_cmd);
ERRMSG("main", "Unknown command", 0);
MSG_ERR(" for request: %s\n", req);
@@ -366,14 +362,15 @@ int main(void)
}
if (req)
free(req);
- a_Misc_close_fd(sock);
+ a_Dpip_dsh_close(sh);
+ a_Dpip_dsh_free(sh);
}
}
/* While there's a request on one of the plugin sockets
* find the matching plugin and start it. */
for (i = 0; n > 0 && i < numdpis; i++) {
- if (FD_ISSET(dpi_attr_list[i].socket, &selected_set)) {
+ if (FD_ISSET(dpi_attr_list[i].sock_fd, &selected_set)) {
--n;
assert(n >= 0);
@@ -387,11 +384,12 @@ int main(void)
* on its socket */
numsocks--;
assert(numsocks >= 0);
- FD_CLR(dpi_attr_list[i].socket, &sock_set);
+ FD_CLR(dpi_attr_list[i].sock_fd, &sock_set);
if ((dpi_attr_list[i].pid = fork()) == -1) {
ERRMSG("main", "fork", errno);
/* exit(1); */
} else if (dpi_attr_list[i].pid == 0) {
+ /* child */
(void) sigprocmask(SIG_SETMASK, &mask_none, NULL);
start_server_plugin(dpi_attr_list[i]);
}
diff --git a/dpid/misc_new.c b/dpid/misc_new.c
index f85f43e4..7f963aed 100644
--- a/dpid/misc_new.c
+++ b/dpid/misc_new.c
@@ -1,17 +1,23 @@
-#include <stdio.h>
-#include <time.h>
-#include <stdlib.h>
-#include <string.h>
+/*
+ * File: misc_new.c
+ *
+ * Copyright 2008 Jorge Arellano Cid <jcid@dillo.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <errno.h> /* errno, err-codes */
#include <unistd.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <errno.h>
-#include <fcntl.h>
-#include "d_size.h"
-#include "misc_new.h"
-#include "dpid_common.h"
+#include <time.h>
+#include <sys/stat.h> /* stat */
+#include <stdlib.h> /* rand, srand */
-#include "misc_new.h" /* for function prototypes */
+#include "../dlib/dlib.h"
+#include "dpid_common.h"
+#include "misc_new.h" /* for function prototypes */
/*
@@ -159,7 +165,7 @@ char *a_Misc_mkfname(char *template)
{
char *tmp = template + strlen(template) - 6;
int i;
- unsigned int random;
+ uint_t random;
struct stat stat_buf;
if (tmp < template)
@@ -185,3 +191,26 @@ char *a_Misc_mkfname(char *template)
MSG_ERR("a_Misc_mkfname: another round for %s \n", template);
}
}
+
+/*
+ * Return a new, random hexadecimal string of 'nchar' characters.
+ */
+char *a_Misc_mksecret(int nchar)
+{
+ int i;
+ uint_t random;
+ char *secret = dNew(char, nchar + 1);
+
+ srand((uint_t)(time(0) ^ getpid()));
+ random = (unsigned) rand();
+ for (i = 0; i < nchar; ++i) {
+ int hexdigit = (random >> (i * 5)) & 0x0f;
+
+ secret[i] = hexdigit > 9 ? hexdigit + 'a' - 10 : hexdigit + '0';
+ }
+ secret[i] = 0;
+ MSG("a_Misc_mksecret: %s\n", secret);
+
+ return secret;
+}
+
diff --git a/dpid/misc_new.h b/dpid/misc_new.h
index e2bf6e9a..325451a1 100644
--- a/dpid/misc_new.h
+++ b/dpid/misc_new.h
@@ -1,13 +1,12 @@
#ifndef MISC_NEW_H
#define MISC_NEW_H
-#include "../dlib/dlib.h"
-
int a_Misc_close_fd(int fd);
Dstr *a_Misc_rdtag(int socket);
char *a_Misc_readtag(int sock);
char *a_Misc_mkdtemp(char *template);
char *a_Misc_mkfname(char *template);
+char *a_Misc_mksecret(int nchar);
#endif