Dillo v3.2.0
Loading...
Searching...
No Matches
dpid.c
Go to the documentation of this file.
1/*
2 Copyright (C) 2003 Ferdi Franceschini <ferdif@optusnet.com.au>
3 Copyright (C) 2025 Rodrigo Arias Mallo <rodarima@gmail.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
22#include <errno.h>
23#include <stdlib.h> /* for exit */
24#include <fcntl.h> /* for F_SETFD, F_GETFD, FD_CLOEXEC */
25
26#include <sys/stat.h>
27#include <sys/wait.h>
28#include <sys/socket.h>
29#include <netinet/in.h>
30#include <netinet/tcp.h>
31#include <arpa/inet.h>
32
33#include <unistd.h>
34#include "dpid_common.h"
35#include "dpid.h"
36#include "dpi.h"
37#include "dpi_socket_dir.h"
38#include "misc_new.h"
39
40#include "../dpip/dpip.h"
41
42#define DPI_EXT (".dpi" EXEEXT)
43
44#define QUEUE 5
45
46volatile sig_atomic_t caught_sigchld = 0;
47char *SharedKey = NULL;
48
53void cleanup(void)
54{
55 char *fname;
56 fname = dStrconcat(dGethomedir(), "/", dotDILLO_DPID_COMM_KEYS, NULL);
57 unlink(fname);
58 dFree(fname);
59}
60
64void free_dpi_attr(struct dp *dpi_attr)
65{
66 if (dpi_attr->id != NULL) {
67 dFree(dpi_attr->id);
68 dpi_attr->id = NULL;
69 }
70 if (dpi_attr->path != NULL) {
71 dFree(dpi_attr->path);
72 dpi_attr->path = NULL;
73 }
74}
75
78void free_plugin_list(struct dp **dpi_attr_list_ptr, int numdpis)
79{
80 int i;
81 struct dp *dpi_attr_list = *dpi_attr_list_ptr;
82
83 if (dpi_attr_list == NULL)
84 return;
85
86 for (i = 0; i < numdpis; i++)
88
90 *dpi_attr_list_ptr = NULL;
91}
92
96{
97 int i = 0;
98 struct service *s;
99
100 for (i=0; i < dList_length(s_list) ; i++) {
101 s = dList_nth_data(s_list, i);
102 dFree(s->name);
103 }
104 dList_free(s_list);
105}
106
109static void terminator(int sig)
110{
111 (void) sig; /* suppress unused parameter warning */
112 cleanup();
113 _exit(0);
114}
115
119{
120 struct sigaction act;
121 sigset_t block;
122
123 sigemptyset(&block);
124 sigaddset(&block, SIGHUP);
125 sigaddset(&block, SIGINT);
126 sigaddset(&block, SIGQUIT);
127 sigaddset(&block, SIGTERM);
128
129 act.sa_handler = terminator;
130 act.sa_mask = block;
131 act.sa_flags = 0;
132
133 if (sigaction(SIGHUP, &act, NULL) ||
134 sigaction(SIGINT, &act, NULL) ||
135 sigaction(SIGQUIT, &act, NULL) ||
136 sigaction(SIGTERM, &act, NULL)) {
137 ERRMSG("est_dpi_terminator", "sigaction", errno);
138 exit(1);
139 }
140
141 if (atexit(cleanup) != 0) {
142 ERRMSG("est_dpi_terminator", "atexit", 0);
143 MSG_ERR("Hey! atexit failed, how did that happen?\n");
144 exit(1);
145 }
146}
147
148static int ends_with(const char *str, const char *suffix)
149{
150 if (!str || !suffix)
151 return 0;
152 size_t lenstr = strlen(str);
153 size_t lensuffix = strlen(suffix);
154 if (lensuffix > lenstr)
155 return 0;
156 return strncmp(str + lenstr - lensuffix, suffix, lensuffix) == 0;
157}
158
163enum file_type get_file_type(char *file_name)
164{
165 if (ends_with(file_name, DPI_EXT))
166 /* Any filename ending in ".dpi" (or ".dpi.exe" on Windows) */
167 return DPI_FILE;
168 else {
169 MSG_ERR("get_file_type: Unknown file type for %s\n", file_name);
170 return UNKNOWN_FILE;
171 }
172}
173
180char *get_dpi_dir(char *dpidrc)
181{
182 FILE *In;
183 int len;
184 char *rcline = NULL, *value = NULL, *p;
185
186 if ((In = fopen(dpidrc, "r")) == NULL) {
187 ERRMSG("dpi_dir", "fopen", errno);
188 MSG_ERR(" - %s\n", dpidrc);
189 return (NULL);
190 }
191
192 while ((rcline = dGetline(In)) != NULL) {
193 if (strncmp(rcline, "dpi_dir", 7) == 0)
194 break;
195 dFree(rcline);
196 }
197 fclose(In);
198
199 if (!rcline) {
200 ERRMSG("dpi_dir", "Failed to find a dpi_dir entry in dpidrc", 0);
201 MSG_ERR("Put your dillo plugins path in %s\n", dpidrc);
202 MSG_ERR("e.g. dpi_dir=/usr/local/lib/dillo/dpi\n");
203 MSG_ERR("with no leading spaces.\n");
204 value = NULL;
205 } else {
206 len = (int) strlen(rcline);
207 if (len && rcline[len - 1] == '\n')
208 rcline[len - 1] = 0;
209
210 if ((p = strchr(rcline, '='))) {
211 while (*++p == ' ');
212 value = dStrdup(p);
213 } else {
214 ERRMSG("dpi_dir", "strchr", 0);
215 MSG_ERR(" - '=' not found in %s\n", rcline);
216 value = NULL;
217 }
218 }
219
220 dFree(rcline);
221 return (value);
222}
223
234int get_dpi_attr(char *dpi_dir, char *service, struct dp *dpi_attr)
235{
236 char *service_dir = NULL;
237 struct stat statinfo;
238 enum file_type ftype;
239 int ret = -1;
240 DIR *dir_stream;
241 struct dirent *dir_entry = NULL;
242
243 service_dir = dStrconcat(dpi_dir, "/", service, NULL);
244 if (stat(service_dir, &statinfo) == -1) {
245 ERRMSG("get_dpi_attr", "stat", errno);
246 MSG_ERR("file=%s\n", service_dir);
247 } else if ((dir_stream = opendir(service_dir)) == NULL) {
248 ERRMSG("get_dpi_attr", "opendir", errno);
249 } else {
250 /* Scan the directory looking for dpi files.
251 * (currently there's only the dpi program, but in the future
252 * there may also be helper scripts.) */
253 while ( (dir_entry = readdir(dir_stream)) != NULL) {
254 if (dir_entry->d_name[0] == '.')
255 continue;
256
257 ftype = get_file_type(dir_entry->d_name);
258 switch (ftype) {
259 case DPI_FILE:
260 dpi_attr->path =
261 dStrconcat(service_dir, "/", dir_entry->d_name, NULL);
262 dpi_attr->id = dStrdup(service);
263 dpi_attr->port = 0;
264 dpi_attr->pid = 1;
265 if (strstr(dpi_attr->path, ".filter") != NULL)
266 dpi_attr->filter = 1;
267 else
268 dpi_attr->filter = 0;
269 ret = 0;
270 break;
271 default:
272 break;
273 }
274 }
275 closedir(dir_stream);
276
277 if (ret != 0)
278 MSG_ERR("get_dpi_attr: No dpi plug-in in %s/%s\n",
279 dpi_dir, service);
280 }
281 dFree(service_dir);
282 return ret;
283}
284
294int register_service(struct dp *dpi_attr, char *service)
295{
296 char *user_dpi_dir, *dpidrc, *user_service_dir, *dir = NULL;
297 int ret = -1;
298
299 user_dpi_dir = dStrconcat(dGethomedir(), "/", dotDILLO_DPI, NULL);
300 user_service_dir =
301 dStrconcat(dGethomedir(), "/", dotDILLO_DPI, "/", service, NULL);
302
303 dpidrc = dStrconcat(dGethomedir(), "/", dotDILLO_DPIDRC, NULL);
304 if (access(dpidrc, F_OK) == -1) {
305 if (access(DPIDRC_SYS, F_OK) == -1) {
306 ERRMSG("register_service", "Error ", 0);
307 MSG_ERR("\n - There is no %s or %s file\n", dpidrc,
308 DPIDRC_SYS);
309 dFree(user_dpi_dir);
310 dFree(user_service_dir);
311 dFree(dpidrc);
312 return(-1);
313 }
314 dFree(dpidrc);
315 dpidrc = dStrdup(DPIDRC_SYS);
316 }
317
318 /* Check home dir for dpis */
319 if (access(user_service_dir, F_OK) == 0) {
320 get_dpi_attr(user_dpi_dir, service, dpi_attr);
321 ret = 0;
322 } else { /* Check system wide dpis */
323 if ((dir = get_dpi_dir(dpidrc)) != NULL) {
324 if (access(dir, F_OK) == 0) {
325 get_dpi_attr(dir, service, dpi_attr);
326 ret = 0;
327 } else {
328 ERRMSG("register_service", "get_dpi_attr failed", 0);
329 }
330 } else {
331 ERRMSG("register_service", "dpi_dir: Error getting dpi dir.", 0);
332 }
333 }
334 dFree(user_dpi_dir);
335 dFree(user_service_dir);
336 dFree(dpidrc);
337 dFree(dir);
338 return ret;
339}
340
348int register_all(struct dp **attlist)
349{
350 char *user_dpidir = NULL, *sys_dpidir = NULL, *dpidrc = NULL;
351 struct dirent *user_dirent, *sys_dirent;
352 int st;
353 int snum;
354 size_t dp_sz = sizeof(struct dp);
355
356 if (*attlist != NULL) {
357 ERRMSG("register_all", "attlist parameter should be NULL", 0);
358 return -1;
359 }
360
361 user_dpidir = dStrconcat(dGethomedir(), "/", dotDILLO_DPI, NULL);
362 if (access(user_dpidir, F_OK) == -1) {
363 /* no dpis in user's space */
364 dFree(user_dpidir);
365 user_dpidir = NULL;
366 }
367 dpidrc = dStrconcat(dGethomedir(), "/", dotDILLO_DPIDRC, NULL);
368 if (access(dpidrc, F_OK) == -1) {
369 dFree(dpidrc);
370 dpidrc = dStrdup(DPIDRC_SYS);
371 if (access(dpidrc, F_OK) == -1) {
372 dFree(dpidrc);
373 dpidrc = NULL;
374 }
375 }
376 if (!dpidrc || (sys_dpidir = get_dpi_dir(dpidrc)) == NULL)
377 sys_dpidir = NULL;
378 dFree(dpidrc);
379
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");
383 exit(1);
384 }
385
386 /* Get list of services in user's .dillo/dpi directory */
387 snum = 0;
388 if (user_dpidir) {
389 DIR *user_dir_stream = opendir(user_dpidir);
390 /* Only complain if error is other than not found as the user may not have
391 * any DPIs installed. */
392 if (user_dir_stream == NULL && errno != ENOENT) {
393 MSG_ERR("cannot open user dpi directory '%s': %s\n",
394 user_dpidir, strerror(errno));
395 } else {
396 while ((user_dirent = readdir(user_dir_stream)) != NULL) {
397 if (user_dirent->d_name[0] == '.')
398 continue;
399 *attlist = (struct dp *) dRealloc(*attlist, (snum + 1) * dp_sz);
400 st=get_dpi_attr(user_dpidir, user_dirent->d_name, &(*attlist)[snum]);
401 if (st == 0)
402 snum++;
403 }
404 closedir(user_dir_stream);
405 }
406 }
407 if (sys_dpidir) {
408 DIR *sys_dir_stream = opendir(sys_dpidir);
409 /* For system DPIs always complain. */
410 if (sys_dir_stream == NULL) {
411 MSG_ERR("cannot open system dpi directory '%s': %s\n",
412 sys_dpidir, strerror(errno));
413 } else {
414 /* if system service is not in user list then add it */
415 while ((sys_dirent = readdir(sys_dir_stream)) != NULL) {
416 if (sys_dirent->d_name[0] == '.')
417 continue;
418 *attlist = (struct dp *) dRealloc(*attlist, (snum + 1) * dp_sz);
419 st=get_dpi_attr(sys_dpidir, sys_dirent->d_name, &(*attlist)[snum]);
420 if (st == 0)
421 snum++;
422 }
423 closedir(sys_dir_stream);
424 }
425 }
426
427 dFree(sys_dpidir);
428 dFree(user_dpidir);
429
430 /* TODO: do we consider snum == 0 an error?
431 * (if so, we should return -1 ) */
432 return (snum);
433}
434
435/*
436 * Compare two struct service pointers
437 * This function is used for sorting services
438 */
439static int services_alpha_comp(const struct service *s1,
440 const struct service *s2)
441{
442 return -strcmp(s1->name, s2->name);
443}
444
452int fill_services_list(struct dp *attlist, int numdpis, Dlist **services_list)
453{
454 FILE *dpidrc_stream;
455 char *p, *line = NULL, *service, *path;
456 int i, st;
457 struct service *s;
458 char *user_dpidir = NULL, *sys_dpidir = NULL, *dpidrc = NULL;
459
460 user_dpidir = dStrconcat(dGethomedir(), "/", dotDILLO_DPI, NULL);
461 if (access(user_dpidir, F_OK) == -1) {
462 /* no dpis in user's space */
463 dFree(user_dpidir);
464 user_dpidir = NULL;
465 }
466 dpidrc = dStrconcat(dGethomedir(), "/", dotDILLO_DPIDRC, NULL);
467 if (access(dpidrc, F_OK) == -1) {
468 dFree(dpidrc);
469 dpidrc = dStrdup(DPIDRC_SYS);
470 if (access(dpidrc, F_OK) == -1) {
471 dFree(dpidrc);
472 dpidrc = NULL;
473 }
474 }
475 if (!dpidrc || (sys_dpidir = get_dpi_dir(dpidrc)) == NULL)
476 sys_dpidir = NULL;
477
478 if (!user_dpidir && !sys_dpidir) {
479 ERRMSG("fill_services_list", "Fatal error ", 0);
480 MSG_ERR("\n - Can't find the directory for dpis.\n");
481 exit(1);
482 }
483
484 if ((dpidrc_stream = fopen(dpidrc, "r")) == NULL) {
485 ERRMSG("fill_services_list", "popen failed", errno);
486 dFree(dpidrc);
487 dFree(sys_dpidir);
488 dFree(user_dpidir);
489 return (-1);
490 }
491
492 if (*services_list != NULL) {
493 ERRMSG("fill_services_list", "services_list parameter is not NULL", 0);
494 fclose(dpidrc_stream);
495 return -1;
496 }
498
499 /* dpidrc parser loop */
500 for (;(line = dGetline(dpidrc_stream)) != NULL; dFree(line)) {
501 st = dParser_parse_rc_line(&line, &service, &path);
502 if (st < 0) {
503 MSG_ERR("dpid: Syntax error in %s: service=\"%s\" path=\"%s\"\n",
504 dpidrc, service, path);
505 continue;
506 } else if (st != 0) {
507 continue;
508 }
509
510 _MSG("dpid: service=%s, path=%s\n", service, path);
511
512 /* ignore dpi_dir silently */
513 if (strcmp(service, "dpi_dir") == 0)
514 continue;
515
516 s = dNew(struct service, 1);
517 /* init services list entry */
518 s->name = dStrdup(service);
519 s->dp_index = -1;
520
522 /* search the dpi for a service by its path */
523 for (i = 0; i < numdpis; i++)
524 if ((p = strstr(attlist[i].path, path)) && *(p - 1) == '/' &&
525 strlen(p) == strlen(path))
526 break;
527 /* if the dpi exist bind service and dpi */
528 if (i < numdpis)
529 s->dp_index = i;
530 }
531 fclose(dpidrc_stream);
532
534
535 dFree(dpidrc);
536 dFree(sys_dpidir);
537 dFree(user_dpidir);
538
539 return (dList_length(*services_list));
540}
541
542/*
543 * Return a socket file descriptor
544 * (useful to set socket options in a uniform way)
545 */
546static int make_socket_fd(void)
547{
548 int ret, one = 1;
549
550 if ((ret = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
551 ERRMSG("make_socket_fd", "socket", errno);
552 } else {
553 /* avoid delays when sending small pieces of data */
554 setsockopt(ret, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one));
555 }
556
557 /* set some buffering to increase the transfer's speed */
558 //setsockopt(sock_fd, SOL_SOCKET, SO_SNDBUF,
559 // &sock_buflen, (socklen_t)sizeof(sock_buflen));
560
561 return ret;
562}
563
569int bind_socket_fd(int base_port, int *p_port)
570{
571 int sock_fd, port;
572 struct sockaddr_in sin;
573 int ok = 0, last_port = base_port + 50;
574
575 if ((sock_fd = make_socket_fd()) == -1) {
576 return (-1); /* avoids nested ifs */
577 }
578 /* Set the socket FD to close on exec */
579 fcntl(sock_fd, F_SETFD, FD_CLOEXEC | fcntl(sock_fd, F_GETFD));
580
581
582 memset(&sin, 0, sizeof(sin));
583 sin.sin_family = AF_INET;
584 sin.sin_addr.s_addr = inet_addr("127.0.0.1");
585
586 /* Try to bind a port on localhost */
587 for (port = base_port; port <= last_port; ++port) {
588 sin.sin_port = htons(port);
589 if ((bind(sock_fd, (struct sockaddr *)&sin, sizeof(sin))) == -1) {
590 if (errno == EADDRINUSE || errno == EADDRNOTAVAIL)
591 continue;
592 ERRMSG("bind_socket_fd", "bind", errno);
593 } else if (listen(sock_fd, QUEUE) == -1) {
594 ERRMSG("bind_socket_fd", "listen", errno);
595 } else {
596 *p_port = port;
597 ok = 1;
598 break;
599 }
600 }
601 if (port > last_port) {
602 MSG_ERR("Hey! Can't find an available port from %d to %d\n",
603 base_port, last_port);
604 }
605
606 return ok ? sock_fd : -1;
607}
608
613int save_comm_keys(int srs_port)
614{
615 int fd, ret = -1;
616 char *fname, port_str[32];
617
618 fname = dStrconcat(dGethomedir(), "/", dotDILLO_DPID_COMM_KEYS, NULL);
619 fd = open(fname, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
620 dFree(fname);
621 if (fd == -1) {
622 MSG("save_comm_keys: open %s\n", dStrerror(errno));
623 } else {
624 snprintf(port_str, 16, "%d %s\n", srs_port, SharedKey);
625 if (CKD_WRITE(fd, port_str) != -1 && CKD_CLOSE(fd) != -1) {
626 ret = 1;
627 }
628 }
629
630 return ret;
631}
632
639{
640 int srs_port, ret = -1;
641
642 FD_ZERO(&sock_set);
643
644 if ((srs_fd = bind_socket_fd(DPID_BASE_PORT, &srs_port)) != -1) {
645 /* create the shared secret */
647 /* save port number and SharedKey */
648 if (save_comm_keys(srs_port) != -1) {
649 FD_SET(srs_fd, &sock_set);
650 ret = 1;
651 }
652 }
653
654 return ret;
655}
656
662int init_dpi_socket(struct dp *dpi_attr)
663{
664 int s_fd, port, ret = -1;
665
666 if ((s_fd = bind_socket_fd(DPID_BASE_PORT, &port)) != -1) {
667 dpi_attr->sock_fd = s_fd;
668 dpi_attr->port = port;
669 FD_SET(s_fd, &sock_set);
670 ret = 1;
671 }
672
673 return ret;
674}
675
687{
688 int i;
689
690 /* Initialise sockets for each dpi */
691 for (i = 0; i < numdpis; i++) {
692 if (init_dpi_socket(dpi_attr_list + i) == -1)
693 return (-1);
694 numsocks++;
695 }
696
697 return (numsocks);
698}
699
702void dpi_sigchld(int sig)
703{
704 if (sig == SIGCHLD)
705 caught_sigchld = 1;
706}
707
710{
711 // pid_t pid;
712 int i, status; //, num_active;
713
714 /* For all of the dpis in the current list
715 * add the ones that have exited to the set of sockets being
716 * watched by 'select'.
717 */
718 for (i = 0; i < numdpis; i++) {
719 if (waitpid(dpi_attr_list[i].pid, &status, WNOHANG) > 0) {
720 dpi_attr_list[i].pid = 1;
721 FD_SET(dpi_attr_list[i].sock_fd, &sock_set);
722 numsocks++;
723 }
724 }
725
726 /* Wait for any old dpis that have exited */
727 while (waitpid(-1, &status, WNOHANG) > 0)
728 ;
729}
730
733{
734 struct sigaction sigact;
735 sigset_t set;
736
737 (void) sigemptyset(&set);
738 sigact.sa_handler = dpi_sigchld;
739 sigact.sa_mask = set;
740 sigact.sa_flags = SA_NOCLDSTOP;
741 if (sigaction(SIGCHLD, &sigact, NULL) == -1) {
742 ERRMSG("est_dpi_sigchld", "sigaction", errno);
743 exit(1);
744 }
745}
746
748int ckd_connect (int sock_fd, struct sockaddr *addr, socklen_t len)
749{
750 ssize_t ret;
751
752 do {
753 ret = connect(sock_fd, addr, len);
754 } while (ret == -1 && errno == EINTR);
755 if (ret == -1) {
756 ERRMSG("dpid.c", "connect", errno);
757 }
758 return ret;
759}
760
764{
765 char *bye_cmd, *auth_cmd;
766 int i, sock_fd;
767 struct sockaddr_in sin;
768
769 bye_cmd = a_Dpip_build_cmd("cmd=%s", "DpiBye");
770 auth_cmd = a_Dpip_build_cmd("cmd=%s msg=%s", "auth", SharedKey);
771
772 memset(&sin, 0, sizeof(sin));
773 sin.sin_family = AF_INET;
774 sin.sin_addr.s_addr = inet_addr("127.0.0.1");
775
776 for (i = 0; i < numdpis; i++) {
777 /* Skip inactive dpis and filters */
778 if (dpi_attr_list[i].pid == 1 || dpi_attr_list[i].filter)
779 continue;
780
781 if ((sock_fd = make_socket_fd()) == -1) {
782 ERRMSG("stop_active_dpis", "socket", errno);
783 continue;
784 }
785
786 sin.sin_port = htons(dpi_attr_list[i].port);
787 if (ckd_connect(sock_fd, (struct sockaddr *)&sin, sizeof(sin)) == -1) {
788 ERRMSG("stop_active_dpis", "connect", errno);
789 MSG_ERR("%s\n", dpi_attr_list[i].path);
790 } else if (CKD_WRITE(sock_fd, auth_cmd) == -1) {
791 ERRMSG("stop_active_dpis", "write", errno);
792 } else if (CKD_WRITE(sock_fd, bye_cmd) == -1) {
793 ERRMSG("stop_active_dpis", "write", errno);
794 }
795 dClose(sock_fd);
796 }
797
798 dFree(auth_cmd);
799 dFree(bye_cmd);
800
801 /* Allow child dpis some time to read dpid_comm_keys before erasing it */
802 sleep (1);
803}
804
810{
811 int i;
812
813 for (i = 0; i < numdpis; i++) {
814 FD_CLR(dpi_attr_list[i].sock_fd, &sock_set);
815 dClose(dpi_attr_list[i].sock_fd);
816 }
817}
818
841
847char *get_message(int sock_fd, char *dpi_tag)
848{
849 char *msg, *d_cmd;
850
851 msg = a_Dpip_get_attr(dpi_tag, "msg");
852 if (msg == NULL) {
853 ERRMSG("get_message", "failed to parse msg", 0);
854 d_cmd = a_Dpip_build_cmd("cmd=%s msg=%s",
855 "DpiError", "Failed to parse request");
856 (void) CKD_WRITE(sock_fd, d_cmd);
857 dFree(d_cmd);
858 }
859 return (msg);
860}
861
862/*
863 * Compare a struct service pointer and a service name
864 * This function is used for searching services by name
865 */
866int service_match(const struct service *A, const char *B)
867{
868 int A_len, B_len, len;
869
870 A_len = strlen(A->name);
871 B_len = strlen(B);
872 len = MAX (A_len, B_len);
873
874 if (A->name[A_len - 1] == '*')
875 len = A_len - 1;
876
877 return(dStrnAsciiCasecmp(A->name, B, len));
878}
879
883void send_sockport(int sock_fd, char *dpi_tag, struct dp *dpi_attr_list)
884{
885 int i;
886 char *dpi_id, *d_cmd, port_str[16];
887 struct service *serv;
888
889 dReturn_if_fail((dpi_id = get_message(sock_fd, dpi_tag)) != NULL);
890
892
893 if (serv == NULL || (i = serv->dp_index) == -1)
894 for (i = 0; i < numdpis; i++)
895 if (!strncmp(dpi_attr_list[i].id, dpi_id,
896 dpi_attr_list[i].id - strchr(dpi_attr_list[i].id, '.')))
897 break;
898
899 if (i < numdpis) {
900 /* found */
901 snprintf(port_str, 8, "%d", dpi_attr_list[i].port);
902 d_cmd = a_Dpip_build_cmd("cmd=%s msg=%s", "send_data", port_str);
903 (void) CKD_WRITE(sock_fd, d_cmd);
904 dFree(d_cmd);
905 }
906
907 dFree(dpi_id);
908}
#define _MSG(...)
Definition bookmarks.c:45
#define MSG(...)
Definition bookmarks.c:46
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
char * dStrdup(const char *s)
Definition dlib.c:77
Dlist * dList_new(int size)
Create a new empty list.
Definition dlib.c:548
int dStrnAsciiCasecmp(const char *s1, const char *s2, size_t n)
Definition dlib.c:215
int dList_length(Dlist *lp)
For completing the ADT.
Definition dlib.c:613
void * dList_nth_data(Dlist *lp, int n0)
Return the nth data item, NULL when not found or 'n0' is out of range.
Definition dlib.c:662
int dClose(int fd)
Close a FD handling EINTR.
Definition dlib.c:951
void dList_sort(Dlist *lp, dCompareFunc func)
Sort the list using a custom function.
Definition dlib.c:758
void dList_append(Dlist *lp, void *data)
Append a data item to the list.
Definition dlib.c:597
void dList_free(Dlist *lp)
Free a list (not its elements)
Definition dlib.c:564
void * dList_find_custom(Dlist *lp, const void *data, dCompareFunc func)
Search a data item using a custom function.
Definition dlib.c:704
int dParser_parse_rc_line(char **line, char **name, char **value)
Take a dillo rc line and return 'name' and 'value' pointers to it.
Definition dlib.c:834
void * dRealloc(void *mem, size_t size)
Definition dlib.c:53
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
int(* dCompareFunc)(const void *a, const void *b)
Definition dlib.h:144
#define MAX(a, b)
Definition dlib.h:27
#define dNew(type, count)
Definition dlib.h:49
void send_sockport(int sock_fd, char *dpi_tag, struct dp *dpi_attr_list)
Definition dpid.c:883
void free_services_list(Dlist *s_list)
Definition dpid.c:95
static void terminator(int sig)
Definition dpid.c:109
char * SharedKey
Definition dpid.c:47
void free_dpi_attr(struct dp *dpi_attr)
Definition dpid.c:64
int init_all_dpi_sockets(struct dp *dpi_attr_list)
Definition dpid.c:686
int bind_socket_fd(int base_port, int *p_port)
Definition dpid.c:569
volatile sig_atomic_t caught_sigchld
Definition dpid.c:46
int register_all_cmd(void)
Definition dpid.c:826
char * get_message(int sock_fd, char *dpi_tag)
Definition dpid.c:847
static int ends_with(const char *str, const char *suffix)
Definition dpid.c:148
int register_all(struct dp **attlist)
Definition dpid.c:348
int init_dpi_socket(struct dp *dpi_attr)
Definition dpid.c:662
int init_ids_srs_socket(void)
Definition dpid.c:638
int ckd_connect(int sock_fd, struct sockaddr *addr, socklen_t len)
Definition dpid.c:748
void est_dpi_sigchld(void)
Definition dpid.c:732
void handle_sigchld(void)
Definition dpid.c:709
int get_dpi_attr(char *dpi_dir, char *service, struct dp *dpi_attr)
Definition dpid.c:234
int service_match(const struct service *A, const char *B)
Definition dpid.c:866
void stop_active_dpis(struct dp *dpi_attr_list, int numdpis)
Definition dpid.c:763
#define DPI_EXT
Definition dpid.c:42
static int make_socket_fd(void)
Definition dpid.c:546
int register_service(struct dp *dpi_attr, char *service)
Definition dpid.c:294
void est_dpi_terminator(void)
Definition dpid.c:118
static int services_alpha_comp(const struct service *s1, const struct service *s2)
Definition dpid.c:439
#define QUEUE
Definition dpid.c:44
enum file_type get_file_type(char *file_name)
Definition dpid.c:163
int fill_services_list(struct dp *attlist, int numdpis, Dlist **services_list)
Definition dpid.c:452
char * get_dpi_dir(char *dpidrc)
Definition dpid.c:180
void free_plugin_list(struct dp **dpi_attr_list_ptr, int numdpis)
Definition dpid.c:78
void dpi_sigchld(int sig)
Definition dpid.c:702
void ignore_dpi_sockets(struct dp *dpi_attr_list, int numdpis)
Definition dpid.c:809
void cleanup(void)
Definition dpid.c:53
int save_comm_keys(int srs_port)
Definition dpid.c:613
Dlist * services_list
Definition main.c:49
#define DPID_BASE_PORT
Definition dpid.h:24
int numdpis
Definition main.c:46
int numsocks
Definition main.c:50
fd_set sock_set
Definition main.c:47
struct dp * dpi_attr_list
Definition main.c:48
int srs_fd
Definition main.c:51
#define CKD_WRITE(fd, msg)
Definition dpid_common.h:37
#define MSG_ERR(...)
Definition dpid_common.h:23
#define dotDILLO_DPI
Definition dpid_common.h:25
#define ERRMSG(CALLER, CALLED, ERR)
Definition dpid_common.h:29
#define CKD_CLOSE(fd)
Definition dpid_common.h:38
file_type
Definition dpid_common.h:43
@ DPI_FILE
Definition dpid_common.h:44
@ UNKNOWN_FILE
Definition dpid_common.h:45
#define dotDILLO_DPIDRC
Definition dpid_common.h:26
#define dotDILLO_DPID_COMM_KEYS
Definition dpid_common.h:27
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_Misc_mksecret(int nchar)
Return a new, random hexadecimal string of 'nchar' characters.
Definition misc_new.c:181
Definition dlib.h:131
Definition dpid.h:35
int filter
Definition dpid.h:41
char * path
Definition dpid.h:37
int sock_fd
Definition dpid.h:38
char * id
Definition dpid.h:36
int port
Definition dpid.h:39
pid_t pid
Definition dpid.h:40
Definition dpid.h:46
int dp_index
Definition dpid.h:48
char * name
Definition dpid.h:47
static void path()
Definition cookies.c:859