aboutsummaryrefslogtreecommitdiff
path: root/src/IO/dpi.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/IO/dpi.c')
-rw-r--r--src/IO/dpi.c497
1 files changed, 265 insertions, 232 deletions
diff --git a/src/IO/dpi.c b/src/IO/dpi.c
index 7c4357da..6f46b2ba 100644
--- a/src/IO/dpi.c
+++ b/src/IO/dpi.c
@@ -21,16 +21,16 @@
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <errno.h> /* for errno */
+#include <fcntl.h>
+#include <ctype.h> /* isxdigit */
-#include <stdio.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
+#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <netdb.h>
@@ -75,7 +75,7 @@ typedef struct {
*/
static Klist_t *ValidConns = NULL; /* Active connections list. It holds
* pointers to dpi_conn_t structures. */
-
+static char SharedKey[32];
/*
* Initialize local data
@@ -92,6 +92,7 @@ static void Dpi_close_fd(int fd)
{
int st;
+ dReturn_if (fd < 0);
do
st = close(fd);
while (st < 0 && errno == EINTR);
@@ -224,14 +225,14 @@ static void Dpi_parse_token(dpi_conn_t *conn)
tag = dStrndup(Tok, (size_t)conn->TokSize);
_MSG("Dpi_parse_token: {%s}\n", tag);
- cmd = a_Dpip_get_attr(Tok, conn->TokSize, "cmd");
+ cmd = a_Dpip_get_attr_l(Tok, conn->TokSize, "cmd");
if (strcmp(cmd, "send_status_message") == 0) {
- msg = a_Dpip_get_attr(Tok, conn->TokSize, "msg");
+ msg = a_Dpip_get_attr_l(Tok, conn->TokSize, "msg");
a_Chain_fcb(OpSend, conn->InfoRecv, msg, cmd);
dFree(msg);
} else if (strcmp(cmd, "chat") == 0) {
- msg = a_Dpip_get_attr(Tok, conn->TokSize, "msg");
+ msg = a_Dpip_get_attr_l(Tok, conn->TokSize, "msg");
a_Chain_fcb(OpSend, conn->InfoRecv, msg, cmd);
dFree(msg);
@@ -241,13 +242,13 @@ static void Dpi_parse_token(dpi_conn_t *conn)
} else if (strcmp(cmd, "start_send_page") == 0) {
conn->Send2EOF = 1;
- urlstr = a_Dpip_get_attr(Tok, conn->TokSize, "url");
+ urlstr = a_Dpip_get_attr_l(Tok, conn->TokSize, "url");
a_Chain_fcb(OpSend, conn->InfoRecv, urlstr, cmd);
dFree(urlstr);
- /* TODO: a_Dpip_get_attr(Tok, conn->TokSize, "send_mode") */
+ /* TODO: a_Dpip_get_attr_l(Tok, conn->TokSize, "send_mode") */
} else if (strcmp(cmd, "reload_request") == 0) {
- urlstr = a_Dpip_get_attr(Tok, conn->TokSize, "url");
+ urlstr = a_Dpip_get_attr_l(Tok, conn->TokSize, "url");
a_Chain_fcb(OpSend, conn->InfoRecv, urlstr, cmd);
dFree(urlstr);
}
@@ -260,6 +261,66 @@ static void Dpi_parse_token(dpi_conn_t *conn)
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*
+ * Write data into a file descriptor taking care of EINTR
+ * and possible data splits.
+ * Return value: 1 on success, -1 on error.
+ */
+static int Dpi_blocking_write(int fd, const char *msg, int msg_len)
+{
+ int st, sent = 0;
+
+ while (sent < msg_len) {
+ st = write(fd, msg + sent, msg_len - sent);
+ if (st < 0) {
+ if (errno == EINTR) {
+ continue;
+ } else {
+ MSG_ERR("[Dpi_blocking_write] %s\n", dStrerror(errno));
+ break;
+ }
+ }
+ sent += st;
+ }
+
+ return (sent == msg_len) ? 1 : -1;
+}
+
+/*
+ * Read all the available data from a filedescriptor.
+ * This is intended for short answers, i.e. when we know the server
+ * will write it all before being preempted. For answers that may come
+ * as an stream with delays, non-blocking is better.
+ * Return value: read data, or NULL on error and no data.
+ */
+static char *Dpi_blocking_read(int fd)
+{
+ int st;
+ const int buf_sz = 8*1024;
+ char buf[buf_sz], *msg = NULL;
+ Dstr *dstr = dStr_sized_new(buf_sz);
+
+ do {
+ st = read(fd, buf, buf_sz);
+ if (st < 0) {
+ if (errno == EINTR) {
+ continue;
+ } else {
+ MSG_ERR("[Dpi_blocking_read] %s\n", dStrerror(errno));
+ break;
+ }
+ } else if (st > 0) {
+ dStr_append_l(dstr, buf, st);
+ }
+ } while (st == buf_sz);
+
+ msg = (dstr->len > 0) ? dstr->str : NULL;
+ dStr_free(dstr, (dstr->len > 0) ? FALSE : TRUE);
+ return msg;
+}
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+/*
* Get a new data buffer (within a 'dbuf'), save it into local data,
* split in tokens and parse the contents.
*/
@@ -290,8 +351,8 @@ static void Dpi_process_dbuf(int Op, void *Data1, dpi_conn_t *conn)
static int Dpi_start_dpid(void)
{
pid_t pid;
- int st_pipe[2], n, ret = 1;
- char buf[16];
+ int st_pipe[2], ret = 1;
+ char *answer;
/* create a pipe to track our child's status */
if (pipe(st_pipe))
@@ -302,15 +363,19 @@ static int Dpi_start_dpid(void)
/* This is the child process. Execute the command. */
char *path1 = dStrconcat(dGethomedir(), "/.dillo/dpid", NULL);
Dpi_close_fd(st_pipe[0]);
- if (execl(path1, "dpid", NULL) == -1) {
+ if (execl(path1, "dpid", (char*)NULL) == -1) {
dFree(path1);
- if (execlp("dpid", "dpid", NULL) == -1) {
- MSG("Dpi_start_dpid (child): %s\n", dStrerror(errno));
- do
- n = write(st_pipe[1], "ERROR", 5);
- while (n == -1 && errno == EINTR);
- Dpi_close_fd(st_pipe[1]);
- _exit (EXIT_FAILURE);
+ path1 = dStrconcat(DILLO_BINDIR, "dpid", NULL);
+ if (execl(path1, "dpid", (char*)NULL) == -1) {
+ dFree(path1);
+ if (execlp("dpid", "dpid", (char*)NULL) == -1) {
+ MSG("Dpi_start_dpid (child): %s\n", dStrerror(errno));
+ if (Dpi_blocking_write(st_pipe[1], "ERROR", 5) == -1) {
+ MSG("Dpi_start_dpid (child): can't write to pipe.\n");
+ }
+ Dpi_close_fd(st_pipe[1]);
+ _exit (EXIT_FAILURE);
+ }
}
}
} else if (pid < 0) {
@@ -323,89 +388,90 @@ static int Dpi_start_dpid(void)
} else {
/* This is the parent process, check our child status... */
Dpi_close_fd(st_pipe[1]);
- do
- n = read(st_pipe[0], buf, 16);
- while (n == -1 && errno == EINTR);
- _MSG("Dpi_start_dpid: n = %d\n", n);
- if (n != 5) {
- ret = 0;
+ if ((answer = Dpi_blocking_read(st_pipe[0])) != NULL) {
+ MSG("Dpi_start_dpid: can't start dpid\n");
+ dFree(answer);
} else {
- MSG("Dpi_start_dpid: %s\n", dStrerror(errno));
+ ret = 0;
}
+ Dpi_close_fd(st_pipe[0]);
}
return ret;
}
/*
- * Make a connection test for a UDS.
- * Return: 0 OK, 1 Not working.
+ * Read dpid's communication keys from its saved file.
+ * Return value: 1 on success, -1 on error.
*/
-static int Dpi_check_uds(char *uds_name)
+static int Dpi_read_comm_keys(int *port)
{
- struct sockaddr_un pun;
- int SockFD, ret = 1;
-
- if (access(uds_name, W_OK) == 0) {
- /* socket connection test */
- memset(&pun, 0, sizeof(struct sockaddr_un));
- pun.sun_family = AF_LOCAL;
- strncpy(pun.sun_path, uds_name, sizeof (pun.sun_path));
-
- if ((SockFD = socket(AF_LOCAL, SOCK_STREAM, 0)) == -1 ||
- connect(SockFD, (void*)&pun, D_SUN_LEN(&pun)) == -1) {
- MSG("Dpi_check_uds: %s %s\n", dStrerror(errno), uds_name);
- } else {
- Dpi_close_fd(SockFD);
- ret = 0;
- }
+ 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;
}
+ if (In)
+ fclose(In);
+ dFree(rcline);
+ dFree(fname);
+
return ret;
}
/*
- * Return the directory where the UDS are in,
- * NULL if it can't be found.
+ * Return a socket file descriptor
*/
-static char *Dpi_get_dpid_uds_dir(void)
+static int Dpi_make_socket_fd()
{
- FILE *in;
- char *saved_name_filename; /* :) */
- char dpid_uds_dir[256], *p = NULL;
-
- saved_name_filename =
- dStrconcat(dGethomedir(), "/.dillo/dpi_socket_dir", NULL);
- in = fopen(saved_name_filename, "r");
- dFree(saved_name_filename);
-
- if (in != NULL) {
- fgets(dpid_uds_dir, 256, in);
- fclose(in);
- if ((p = strchr(dpid_uds_dir, '\n'))) {
- *p = 0;
- }
- if (access(dpid_uds_dir, F_OK) == 0) {
- p = dStrdup(dpid_uds_dir);
- _MSG("Dpi_get_dpid_uds_dir:: %s\n", p);
- }
- }
+ int fd, one = 1, ret = -1;
- _MSG("Dpi_get_dpid_uds_dir: %s \n", dStrerror(errno));
- return p;
+ if ((fd = socket(AF_INET, SOCK_STREAM, 0)) != -1) {
+ /* avoid delays when sending small pieces of data */
+ setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one));
+ ret = fd;
+ }
+ return ret;
}
/*
- * Return the dpid's UDS name, NULL on failure.
+ * Make a connection test for a IDS.
+ * Return: 1 OK, -1 Not working.
*/
-static char *Dpi_get_dpid_uds_name(void)
+static int Dpi_check_dpid_ids()
{
- char *dpid_uds_dir, *dpid_uds_name = NULL;
-
- if ((dpid_uds_dir = Dpi_get_dpid_uds_dir()) != NULL)
- dpid_uds_name= dStrconcat(dpid_uds_dir, "/", "dpid.srs", NULL);
-
- dFree(dpid_uds_dir);
- return dpid_uds_name;
+ struct sockaddr_in sin;
+ const socklen_t sin_sz = sizeof(sin);
+ int sock_fd, dpid_port, ret = -1;
+
+ /* socket connection test */
+ memset(&sin, 0, sizeof(sin));
+ sin.sin_family = AF_INET;
+ sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+
+ if (Dpi_read_comm_keys(&dpid_port) != -1) {
+ sin.sin_port = htons(dpid_port);
+ if ((sock_fd = Dpi_make_socket_fd()) == -1) {
+ MSG("Dpi_check_dpid_ids: sock_fd=%d %s\n", sock_fd, dStrerror(errno));
+ } else if (connect(sock_fd, (struct sockaddr *)&sin, sin_sz) == -1) {
+ MSG("Dpi_check_dpid_ids: %s\n", dStrerror(errno));
+ } else {
+ Dpi_close_fd(sock_fd);
+ ret = 1;
+ }
+ }
+ return ret;
}
/*
@@ -415,20 +481,16 @@ static char *Dpi_get_dpid_uds_name(void)
static int Dpi_check_dpid(int num_tries)
{
static int starting = 0;
- char *dpid_uds_name;
int check_st = 1, ret = 2;
- if ((dpid_uds_name = Dpi_get_dpid_uds_name()))
- check_st = Dpi_check_uds(dpid_uds_name);
-
- _MSG("Dpi_check_dpid: dpid_uds_name=%s, check_st=%d\n",
- dpid_uds_name, check_st);
+ check_st = Dpi_check_dpid_ids();
+ _MSG("Dpi_check_dpid: check_st=%d\n", check_st);
- if (check_st == 0) {
+ if (check_st == 1) {
/* connection test with dpi server passed */
starting = 0;
ret = 0;
- } else if (!dpid_uds_name || check_st) {
+ } else {
if (!starting) {
/* start dpid */
if (Dpi_start_dpid() == 0) {
@@ -436,6 +498,7 @@ static int Dpi_check_dpid(int num_tries)
ret = 1;
}
} else if (++starting < num_tries) {
+ /* starting */
ret = 1;
} else {
/* we waited too much, report an error... */
@@ -443,7 +506,6 @@ static int Dpi_check_dpid(int num_tries)
}
}
- dFree(dpid_uds_name);
_MSG("Dpi_check_dpid:: %s\n",
(ret == 0) ? "OK" : (ret == 1 ? "EAGAIN" : "ERROR"));
return ret;
@@ -467,132 +529,137 @@ static int Dpi_blocking_start_dpid(void)
}
/*
- * Return the UDS name of a dpi server.
+ * Return the dpi server's port number, or -1 on error.
* (A query is sent to dpid and then its answer parsed)
* note: as the available servers and/or the dpi socket directory can
* change at any time, we'll ask each time. If someday we find
* that connecting each time significantly degrades performance,
* an optimized approach can be tried.
*/
-static char *Dpi_get_server_uds_name(const char *server_name)
+static int Dpi_get_server_port(const char *server_name)
{
- char *dpid_uds_dir, *dpid_uds_name = NULL,
- *server_uds_name = NULL;
- int st;
-
- dReturn_val_if_fail (server_name != NULL, NULL);
- _MSG("Dpi_get_server_uds_name:: server_name = [%s]\n", server_name);
-
- dpid_uds_dir = Dpi_get_dpid_uds_dir();
- if (dpid_uds_dir) {
- struct sockaddr_un dpid;
- int sock, req_sz, rdlen;
- char buf[128], *cmd, *request, *rply;
- size_t buflen;
-
- /* Get the server's uds name from dpid */
- sock = socket(AF_LOCAL, SOCK_STREAM, 0);
- dpid.sun_family = AF_LOCAL;
- dpid_uds_name = dStrconcat(dpid_uds_dir, "/", "dpid.srs", NULL);
- _MSG("dpid_uds_name = [%s]\n", dpid_uds_name);
- strncpy(dpid.sun_path, dpid_uds_name, sizeof(dpid.sun_path));
-
- if (connect(sock, (struct sockaddr *) &dpid, sizeof(dpid)) == -1)
- perror("connect");
- /* ask dpid to check the server plugin and send its UDS name back */
+ int sock_fd = -1, dpi_port = -1;
+ int dpid_port, ok = 0;
+ struct sockaddr_in sin;
+ char *cmd, *request, *rply = NULL, *port_str;
+ socklen_t sin_sz;
+
+ dReturn_val_if_fail (server_name != NULL, dpi_port);
+ _MSG("Dpi_get_server_port:: server_name = [%s]\n", server_name);
+
+ /* Read dpid's port from saved file */
+ if (Dpi_read_comm_keys(&dpid_port) != -1) {
+ ok = 1;
+ }
+ if (ok) {
+ /* Connect a socket with dpid */
+ ok = 0;
+ sin_sz = sizeof(sin);
+ memset(&sin, 0, sizeof(sin));
+ sin.sin_family = AF_INET;
+ sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ sin.sin_port = htons(dpid_port);
+ if ((sock_fd = Dpi_make_socket_fd()) == -1 ||
+ connect(sock_fd, (struct sockaddr *)&sin, sin_sz) == -1) {
+ MSG("Dpi_get_server_port: %s\n", dStrerror(errno));
+ } else {
+ ok = 1;
+ }
+ }
+ if (ok) {
+ /* ask dpid to check the dpi and send its port number back */
+ ok = 0;
request = a_Dpip_build_cmd("cmd=%s msg=%s", "check_server", server_name);
_MSG("[%s]\n", request);
- do
- st = write(sock, request, strlen(request));
- while (st < 0 && errno == EINTR);
- if (st < 0 && errno != EINTR)
- perror("writing request");
- dFree(request);
- shutdown(sock, 1); /* signals no more writes to dpid */
+ if (Dpi_blocking_write(sock_fd, request, strlen(request)) == -1) {
+ MSG("Dpi_get_server_port: %s\n", dStrerror(errno));
+ } else {
+ ok = 1;
+ }
+ dFree(request);
+ }
+ if (ok) {
/* Get the reply */
- rply = NULL;
- buf[0] = '\0';
- buflen = sizeof(buf)/sizeof(buf[0]);
- for (req_sz = 0; (rdlen = read(sock, buf, buflen)) != 0;
- req_sz += rdlen) {
- if (rdlen == -1 && errno == EINTR)
- continue;
- if (rdlen == -1) {
- perror(" ** Dpi_get_server_uds_name **");
- break;
- }
- rply = dRealloc(rply, (uint_t)(req_sz + rdlen + 1));
- if (req_sz == 0)
- rply[0] = '\0';
- strncat(rply, buf, (size_t)rdlen);
+ ok = 0;
+ if ((rply = Dpi_blocking_read(sock_fd)) == NULL) {
+ MSG("Dpi_get_server_port: can't read server port from dpid.\n");
+ } else {
+ ok = 1;
}
- Dpi_close_fd(sock);
- _MSG("rply = [%s]\n", rply);
-
+ }
+ if (ok) {
/* Parse reply */
- if (rdlen == 0 && rply) {
- cmd = a_Dpip_get_attr(rply, (int)strlen(rply), "cmd");
- if (strcmp(cmd, "send_data") == 0)
- server_uds_name = a_Dpip_get_attr(rply, (int)strlen(rply), "msg");
- dFree(cmd);
- dFree(rply);
+ ok = 0;
+ cmd = a_Dpip_get_attr(rply, "cmd");
+ if (strcmp(cmd, "send_data") == 0) {
+ port_str = a_Dpip_get_attr(rply, "msg");
+ _MSG("Dpi_get_server_port: rply=%s\n", rply);
+ _MSG("Dpi_get_server_port: port_str=%s\n", port_str);
+ dpi_port = strtol(port_str, NULL, 10);
+ dFree(port_str);
+ ok = 1;
}
+ dFree(cmd);
}
- dFree(dpid_uds_dir);
- dFree(dpid_uds_name);
- _MSG("Dpi_get_server_uds_name:: %s\n", server_uds_name);
- return server_uds_name;
+ dFree(rply);
+ Dpi_close_fd(sock_fd);
+
+ return ok ? dpi_port : -1;
}
/*
* Connect a socket to a dpi server and return the socket's FD.
- * We have to ask 'dpid' (dpi daemon) for the UDS of the target dpi server.
+ * We have to ask 'dpid' (dpi daemon) for the port of the target dpi server.
* Once we have it, then the proper file descriptor is returned (-1 on error).
*/
static int Dpi_connect_socket(const char *server_name, int retry)
{
- char *server_uds_name;
- struct sockaddr_un pun;
- int SockFD, err;
-
- /* Query dpid for the UDS name for this server */
- server_uds_name = Dpi_get_server_uds_name(server_name);
- _MSG("server_uds_name = [%s]\n", server_uds_name);
+ struct sockaddr_in sin;
+ int sock_fd, err, dpi_port, ret=-1;
+ char *cmd = NULL;
- if (access(server_uds_name, F_OK) != 0) {
- MSG("server socket was NOT found\n");
+ /* Query dpid for the port number for this server */
+ if ((dpi_port = Dpi_get_server_port(server_name)) == -1) {
+ _MSG("Dpi_connect_socket:: can't get port number for %s\n", server_name);
return -1;
}
+ _MSG("Dpi_connect_socket: server=%s port=%d\n", server_name, dpi_port);
/* connect with this server's socket */
- memset(&pun, 0, sizeof(struct sockaddr_un));
- pun.sun_family = AF_LOCAL;
- strncpy(pun.sun_path, server_uds_name, sizeof (pun.sun_path));
- dFree(server_uds_name);
+ memset(&sin, 0, sizeof(sin));
+ sin.sin_family = AF_INET;
+ sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ sin.sin_port = htons(dpi_port);
- if ((SockFD = socket(AF_LOCAL, SOCK_STREAM, 0)) == -1)
+ if ((sock_fd = Dpi_make_socket_fd()) == -1) {
perror("[dpi::socket]");
- else if (connect(SockFD, (void*)&pun, D_SUN_LEN(&pun)) == -1) {
+ } else if (connect(sock_fd, (void*)&sin, sizeof(sin)) == -1) {
err = errno;
- SockFD = -1;
+ sock_fd = -1;
MSG("[dpi::connect] errno:%d %s\n", errno, dStrerror(errno));
if (retry) {
switch (err) {
case ECONNREFUSED: case EBADF: case ENOTSOCK: case EADDRNOTAVAIL:
- /* the server may crash and its socket name survive */
- unlink(pun.sun_path);
- SockFD = Dpi_connect_socket(server_name, FALSE);
+ sock_fd = Dpi_connect_socket(server_name, FALSE);
break;
}
}
+
+ /* send authentication Key (the server closes sock_fd on error) */
+ } else if (!(cmd = a_Dpip_build_cmd("cmd=%s msg=%s", "auth", SharedKey))) {
+ MSG_ERR("[Dpi_connect_socket] Can't make auth message.\n");
+ } else if (Dpi_blocking_write(sock_fd, cmd, strlen(cmd)) == -1) {
+ MSG_ERR("[Dpi_connect_socket] Can't send auth message.\n");
+ } else {
+ ret = sock_fd;
}
+ dFree(cmd);
- return SockFD;
+ return ret;
}
-
/*
* CCC function for the Dpi module
*/
@@ -616,13 +683,13 @@ void a_Dpi_ccc(int Op, int Branch, int Dir, ChainLink *Info,
*fd = SockFD;
Info->LocalKey = fd;
a_Chain_link_new(Info, a_Dpi_ccc, BCK, a_IO_ccc, 1, 1);
- a_Chain_bcb(OpStart, Info, Info->LocalKey, NULL);
- /* tell the capi to start the receiving branch */
- a_Chain_fcb(OpSend, Info, Info->LocalKey, "SockFD");
+ a_Chain_bcb(OpStart, Info, NULL, NULL);
}
}
if (st == 0 && SockFD != -1) {
+ a_Chain_bcb(OpSend, Info, &SockFD, "FD");
+ a_Chain_fcb(OpSend, Info, &SockFD, "FD");
a_Chain_fcb(OpSend, Info, NULL, "DpidOK");
} else {
MSG_ERR("dpi.c: can't start dpi daemon\n");
@@ -646,7 +713,7 @@ void a_Dpi_ccc(int Op, int Branch, int Dir, ChainLink *Info,
MSG_WARN("Unused CCC\n");
break;
}
- } else { /* FWD */
+ } else { /* 1 FWD */
/* Send commands to dpi-server (status) */
switch (Op) {
case OpAbort:
@@ -676,7 +743,7 @@ void a_Dpi_ccc(int Op, int Branch, int Dir, ChainLink *Info,
MSG_WARN("Unused CCC\n");
break;
}
- } else { /* BCK */
+ } else { /* 2 BCK */
switch (Op) {
case OpStart:
conn = Dpi_conn_new(Info);
@@ -688,7 +755,12 @@ void a_Dpi_ccc(int Op, int Branch, int Dir, ChainLink *Info,
}
a_Chain_link_new(Info, a_Dpi_ccc, BCK, a_IO_ccc, 2, 2);
- a_Chain_bcb(OpStart, Info, NULL, Data1); /* IORead, SockFD */
+ a_Chain_bcb(OpStart, Info, NULL, NULL); /* IORead */
+ break;
+ case OpSend:
+ if (Data2 && !strcmp(Data2, "FD")) {
+ a_Chain_bcb(OpSend, Info, Data1, Data2);
+ }
break;
case OpAbort:
a_Chain_bcb(OpAbort, Info, NULL, NULL);
@@ -703,77 +775,38 @@ void a_Dpi_ccc(int Op, int Branch, int Dir, ChainLink *Info,
}
}
-/*! Send DpiBye to dpid
- * Note: currently disabled. Maybe it'd be better to have a
- * dpid_idle_timeout variable in the config file.
+/*! Let dpid know dillo is no longer running.
+ * Note: currently disabled. It may serve to let the cookies dpi know
+ * when to expire session cookies.
*/
-void a_Dpi_bye_dpid()
+void a_Dpi_dillo_exit()
{
- char *DpiBye_cmd;
- struct sockaddr_un sa;
- size_t sun_path_len, addr_len;
- char *srs_name;
- int new_socket;
-
- srs_name = Dpi_get_dpid_uds_name();
- sun_path_len = sizeof(sa.sun_path);
- addr_len = sizeof(sa);
- sa.sun_family = AF_LOCAL;
-
- if ((new_socket = socket(AF_LOCAL, SOCK_STREAM, 0)) == -1) {
- MSG("a_Dpi_bye_dpid: %s\n", dStrerror(errno));
- }
- strncpy(sa.sun_path, srs_name, sizeof (sa.sun_path));
- if (connect(new_socket, (struct sockaddr *) &sa, addr_len) == -1) {
- MSG("a_Dpi_bye_dpid: %s\n", dStrerror(errno));
- MSG("%s\n", sa.sun_path);
- }
- DpiBye_cmd = a_Dpip_build_cmd("cmd=%s", "DpiBye");
- (void) write(new_socket, DpiBye_cmd, strlen(DpiBye_cmd));
- dFree(DpiBye_cmd);
- Dpi_close_fd(new_socket);
}
-
/*
* Send a command to a dpi server, and block until the answer is got.
* Return value: the dpip tag answer as an string, NULL on error.
*/
char *a_Dpi_send_blocking_cmd(const char *server_name, const char *cmd)
{
- int cst, SockFD;
- ssize_t st;
- char buf[16384], *retval = NULL;
+ int cst, sock_fd;
+ char *ret = NULL;
/* test the dpid, and wait a bit for it to start if necessary */
if ((cst = Dpi_blocking_start_dpid()) != 0) {
- return retval;
+ return ret;
}
- SockFD = Dpi_connect_socket(server_name, TRUE);
- if (SockFD != -1) {
- /* TODO: handle the case of (st < strlen(cmd)) */
- do
- st = write(SockFD, cmd, strlen(cmd));
- while (st == -1 && errno == EINTR);
-
- /* TODO: if the answer is too long... */
- do
- st = read(SockFD, buf, 16384);
- while (st < 0 && errno == EINTR);
-
- if (st == -1)
- perror("[a_Dpi_send_blocking_cmd]");
- else if (st > 0)
- retval = dStrndup(buf, (size_t)st);
-
- Dpi_close_fd(SockFD);
-
- } else {
- perror("[a_Dpi_send_blocking_cmd]");
+ if ((sock_fd = Dpi_connect_socket(server_name, TRUE)) == -1) {
+ MSG_ERR("[a_Dpi_send_blocking_cmd] Can't connect to server.\n");
+ } else if (Dpi_blocking_write(sock_fd, cmd, strlen(cmd)) == -1) {
+ MSG_ERR("[a_Dpi_send_blocking_cmd] Can't send message.\n");
+ } if ((ret = Dpi_blocking_read(sock_fd)) == NULL) {
+ MSG_ERR("[a_Dpi_send_blocking_cmd] Can't read message.\n");
}
+ Dpi_close_fd(sock_fd);
- return retval;
+ return ret;
}