📄 dpid.c
字号:
if (user_dirent->d_name[0] == '.') continue; *attlist = (struct dp *) g_realloc(*attlist, (snum + 1) * dp_sz); st=get_dpi_attr(user_dpidir, user_dirent->d_name, &(*attlist)[snum]); if (st == 0) snum++; } usr_srv_num = snum; closedir(user_dir_stream); } if (sys_dpidir && (sys_dir_stream = opendir(sys_dpidir)) != NULL) { /* if system service is not in user list then add it */ while ((sys_dirent = readdir(sys_dir_stream)) != NULL) { if (sys_dirent->d_name[0] == '.') continue; not_in_user_list = 1; for (j = 0; j < usr_srv_num; j++) { basename = g_basename((*attlist)[j].path); if (strcmp(sys_dirent->d_name, basename) == 0) { not_in_user_list = 0; break; } } if (not_in_user_list) { *attlist = (struct dp *) g_realloc(*attlist, (snum + 1) * dp_sz); st=get_dpi_attr(sys_dpidir, sys_dirent->d_name, &(*attlist)[snum]); if (st == 0) snum++; } } closedir(sys_dir_stream); } g_free(sys_dpidir); g_free(user_dpidir); /* todo: do we consider snum == 0 an error? * (if so, we should return -1 ) */ return (snum);}/*! Initialise the service request socket * \Return: * \li Number of sockets (1 == success) * \li -1 on failure */int init_srs_socket(char *sockdir){ int retval = -1; struct sockaddr_un srs_sa; size_t sun_path_len; socklen_t addr_sz; srs_name = g_strconcat(sockdir, "/", SRS_NAME, NULL); FD_ZERO(&sock_set); /* Initialise srs, service request socket on startup */ if ((srs = socket(AF_LOCAL, SOCK_STREAM, 0)) == -1) { ERRMSG("init_srs_socket", "socket", errno); return (retval); /* avoids nesting ifs too deeply */ } /* Set srs to close on exec */ fcntl(srs, F_SETFD, FD_CLOEXEC | fcntl(srs, F_GETFD)); srs_sa.sun_family = AF_LOCAL; sun_path_len = sizeof(srs_sa.sun_path); if ( strlen(srs_name) > sun_path_len) { ERRMSG("init_srs_socket", "srs_name is too long", 0); fprintf(stderr, "\n - it should be <= %lu chars", (gulong)sun_path_len); fprintf(stderr, "\n - srs_name = %s\n", srs_name); return(retval); } strncpy(srs_sa.sun_path, srs_name, sun_path_len); addr_sz = (socklen_t) D_SUN_LEN(&srs_sa); if ((bind(srs, (struct sockaddr *) &srs_sa, addr_sz)) == -1) { if (errno == EADDRINUSE) { ERRMSG("init_srs_socket", "bind", errno); fprintf(stderr, "srs_sa.sun_path = %s\n", srs_sa.sun_path); dpi_errno = dpid_srs_addrinuse; } else { ERRMSG("init_srs_socket", "bind", errno); fprintf(stderr, "srs_sa.sun_path = %s\n", srs_sa.sun_path); } } else if (chmod(srs_sa.sun_path, S_IRUSR | S_IWUSR) == -1) { ERRMSG("init_srs_socket", "chmod", errno); fprintf(stderr, "srs_sa.sun_path = %s\n", srs_sa.sun_path); } else if (listen(srs, QUEUE) == -1) { ERRMSG("init_srs_socket", "listen", errno); } else { retval = 1; } FD_SET(srs, &sock_set); return (retval);}/*! Initialise a single dpi socket * \Return * \li 1 on success * \li -1 on failure */int init_dpi_socket(struct dp *dpi_attr, char *sockdir){ int caught_error = 0, s; char *dpi_nm; /* pointer to basename in dpi_attr->path */ struct sockaddr_un sa; size_t sp_len; socklen_t addr_sz; size_t sock_buflen = 8192; sp_len = sizeof(sa.sun_path); if ((s = socket(AF_LOCAL, SOCK_STREAM, 0)) == -1) { ERRMSG("init_all_dpi_sockets", "socket", errno); return (-1); /* avoids nested ifs */ } /* Set the socket FD to close on exec */ fcntl(s, F_SETFD, FD_CLOEXEC | fcntl(s, F_GETFD)); /* set some buffering to increase the transfer's speed */ setsockopt(s, SOL_SOCKET, SO_SNDBUF, &sock_buflen, (socklen_t)sizeof(sock_buflen)); dpi_attr->socket = s; dpi_attr->sa.sun_family = AF_LOCAL; dpi_nm = g_basename(dpi_attr->path); dpi_attr->sockpath = g_strconcat(sockdir, "/", dpi_nm, NULL); if ( strlen(dpi_attr->sockpath) > sp_len) { ERRMSG("init_all_dpi_sockets", "socket path is too long", 0); fprintf(stderr, "\n - it should be <= %lu chars", (gulong)sp_len); fprintf(stderr, "\n - socket path = %s\n", dpi_attr->sockpath); return(-1); } strncpy(dpi_attr->sa.sun_path, dpi_attr->sockpath, sp_len); addr_sz = (socklen_t) D_SUN_LEN(&dpi_attr->sa); if ((bind(s, (struct sockaddr *) &dpi_attr->sa, addr_sz)) == -1) { ERRMSG("init_all_dpi_sockets", "bind", errno); fprintf(stderr, "%s\n", dpi_attr->sa.sun_path); caught_error = 1; } else if (chmod(dpi_attr->sa.sun_path, S_IRUSR | S_IWUSR) == -1) { ERRMSG("init_all_dpi_sockets", "chmod", errno); fprintf(stderr, "%s\n", dpi_attr->sa.sun_path); caught_error = 1; } else if (listen(s, QUEUE) == -1) { ERRMSG("init_all_dpi_sockets", "listen", errno); caught_error = 1; } if (caught_error) { return (-1); } else { FD_SET(s, &sock_set); return (1); }}/*! Setup sockets for the plugins and add them to * to the set of sockets (sock_set) watched by select. * \Return * \li Number of sockets on success * \li -1 on failure * \Modifies * dpi_attr_list.sa, dpi_attr_list.socket, numsocks, sock_set, srs * \Uses * numdpis, srs, srs_name */int init_all_dpi_sockets(struct dp *dpi_attr_list, char *sockdir){ int i; struct sockaddr_un sa; size_t sp_len; sp_len = sizeof(sa.sun_path); /* Initialise sockets for each dpi */ for (i = 0; i < numdpis; i++) { if (init_dpi_socket(dpi_attr_list + i, sockdir) == -1) return (-1); numsocks++; } return (numsocks);}/*! SIGCHLD handler */void dpi_sigchld(int sig){ caught_sigchld = 1;}/*! Called by main loop when caught_sigchld == 1 */void handle_sigchld(void){ int i, status; /* For all of the dpis in the current list * add the ones that have exited to the set of sockets being * watched by 'select'. */ for (i = 0; i < numdpis; i++) { if (waitpid(dpi_attr_list[i].pid, &status, WNOHANG) > 0) { dpi_attr_list[i].pid = 1; FD_SET(dpi_attr_list[i].socket, &sock_set); numsocks++; } } /* Wait for any old dpis that have exited */ while (waitpid(-1, &status, WNOHANG) > 0) ;}/*! Establish SIGCHLD handler */void est_dpi_sigchld(void){ struct sigaction sigact; sigset_t set; (void) sigemptyset(&set); sigact.sa_handler = dpi_sigchld; sigact.sa_mask = set; sigact.sa_flags = SA_NOCLDSTOP; if (sigaction(SIGCHLD, &sigact, NULL) == -1) { ERRMSG("est_dpi_sigchld", "sigaction", errno); exit(1); }}/*! Send DpiBye command to all active non-filter dpis */void stop_active_dpis(struct dp *dpi_attr_list, int numdpis){ static char *DpiBye_cmd = NULL; int i, dpi_socket; struct sockaddr_un dpi_addr; struct sockaddr_un sa; size_t sun_path_len, addr_len; if (!DpiBye_cmd) DpiBye_cmd = a_Dpip_build_cmd("cmd=%s", "DpiBye"); sun_path_len = sizeof(sa.sun_path); addr_len = sizeof(dpi_addr); dpi_addr.sun_family = AF_LOCAL; for (i = 0; i < numdpis; i++) { /* Skip inactive dpis and filters */ if (dpi_attr_list[i].pid == 1 || dpi_attr_list[i].filter) continue; if ((dpi_socket = socket(AF_LOCAL, SOCK_STREAM, 0)) == -1) { ERRMSG("stop_active_dpis", "socket", errno); } if ( strlen(dpi_attr_list[i].sockpath) > sun_path_len) { ERRMSG("stop_active_dpis", "socket path is too long", 0); fprintf(stderr,"\n - it should be <= %lu chars",(gulong)sun_path_len); fprintf(stderr,"\n - socket path = %s\n", dpi_attr_list[i].sockpath); } strncpy(dpi_addr.sun_path, dpi_attr_list[i].sockpath, sun_path_len); if (connect(dpi_socket, (struct sockaddr *) &dpi_addr, addr_len) == -1) { ERRMSG("stop_active_dpis", "connect", errno); fprintf(stderr, "%s\n", dpi_addr.sun_path); } (void) write(dpi_socket, DpiBye_cmd, strlen(DpiBye_cmd)); a_Misc_close_fd(dpi_socket); }}/*! Removes dpis in dpi_attr_list from the * set of sockets watched by select and * closes their sockets. */void ignore_dpi_sockets(struct dp *dpi_attr_list, int numdpis){ int i; for (i = 0; i < numdpis; i++) { FD_CLR(dpi_attr_list[i].socket, &sock_set); a_Misc_close_fd(dpi_attr_list[i].socket); }}/*! Registers available dpis and stops active non-filter dpis. * Called when dpid receives * cmd='register' service='all' * command * \Return * Number of available dpis */int register_all_cmd(char *sockdir){ stop_active_dpis(dpi_attr_list, numdpis); rm_dpi_sockets(dpi_attr_list, numdpis); free_plugin_list(&dpi_attr_list, numdpis); numdpis = 0; numsocks = 1; /* the srs socket */ FD_ZERO(&sock_set); FD_SET(srs, &sock_set); numdpis = register_all(&dpi_attr_list); numsocks = init_all_dpi_sockets(dpi_attr_list, sockdir); return (numdpis);}/*! * Get value of msg field from dpi_tag * \Return * message on success, NULL on failure */char *get_message(int sock, char *dpi_tag){ char *msg, *d_cmd; msg = a_Dpip_get_attr(dpi_tag, strlen(dpi_tag), "msg"); if (msg == NULL) { ERRMSG("get_message", "failed to parse msg\n", 0); d_cmd = a_Dpip_build_cmd("cmd=%s msg=%s", "DpiError", "Failed to parse request"); (void) CKD_WRITE(sock, d_cmd); g_free(d_cmd); } return (msg);}/*! * Send socket path that matches dpi_id to client */void send_sockpath(gint sock, gchar *dpi_tag, struct dp *dpi_attr_list){ gint i; gchar *dpi_id; char *d_cmd; g_return_if_fail((dpi_id = get_message(sock, dpi_tag)) != NULL); for (i = 0; i < numdpis; i++) if (strstr(dpi_attr_list[i].id, dpi_id)) break; if (i < numdpis) { /* found */ if (access(dpi_attr_list[i].path, F_OK) == -1) { ERRMSG("send_sockpath", "access", errno); fprintf(stderr, " - %s\n", dpi_attr_list[i].sockpath); d_cmd = a_Dpip_build_cmd("cmd=%s msg=%s", "DpiError", "Plugin currently unavailable"); (void) CKD_WRITE(sock, d_cmd); g_free(d_cmd); } else { d_cmd = a_Dpip_build_cmd("cmd=%s msg=%s", "send_data", dpi_attr_list[i].sockpath); (void) CKD_WRITE(sock, d_cmd); g_free(d_cmd); } } g_free(dpi_id);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -