Dillo v3.1.1-91-g6d5b3ee3
Loading...
Searching...
No Matches
dpi.c
Go to the documentation of this file.
1/*
2 * File: dpi.c
3 *
4 * Copyright (C) 2002-2007 Jorge Arellano Cid <jcid@dillo.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 */
11
21#include <unistd.h>
22#include <stdlib.h>
23#include <sys/types.h>
24#include <string.h>
25#include <stdio.h>
26#include <errno.h> /* for errno */
27#include <fcntl.h>
28#include <ctype.h> /* isxdigit */
29#include <stdint.h>
30
31#include <sys/socket.h>
32#include <sys/un.h>
33#include <netinet/in.h>
34#include <netinet/tcp.h>
35#include <arpa/inet.h>
36#include <netdb.h>
37
38#include "../msg.h"
39#include "../klist.h"
40#include "IO.h"
41#include "Url.h"
42#include "../../dpip/dpip.h"
43#include "dlib/dlib.h"
44
45/* This one is tricky, some sources state it should include the byte
46 * for the terminating NULL, and others say it shouldn't. */
47# define D_SUN_LEN(ptr) ((size_t) (((struct sockaddr_un *) 0)->sun_path) \
48 + strlen ((ptr)->sun_path))
49
50/* Solaris may not have this one... */
51#ifndef AF_LOCAL
52#define AF_LOCAL AF_UNIX
53#endif
54
55typedef struct {
56 int InTag;
57 int Send2EOF;
58
59 int DataTotalSize;
60 int DataRecvSize;
61
62 Dstr *Buf;
63
64 int BufIdx;
65 int TokIdx;
66 int TokSize;
67 int TokIsTag;
68
69 ChainLink *InfoRecv;
70 int Key;
71} dpi_conn_t;
72
73
74/*
75 * Local data
76 */
77static Klist_t *ValidConns = NULL; /* Active connections list. It holds
78 * pointers to dpi_conn_t structures. */
79static char SharedKey[32];
80
81/*
82 * Initialize local data
83 */
84void a_Dpi_init(void)
85{
86 /* empty */
87}
88
92static dpi_conn_t *Dpi_conn_new(ChainLink *Info)
93{
94 dpi_conn_t *conn = dNew0(dpi_conn_t, 1);
95
96 conn->Buf = dStr_sized_new(8*1024);
97 conn->InfoRecv = Info;
98 conn->Key = a_Klist_insert(&ValidConns, conn);
99
100 return conn;
101}
102
106static void Dpi_conn_free(dpi_conn_t *conn)
107{
108 a_Klist_remove(ValidConns, conn->Key);
109 dStr_free(conn->Buf, 1);
110 dFree(conn);
111}
112
117static int Dpi_conn_valid(int key)
118{
119 return (a_Klist_get_data(ValidConns, key)) ? 1 : 0;
120}
121
125static void Dpi_append_dbuf(dpi_conn_t *conn, DataBuf *dbuf)
126{
127 if (dbuf->Code == 0 && dbuf->Size > 0) {
128 dStr_append_l(conn->Buf, dbuf->Buf, dbuf->Size);
129 }
130}
131
142static int Dpi_get_token(dpi_conn_t *conn)
143{
144 int i, resp = -1;
145 char *buf = conn->Buf->str;
146
147 if (conn->BufIdx == conn->Buf->len) {
148 dStr_truncate(conn->Buf, 0);
149 conn->BufIdx = 0;
150 return resp;
151 }
152
153 if (conn->Send2EOF) {
154 conn->TokIdx = conn->BufIdx;
155 conn->TokSize = conn->Buf->len - conn->BufIdx;
156 conn->BufIdx = conn->Buf->len;
157 return 0;
158 }
159
160 _MSG("conn->BufIdx = %d; conn->Buf->len = %d\nbuf: [%s]\n",
161 conn->BufIdx,conn->Buf->len, conn->Buf->str + conn->BufIdx);
162
163 if (!conn->InTag) {
164 /* search for start of tag */
165 while (conn->BufIdx < conn->Buf->len && buf[conn->BufIdx] != '<')
166 ++conn->BufIdx;
167 if (conn->BufIdx < conn->Buf->len) {
168 /* found */
169 conn->InTag = 1;
170 conn->TokIdx = conn->BufIdx;
171 } else {
172 MSG_ERR("[Dpi_get_token] Can't find token start\n");
173 }
174 }
175
176 if (conn->InTag) {
177 /* search for end of tag (EOT=" '>") */
178 for (i = conn->BufIdx; i < conn->Buf->len; ++i)
179 if (buf[i] == '>' && i >= 2 && buf[i-1] == '\'' && buf[i-2] == ' ')
180 break;
181 conn->BufIdx = i;
182
183 if (conn->BufIdx < conn->Buf->len) {
184 /* found EOT */
185 conn->TokIsTag = 1;
186 conn->TokSize = conn->BufIdx - conn->TokIdx + 1;
187 ++conn->BufIdx;
188 conn->InTag = 0;
189 resp = 0;
190 }
191 }
192
193 return resp;
194}
195
199static void Dpi_parse_token(dpi_conn_t *conn)
200{
201 char *tag, *cmd, *msg, *urlstr;
202 DataBuf *dbuf;
203 char *Tok = conn->Buf->str + conn->TokIdx;
204
205 if (conn->Send2EOF) {
206 /* we're receiving data chunks from a HTML page */
207 dbuf = a_Chain_dbuf_new(Tok, conn->TokSize, 0);
208 a_Chain_fcb(OpSend, conn->InfoRecv, dbuf, "send_page_2eof");
209 dFree(dbuf);
210 return;
211 }
212
213 tag = dStrndup(Tok, (size_t)conn->TokSize);
214 _MSG("Dpi_parse_token: {%s}\n", tag);
215
216 cmd = a_Dpip_get_attr_l(Tok, conn->TokSize, "cmd");
217 if (strcmp(cmd, "send_status_message") == 0) {
218 msg = a_Dpip_get_attr_l(Tok, conn->TokSize, "msg");
219 a_Chain_fcb(OpSend, conn->InfoRecv, msg, cmd);
220 dFree(msg);
221
222 } else if (strcmp(cmd, "chat") == 0) {
223 msg = a_Dpip_get_attr_l(Tok, conn->TokSize, "msg");
224 a_Chain_fcb(OpSend, conn->InfoRecv, msg, cmd);
225 dFree(msg);
226
227 } else if (strcmp(cmd, "dialog") == 0) {
228 /* For now will send the dpip tag... */
229 a_Chain_fcb(OpSend, conn->InfoRecv, tag, cmd);
230
231 } else if (strcmp(cmd, "start_send_page") == 0) {
232 conn->Send2EOF = 1;
233 urlstr = a_Dpip_get_attr_l(Tok, conn->TokSize, "url");
234 a_Chain_fcb(OpSend, conn->InfoRecv, urlstr, cmd);
235 dFree(urlstr);
236 /* TODO: a_Dpip_get_attr_l(Tok, conn->TokSize, "send_mode") */
237
238 } else if (strcmp(cmd, "reload_request") == 0) {
239 urlstr = a_Dpip_get_attr_l(Tok, conn->TokSize, "url");
240 a_Chain_fcb(OpSend, conn->InfoRecv, urlstr, cmd);
241 dFree(urlstr);
242 }
243 dFree(cmd);
244
245 dFree(tag);
246}
247
248
249/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
250
256static int Dpi_blocking_write(int fd, const char *msg, int msg_len)
257{
258 int st, sent = 0;
259
260 while (sent < msg_len) {
261 st = write(fd, msg + sent, msg_len - sent);
262 if (st < 0) {
263 if (errno == EINTR) {
264 continue;
265 } else {
266 MSG_ERR("[Dpi_blocking_write] %s\n", dStrerror(errno));
267 break;
268 }
269 }
270 sent += st;
271 }
272
273 return (sent == msg_len) ? 1 : -1;
274}
275
283static char *Dpi_blocking_read(int fd)
284{
285 int st;
286 const int buf_sz = 8*1024;
287 char buf[buf_sz], *msg = NULL;
288 Dstr *dstr = dStr_sized_new(buf_sz);
289
290 do {
291 st = read(fd, buf, buf_sz);
292 if (st < 0) {
293 if (errno == EINTR) {
294 continue;
295 } else {
296 MSG_ERR("[Dpi_blocking_read] %s\n", dStrerror(errno));
297 break;
298 }
299 } else if (st > 0) {
300 dStr_append_l(dstr, buf, st);
301 }
302 } while (st == buf_sz);
303
304 msg = (dstr->len > 0) ? dstr->str : NULL;
305 dStr_free(dstr, (dstr->len > 0) ? FALSE : TRUE);
306 return msg;
307}
308
309/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
310
315static void Dpi_process_dbuf(int Op, void *Data1, dpi_conn_t *conn)
316{
317 DataBuf *dbuf = Data1;
318 int key = conn->Key;
319
320 /* Very useful for debugging: show the data stream as received. */
321 /* fwrite(dbuf->Buf, dbuf->Size, 1, stdout); */
322
323 if (Op == IORead) {
324 Dpi_append_dbuf(conn, dbuf);
325 /* 'conn' has to be validated because Dpi_parse_token() MAY call abort */
326 while (Dpi_conn_valid(key) && Dpi_get_token(conn) != -1) {
327 Dpi_parse_token(conn);
328 }
329
330 } else if (Op == IOClose) {
331 /* unused */
332 }
333}
334
339static int Dpi_start_dpid(void)
340{
341 pid_t pid;
342 int st_pipe[2], ret = 1;
343 char *answer;
344
345 /* create a pipe to track our child's status */
346 if (pipe(st_pipe))
347 return 1;
348
349 pid = fork();
350 if (pid == 0) {
351 /* This is the child process. Execute the command. */
352 char *path1 = dStrconcat(dGethomedir(), "/.dillo/dpid", NULL);
353 dClose(st_pipe[0]);
354 if (execl(path1, "dpid", (char*)NULL) == -1) {
355 dFree(path1);
356 path1 = dStrconcat(DILLO_BINDIR, "dpid", NULL);
357 if (execl(path1, "dpid", (char*)NULL) == -1) {
358 dFree(path1);
359 if (execlp("dpid", "dpid", (char*)NULL) == -1) {
360 MSG("Dpi_start_dpid (child): %s\n", dStrerror(errno));
361 if (Dpi_blocking_write(st_pipe[1], "ERROR", 5) == -1) {
362 MSG("Dpi_start_dpid (child): can't write to pipe.\n");
363 }
364 dClose(st_pipe[1]);
365 _exit (EXIT_FAILURE);
366 }
367 }
368 }
369 } else if (pid < 0) {
370 /* The fork failed. Report failure. */
371 MSG("Dpi_start_dpid: %s\n", dStrerror(errno));
372 /* close the unused pipe */
373 dClose(st_pipe[0]);
374 dClose(st_pipe[1]);
375 } else {
376 /* This is the parent process, check our child status... */
377 dClose(st_pipe[1]);
378 if ((answer = Dpi_blocking_read(st_pipe[0])) != NULL) {
379 MSG("Dpi_start_dpid: can't start dpid\n");
380 dFree(answer);
381 } else {
382 ret = 0;
383 }
384 dClose(st_pipe[0]);
385 }
386
387 return ret;
388}
389
394static int Dpi_read_comm_keys(int *port)
395{
396 FILE *In;
397 char *fname, *rcline = NULL, *tail;
398 int i, ret = -1;
399
400 fname = dStrconcat(dGethomedir(), "/.dillo/dpid_comm_keys", NULL);
401 if ((In = fopen(fname, "r")) == NULL) {
402 MSG_ERR("[Dpi_read_comm_keys] %s\n", dStrerror(errno));
403 } else if ((rcline = dGetline(In)) == NULL) {
404 MSG_ERR("[Dpi_read_comm_keys] empty file: %s\n", fname);
405 } else {
406 *port = strtol(rcline, &tail, 10);
407 for (i = 0; *tail && isxdigit(tail[i+1]); ++i)
408 SharedKey[i] = tail[i+1];
409 SharedKey[i] = 0;
410 ret = 1;
411 }
412 if (In)
413 fclose(In);
414 dFree(rcline);
415 dFree(fname);
416
417 return ret;
418}
419
423static int Dpi_make_socket_fd(void)
424{
425 int fd, one = 1, ret = -1;
426
427 if ((fd = socket(AF_INET, SOCK_STREAM, 0)) != -1) {
428 /* avoid delays when sending small pieces of data */
429 setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one));
430 ret = fd;
431 }
432 return ret;
433}
434
439static int Dpi_check_dpid_ids(void)
440{
441 struct sockaddr_in sin;
442 const socklen_t sin_sz = sizeof(sin);
443 int sock_fd, dpid_port, ret = -1;
444
445 /* socket connection test */
446 memset(&sin, 0, sizeof(sin));
447 sin.sin_family = AF_INET;
448 sin.sin_addr.s_addr = inet_addr("127.0.0.1");
449
450 if (Dpi_read_comm_keys(&dpid_port) != -1) {
451 sin.sin_port = htons(dpid_port);
452 if ((sock_fd = Dpi_make_socket_fd()) == -1) {
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) {
455 MSG("Dpi_check_dpid_ids: %s\n", dStrerror(errno));
456 } else {
457 dClose(sock_fd);
458 ret = 1;
459 }
460 }
461 return ret;
462}
463
468static int Dpi_check_dpid(int num_tries)
469{
470 static int starting = 0;
471 int check_st = 1, ret = 2;
472
473 check_st = Dpi_check_dpid_ids();
474 _MSG("Dpi_check_dpid: check_st=%d\n", check_st);
475
476 if (check_st == 1) {
477 /* connection test with dpi server passed */
478 starting = 0;
479 ret = 0;
480 } else {
481 if (!starting) {
482 /* start dpid */
483 if (Dpi_start_dpid() == 0) {
484 starting = 1;
485 ret = 1;
486 }
487 } else if (++starting < num_tries) {
488 /* starting */
489 ret = 1;
490 } else {
491 /* we waited too much, report an error... */
492 starting = 0;
493 }
494 }
495
496 _MSG("Dpi_check_dpid: %s\n",
497 (ret == 0) ? "OK" : (ret == 1 ? "EAGAIN" : "ERROR"));
498 return ret;
499}
500
506{
507 int cst, try = 0,
508 n_tries = 12; /* 3 seconds */
509
510 /* test the dpid, and wait a bit for it to start if necessary */
511 while ((cst = Dpi_check_dpid(n_tries)) == 1) {
512 MSG("Dpi_blocking_start_dpid: try %d\n", ++try);
513 dUsleep(250000UL);
514 }
515 return cst;
516}
517
526static int Dpi_get_server_port(const char *server_name)
527{
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;
532 socklen_t sin_sz;
533
534 dReturn_val_if_fail (server_name != NULL, dpi_port);
535 _MSG("Dpi_get_server_port: server_name = [%s]\n", server_name);
536
537 /* Read dpid's port from saved file */
538 if (Dpi_read_comm_keys(&dpid_port) != -1) {
539 ok = 1;
540 }
541 if (ok) {
542 /* Connect a socket with dpid */
543 ok = 0;
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);
549 if ((sock_fd = Dpi_make_socket_fd()) == -1 ||
550 connect(sock_fd, (struct sockaddr *)&sin, sin_sz) == -1) {
551 MSG("Dpi_get_server_port: %s\n", dStrerror(errno));
552 } else {
553 ok = 1;
554 }
555 }
556 if (ok) {
557 /* ask dpid to check the dpi and send its port number back */
558 ok = 0;
559 request = a_Dpip_build_cmd("cmd=%s msg=%s", "check_server", server_name);
560 _MSG("[%s]\n", request);
561
562 if (Dpi_blocking_write(sock_fd, request, strlen(request)) == -1) {
563 MSG("Dpi_get_server_port: %s\n", dStrerror(errno));
564 } else {
565 ok = 1;
566 }
567 dFree(request);
568 }
569 if (ok) {
570 /* Get the reply */
571 ok = 0;
572 if ((rply = Dpi_blocking_read(sock_fd)) == NULL) {
573 MSG("Dpi_get_server_port: can't read server port from dpid.\n");
574 } else {
575 ok = 1;
576 }
577 }
578 if (ok) {
579 /* Parse reply */
580 ok = 0;
581 cmd = a_Dpip_get_attr(rply, "cmd");
582 if (strcmp(cmd, "send_data") == 0) {
583 port_str = a_Dpip_get_attr(rply, "msg");
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);
587 dFree(port_str);
588 ok = 1;
589 }
590 dFree(cmd);
591 }
592 dFree(rply);
593 dClose(sock_fd);
594
595 return ok ? dpi_port : -1;
596}
597
598
604static int Dpi_connect_socket(const char *server_name)
605{
606 struct sockaddr_in sin;
607 int sock_fd, dpi_port, ret = -1;
608 char *cmd = NULL;
609
610 /* Query dpid for the port number for this server */
611 if ((dpi_port = Dpi_get_server_port(server_name)) == -1) {
612 _MSG("Dpi_connect_socket: can't get port number for %s\n", server_name);
613 return -1;
614 }
615 _MSG("Dpi_connect_socket: server=%s port=%d\n", server_name, dpi_port);
616
617 /* connect with this server's socket */
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);
622
623 if ((sock_fd = Dpi_make_socket_fd()) == -1) {
624 MSG_ERR("[Dpi_connect_socket] %s\n", dStrerror(errno));
625 } else if (connect(sock_fd, (void*)&sin, sizeof(sin)) == -1) {
626 MSG_ERR("[Dpi_connect_socket] errno:%d %s\n", errno, dStrerror(errno));
627
628 /* send authentication Key (the server closes sock_fd on auth error) */
629 } else if (!(cmd = a_Dpip_build_cmd("cmd=%s msg=%s", "auth", SharedKey))) {
630 MSG_ERR("[Dpi_connect_socket] Can't make auth message.\n");
631 } else if (Dpi_blocking_write(sock_fd, cmd, strlen(cmd)) == -1) {
632 MSG_ERR("[Dpi_connect_socket] Can't send auth message.\n");
633 } else {
634 ret = sock_fd;
635 }
636 dFree(cmd);
637 if (sock_fd != -1 && ret == -1) /* can't send cmd? */
638 dClose(sock_fd);
639
640 return ret;
641}
642
646void a_Dpi_ccc(int Op, int Branch, int Dir, ChainLink *Info,
647 void *Data1, void *Data2)
648{
649 dpi_conn_t *conn;
650 int SockFD = -1, st;
651
652 dReturn_if_fail( a_Chain_check("a_Dpi_ccc", Op, Branch, Dir, Info) );
653
654 if (Branch == 1) {
655 if (Dir == BCK) {
656 /* Send commands to dpi-server */
657 switch (Op) {
658 case OpStart:
659 if ((st = Dpi_blocking_start_dpid()) == 0) {
660 if ((SockFD = Dpi_connect_socket(Data1)) != -1) {
661 int *fd = dNew(int, 1);
662 *fd = SockFD;
663 Info->LocalKey = fd;
664 a_Chain_link_new(Info, a_Dpi_ccc, BCK, a_IO_ccc, 1, 1);
665 a_Chain_bcb(OpStart, Info, NULL, NULL);
666 /* Let the FD known and tracked */
667 a_Chain_bcb(OpSend, Info, &SockFD, "FD");
668 a_Chain_fcb(OpSend, Info, &SockFD, "FD");
669 a_Chain_fcb(OpSend, Info, NULL, "DpidOK");
670 } else {
671 a_Dpi_ccc(OpAbort, 1, FWD, Info, NULL, NULL);
672 }
673 } else {
674 MSG_ERR("dpi.c: can't start dpi daemon\n");
675 a_Dpi_ccc(OpAbort, 1, FWD, Info, NULL, "DpidERROR");
676 }
677 break;
678 case OpSend:
679 a_Chain_bcb(OpSend, Info, Data1, NULL);
680 break;
681 case OpEnd:
682 a_Chain_bcb(OpEnd, Info, NULL, NULL);
683 dFree(Info->LocalKey);
684 dFree(Info);
685 break;
686 case OpAbort:
687 a_Chain_bcb(OpAbort, Info, NULL, NULL);
688 dFree(Info->LocalKey);
689 dFree(Info);
690 break;
691 default:
692 MSG_WARN("Unused CCC\n");
693 break;
694 }
695 } else { /* 1 FWD */
696 /* Send commands to dpi-server (status) */
697 switch (Op) {
698 case OpAbort:
699 a_Chain_fcb(OpAbort, Info, NULL, Data2);
700 dFree(Info);
701 break;
702 default:
703 MSG_WARN("Unused CCC\n");
704 break;
705 }
706 }
707
708 } else if (Branch == 2) {
709 if (Dir == FWD) {
710 /* Receiving from server */
711 switch (Op) {
712 case OpSend:
713 /* Data1 = dbuf */
714 Dpi_process_dbuf(IORead, Data1, Info->LocalKey);
715 break;
716 case OpEnd:
717 a_Chain_fcb(OpEnd, Info, NULL, NULL);
718 Dpi_conn_free(Info->LocalKey);
719 dFree(Info);
720 break;
721 default:
722 MSG_WARN("Unused CCC\n");
723 break;
724 }
725 } else { /* 2 BCK */
726 switch (Op) {
727 case OpStart:
728 conn = Dpi_conn_new(Info);
729 Info->LocalKey = conn;
730
731 /* Hack: for receiving HTTP through the DPI framework */
732 if (strcmp(Data2, "http") == 0) {
733 conn->Send2EOF = 1;
734 }
735
736 a_Chain_link_new(Info, a_Dpi_ccc, BCK, a_IO_ccc, 2, 2);
737 a_Chain_bcb(OpStart, Info, NULL, NULL); /* IORead */
738 break;
739 case OpSend:
740 if (Data2 && !strcmp(Data2, "FD")) {
741 a_Chain_bcb(OpSend, Info, Data1, Data2);
742 }
743 break;
744 case OpAbort:
745 a_Chain_bcb(OpAbort, Info, NULL, NULL);
746 Dpi_conn_free(Info->LocalKey);
747 dFree(Info);
748 break;
749 default:
750 MSG_WARN("Unused CCC\n");
751 break;
752 }
753 }
754 }
755}
756
762{
763
764}
765
770char *a_Dpi_send_blocking_cmd(const char *server_name, const char *cmd)
771{
772 int cst, sock_fd;
773 char *ret = NULL;
774
775 /* test the dpid, and wait a bit for it to start if necessary */
776 if ((cst = Dpi_blocking_start_dpid()) != 0) {
777 return ret;
778 }
779
780 if ((sock_fd = Dpi_connect_socket(server_name)) == -1) {
781 MSG_ERR("[a_Dpi_send_blocking_cmd] Can't connect to server.\n");
782 } else if (Dpi_blocking_write(sock_fd, cmd, strlen(cmd)) == -1) {
783 MSG_ERR("[a_Dpi_send_blocking_cmd] Can't send message.\n");
784 } else if ((ret = Dpi_blocking_read(sock_fd)) == NULL) {
785 MSG_ERR("[a_Dpi_send_blocking_cmd] Can't read message.\n");
786 }
787 dClose(sock_fd);
788
789 return ret;
790}
791
void a_IO_ccc(int Op, int Branch, int Dir, ChainLink *Info, void *Data1, void *Data2)
CCC function for the IO module.
Definition IO.c:359
#define IORead
Definition IO.h:11
#define IOClose
Definition IO.h:13
#define _MSG(...)
Definition bookmarks.c:45
#define MSG(...)
Definition bookmarks.c:46
int a_Chain_bcb(int Op, ChainLink *Info, void *Data1, void *Data2)
Issue the backward callback of the 'Info' link.
Definition chain.c:126
DataBuf * a_Chain_dbuf_new(void *buf, int size, int code)
Allocate and initialize a new DataBuf structure.
Definition chain.c:171
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.
Definition chain.c:55
int a_Chain_check(char *FuncStr, int Op, int Branch, int Dir, ChainLink *Info)
Check whether the CCC is operative.
Definition chain.c:186
int a_Chain_fcb(int Op, ChainLink *Info, void *Data1, void *Data2)
Issue the forward callback of the 'Info' link.
Definition chain.c:103
#define OpAbort
Definition chain.h:17
#define FWD
Definition chain.h:29
#define OpStart
Definition chain.h:13
#define BCK
Definition chain.h:30
#define OpSend
Definition chain.h:14
#define OpEnd
Definition chain.h:16
char * dGetline(FILE *stream)
Get a line from a FILE stream.
Definition dlib.c:928
char * dStrconcat(const char *s1,...)
Concatenate a NULL-terminated list of strings.
Definition dlib.c:102
void dFree(void *mem)
Definition dlib.c:68
Dstr * dStr_sized_new(int sz)
Create a new string with a given size.
Definition dlib.c:254
void dStr_free(Dstr *ds, int all)
Free a dillo string.
Definition dlib.c:337
int dClose(int fd)
Close a FD handling EINTR.
Definition dlib.c:951
void dStr_append_l(Dstr *ds, const char *s, int l)
Append a C string to a Dstr (providing length).
Definition dlib.c:308
int dUsleep(unsigned long usec)
Portable usleep() function.
Definition dlib.c:967
char * dStrndup(const char *s, size_t sz)
Definition dlib.c:88
void dStr_truncate(Dstr *ds, int len)
Truncate a Dstr to be 'len' bytes long.
Definition dlib.c:368
char * dGethomedir(void)
Return the home directory in a static string (don't free)
Definition dlib.c:906
#define dStrerror
Definition dlib.h:95
#define dReturn_if_fail(expr)
Definition dlib.h:72
#define dNew0(type, count)
Definition dlib.h:51
#define dReturn_val_if_fail(expr, val)
Definition dlib.h:76
#define TRUE
Definition dlib.h:23
#define FALSE
Definition dlib.h:19
#define dNew(type, count)
Definition dlib.h:49
#define MSG_ERR(...)
Definition dpid_common.h:23
char * a_Dpip_build_cmd(const char *format,...)
Printf like function for building dpip commands.
Definition dpip.c:83
char * a_Dpip_get_attr(const char *tag, const char *attrname)
Task: given a tag and an attribute name, return its value.
Definition dpip.c:192
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...
Definition dpip.c:134
void a_Klist_remove(Klist_t *Klist, int Key)
Remove data by Key.
Definition klist.c:86
void * a_Klist_get_data(Klist_t *Klist, int Key)
Return the data pointer for a given Key (or NULL if not found)
Definition klist.c:43
int a_Klist_insert(Klist_t **Klist, void *Data)
Insert a data pointer and return a key for it.
Definition klist.c:56
#define MSG_WARN(...)
Definition msg.h:26
static int Dpi_check_dpid_ids(void)
Make a connection test for a IDS.
Definition dpi.c:439
static char SharedKey[32]
Definition dpi.c:79
static int Dpi_start_dpid(void)
Start dpid.
Definition dpi.c:339
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.
Definition dpi.c:256
static dpi_conn_t * Dpi_conn_new(ChainLink *Info)
Create a new connection data structure.
Definition dpi.c:92
static void Dpi_parse_token(dpi_conn_t *conn)
Parse a dpi tag and take the appropriate actions.
Definition dpi.c:199
static int Dpi_conn_valid(int key)
Check whether a conn is still valid.
Definition dpi.c:117
static int Dpi_read_comm_keys(int *port)
Read dpid's communication keys from its saved file.
Definition dpi.c:394
static int Dpi_get_token(dpi_conn_t *conn)
Split the data stream into tokens.
Definition dpi.c:142
void a_Dpi_dillo_exit(void)
Let dpid know dillo is no longer running.
Definition dpi.c:761
void a_Dpi_ccc(int Op, int Branch, int Dir, ChainLink *Info, void *Data1, void *Data2)
CCC function for the Dpi module.
Definition dpi.c:646
static Klist_t * ValidConns
Definition dpi.c:77
static int Dpi_get_server_port(const char *server_name)
Return the dpi server's port number, or -1 on error.
Definition dpi.c:526
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.
Definition dpi.c:770
static int Dpi_blocking_start_dpid(void)
Confirm that the dpid is running.
Definition dpi.c:505
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...
Definition dpi.c:315
static char * Dpi_blocking_read(int fd)
Read all the available data from a filedescriptor.
Definition dpi.c:283
static int Dpi_make_socket_fd(void)
Return a socket file descriptor.
Definition dpi.c:423
static void Dpi_append_dbuf(dpi_conn_t *conn, DataBuf *dbuf)
Append the new buffer in 'dbuf' to Buf in 'conn'.
Definition dpi.c:125
static int Dpi_check_dpid(int num_tries)
Confirm that the dpid is running.
Definition dpi.c:468
static void Dpi_conn_free(dpi_conn_t *conn)
Free a connection data structure.
Definition dpi.c:106
void a_Dpi_init(void)
Definition dpi.c:84
static int Dpi_connect_socket(const char *server_name)
Connect a socket to a dpi server and return the socket's FD.
Definition dpi.c:604
A convenience data structure for passing data chunks between nodes.
Definition chain.h:52
char * Buf
Definition chain.h:53
int Code
Definition chain.h:55
int Size
Definition chain.h:54
Definition dlib.h:102
Dstr_char_t * str
Definition dlib.h:105
int len
Definition dlib.h:104