📄 dpid.c
字号:
/* Copyright (C) 2003 Ferdi Franceschini <ferdif@optusnet.com.au> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *//*! \file * Main functions to set-up dpi information and to initialise sockets */#include <errno.h>#include <glib.h>#include <sys/stat.h>#include <sys/wait.h>#include <unistd.h>#include "dpid_common.h"#include "dpid.h"#include "dpi.h"#include "dpi_socket_dir.h"#include "dpi_service.h"#include "misc_new.h"#include "../dpip/dpip.h"#define QUEUE 5volatile sig_atomic_t caught_sigchld = 0;/*! Close and remove the sockets in the * given dpi attribute list */void rm_dpi_sockets(struct dp *dpi_attr_list, int numdpis){ gint i; for (i = 0; i < numdpis; i++) { a_Misc_close_fd(dpi_attr_list[i].socket); (void) unlink(dpi_attr_list[i].sockpath); }}/*! Close and remove inactive dpi sockets * \Return * Number of active dpis. */int rm_inactive_dpi_sockets(struct dp *dpi_attr_list, int numdpis){ int i, active = 0; for (i = 0; i < numdpis; i++) { if (dpi_attr_list[i].pid == 1) { a_Misc_close_fd(dpi_attr_list[i].socket); (void) unlink(dpi_attr_list[i].sockpath); } else active++; } return (active);}/*! Remove sockets */void cleanup(char *socket_dir){ DIR *dir; struct dirent *dir_entry = NULL; char *sockpath; dir = opendir(socket_dir); if (dir == NULL) { ERRMSG("cleanup", "opendir", errno); return; } while ( (dir_entry = readdir(dir)) != NULL ) { if ( dir_entry->d_name[0] == '.' ) continue; sockpath = g_strconcat(socket_dir, "/", dir_entry->d_name, NULL); unlink(sockpath); g_free(sockpath); } closedir(dir);}/*! Free memory used to describe * a set of dpi attributes */void free_dpi_attr(struct dp *dpi_attr){ if (dpi_attr->id != NULL) { g_free(dpi_attr->id); dpi_attr->id = NULL; } if (dpi_attr->path != NULL) { g_free(dpi_attr->path); dpi_attr->path = NULL; } if (dpi_attr->sockpath != NULL) { g_free(dpi_attr->sockpath); dpi_attr->sockpath = NULL; }}/*! Free memory used by the plugin list */void free_plugin_list(struct dp **dpi_attr_list_ptr, int numdpis){ int i; struct dp *dpi_attr_list = *dpi_attr_list_ptr; if (dpi_attr_list == NULL) return; for (i = 0; i < numdpis; i++) free_dpi_attr(dpi_attr_list + i); g_free(dpi_attr_list); *dpi_attr_list_ptr = NULL;}/*! \todo * Remove terminator and est_terminator unless we really want to clean up * on abnormal exit. */#if 0/*! Signal handler for SIGINT, SIGQUIT, and SIGTERM. Calls cleanup */void terminator(int sig){ (void) signal(SIGCHLD, SIG_DFL); cleanup(); (void) signal(sig, SIG_DFL); (void) raise(sig); _exit(0);}/*! Establish handler for termination signals * and register cleanup with atexit */void est_terminator(void){ struct sigaction act; sigset_t block; (void) sigemptyset(&block); (void) sigaddset(&block, SIGINT); (void) sigaddset(&block, SIGQUIT); (void) sigaddset(&block, SIGTERM); (void) sigaddset(&block, SIGSEGV); act.sa_handler = terminator; act.sa_mask = block; act.sa_flags = 0; if (sigaction(SIGINT, &act, NULL) || sigaction(SIGQUIT, &act, NULL) || sigaction(SIGTERM, &act, NULL) || sigaction(SIGSEGV, &act, NULL)) { ERRMSG("est_terminator", "sigaction", errno); exit(1); } if (atexit(cleanup) != 0) { ERRMSG("est_terminator", "atexit", 0); fprintf(stderr, "Hey! atexit failed, how did that happen?\n"); exit(1); }}#endif/*! Identify a given file * Currently there is only one file type associated with dpis. * More file types will be added as needed */enum file_type get_file_type(gchar *file_name){ gchar *dot = strrchr(file_name, '.'); if (dot && !strcmp(dot, ".dpi")) return DPI_FILE; /* Any filename ending in ".dpi" */ else { fprintf(stderr, "get_file_type: Unknown file type for %s\n", file_name); return UNKNOWN_FILE; }}/*! Scans a service directory in dpi_dir and fills dpi_attr * \Note * Caller must allocate memory for dpi_attr. * \Return * \li 0 on success * \li -1 on failure * \todo * Add other file types, but first we need to add files associated with a dpi * to the design. */int get_dpi_attr(char *dpi_dir, char *service, struct dp *dpi_attr){ char *service_dir = NULL; struct stat statinfo; enum file_type ftype; int retval = -1; DIR *dir_stream; struct dirent *dir_entry = NULL; service_dir = g_strconcat(dpi_dir, "/", service, NULL); if (stat(service_dir, &statinfo) == -1) { ERRMSG("get_dpi_attr", "stat", errno); fprintf(stderr, "file=%s\n", service_dir); } else if ( (dir_stream = opendir(service_dir)) == NULL) { ERRMSG("get_dpi_attr", "opendir", errno); } else { /* Scan the directory loking for dpi files. * (currently there's only the dpi program, but in the future * there may also be helper scripts.) */ while ( (dir_entry = readdir(dir_stream)) != NULL) { if (dir_entry->d_name[0] == '.') continue; ftype = get_file_type(dir_entry->d_name); switch (ftype) { case DPI_FILE: dpi_attr->path = g_strconcat(service_dir, "/", dir_entry->d_name, NULL); dpi_attr->id = g_strdup(service); dpi_attr->sockpath = NULL; dpi_attr->pid = 1; if (strstr(dpi_attr->path, ".filter") != NULL) dpi_attr->filter = 1; else dpi_attr->filter = 0; retval = 0; break; default: break; } } closedir(dir_stream); if (retval != 0) fprintf(stderr,"get_dpi_attr: No dpi plug-in in %s/%s\n", dpi_dir, service); } g_free(service_dir); return retval;}/*! Register a service * Retrieves attributes for "service" and stores them * in dpi_attr. It looks for "service" in ~/.dillo/dpi * first, and then in the system wide dpi directory. * Caller must allocate memory for dpi_attr. * \Return * \li 0 on success * \li -1 on failure */int register_service(struct dp *dpi_attr, char *service){ char *user_dpi_dir, *dpidrc, *user_service_dir, *dir = NULL; int retval = -1; /* g_get_home_dir makes it hard to test for mem leaks */ user_dpi_dir = g_strconcat(a_Misc_get_home(), "/", dotDILLO_DPI, NULL); user_service_dir = g_strconcat(a_Misc_get_home(), "/", dotDILLO_DPI, "/", service, NULL); dpidrc = g_strconcat(a_Misc_get_home(), "/", dotDILLO_DPIDRC, NULL); if ( access(dpidrc, F_OK) == -1 ) { if ( access(DPIDRC_SYS, F_OK) == -1 ) { ERRMSG("register_service", "Error ", 0); fprintf(stderr, "\n - There is no %s or %s file\n", dpidrc, DPIDRC_SYS); g_free(user_dpi_dir); g_free(user_service_dir); g_free(dpidrc); return(-1); } g_free(dpidrc); dpidrc = g_strdup(DPIDRC_SYS); } /* Check home dir for dpis */ if (access(user_service_dir, F_OK) == 0) { get_dpi_attr(user_dpi_dir, service, dpi_attr); retval = 0; } else { /* Check system wide dpis */ if ((dir = get_dpi_dir(dpidrc)) != NULL) { if (access(dir, F_OK) == 0) { get_dpi_attr(dir, service, dpi_attr); retval = 0; } else { ERRMSG("register_service", "get_dpi_attr failed\n", 0); } } else { ERRMSG("register_service", "dpi_dir: Error getting dpi dir.\n", 0); } } g_free(user_dpi_dir); g_free(user_service_dir); g_free(dpidrc); g_free(dir); return (retval);}/*! * Create dpi directory for available * plugins and create plugin list. * \Return * \li Returns number of available plugins on success * \li -1 on failure */int register_all(struct dp **attlist){ DIR *user_dir_stream, *sys_dir_stream; char *user_dpidir = NULL, *sys_dpidir = NULL, *dpidrc = NULL; char *basename=NULL; struct dirent *user_dirent, *sys_dirent; int j, st, not_in_user_list; int snum, usr_srv_num; size_t dp_sz = sizeof(struct dp); if (*attlist != NULL) { ERRMSG("register_all", "attlist parameter should be NULL\n", 0); return -1; } user_dpidir = g_strconcat(a_Misc_get_home(), "/", dotDILLO_DPI, NULL); if (access(user_dpidir, F_OK) == -1) { /* no dpis in user's space */ g_free(user_dpidir); user_dpidir = NULL; } dpidrc = g_strconcat(a_Misc_get_home(), "/", dotDILLO_DPIDRC, NULL); if (access(dpidrc, F_OK) == -1) { g_free(dpidrc); dpidrc = g_strdup(DPIDRC_SYS); if (access(dpidrc, F_OK) == -1) { g_free(dpidrc); dpidrc = NULL; } } if (!dpidrc || (sys_dpidir = get_dpi_dir(dpidrc)) == NULL) sys_dpidir = NULL; g_free(dpidrc); if (!user_dpidir && !sys_dpidir) { ERRMSG("register_all", "Fatal error ", 0); fprintf(stderr, "\n - Can't find the directory for dpis.\n"); exit(1); } /* Get list of services in user's .dillo/dpi directory */ snum = usr_srv_num = 0; if (user_dpidir && (user_dir_stream = opendir(user_dpidir)) != NULL) { while ((user_dirent = readdir(user_dir_stream)) != NULL) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -