31#include <sys/socket.h>
33#include <netinet/in.h>
34#include <netinet/tcp.h>
42#include "../../dpip/dpip.h"
47# define D_SUN_LEN(ptr) ((size_t) (((struct sockaddr_un *) 0)->sun_path) \
48 + strlen ((ptr)->sun_path))
52#define AF_LOCAL AF_UNIX
94 dpi_conn_t *conn =
dNew0(dpi_conn_t, 1);
97 conn->InfoRecv = Info;
127 if (dbuf->
Code == 0 && dbuf->
Size > 0) {
145 char *buf = conn->Buf->str;
147 if (conn->BufIdx == conn->Buf->len) {
153 if (conn->Send2EOF) {
154 conn->TokIdx = conn->BufIdx;
155 conn->TokSize = conn->Buf->len - conn->BufIdx;
156 conn->BufIdx = conn->Buf->len;
160 _MSG(
"conn->BufIdx = %d; conn->Buf->len = %d\nbuf: [%s]\n",
161 conn->BufIdx,conn->Buf->len, conn->Buf->str + conn->BufIdx);
165 while (conn->BufIdx < conn->Buf->len && buf[conn->BufIdx] !=
'<')
167 if (conn->BufIdx < conn->Buf->len) {
170 conn->TokIdx = conn->BufIdx;
172 MSG_ERR(
"[Dpi_get_token] Can't find token start\n");
178 for (i = conn->BufIdx; i < conn->Buf->len; ++i)
179 if (buf[i] ==
'>' && i >= 2 && buf[i-1] ==
'\'' && buf[i-2] ==
' ')
183 if (conn->BufIdx < conn->Buf->len) {
186 conn->TokSize = conn->BufIdx - conn->TokIdx + 1;
201 char *tag, *cmd, *msg, *urlstr;
203 char *Tok = conn->
Buf->str + conn->TokIdx;
205 if (conn->Send2EOF) {
213 tag =
dStrndup(Tok, (
size_t)conn->TokSize);
214 _MSG(
"Dpi_parse_token: {%s}\n", tag);
217 if (strcmp(cmd,
"send_status_message") == 0) {
222 }
else if (strcmp(cmd,
"chat") == 0) {
227 }
else if (strcmp(cmd,
"dialog") == 0) {
231 }
else if (strcmp(cmd,
"start_send_page") == 0) {
238 }
else if (strcmp(cmd,
"reload_request") == 0) {
260 while (sent < msg_len) {
261 st = write(fd, msg + sent, msg_len - sent);
263 if (errno == EINTR) {
273 return (sent == msg_len) ? 1 : -1;
286 const int buf_sz = 8*1024;
287 char buf[buf_sz], *msg = NULL;
291 st = read(fd, buf, buf_sz);
293 if (errno == EINTR) {
302 }
while (st == buf_sz);
304 msg = (dstr->
len > 0) ? dstr->
str : NULL;
342 int st_pipe[2], ret = 1;
354 if (execl(path1,
"dpid", (
char*)NULL) == -1) {
356 path1 =
dStrconcat(DILLO_BINDIR,
"dpid", NULL);
357 if (execl(path1,
"dpid", (
char*)NULL) == -1) {
359 if (execlp(
"dpid",
"dpid", (
char*)NULL) == -1) {
362 MSG(
"Dpi_start_dpid (child): can't write to pipe.\n");
365 _exit (EXIT_FAILURE);
369 }
else if (pid < 0) {
379 MSG(
"Dpi_start_dpid: can't start dpid\n");
397 char *fname, *rcline = NULL, *tail;
401 if ((In = fopen(fname,
"r")) == NULL) {
403 }
else if ((rcline =
dGetline(In)) == NULL) {
404 MSG_ERR(
"[Dpi_read_comm_keys] empty file: %s\n", fname);
406 *port = strtol(rcline, &tail, 10);
407 for (i = 0; *tail && isxdigit(tail[i+1]); ++i)
425 int fd, one = 1, ret = -1;
427 if ((fd = socket(AF_INET, SOCK_STREAM, 0)) != -1) {
429 setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one,
sizeof(one));
441 struct sockaddr_in sin;
442 const socklen_t sin_sz =
sizeof(sin);
443 int sock_fd, dpid_port, ret = -1;
446 memset(&sin, 0,
sizeof(sin));
447 sin.sin_family = AF_INET;
448 sin.sin_addr.s_addr = inet_addr(
"127.0.0.1");
451 sin.sin_port = htons(dpid_port);
453 MSG(
"Dpi_check_dpid_ids: sock_fd=%d %s\n", sock_fd,
dStrerror(errno));
454 }
else if (connect(sock_fd, (
struct sockaddr *)&sin, sin_sz) == -1) {
470 static int starting = 0;
471 int check_st = 1, ret = 2;
474 _MSG(
"Dpi_check_dpid: check_st=%d\n", check_st);
487 }
else if (++starting < num_tries) {
496 _MSG(
"Dpi_check_dpid: %s\n",
497 (ret == 0) ?
"OK" : (ret == 1 ?
"EAGAIN" :
"ERROR"));
512 MSG(
"Dpi_blocking_start_dpid: try %d\n", ++
try);
528 int sock_fd = -1, dpi_port = -1;
529 int dpid_port, ok = 0;
530 struct sockaddr_in sin;
531 char *cmd, *request, *rply = NULL, *port_str;
535 _MSG(
"Dpi_get_server_port: server_name = [%s]\n", server_name);
544 sin_sz =
sizeof(sin);
545 memset(&sin, 0,
sizeof(sin));
546 sin.sin_family = AF_INET;
547 sin.sin_addr.s_addr = inet_addr(
"127.0.0.1");
548 sin.sin_port = htons(dpid_port);
550 connect(sock_fd, (
struct sockaddr *)&sin, sin_sz) == -1) {
560 _MSG(
"[%s]\n", request);
573 MSG(
"Dpi_get_server_port: can't read server port from dpid.\n");
582 if (strcmp(cmd,
"send_data") == 0) {
584 _MSG(
"Dpi_get_server_port: rply=%s\n", rply);
585 _MSG(
"Dpi_get_server_port: port_str=%s\n", port_str);
586 dpi_port = strtol(port_str, NULL, 10);
595 return ok ? dpi_port : -1;
606 struct sockaddr_in sin;
607 int sock_fd, dpi_port, ret = -1;
612 _MSG(
"Dpi_connect_socket: can't get port number for %s\n", server_name);
615 _MSG(
"Dpi_connect_socket: server=%s port=%d\n", server_name, dpi_port);
618 memset(&sin, 0,
sizeof(sin));
619 sin.sin_family = AF_INET;
620 sin.sin_addr.s_addr = inet_addr(
"127.0.0.1");
621 sin.sin_port = htons(dpi_port);
625 }
else if (connect(sock_fd, (
void*)&sin,
sizeof(sin)) == -1) {
630 MSG_ERR(
"[Dpi_connect_socket] Can't make auth message.\n");
632 MSG_ERR(
"[Dpi_connect_socket] Can't send auth message.\n");
637 if (sock_fd != -1 && ret == -1)
647 void *Data1,
void *Data2)
661 int *fd =
dNew(
int, 1);
674 MSG_ERR(
"dpi.c: can't start dpi daemon\n");
708 }
else if (Branch == 2) {
732 if (strcmp(Data2,
"http") == 0) {
740 if (Data2 && !strcmp(Data2,
"FD")) {
781 MSG_ERR(
"[a_Dpi_send_blocking_cmd] Can't connect to server.\n");
783 MSG_ERR(
"[a_Dpi_send_blocking_cmd] Can't send message.\n");
785 MSG_ERR(
"[a_Dpi_send_blocking_cmd] Can't read message.\n");
void a_IO_ccc(int Op, int Branch, int Dir, ChainLink *Info, void *Data1, void *Data2)
CCC function for the IO module.
int a_Chain_bcb(int Op, ChainLink *Info, void *Data1, void *Data2)
Issue the backward callback of the 'Info' link.
DataBuf * a_Chain_dbuf_new(void *buf, int size, int code)
Allocate and initialize a new DataBuf structure.
ChainLink * a_Chain_link_new(ChainLink *AInfo, ChainFunction_t AFunc, int Direction, ChainFunction_t BFunc, int AtoB_branch, int BtoA_branch)
Create a new link from module A to module B.
int a_Chain_check(char *FuncStr, int Op, int Branch, int Dir, ChainLink *Info)
Check whether the CCC is operative.
int a_Chain_fcb(int Op, ChainLink *Info, void *Data1, void *Data2)
Issue the forward callback of the 'Info' link.
char * dGetline(FILE *stream)
Get a line from a FILE stream.
char * dStrconcat(const char *s1,...)
Concatenate a NULL-terminated list of strings.
Dstr * dStr_sized_new(int sz)
Create a new string with a given size.
void dStr_free(Dstr *ds, int all)
Free a dillo string.
int dClose(int fd)
Close a FD handling EINTR.
void dStr_append_l(Dstr *ds, const char *s, int l)
Append a C string to a Dstr (providing length).
int dUsleep(unsigned long usec)
Portable usleep() function.
char * dStrndup(const char *s, size_t sz)
void dStr_truncate(Dstr *ds, int len)
Truncate a Dstr to be 'len' bytes long.
char * dGethomedir(void)
Return the home directory in a static string (don't free)
#define dReturn_if_fail(expr)
#define dNew0(type, count)
#define dReturn_val_if_fail(expr, val)
#define dNew(type, count)
char * a_Dpip_build_cmd(const char *format,...)
Printf like function for building dpip commands.
char * a_Dpip_get_attr(const char *tag, const char *attrname)
Task: given a tag and an attribute name, return its value.
char * a_Dpip_get_attr_l(const char *tag, size_t tagsize, const char *attrname)
Task: given a tag, its size and an attribute name, return the attribute value (stuffing of ' is remov...
void a_Klist_remove(Klist_t *Klist, int Key)
Remove data by Key.
void * a_Klist_get_data(Klist_t *Klist, int Key)
Return the data pointer for a given Key (or NULL if not found)
int a_Klist_insert(Klist_t **Klist, void *Data)
Insert a data pointer and return a key for it.
static int Dpi_check_dpid_ids(void)
Make a connection test for a IDS.
static char SharedKey[32]
static int Dpi_start_dpid(void)
Start dpid.
static int Dpi_blocking_write(int fd, const char *msg, int msg_len)
Write data into a file descriptor taking care of EINTR and possible data splits.
static dpi_conn_t * Dpi_conn_new(ChainLink *Info)
Create a new connection data structure.
static void Dpi_parse_token(dpi_conn_t *conn)
Parse a dpi tag and take the appropriate actions.
static int Dpi_conn_valid(int key)
Check whether a conn is still valid.
static int Dpi_read_comm_keys(int *port)
Read dpid's communication keys from its saved file.
static int Dpi_get_token(dpi_conn_t *conn)
Split the data stream into tokens.
void a_Dpi_dillo_exit(void)
Let dpid know dillo is no longer running.
void a_Dpi_ccc(int Op, int Branch, int Dir, ChainLink *Info, void *Data1, void *Data2)
CCC function for the Dpi module.
static Klist_t * ValidConns
static int Dpi_get_server_port(const char *server_name)
Return the dpi server's port number, or -1 on error.
char * a_Dpi_send_blocking_cmd(const char *server_name, const char *cmd)
Send a command to a dpi server, and block until the answer is got.
static int Dpi_blocking_start_dpid(void)
Confirm that the dpid is running.
static void Dpi_process_dbuf(int Op, void *Data1, dpi_conn_t *conn)
Get a new data buffer (within a 'dbuf'), save it into local data, split in tokens and parse the conte...
static char * Dpi_blocking_read(int fd)
Read all the available data from a filedescriptor.
static int Dpi_make_socket_fd(void)
Return a socket file descriptor.
static void Dpi_append_dbuf(dpi_conn_t *conn, DataBuf *dbuf)
Append the new buffer in 'dbuf' to Buf in 'conn'.
static int Dpi_check_dpid(int num_tries)
Confirm that the dpid is running.
static void Dpi_conn_free(dpi_conn_t *conn)
Free a connection data structure.
static int Dpi_connect_socket(const char *server_name)
Connect a socket to a dpi server and return the socket's FD.
Main data structure for CCC nodes.
A convenience data structure for passing data chunks between nodes.