int pscc_log_init() { util_log_type_t log_level = UTIL_LOG_TYPE_UNKNOWN; log_level = util_read_log_file(UTIL_LOG_MODULE_PSCC); pscc_set_log_level(log_level); pscc_log_fd = inotify_init(); if (pscc_log_fd < 0) { PSCC_DBG_TRACE(LOG_ERR,"Error %d (%s) when init inotify", errno, strerror(errno), UTIL_LOG_FILE); goto exit; } pscc_log_file_wd = inotify_add_watch(pscc_log_fd, UTIL_LOG_FILE, IN_MODIFY | IN_MOVE_SELF); if (pscc_log_file_wd < 0) { PSCC_DBG_TRACE(LOG_ERR,"Error %d (%s) when adding watch on file %s", errno, strerror(errno), UTIL_LOG_FILE); } pscc_log_dir_wd = inotify_add_watch(pscc_log_fd, UTIL_LOG_DIR, IN_CREATE); if (pscc_log_dir_wd < 0) { PSCC_DBG_TRACE(LOG_ERR,"Error %d (%s) when adding watch on dir %s", errno, strerror(errno), UTIL_LOG_DIR); } exit: return pscc_log_fd; }
/** * exec_script() **/ static int exec_script(char *const *argv, char *const *env) { pid_t pid; switch (pid = vfork()) { case -1: PSCC_DBG_TRACE(LOG_ERR, "vfork: %s\n", strerror(errno)); break; case 0: execve(argv[0], argv, env); PSCC_DBG_TRACE(LOG_ERR, "%s: %s\n", argv[0], strerror(errno)); _exit(127); /* NOTREACHED */ } return pid; }
int pscc_log_select_callback(const int fd, const void *data_p) { struct inotify_event *inotify_data_p = NULL; char tmp_data[100]; int res = -1; (void)data_p; util_log_type_t log_level = UTIL_LOG_TYPE_UNKNOWN; res = read(fd, &tmp_data, sizeof(tmp_data)); if (res < 0) { PSCC_DBG_TRACE(LOG_ERR,"Error %d (%s) when reading inotify ", errno, strerror(errno)); goto exit; } inotify_data_p = (struct inotify_event *)tmp_data; if ((inotify_data_p->mask & IN_IGNORED) > 0) { PSCC_DBG_TRACE(LOG_INFO,"log configuration file updated, waiting for file to settle"); } if ((inotify_data_p->mask & IN_CREATE) > 0 && strncmp(inotify_data_p->name, UTIL_LOG_FILE_NAME, inotify_data_p->len) == 0) { PSCC_DBG_TRACE(LOG_DEBUG,"log file created add new watch"); (void)inotify_rm_watch(pscc_log_fd, pscc_log_file_wd); pscc_log_file_wd = inotify_add_watch(pscc_log_fd, UTIL_LOG_FILE, IN_MODIFY); if (pscc_log_file_wd < 0) { PSCC_DBG_TRACE(LOG_ERR,"Error %d (%s) when adding watch on file ", errno, strerror(errno), UTIL_LOG_FILE); } } if ((inotify_data_p->mask & IN_IGNORED) == 0) { log_level = util_read_log_file(UTIL_LOG_MODULE_PSCC); pscc_set_log_level(log_level); } exit: return TRUE; }
/** * pscc_obj_delete - delete ps connection control object **/ int pscc_obj_delete(int connid) { pscc_object_t* cur; cur = pscc_obj_get(connid); if (cur==NULL) { PSCC_DBG_TRACE(LOG_ERR, "Failed finding object for connid=%d\n", connid); return (-1); } mpl_list_remove(&objects_list,&cur->list_entry); mpl_param_list_destroy(&cur->param_list_p); free(cur); return (0); }
/** * pscc_obj_add - add ps connection control object **/ pscc_object_t *pscc_obj_add(int connid) { pscc_object_t *temp; temp = malloc(sizeof(pscc_object_t)); if(temp==NULL) { PSCC_DBG_TRACE(LOG_ERR, "Failed allocating memory\n"); return (NULL); } temp->connid = connid; temp->state = pscc_connection_status_disconnected; temp->param_list_p = NULL; mpl_list_add(&objects_list,&temp->list_entry); return (temp); }
/** * pscc_runscript_call() **/ int pscc_runscript_call(pscc_object_t*obj) { char *const argv[2] = {pscc_runscript_path, NULL }; char **env = NULL; int elem_size; int env_idx = 0; pscc_paramid_t id; mpl_param_element_t* param_elem_p; pid_t pid; int status = 0; int i,number_of_params; int number_of_envs; if (NULL == pscc_runscript_path) return 0; number_of_params = (sizeof(pscc_runscript_parameters)/sizeof(int)); number_of_envs = (number_of_params + 2);//2 here means the first element is for connection status // and the last one is for "/0" env = malloc(sizeof(char *) * number_of_envs); if(NULL == env) { PSCC_DBG_TRACE(LOG_ERR, "malloc failed\n"); return(-1); } elem_size = strlen("connection_status") + strlen(pscc_names_connection_status[pscc_obj_get_state(obj)]) + 2; env[env_idx] = malloc(elem_size); if(NULL == env[env_idx]) { PSCC_DBG_TRACE(LOG_ERR, "malloc failed\n"); free(env); return(-1); } snprintf(env[env_idx], elem_size, "connection_status=%s", pscc_names_connection_status[pscc_obj_get_state(obj)]); env_idx++; for(i=0;i<number_of_params;i++) { id=pscc_runscript_parameters[i]; param_elem_p = pscc_get_param(obj->connid, id); if (NULL == param_elem_p) { continue; } switch (id) { case pscc_paramid_dns_address: { mpl_param_element_t* tmp_elem_p = param_elem_p; int my_idx = 0; elem_size = strlen("dns_addresses="); do { elem_size += snprintf(NULL, 0, "%s ", mpl_param_value_get_string(id, tmp_elem_p->value_p)); } while (NULL != (tmp_elem_p = mpl_param_list_find_next(id, tmp_elem_p))); elem_size++; env[env_idx] = malloc(elem_size); if(NULL == env[env_idx]) { PSCC_DBG_TRACE(LOG_ERR, "malloc failed\n"); continue; } tmp_elem_p = param_elem_p; strcpy(&env[env_idx][my_idx], "dns_addresses="); my_idx += strlen("dns_addresses="); do { my_idx += snprintf(&env[env_idx][my_idx], elem_size-my_idx, "%s ", mpl_param_value_get_string(pscc_paramid_dns_address, tmp_elem_p->value_p)); } while (NULL != (tmp_elem_p = mpl_param_list_find_next(pscc_paramid_dns_address, tmp_elem_p))); env[env_idx][my_idx++]='\0'; break; } default: elem_size = mpl_param_pack(param_elem_p, NULL, 0); if (elem_size < 0) { PSCC_DBG_TRACE(LOG_ERR, "param_pack failed\n"); continue; } elem_size++; env[env_idx] = malloc(elem_size); if(NULL == env[env_idx]) { PSCC_DBG_TRACE(LOG_ERR, "malloc failed\n"); continue; } elem_size = mpl_param_pack_no_prefix(param_elem_p, env[env_idx], elem_size); if (elem_size < 0) { PSCC_DBG_TRACE(LOG_ERR, "param_pack failed\n"); free(env[env_idx]); env[env_idx] = NULL; continue; } break; } env_idx++; } env[env_idx] = NULL; pid = exec_script(argv, env); if (pid == -1) status = -1; else if (pid != 0) { /* Wait for the script to finish */ while (waitpid(pid, &status, 0) == -1) { if (errno != EINTR) { PSCC_DBG_TRACE(LOG_ERR, "waitpid: %s", strerror(errno)); status = -1; break; } } } /* Cleanup */ env_idx = 0; while (env[env_idx] != NULL) free(env[env_idx++]); free(env); return status; }