27#include <sys/socket.h>
28#include <netinet/in.h>
29#include <netinet/tcp.h>
39#include "../dpip/dpip.h"
41#define DPI_EXT (".dpi" EXEEXT)
65 if (dpi_attr->
id != NULL) {
69 if (dpi_attr->
path != NULL) {
71 dpi_attr->
path = NULL;
89 *dpi_attr_list_ptr = NULL;
119 struct sigaction act;
123 sigaddset(&block, SIGHUP);
124 sigaddset(&block, SIGINT);
125 sigaddset(&block, SIGQUIT);
126 sigaddset(&block, SIGTERM);
132 if (sigaction(SIGHUP, &act, NULL) ||
133 sigaction(SIGINT, &act, NULL) ||
134 sigaction(SIGQUIT, &act, NULL) ||
135 sigaction(SIGTERM, &act, NULL)) {
136 ERRMSG(
"est_dpi_terminator",
"sigaction", errno);
141 ERRMSG(
"est_dpi_terminator",
"atexit", 0);
142 MSG_ERR(
"Hey! atexit failed, how did that happen?\n");
147static int ends_with(
const char *str,
const char *suffix)
151 size_t lenstr = strlen(str);
152 size_t lensuffix = strlen(suffix);
153 if (lensuffix > lenstr)
155 return strncmp(str + lenstr - lensuffix, suffix, lensuffix) == 0;
168 MSG_ERR(
"get_file_type: Unknown file type for %s\n", file_name);
183 char *rcline = NULL, *value = NULL, *p;
185 if ((In = fopen(dpidrc,
"r")) == NULL) {
186 ERRMSG(
"dpi_dir",
"fopen", errno);
191 while ((rcline =
dGetline(In)) != NULL) {
192 if (strncmp(rcline,
"dpi_dir", 7) == 0)
199 ERRMSG(
"dpi_dir",
"Failed to find a dpi_dir entry in dpidrc", 0);
200 MSG_ERR(
"Put your dillo plugins path in %s\n", dpidrc);
201 MSG_ERR(
"e.g. dpi_dir=/usr/local/lib/dillo/dpi\n");
202 MSG_ERR(
"with no leading spaces.\n");
205 len = (int) strlen(rcline);
206 if (len && rcline[len - 1] ==
'\n')
209 if ((p = strchr(rcline,
'='))) {
213 ERRMSG(
"dpi_dir",
"strchr", 0);
214 MSG_ERR(
" - '=' not found in %s\n", rcline);
235 char *service_dir = NULL;
236 struct stat statinfo;
240 struct dirent *dir_entry = NULL;
243 if (stat(service_dir, &statinfo) == -1) {
244 ERRMSG(
"get_dpi_attr",
"stat", errno);
245 MSG_ERR(
"file=%s\n", service_dir);
246 }
else if ((dir_stream = opendir(service_dir)) == NULL) {
247 ERRMSG(
"get_dpi_attr",
"opendir", errno);
252 while ( (dir_entry = readdir(dir_stream)) != NULL) {
253 if (dir_entry->d_name[0] ==
'.')
260 dStrconcat(service_dir,
"/", dir_entry->d_name, NULL);
264 if (strstr(dpi_attr->
path,
".filter") != NULL)
274 closedir(dir_stream);
277 MSG_ERR(
"get_dpi_attr: No dpi plug-in in %s/%s\n",
295 char *user_dpi_dir, *dpidrc, *user_service_dir, *dir = NULL;
303 if (access(dpidrc, F_OK) == -1) {
304 if (access(DPIDRC_SYS, F_OK) == -1) {
305 ERRMSG(
"register_service",
"Error ", 0);
306 MSG_ERR(
"\n - There is no %s or %s file\n", dpidrc,
309 dFree(user_service_dir);
318 if (access(user_service_dir, F_OK) == 0) {
323 if (access(dir, F_OK) == 0) {
327 ERRMSG(
"register_service",
"get_dpi_attr failed", 0);
330 ERRMSG(
"register_service",
"dpi_dir: Error getting dpi dir.", 0);
334 dFree(user_service_dir);
349 DIR *user_dir_stream, *sys_dir_stream;
350 char *user_dpidir = NULL, *sys_dpidir = NULL, *dpidrc = NULL;
351 struct dirent *user_dirent, *sys_dirent;
354 size_t dp_sz =
sizeof(
struct dp);
356 if (*attlist != NULL) {
357 ERRMSG(
"register_all",
"attlist parameter should be NULL", 0);
362 if (access(user_dpidir, F_OK) == -1) {
368 if (access(dpidrc, F_OK) == -1) {
371 if (access(dpidrc, F_OK) == -1) {
376 if (!dpidrc || (sys_dpidir =
get_dpi_dir(dpidrc)) == NULL)
380 if (!user_dpidir && !sys_dpidir) {
381 ERRMSG(
"register_all",
"Fatal error ", 0);
382 MSG_ERR(
"\n - Can't find the directory for dpis.\n");
388 if (user_dpidir && (user_dir_stream = opendir(user_dpidir)) != NULL) {
389 while ((user_dirent = readdir(user_dir_stream)) != NULL) {
390 if (user_dirent->d_name[0] ==
'.')
392 *attlist = (
struct dp *)
dRealloc(*attlist, (snum + 1) * dp_sz);
393 st=
get_dpi_attr(user_dpidir, user_dirent->d_name, &(*attlist)[snum]);
397 closedir(user_dir_stream);
399 if (sys_dpidir && (sys_dir_stream = opendir(sys_dpidir)) != NULL) {
401 while ((sys_dirent = readdir(sys_dir_stream)) != NULL) {
402 if (sys_dirent->d_name[0] ==
'.')
404 *attlist = (
struct dp *)
dRealloc(*attlist, (snum + 1) * dp_sz);
405 st=
get_dpi_attr(sys_dpidir, sys_dirent->d_name, &(*attlist)[snum]);
409 closedir(sys_dir_stream);
443 char *user_dpidir = NULL, *sys_dpidir = NULL, *dpidrc = NULL;
446 if (access(user_dpidir, F_OK) == -1) {
452 if (access(dpidrc, F_OK) == -1) {
455 if (access(dpidrc, F_OK) == -1) {
460 if (!dpidrc || (sys_dpidir =
get_dpi_dir(dpidrc)) == NULL)
463 if (!user_dpidir && !sys_dpidir) {
464 ERRMSG(
"fill_services_list",
"Fatal error ", 0);
465 MSG_ERR(
"\n - Can't find the directory for dpis.\n");
469 if ((dpidrc_stream = fopen(dpidrc,
"r")) == NULL) {
470 ERRMSG(
"fill_services_list",
"popen failed", errno);
478 ERRMSG(
"fill_services_list",
"services_list parameter is not NULL", 0);
479 fclose(dpidrc_stream);
485 for (;(line =
dGetline(dpidrc_stream)) != NULL;
dFree(line)) {
488 MSG_ERR(
"dpid: Syntax error in %s: service=\"%s\" path=\"%s\"\n",
491 }
else if (st != 0) {
498 if (strcmp(
service,
"dpi_dir") == 0)
509 if ((p = strstr(attlist[i].
path,
path)) && *(p - 1) ==
'/' &&
510 strlen(p) == strlen(
path))
516 fclose(dpidrc_stream);
535 if ((ret = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
536 ERRMSG(
"make_socket_fd",
"socket", errno);
539 setsockopt(ret, IPPROTO_TCP, TCP_NODELAY, &one,
sizeof(one));
557 struct sockaddr_in sin;
558 int ok = 0, last_port = base_port + 50;
564 fcntl(sock_fd, F_SETFD, FD_CLOEXEC | fcntl(sock_fd, F_GETFD));
567 memset(&sin, 0,
sizeof(sin));
568 sin.sin_family = AF_INET;
569 sin.sin_addr.s_addr = inet_addr(
"127.0.0.1");
572 for (port = base_port; port <= last_port; ++port) {
573 sin.sin_port = htons(port);
574 if ((bind(sock_fd, (
struct sockaddr *)&sin,
sizeof(sin))) == -1) {
575 if (errno == EADDRINUSE || errno == EADDRNOTAVAIL)
577 ERRMSG(
"bind_socket_fd",
"bind", errno);
578 }
else if (listen(sock_fd,
QUEUE) == -1) {
579 ERRMSG(
"bind_socket_fd",
"listen", errno);
586 if (port > last_port) {
587 MSG_ERR(
"Hey! Can't find an available port from %d to %d\n",
588 base_port, last_port);
591 return ok ? sock_fd : -1;
601 char *fname, port_str[32];
604 fd = open(fname, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
609 snprintf(port_str, 16,
"%d %s\n", srs_port,
SharedKey);
625 int srs_port, ret = -1;
649 int s_fd, port, ret = -1;
653 dpi_attr->
port = port;
676 for (i = 0; i <
numdpis; i++) {
703 for (i = 0; i <
numdpis; i++) {
712 while (waitpid(-1, &status, WNOHANG) > 0)
719 struct sigaction sigact;
722 (void) sigemptyset(&set);
724 sigact.sa_mask = set;
725 sigact.sa_flags = SA_NOCLDSTOP;
726 if (sigaction(SIGCHLD, &sigact, NULL) == -1) {
727 ERRMSG(
"est_dpi_sigchld",
"sigaction", errno);
733int ckd_connect (
int sock_fd,
struct sockaddr *addr, socklen_t len)
738 ret = connect(sock_fd, addr, len);
739 }
while (ret == -1 && errno == EINTR);
741 ERRMSG(
"dpid.c",
"connect", errno);
750 char *bye_cmd, *auth_cmd;
752 struct sockaddr_in sin;
757 memset(&sin, 0,
sizeof(sin));
758 sin.sin_family = AF_INET;
759 sin.sin_addr.s_addr = inet_addr(
"127.0.0.1");
761 for (i = 0; i <
numdpis; i++) {
767 ERRMSG(
"stop_active_dpis",
"socket", errno);
772 if (
ckd_connect(sock_fd, (
struct sockaddr *)&sin,
sizeof(sin)) == -1) {
773 ERRMSG(
"stop_active_dpis",
"connect", errno);
775 }
else if (
CKD_WRITE(sock_fd, auth_cmd) == -1) {
776 ERRMSG(
"stop_active_dpis",
"write", errno);
777 }
else if (
CKD_WRITE(sock_fd, bye_cmd) == -1) {
778 ERRMSG(
"stop_active_dpis",
"write", errno);
798 for (i = 0; i <
numdpis; i++) {
838 ERRMSG(
"get_message",
"failed to parse msg", 0);
840 "DpiError",
"Failed to parse request");
853 int A_len, B_len, len;
855 A_len = strlen(A->
name);
857 len =
MAX (A_len, B_len);
859 if (A->
name[A_len - 1] ==
'*')
871 char *dpi_id, *d_cmd, port_str[16];
878 if (serv == NULL || (i = serv->
dp_index) == -1)
char * dGetline(FILE *stream)
Get a line from a FILE stream.
char * dStrconcat(const char *s1,...)
Concatenate a NULL-terminated list of strings.
char * dStrdup(const char *s)
Dlist * dList_new(int size)
Create a new empty list.
int dStrnAsciiCasecmp(const char *s1, const char *s2, size_t n)
int dList_length(Dlist *lp)
For completing the ADT.
void * dList_nth_data(Dlist *lp, int n0)
Return the nth data item, NULL when not found or 'n0' is out of range.
int dClose(int fd)
Close a FD handling EINTR.
void dList_sort(Dlist *lp, dCompareFunc func)
Sort the list using a custom function.
void dList_append(Dlist *lp, void *data)
Append a data item to the list.
void dList_free(Dlist *lp)
Free a list (not its elements)
void * dList_find_custom(Dlist *lp, const void *data, dCompareFunc func)
Search a data item using a custom function.
int dParser_parse_rc_line(char **line, char **name, char **value)
Take a dillo rc line and return 'name' and 'value' pointers to it.
void * dRealloc(void *mem, size_t size)
char * dGethomedir(void)
Return the home directory in a static string (don't free)
#define dReturn_if_fail(expr)
int(* dCompareFunc)(const void *a, const void *b)
#define dNew(type, count)
void send_sockport(int sock_fd, char *dpi_tag, struct dp *dpi_attr_list)
void free_services_list(Dlist *s_list)
static void terminator(int sig)
void free_dpi_attr(struct dp *dpi_attr)
int init_all_dpi_sockets(struct dp *dpi_attr_list)
int bind_socket_fd(int base_port, int *p_port)
volatile sig_atomic_t caught_sigchld
int register_all_cmd(void)
char * get_message(int sock_fd, char *dpi_tag)
static int ends_with(const char *str, const char *suffix)
int register_all(struct dp **attlist)
int init_dpi_socket(struct dp *dpi_attr)
int init_ids_srs_socket(void)
int ckd_connect(int sock_fd, struct sockaddr *addr, socklen_t len)
void est_dpi_sigchld(void)
void handle_sigchld(void)
int get_dpi_attr(char *dpi_dir, char *service, struct dp *dpi_attr)
int service_match(const struct service *A, const char *B)
void stop_active_dpis(struct dp *dpi_attr_list, int numdpis)
static int make_socket_fd(void)
int register_service(struct dp *dpi_attr, char *service)
void est_dpi_terminator(void)
static int services_alpha_comp(const struct service *s1, const struct service *s2)
enum file_type get_file_type(char *file_name)
int fill_services_list(struct dp *attlist, int numdpis, Dlist **services_list)
char * get_dpi_dir(char *dpidrc)
void free_plugin_list(struct dp **dpi_attr_list_ptr, int numdpis)
void dpi_sigchld(int sig)
void ignore_dpi_sockets(struct dp *dpi_attr_list, int numdpis)
int save_comm_keys(int srs_port)
struct dp * dpi_attr_list
#define CKD_WRITE(fd, msg)
#define ERRMSG(CALLER, CALLED, ERR)
#define dotDILLO_DPID_COMM_KEYS
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_Misc_mksecret(int nchar)
Return a new, random hexadecimal string of 'nchar' characters.