void endpoint<connection,config>::remove_connection(connection_ptr con) { std::stringstream s; s << "remove_connection. New count: " << m_connections.size()-1; m_alog.write(log::alevel::devel,s.str()); scoped_lock_type lock(m_mutex); // unregister the termination handler con->set_termination_handler(termination_handler()); m_connections.erase(con); }
void readSystemDefaults() { MYSQL_RES *result; MYSQL_ROW row; int state; char query[255]; MYSQL *conn; conn=mysqlConnect(); if( conn == NULL ) { my_printf("%s\n",mysql_error(conn)); return; } //READ SYSTEM DEFAULTS strcpy(query,"SELECT record_data_time,localita,nome,reboot_time,offset_effe FROM system_ini"); state = mysql_query(conn, query); if( state != 0 ) { printf("%s\n",mysql_error(conn)); my_printf("%s - %s\n",query,mysql_error(conn)); termination_handler(2); } result = mysql_store_result(conn); if( ( row = mysql_fetch_row(result)) != NULL ) { RECORDDATATIME=60*atoi(row[0]); if(row[1]) strcpy(LOCALITA,row[1]); else strcpy(LOCALITA,""); if(row[2]) strcpy(NOME,row[2]); else strcpy(NOME,""); MAXATTEMPTS=atoi(row[3])/2; OFFSET_EFFE=atoi(row[4]); } mysql_free_result(result); mysql_close(conn); //END READ SYSTEM DEFAULTS }
int main(int argc, char** argv) { if (!fork_out(argv[0])) { return 1; // Error while creating child processes } // Initialize the SDL library with the Video subsystem SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE); // start the PDL library PDL_Init(0); // Tell it to use OpenGL version 2.0 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); // Set the video mode to full screen with OpenGL-ES support Surface = SDL_SetVideoMode(320, 480, 0, SDL_OPENGL); // Event descriptor SDL_Event Event; do { while (SDL_PollEvent(&Event)) { switch (Event.type) { // List of keys that have been pressed case SDL_KEYDOWN: switch (Event.key.keysym.sym) { // Escape forces us to quit the app // This is also sent when the user makes a back gesture case SDLK_ESCAPE: Event.type = SDL_QUIT; break; default: break; } break; default: break; } } } while (Event.type != SDL_QUIT); // We exit anytime we get a request to quit the app // Cleanupp PDL_Quit(); SDL_Quit(); termination_handler(); return 0; }
// called by main_loop(), 专门与wdctl进程进行UNIX域 通讯的线程 // @arg = "/tmp/wdctl.sock", 域套接字名称 void thread_wdctl(void *arg) { int fd; char *sock_name; struct sockaddr_un sa_un; int result; pthread_t tid; socklen_t len; debug(LOG_DEBUG, "Starting wdctl."); memset(&sa_un, 0, sizeof(sa_un)); sock_name = (char *)arg; //="tmp/wdctl.sock" debug(LOG_DEBUG, "Socket name: %s", sock_name); if (strlen(sock_name) > (sizeof(sa_un.sun_path) - 1)) { /* TODO: Die handler with logging.... */ debug(LOG_ERR, "WDCTL socket name too long"); exit(1); } debug(LOG_DEBUG, "Creating socket"); wdctl_socket_server = socket(PF_UNIX, SOCK_STREAM, 0); debug(LOG_DEBUG, "Got server socket %d", wdctl_socket_server); /* If it exists, delete... Not the cleanest way to deal. */ unlink(sock_name); debug(LOG_DEBUG, "Filling sockaddr_un"); strcpy(sa_un.sun_path, sock_name); /* XXX No size check because we * check a few lines before. */ sa_un.sun_family = AF_UNIX; debug(LOG_DEBUG, "Binding socket (%s) (%d)", sa_un.sun_path, strlen(sock_name)); /* Which to use, AF_UNIX, PF_UNIX, AF_LOCAL, PF_LOCAL? */ if (bind(wdctl_socket_server, (struct sockaddr *)&sa_un, strlen(sock_name) + sizeof(sa_un.sun_family))) { // 绑定域套接字名称为 "tmp/wdctl.sock" debug(LOG_ERR, "Could not bind control socket: %s", strerror(errno)); pthread_exit(NULL); } if (listen(wdctl_socket_server, 5)) { // 监听域套接字 debug(LOG_ERR, "Could not listen on control socket: %s", strerror(errno)); pthread_exit(NULL); } while (1) { // 循环接受(accept) wdctl控制进程的连接 len = sizeof(sa_un); memset(&sa_un, 0, len); if ((fd = accept(wdctl_socket_server, (struct sockaddr *)&sa_un, &len)) == -1){ debug(LOG_ERR, "Accept failed on control socket: %s", strerror(errno)); } else { debug(LOG_DEBUG, "Accepted connection on wdctl socket %d (%s)", fd, sa_un.sun_path); // 创建一个线程来处理wdctl进程的命令 result = pthread_create(&tid, NULL, &thread_wdctl_handler, (void *)fd); if (result != 0) { debug(LOG_ERR, "FATAL: Failed to create a new thread (wdctl handler) - exiting"); termination_handler(0); } pthread_detach(tid); } } }
/**@internal * Main execution loop */ static void main_loop(void) { int result; pthread_t tid; s_config *config = config_get_config(); request *r; void **params; /* Set the time when wifidog started */ if (!started_time) { debug(LOG_INFO, "Setting started_time"); started_time = time(NULL); } else if (started_time < MINIMUM_STARTED_TIME) { debug(LOG_WARNING, "Detected possible clock skew - re-setting started_time"); started_time = time(NULL); } /* If we don't have the Gateway IP address, get it. Can't fail. */ if (!config->gw_address) { debug(LOG_DEBUG, "Finding IP address of %s", config->gw_interface); if ((config->gw_address = get_iface_ip(config->gw_interface)) == NULL) { debug(LOG_ERR, "Could not get IP address information of %s, exiting...", config->gw_interface); exit(1); } debug(LOG_DEBUG, "%s = %s", config->gw_interface, config->gw_address); } /* If we don't have the Gateway ID, construct it from the internal MAC address. * "Can't fail" so exit() if the impossible happens. */ if (!config->gw_mac) { debug(LOG_DEBUG, "Finding MAC address of %s", config->gw_interface); if ((config->gw_mac = get_iface_mac(config->gw_interface)) == NULL) { debug(LOG_ERR, "Could not get MAC address information of %s, exiting...", config->gw_interface); exit(1); } debug(LOG_DEBUG, "%s = %s", config->gw_interface, config->gw_mac); } /* Initializes the web server */ debug(LOG_NOTICE, "Creating web server on %s:%d", config->gw_address, config->gw_port); if ((webserver = httpdCreate(config->gw_address, config->gw_port)) == NULL) { debug(LOG_ERR, "Could not create web server: %s", strerror(errno)); exit(1); } debug(LOG_DEBUG, "Assigning callbacks to web server"); httpdAddCContent(webserver, "/", "ctbrihuang", 0, NULL, http_callback_wifidog); httpdAddCContent(webserver, "/ctbrihuang", "", 0, NULL, http_callback_wifidog); httpdAddCContent(webserver, "/debug", "", 0, NULL, http_callback_404); httpdAddCContent(webserver, "/ctbrihuang", "about", 0, NULL, http_callback_about); httpdAddCContent(webserver, "/ctbrihuang", "status", 0, NULL, http_callback_status); httpdAddCContent(webserver, "/smartwifi", "auth", 0, NULL, http_callback_auth); /*httpdAddCContent(webserver, "/ctbrihuang", "logout", 0, NULL, http_callback_logout); */ httpdAddC404Content(webserver, http_callback_404); fw_destroy(); if (!fw_init()) { debug(LOG_ERR, "FATAL: Failed to initialize firewall"); exit(1); } /* Start update thread */ result = pthread_create(&tid_update, NULL, (void *)thread_update, NULL); if (result != 0) { debug(LOG_ERR, "FATAL: Failed to create a new thread (update) - exiting"); termination_handler(0); } pthread_detach(tid_update); /* Start clean up thread */ result = pthread_create(&tid_fw_counter, NULL, (void *)thread_client_timeout_check, NULL); if (result != 0) { debug(LOG_ERR, "FATAL: Failed to create a new thread (fw_counter) - exiting"); termination_handler(0); } pthread_detach(tid_fw_counter); /* Start control thread */ result = pthread_create(&tid, NULL, (void *)thread_wdctl, (void *)safe_strdup(config->wdctl_sock)); if (result != 0) { debug(LOG_ERR, "FATAL: Failed to create a new thread (wdctl) - exiting"); termination_handler(0); } pthread_detach(tid); /* Start heartbeat thread */ result = pthread_create(&tid_ping, NULL, (void *)thread_ping, NULL); if (result != 0) { debug(LOG_ERR, "FATAL: Failed to create a new thread (ping) - exiting"); termination_handler(0); } pthread_detach(tid_ping); result = pthread_create(&tid_ding, NULL, (void *)thread_ding, NULL); if (result != 0) { debug(LOG_ERR, "FATAL: Failed to create a new thread (ding) - exiting"); termination_handler(0); } pthread_detach(tid_ding); result = pthread_create(&tid_authlog, NULL, (void *)thread_client_timeout_log, NULL); if (result != 0) { debug(LOG_ERR, "FATAL: Failed to create a new thread authlog - exiting"); termination_handler(0); } pthread_detach(tid_authlog); debug(LOG_NOTICE, "Waiting for connections"); while(1) { webserver->lastError = 0; r = httpdGetConnection(webserver, NULL); /* We can't convert this to a switch because there might be * values that are not -1, 0 or 1. */ if (webserver->lastError == -1) { /* Interrupted system call */ debug(LOG_DEBUG, "lastError is -1"); continue; /* restart loop */ } else if (webserver->lastError < -1) { /* * FIXME * An error occurred - should we abort? * reboot the device ? */ debug(LOG_ERR, "FATAL: httpdGetConnection returned unexpected value %d, exiting.", webserver->lastError); termination_handler(0); } else if (r != NULL) { /* * We got a connection * * We should create another thread */ debug(LOG_INFO, "Received connection from %s, spawning worker thread", r->clientAddr); /* The void**'s are a simulation of the normal C * function calling sequence. */ params = safe_malloc(2 * sizeof(void *)); *params = webserver; *(params + 1) = r; result = pthread_create(&tid, NULL, (void *)thread_httpd, (void *)params); if (result != 0) { debug(LOG_ERR, "FATAL: Failed to create a new thread (httpd) - exiting"); termination_handler(0); } pthread_detach(tid); } else { debug(LOG_DEBUG, "lastError=%d", webserver->lastError); /* webserver->lastError should be 2 */ /* XXX We failed an ACL.... No handling because * we don't set any... */ } } /* never reached */ }
/**@internal * Main execution loop */ static void main_loop(void) { int result; pthread_t tid; s_config *config = config_get_config(); struct timespec wait_time; int msec; request *r; void **params; int* thread_serial_num_p; /* Set the time when nodogsplash started */ if (!started_time) { debug(LOG_INFO, "Setting started_time"); started_time = time(NULL); } else if (started_time < MINIMUM_STARTED_TIME) { debug(LOG_WARNING, "Detected possible clock skew - re-setting started_time"); started_time = time(NULL); } /* If we don't have the Gateway IP address, get it. Exit on failure. */ if (!config->gw_address) { debug(LOG_DEBUG, "Finding IP address of %s", config->gw_interface); if ((config->gw_address = get_iface_ip(config->gw_interface)) == NULL) { debug(LOG_ERR, "Could not get IP address information of %s, exiting...", config->gw_interface); exit(1); } if ((config->gw_mac = get_iface_mac(config->gw_interface)) == NULL) { debug(LOG_ERR, "Could not get MAC address information of %s, exiting...", config->gw_interface); exit(1); } debug(LOG_NOTICE, "Detected gateway %s at %s (%s)", config->gw_interface, config->gw_address, config->gw_mac); } /* Initializes the web server */ if ((webserver = httpdCreate(config->gw_address, config->gw_port)) == NULL) { debug(LOG_ERR, "Could not create web server: %s", strerror(errno)); exit(1); } debug(LOG_NOTICE, "Created web server on %s:%d", config->gw_address, config->gw_port); /* Set web root for server */ debug(LOG_DEBUG, "Setting web root: %s",config->webroot); httpdSetFileBase(webserver,config->webroot); /* Add images files to server: any file in config->imagesdir can be served */ debug(LOG_DEBUG, "Setting images subdir: %s",config->imagesdir); httpdAddWildcardContent(webserver,config->imagesdir,NULL,config->imagesdir); /* Add pages files to server: any file in config->pagesdir can be served */ debug(LOG_DEBUG, "Setting pages subdir: %s",config->pagesdir); httpdAddWildcardContent(webserver,config->pagesdir,NULL,config->pagesdir); debug(LOG_DEBUG, "Registering callbacks to web server"); httpdAddCContent(webserver, "/", "", 0, NULL, http_nodogsplash_callback_index); httpdAddCWildcardContent(webserver, config->authdir, NULL, http_nodogsplash_callback_auth); httpdAddCWildcardContent(webserver, config->denydir, NULL, http_nodogsplash_callback_deny); httpdAddC404Content(webserver, http_nodogsplash_callback_404); /* Reset the firewall (cleans it, in case we are restarting after nodogsplash crash) */ fw_destroy(); /* Then initialize it */ debug(LOG_NOTICE, "Initializing firewall rules"); if( fw_init() != 0 ) { debug(LOG_ERR, "Error initializing firewall rules! Cleaning up"); fw_destroy(); debug(LOG_ERR, "Exiting because of error initializing firewall rules"); exit(1); } /* Start client statistics and timeout clean-up thread */ result = pthread_create(&tid_client_check, NULL, (void *)thread_client_timeout_check, NULL); if (result != 0) { debug(LOG_ERR, "FATAL: Failed to create thread_client_timeout_check - exiting"); termination_handler(0); } pthread_detach(tid_client_check); /* Start control thread */ result = pthread_create(&tid, NULL, (void *)thread_ndsctl, (void *)safe_strdup(config->ndsctl_sock)); if (result != 0) { debug(LOG_ERR, "FATAL: Failed to create thread_ndsctl - exiting"); termination_handler(0); } pthread_detach(tid); /* * Enter the httpd request handling loop */ debug(LOG_NOTICE, "Waiting for connections"); while(1) { r = httpdGetConnection(webserver, NULL); /* We can't convert this to a switch because there might be * values that are not -1, 0 or 1. */ if (webserver->lastError == -1) { /* Interrupted system call */ continue; /* continue loop from the top */ } else if (webserver->lastError < -1) { /* * FIXME * An error occurred - should we abort? * reboot the device ? */ debug(LOG_ERR, "FATAL: httpdGetConnection returned unexpected value %d, exiting.", webserver->lastError); termination_handler(0); } else if (r != NULL) { /* We got a connection */ handle_http_request(webserver, r); } else { /* webserver->lastError should be 2 */ /* XXX We failed an ACL.... No handling because * we don't set any... */ } } /* never reached */ }
/** Launches a thread that monitors the control socket for request @param arg Must contain a pointer to a string containing the Unix domain socket to open @todo This thread loops infinitely, need a watchdog to verify that it is still running? */ void* thread_ndsctl(void *arg) { int sock, fd; char *sock_name; struct sockaddr_un sa_un; int result; pthread_t tid; socklen_t len; struct ndsctl_args *child_thread_args; debug(LOG_DEBUG, "Starting ndsctl."); memset(&sa_un, 0, sizeof(sa_un)); sock_name = (char *)arg; debug(LOG_DEBUG, "Socket name: %s", sock_name); if (strlen(sock_name) > (sizeof(sa_un.sun_path) - 1)) { /* TODO: Die handler with logging.... */ debug(LOG_ERR, "NDSCTL socket name too long"); exit(1); } debug(LOG_DEBUG, "Creating socket"); sock = socket(PF_UNIX, SOCK_STREAM, 0); debug(LOG_DEBUG, "Got server socket %d", sock); /* If it exists, delete... Not the cleanest way to deal. */ unlink(sock_name); debug(LOG_DEBUG, "Filling sockaddr_un"); strcpy(sa_un.sun_path, sock_name); /* XXX No size check because we * check a few lines before. */ sa_un.sun_family = AF_UNIX; debug(LOG_DEBUG, "Binding socket (%s) (%d)", sa_un.sun_path, strlen(sock_name)); /* Which to use, AF_UNIX, PF_UNIX, AF_LOCAL, PF_LOCAL? */ if (bind(sock, (struct sockaddr *)&sa_un, strlen(sock_name) + sizeof(sa_un.sun_family))) { debug(LOG_ERR, "Could not bind control socket: %s", strerror(errno)); pthread_exit(NULL); } if (listen(sock, 5)) { debug(LOG_ERR, "Could not listen on control socket: %s", strerror(errno)); pthread_exit(NULL); } while (1) { memset(&sa_un, 0, sizeof(sa_un)); len = (socklen_t) sizeof(sa_un); /* <<< ADDED BY DPLACKO */ if ((fd = accept(sock, (struct sockaddr *)&sa_un, &len)) == -1) { debug(LOG_ERR, "Accept failed on control socket: %s", strerror(errno)); pthread_exit(NULL); } else { debug(LOG_DEBUG, "Accepted connection on ndsctl socket %d (%s)", fd, sa_un.sun_path); child_thread_args = calloc(1, sizeof(struct ndsctl_args)); child_thread_args->fd = fd; child_thread_args->ndsctl_master_id = pthread_self(); result = pthread_create(&tid, NULL, &thread_ndsctl_handler, (void *) child_thread_args); if (result != 0) { debug(LOG_ERR, "FATAL: Failed to create a new thread (ndsctl handler) - exiting"); termination_handler(0); } pthread_detach(tid); } } return NULL; }
/**@internal * Main execution loop */ static void main_loop(void) { int result; pthread_t tid; s_config *config = config_get_config(); request *r; void **params; /* Set the time when wifidog started */ if (!started_time) { debug(LOG_INFO, "Setting started_time"); started_time = time(NULL); } else if (started_time < MINIMUM_STARTED_TIME) { debug(LOG_WARNING, "Detected possible clock skew - re-setting started_time"); started_time = time(NULL); } /* save the pid file if needed */ if ((!config) && (!config->pidfile)) save_pid_file(config->pidfile); /* If we don't have the Gateway IP address, get it. Can't fail. */ if (!config->gw_address) { debug(LOG_DEBUG, "Finding IP address of %s", config->gw_interface); if ((config->gw_address = get_iface_ip(config->gw_interface)) == NULL) { debug(LOG_ERR, "Could not get IP address information of %s, exiting...", config->gw_interface); exit(1); } debug(LOG_DEBUG, "%s = %s", config->gw_interface, config->gw_address); } /* If we don't have the Gateway ID, construct it from the internal MAC address. * "Can't fail" so exit() if the impossible happens. */ if (!config->gw_id) { debug(LOG_DEBUG, "Finding MAC address of %s", config->external_interface); if ((config->gw_id = get_iface_mac(config->external_interface)) == NULL) { debug(LOG_ERR, "Could not get MAC address information of %s, exiting...", config->external_interface); exit(1); } debug(LOG_DEBUG, "%s = %s", config->gw_interface, config->gw_id); } /* Initializes the web server */ debug(LOG_NOTICE, "Creating web server on %s:%d", config->gw_address, config->gw_port); if ((webserver = httpdCreate(config->gw_address, config->gw_port)) == NULL) { debug(LOG_ERR, "Could not create web server: %s", strerror(errno)); exit(1); } register_fd_cleanup_on_fork(webserver->serverSock); debug(LOG_DEBUG, "Assigning callbacks to web server"); httpdAddCContent(webserver, "/wifidog", "about", 0, NULL, http_callback_about); httpdAddCContent(webserver, "/wifidog", "status", 0, NULL, http_callback_status); httpdAddCContent(webserver, "/wifidog", "release", 0, NULL, http_callback_release); httpdAddCContent(webserver, "/wifidog", "allow", 0, NULL, http_callback_allow_redirect); httpdSetErrorFunction(webserver, 404, http_callback_404); /* Set the auth server ip address. */ set_auth_svr_lastip(config); /* Reset the firewall (if WiFiDog crashed) */ fw_destroy(); /* Then initialize it */ if (!fw_init()) { debug(LOG_ERR, "FATAL: Failed to initialize firewall"); exit(1); } /* Start control thread */ result = pthread_create(&tid, NULL, (void *)thread_wdctl, (void *)safe_strdup(config->wdctl_sock)); if (result != 0) { debug(LOG_ERR, "FATAL: Failed to create a new thread (wdctl) - exiting"); termination_handler(0); } pthread_detach(tid); debug(LOG_NOTICE, "Waiting for connections"); while (1) { r = httpdGetConnection(webserver, NULL); /* We can't convert this to a switch because there might be * values that are not -1, 0 or 1. */ if (webserver->lastError == -1) { /* Interrupted system call */ if (NULL != r) { httpdEndRequest(r); } } else if (webserver->lastError < -1) { /* * FIXME * An error occurred - should we abort? * reboot the device ? */ debug(LOG_ERR, "FATAL: httpdGetConnection returned unexpected value %d, exiting.", webserver->lastError); termination_handler(0); } else if (r != NULL) { /* * We got a connection * * We should create another thread */ debug(LOG_INFO, "Received connection from %s, spawning worker thread", r->clientAddr); /* The void**'s are a simulation of the normal C * function calling sequence. */ params = safe_malloc(2 * sizeof(void *)); *params = webserver; *(params + 1) = r; result = pthread_create(&tid, NULL, (void *)thread_httpd, (void *)params); if (result != 0) { debug(LOG_ERR, "FATAL: Failed to create a new thread (httpd) - exiting"); termination_handler(0); } pthread_detach(tid); } else { /* webserver->lastError should be 2 */ /* XXX We failed an ACL.... No handling because * we don't set any... */ } //update the auth server ip update_auth_svr_lastip(config); } /* never reached */ }
/**@internal * Main execution loop */ static void main_loop(void) { int result = 0; pthread_t tid; s_config *config; config = config_get_config(); /* Set the time when nodogsplash started */ if (!started_time) { debug(LOG_INFO, "Setting started_time"); started_time = time(NULL); } else if (started_time < MINIMUM_STARTED_TIME) { debug(LOG_WARNING, "Detected possible clock skew - re-setting started_time"); started_time = time(NULL); } /* If we don't have the Gateway IP address, get it. Exit on failure. */ if (!config->gw_address) { debug(LOG_DEBUG, "Finding IP address of %s", config->gw_interface); if ((config->gw_address = get_iface_ip(config->gw_interface)) == NULL) { debug(LOG_ERR, "Could not get IP address information of %s, exiting...", config->gw_interface); exit(1); } } if ((config->gw_mac = get_iface_mac(config->gw_interface)) == NULL) { debug(LOG_ERR, "Could not get MAC address information of %s, exiting...", config->gw_interface); exit(1); } debug(LOG_NOTICE, "Detected gateway %s at %s (%s)", config->gw_interface, config->gw_address, config->gw_mac); /* Initializes the web server */ if ((webserver = MHD_start_daemon( MHD_USE_EPOLL_INTERNALLY, config->gw_port, NULL, NULL, libmicrohttpd_cb, NULL, MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 120, MHD_OPTION_LISTENING_ADDRESS_REUSE, 1, MHD_OPTION_END)) == NULL) { debug(LOG_ERR, "Could not create web server: %s", strerror(errno)); exit(1); } /* TODO: set listening socket */ debug(LOG_NOTICE, "Created web server on %s:%d", config->gw_address, config->gw_port); /* httpdAddCContent(webserver, "/", "", 0, NULL, http_nodogsplash_callback_index); httpdAddCWildcardContent(webserver, config->authdir, NULL, http_nodogsplash_callback_auth); httpdAddCWildcardContent(webserver, config->denydir, NULL, http_nodogsplash_callback_deny); httpdAddC404Content(webserver, http_nodogsplash_callback_404); */ /* Reset the firewall (cleans it, in case we are restarting after nodogsplash crash) */ fw_destroy(); /* Then initialize it */ debug(LOG_NOTICE, "Initializing firewall rules"); if (fw_init() != 0) { debug(LOG_ERR, "Error initializing firewall rules! Cleaning up"); fw_destroy(); debug(LOG_ERR, "Exiting because of error initializing firewall rules"); exit(1); } /* Start client statistics and timeout clean-up thread */ result = pthread_create(&tid_client_check, NULL, thread_client_timeout_check, NULL); if (result != 0) { debug(LOG_ERR, "FATAL: Failed to create thread_client_timeout_check - exiting"); termination_handler(0); } pthread_detach(tid_client_check); /* Start control thread */ result = pthread_create(&tid, NULL, thread_ndsctl, (void *)(config->ndsctl_sock)); if (result != 0) { debug(LOG_ERR, "FATAL: Failed to create thread_ndsctl - exiting"); termination_handler(1); } result = pthread_join(tid, NULL); if (result) { debug(LOG_INFO, "Failed to wait for nodogsplash thread."); } MHD_stop_daemon(webserver); termination_handler(result); }
int main(int argc, char *argv[], char **envp) { QueryHandle *res; time_t tt; GLOBAL *g; INSTANCE *instances; int fval = 0, i = 0, reload = 0; char *inst, *instance; FILE *pidf; openlog(PROGNAME, 0, LOG_INFO | LOG_CRIT | LOG_ERR); syslog(LOG_INFO, "LMS Daemon started."); // initialize global structure g = (GLOBAL *) realloc(NULL, sizeof(GLOBAL)); g->api_version = APIVERSION; g->db = (DB *) realloc(NULL, sizeof(DB)); g->db->conn = NULL; // initialize proces name change init_set_proc_title(argc, argv, envp); // configuration load sequence - check if LMSini is set configfile = ( getenv("LMSINI") ? getenv("LMSINI") : "/etc/lms/lms.ini" ); // read environment and command line driver = ( getenv("LMSDBTYPE") ? getenv("DBTYPE") : strdup("mysql") ); passwd = ( getenv("LMSDBPASS") ? getenv("LMSDBPASS") : "" ); dbname = ( getenv("LMSDBNAME") ? getenv("LMSDBNAME") : "lms" ); user = ( getenv("LMSDBUSER") ? getenv("LMSDBUSER") : "lms" ); port = ( getenv("LMSDBPORT") ? atoi(getenv("LMSDBPORT")) : 0 ); if( getenv("LMSDBHOST") ) strcpy(host, getenv("LMSDBHOST")); else strcpy(host, "localhost"); gethostname(dhost, 255); // date/time localization according to environement settings setlocale(LC_TIME, ""); // command line arguments parse_command_line(argc, argv); // load configuration file if exist (if not it will use default parameters - only database section) ini = config_load(configfile, g->db, dhost, "database"); // assign variables driver = config_getstring(ini, "database", "type", driver); passwd = config_getstring(ini, "database", "password", passwd); dbname = config_getstring(ini, "database", "database", dbname); user = config_getstring(ini, "database", "user", user); port = config_getint(ini, "database", "port", port); strcpy(host, config_getstring(ini, "database", "host", host)); // change process name (hide command line args) set_proc_title(PROGNAME); str_replace(&driver, "postgres", "pgsql"); // postgres in ini file is pgsql str_replace(&driver, "mysqli", "mysql"); // mysqli in ini file is mysql char dbdrv_path[strlen(LMS_LIB_DIR) + strlen(driver) + 4]; sprintf(dbdrv_path, LMS_LIB_DIR "/%s.so", driver); if( !file_exists(dbdrv_path)) { syslog(LOG_CRIT, "Database driver '%s' does not exist. Could not find '%s'.", driver, dbdrv_path); fprintf(stderr, "Database driver '%s' does not exist. Could not find '%s'.\n", driver, dbdrv_path); exit(1); } void *dbdrv; dbdrv = dlopen(dbdrv_path, RTLD_NOW); if( !dbdrv ) { char * errMsg = dlerror(); syslog(LOG_CRIT, "Unable to load database driver '%s': %s", dbdrv_path, errMsg); fprintf(stderr, "Unable to load database driver '%s': %s.\n", dbdrv_path, errMsg); exit(1); } else { syslog(LOG_INFO, "Database driver '%s' loaded.", driver); } g->db->connect = dlsym(dbdrv, "db_connect"); g->db->disconnect = dlsym(dbdrv, "db_disconnect"); g->db->query = dlsym(dbdrv, "db_query"); g->db->pquery = dlsym(dbdrv, "db_pquery"); g->db->exec = dlsym(dbdrv, "db_exec"); g->db->pexec = dlsym(dbdrv, "db_pexec"); g->db->last_insert_id = dlsym(dbdrv, "db_last_insert_id"); g->db->free = dlsym(dbdrv, "db_free"); g->db->begin = dlsym(dbdrv, "db_begin"); g->db->commit = dlsym(dbdrv, "db_commit"); g->db->abort = dlsym(dbdrv, "db_abort"); g->db->get_data = dlsym(dbdrv, "db_get_data"); g->db->nrows = dlsym(dbdrv, "db_nrows"); g->db->ncols = dlsym(dbdrv, "db_ncols"); g->db->concat = dlsym(dbdrv, "db_concat"); g->db->escape = dlsym(dbdrv, "db_escape"); g->db->colname = dlsym(dbdrv, "db_colname"); // test database connection if( !(g->db->conn = g->db->connect(dbname,user,passwd,host,port,ssl)) ) { fprintf(stderr, "CRITICAL: Could not connect to database. See logs for details.\n"); termination_handler(1); } res = g->db->pquery(g->db->conn, "SELECT count(*) FROM dbinfo"); if( ! g->db->nrows(res) ) { fprintf(stderr, "CRITICAL: Could not query database. See logs for details.\n"); termination_handler(1); } g->db->free(&res); g->db->disconnect(g->db->conn); g->str_replace = &str_replace; g->str_save = &str_save; g->str_concat = &str_concat; g->str_lwc = &str_lwc; g->str_upc = &str_upc; g->va_list_join = &va_list_join; g->config_getstring = &config_getstring; g->config_getint = &config_getint; g->config_getbool = &config_getbool; g->config_getdouble = &config_getdouble; // catch SIGCHLD to catch zombies sa.sa_handler = sig_child; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sigaction(SIGCHLD, &sa, &orig); // daemonize if ( !quit && !dontfork ) { fval = fork(); switch(fval) { case -1: fprintf(stderr, "Fork error. Exiting."); termination_handler(1); case 0: setsid(); break; default: #ifdef DEBUG1 syslog(LOG_INFO, "DEBUG: [lmsd] Daemonize. Forked child %d.", fval); #endif if (pidfile != NULL && (pidf = fopen(pidfile, "w")) != NULL) { fprintf(pidf, "%d", fval); fclose(pidf); } exit(0); // parent exits } } // termination signals handling signal(SIGINT, termination_handler); signal(SIGTERM, termination_handler); // main loop **************************************************** for(;;) { int i_no = 0; if( quit ) { reload = 1; tt = time(0); } else // daemon mode { reload = 0; tt = cron_sync_sleep(); } // run shell command, i.e. secure connections tuneling if( command!=NULL ) { #ifdef DEBUG1 syslog(LOG_INFO, "DEBUG: [lmsd] Executing command: %s.", command); #endif system(command); } // try to connect to database if( !(g->db->conn = g->db->connect(dbname,user,passwd,host,port,ssl)) ) { if( quit ) termination_handler(1); continue; } if( !reload ) { // check reload order res = g->db->pquery(g->db->conn, "SELECT reload FROM hosts WHERE name = '?' AND reload != 0", dhost); if( g->db->nrows(res) ) { reload = 1; } g->db->free(&res); } instances = (INSTANCE *) malloc(sizeof(INSTANCE)); // get instances list even if reload == 0 // maybe we should do that once before main loop, but in // this way we can change configuration without daemon restart if( iopt ) // from command line... { inst = strdup(iopt); for( instance=strtok(inst," "); instance!=NULL; instance=strtok(NULL, " ") ) { char *name = strdup(instance); str_replace(&name, "\\s", " "); // instance name with spaces res = g->db->pquery(g->db->conn, "SELECT module, crontab FROM daemoninstances, hosts WHERE hosts.id = hostid AND disabled = 0 AND hosts.name = '?' AND daemoninstances.name = '?'", dhost, name); if( g->db->nrows(res) ) { char *crontab = g->db->get_data(res, 0, "crontab"); if( runall || (reload && !strlen(crontab)) || (!quit && crontab_match(tt, crontab)) ) { instances = (INSTANCE *) realloc(instances, sizeof(INSTANCE)*(i_no+1)); instances[i_no].name = strdup(name); instances[i_no].module = strdup(g->db->get_data(res, 0, "module")); instances[i_no].crontab = strdup(crontab); i_no++; } } else { syslog(LOG_CRIT, "Host '%s' and/or instance '%s' not found in database!", dhost, name); fprintf(stderr, "Host '%s' and/or instance '%s' not found in database!\n", dhost, name); } g->db->free(&res); free(name); } free(inst); } else // ... or from database { res = g->db->pquery(g->db->conn, "SELECT module, crontab, daemoninstances.name AS name FROM daemoninstances, hosts WHERE hosts.id = hostid AND disabled = 0 AND hosts.name = '?' ORDER BY priority", dhost); for(i=0; i<g->db->nrows(res); i++) { char *crontab = g->db->get_data(res, i, "crontab"); if( runall || (reload && !strlen(crontab)) || (!quit && crontab_match(tt, crontab)) ) { instances = (INSTANCE *) realloc(instances, sizeof(INSTANCE)*(i_no+1)); instances[i_no].name = strdup(g->db->get_data(res, i, "name")); instances[i_no].module = strdup(g->db->get_data(res, i, "module")); instances[i_no].crontab = strdup(crontab); i_no++; } } g->db->free(&res); } g->db->disconnect(g->db->conn); if( i_no ) { // forking reload - we can do a job for longer than one minute if( quit ) fval = 0; // don't fork in "quit mode" else fval = fork(); if( fval < 0 ) { syslog(LOG_CRIT, "Fork error. Can't reload."); if ( quit ) termination_handler(1); } else if( fval == 0 ) // child or "quit mode" { set_proc_title(PROGNAME": reload"); // restore old handler so we can wait for childs executed by modules if( !quit ) sigaction(SIGCHLD, &orig, NULL); #ifdef DEBUG1 syslog(LOG_INFO, "DEBUG: [lmsd] Reloading..."); #endif // try to connect to database again if( !(g->db->conn = g->db->connect(dbname,user,passwd,host,port,ssl)) ) { if( quit ) termination_handler(1); else exit(1); } // write reload timestamp and disable reload order if( reload ) g->db->pexec(g->db->conn, "UPDATE hosts SET lastreload = %NOW%, reload = 0 WHERE name = '?'", dhost); for(i=0; i<i_no; i++) { MODULE *m; MODULE *mod = (MODULE*) malloc(sizeof(MODULE)); MODULE * (*init)(GLOBAL *, MODULE *); char path[strlen(LMS_LIB_DIR) + strlen(instances[i].module) + 4]; // get instance configuration and members mod->ini = config_load(configfile, g->db, dhost, instances[i].name); mod->instance = strdup(instances[i].name); // set path to module if not specified // be sure that it has .so extension str_replace(&instances[i].module, ".so", ""); if( instances[i].module[0] == '/' ) sprintf(path, "%s.so", instances[i].module); else sprintf(path, LMS_LIB_DIR "/%s.so", instances[i].module); mod->file = strdup(path); // try to load module mod->dlh = dlopen(mod->file, RTLD_NOW); if( !mod->dlh ) { syslog(LOG_ERR, "Unable to load module '%s': %s", mod->file, dlerror()); free_module(mod); continue; } // initialize module init = dlsym(mod->dlh, "init"); if( !init ) { syslog(LOG_CRIT, "Unable to find initialization function in module '%s'. Is that file really a lmsd module?", mod->file); free_module(mod); continue; } if( !(m = init(g, mod))) { syslog(LOG_CRIT, "Unable to initialize module '%s'. Perhaps there is a version mismatch?", mod->file); free_module(mod); continue; } syslog(LOG_INFO, "Running module: %s", instances[i].module); // now run module m->reload(g, m); // cleanup free_module(m); } g->db->disconnect(g->db->conn); // exit child (reload) thread if( !quit ) { #ifdef DEBUG1 syslog(LOG_INFO, "DEBUG: [lmsd] Reload finished. Exiting child."); #endif exit(0); } } else sleep(10); // it's important to sleep parent for some time for(i=0; i<i_no; i++) { free(instances[i].name); free(instances[i].module); free(instances[i].crontab); } } if( quit ) termination_handler(0); free(instances); } // end of loop ********************************************** return 0; }
/**@internal * Main execution loop */ static void main_loop(void) { int result; pthread_t tid; s_config *config = config_get_config(); struct timespec wait_time; int msec; request *r; void **params; FILE *fh; int* thread_serial_num_p; /* Set the time when nodogsplash started */ if (!started_time) { debug(LOG_INFO, "Setting started_time"); started_time = time(NULL); } else if (started_time < MINIMUM_STARTED_TIME) { debug(LOG_WARNING, "Detected possible clock skew - re-setting started_time"); started_time = time(NULL); } /* If we don't have the Gateway IP address, get it. Exit on failure. */ if (!config->gw_address) { debug(LOG_DEBUG, "Finding IP address of %s", config->gw_interface); if ((config->gw_address = get_iface_ip(config->gw_interface)) == NULL) { debug(LOG_ERR, "Could not get IP address information of %s, exiting...", config->gw_interface); exit(1); } debug(LOG_NOTICE, "Detected gateway %s at %s", config->gw_interface, config->gw_address); } /* Initializes the web server */ if ((webserver = httpdCreate(config->gw_address, config->gw_port)) == NULL) { debug(LOG_ERR, "Could not create web server: %s", strerror(errno)); exit(1); } debug(LOG_NOTICE, "Created web server on %s:%d", config->gw_address, config->gw_port); /* Set web root for server */ debug(LOG_DEBUG, "Setting web root: %s",config->webroot); httpdSetFileBase(webserver,config->webroot); /* Add images files to server: any file in config->imagesdir can be served */ debug(LOG_DEBUG, "Setting images subdir: %s",config->imagesdir); httpdAddWildcardContent(webserver,config->imagesdir,NULL,config->imagesdir); /* Add pages files to server: any file in config->pagesdir can be served */ debug(LOG_DEBUG, "Setting pages subdir: %s",config->pagesdir); httpdAddWildcardContent(webserver,config->pagesdir,NULL,config->pagesdir); debug(LOG_DEBUG, "Registering callbacks to web server"); httpdAddCContent(webserver, "/", "", 0, NULL, http_nodogsplash_callback_index); httpdAddCWildcardContent(webserver, config->authdir, NULL, http_nodogsplash_callback_auth); httpdAddCWildcardContent(webserver, config->denydir, NULL, http_nodogsplash_callback_deny); httpdAddC404Content(webserver, http_nodogsplash_callback_404); /* Reset the firewall (cleans it, in case we are restarting after nodogsplash crash) */ fw_destroy(); /* Then initialize it */ debug(LOG_NOTICE, "Initializing firewall rules"); if( fw_init() != 0 ) { debug(LOG_ERR, "Error initializing firewall rules! Cleaning up"); fw_destroy(); debug(LOG_ERR, "Exiting because of error initializing firewall rules"); exit(1); } /* Start client statistics and timeout clean-up thread */ result = pthread_create(&tid_client_check, NULL, (void *)thread_client_timeout_check, NULL); if (result != 0) { debug(LOG_ERR, "FATAL: Failed to create thread_client_timeout_check - exiting"); termination_handler(0); } pthread_detach(tid_client_check); /* Start control thread */ result = pthread_create(&tid, NULL, (void *)thread_ndsctl, (void *)safe_strdup(config->ndsctl_sock)); if (result != 0) { debug(LOG_ERR, "FATAL: Failed to create thread_ndsctl - exiting"); termination_handler(0); } pthread_detach(tid); /* * Enter the httpd request handling loop */ debug(LOG_NOTICE, "Waiting for connections"); created_httpd_threads = 0; current_httpd_threads = 0; while(1) { r = httpdGetConnection(webserver, NULL); /* We can't convert this to a switch because there might be * values that are not -1, 0 or 1. */ if (webserver->lastError == -1) { /* Interrupted system call */ continue; /* continue loop from the top */ } else if (webserver->lastError < -1) { /* * FIXME * An error occurred - should we abort? * reboot the device ? */ debug(LOG_ERR, "FATAL: httpdGetConnection returned unexpected value %d, exiting.", webserver->lastError); termination_handler(0); } else if (r != NULL) { /* * We got a connection * * We create another thread to handle the request, * possibly sleeping first if there are too many already */ debug(LOG_DEBUG,"%d current httpd threads.", current_httpd_threads); if(config->decongest_httpd_threads && current_httpd_threads >= config->httpd_thread_threshold) { msec = current_httpd_threads * config->httpd_thread_delay_ms; wait_time.tv_sec = msec / 1000; wait_time.tv_nsec = (msec % 1000) * 1000000; debug(LOG_INFO, "Httpd thread creation delayed %ld sec %ld nanosec for congestion.", wait_time.tv_sec, wait_time.tv_nsec); nanosleep(&wait_time,NULL); } thread_serial_num_p = (int*) malloc(sizeof(int)); /* thread_httpd() must free */ *thread_serial_num_p = created_httpd_threads; debug(LOG_INFO, "Creating httpd request thread %d for %s", *thread_serial_num_p, r->clientAddr); /* The void**'s are a simulation of the normal C * function calling sequence. */ params = safe_malloc(3 * sizeof(void *)); /* thread_httpd() must free */ *params = webserver; *(params + 1) = r; *(params + 2) = thread_serial_num_p; created_httpd_threads++; result = pthread_create(&tid, NULL, (void *)thread_httpd, (void *)params); if (result != 0) { debug(LOG_ERR, "FATAL: pthread_create failed to create httpd request thread - exiting..."); termination_handler(0); } pthread_detach(tid); } else { /* webserver->lastError should be 2 */ /* XXX We failed an ACL.... No handling because * we don't set any... */ } } /* never reached */ }
void loadAllSystems() { int i=0,j=0,k,l; struct timeval tim; double t1; int knx_ch_in; int knx_ch_out; MYSQL *conn; panels=NULL; NUMPANELS=0; NUMSMSDEVICES=0; NUMSMSNUMBERS=0; NUMKNXCHANNELS=0; ANALOGCHANNELS=0; DIGITALCHANNELS=0; DIGITALOUTCHANNELS=0; READINGCHANNELS=0; SCENARIPRESENZECOUNT=0; SCENARIBGBNCOUNT=0; IRRIGAZIONECIRCUITS=0; IRRIGAZIONESYSTEMS=0; MAXATTEMPTS=5; OFFSET_EFFE=0; LOCALITA[30]; RECORDDATATIME=300; RNDSEED=0; NUMBACNETDEVICES=0; NUMBACNETLINES=0; NUMCEIABIGATEWAYS=0; gettimeofday(&tim, NULL); t1=tim.tv_sec+(tim.tv_usec/1000000.0); //MYSQL STUFF conn=mysqlConnect(); if( conn == NULL ) { my_printf("error connecting: %s\n",mysql_error(conn)); termination_handler(2); } //READ SYSTEM DEFAULTS (needs mysql); my_printf("reading system defaults\n"); readSystemDefaults(); //READ EFFEMERIDI (needs mysql); my_printf("reading effemeridi\n"); readEffemeridi(); mysql_close(conn); if(loadSMS(0)) termination_handler(2); if(loadSystemTable(0)) termination_handler(2); if(loadMultimeterTable(0)) termination_handler(2); if(loadKnx(0)) termination_handler(2); if(loadBacnet(0)) termination_handler(2); if(loadCEIABI(0)) termination_handler(2); /* for(i=0;i<NUMMULTIMETERS;i++) { my_printf("%d %s\n",multimeters[i].multimeter_num,multimeters[i].address); for(j=0;j<multimeters[i].in_bytes_1_length;j++) my_printf("%x ",multimeters[i].in_bytes_1[j]); my_printf("\n"); for(j=0;j<multimeters[i].in_bytes_2_length;j++) my_printf("%x ",multimeters[i].in_bytes_2[j]); my_printf("\n"); } */ TOTALSYSTEMS=NUMSYSTEMS+NUMMULTIMETERS+ NUMKNXGATEWAYS+NUMBACNETDEVICES+NUMCEIABIGATEWAYS; pid=(int *)malloc((TOTALSYSTEMS) * sizeof(int)); deviceToid=(int ***)malloc(6*sizeof(int **)); deviceToid[ANALOG]=(int **)malloc(NUMSYSTEMS * sizeof(int *)); //analog deviceToid[DIGITAL]=(int **)malloc(NUMSYSTEMS * sizeof(int *)); //digital deviceToid[DIGITAL_OUT]=(int **)malloc(NUMSYSTEMS * sizeof(int *)); //digital_out deviceToid[MULTIMETER]=(int **)malloc(NUMMULTIMETERS * sizeof(int *)); //mm deviceToid[KNX_IN]=(int **)malloc(NUMKNXGATEWAYS * sizeof(int *)); //knx_in deviceToid[KNX_OUT]=(int **)malloc(NUMKNXGATEWAYS * sizeof(int *)); //knx_out deviceToid[BACNET]=(int **)malloc(NUMBACNETDEVICES * sizeof(int *)); //bacnet deviceToid[CEIABI]=(int **)malloc(NUMCEIABIGATEWAYS * sizeof(int *)); //ceiabi for(i=0;i<NUMSYSTEMS;i++) { deviceToid[ANALOG][i]=(int *)malloc(systems[i].in_ch_an*sizeof(int)); for(k=0;k<systems[i].in_ch_an;k++) deviceToid[ANALOG][i][k]=-1; deviceToid[DIGITAL][i]=(int *)malloc(systems[i].in_ch_d*sizeof(int)); for(k=0;k<systems[i].in_ch_d;k++) deviceToid[DIGITAL][i][k]=-1; deviceToid[DIGITAL_OUT][i]=(int *)malloc(systems[i].out_ch_d*sizeof(int)); for(k=0;k<systems[i].out_ch_d;k++) deviceToid[DIGITAL_OUT][i][k]=-1; } for(i=0;i<NUMMULTIMETERS;i++) { deviceToid[MULTIMETER][i]=(int *)malloc((multimeters[i].out_ch_1+multimeters[i].out_ch_2)*sizeof(int)); for(k=0;k<multimeters[i].out_ch_1+multimeters[i].out_ch_2;k++) deviceToid[MULTIMETER][i][k]=-1; } for(i=0;i<NUMKNXGATEWAYS;i++) { deviceToid[KNX_IN][i]=(int *)malloc((knxGateways[i].ch_in)*sizeof(int)); for(k=0;k<knxGateways[i].ch_in;k++) deviceToid[KNX_IN][i][k]=-1; deviceToid[KNX_OUT][i]=(int *)malloc((knxGateways[i].ch_out)*sizeof(int)); for(k=0;k<knxGateways[i].ch_out;k++) deviceToid[KNX_OUT][i][k]=-1; } knx_ch_in=0; knx_ch_out=0; for(k=0;k<NUMKNXCHANNELS;k++) { l=id_knx_gatewayToId(knxTable[k].id_knx_gateway); if(l!=-1) { if(knxTable[k].input_output==1) { deviceToid[KNX_IN][l][knx_ch_in]=k; knx_ch_in++; } else { deviceToid[KNX_OUT][l][knx_ch_out]=k; knx_ch_out++; } } } for(i=0;i<NUMBACNETDEVICES;i++) { deviceToid[BACNET][i]=(int *)malloc(bacnetDevices[i].in_ch*sizeof(int)); for(k=0;k<bacnetDevices[i].in_ch;k++) deviceToid[BACNET][i][k]=-1; } for(i=0;i<NUMCEIABIGATEWAYS;i++) { deviceToid[CEIABI][i]=(int *)malloc(CEIABIGateways[i].in_ch*sizeof(int)); for(k=0;k<CEIABIGateways[i].in_ch;k++) deviceToid[CEIABI][i][k]=-1; } /* my_printf("ANALOGCHANNELS - DIGITALCHANNELS - DIGITALOUTCHANNELS - READINGCHANNELS\n"); my_printf("%d - %d - %d - %d\n",ANALOGCHANNELS,DIGITALCHANNELS,DIGITALOUTCHANNELS,READINGCHANNELS); */ if(loadDigitalOutTable(0)) termination_handler(2); if(loadScenariPresenzeTable(0)) termination_handler(2); if(loadScenariBgBnTable(0)) termination_handler(2); if(loadDigitalTable(0)) termination_handler(2); if(loadAnalogTable(0)) termination_handler(2); if(loadReadingTable(0)) termination_handler(2); if(loadIrrigazioneTables(0,0)) termination_handler(2); if(loadIntrusione()) termination_handler(2); /* my_printf("--- PANELS ---\n"); loadPanels(); for(i=0;i<NUMPANELS;i++) for(j=0;j<16;j++) my_printf("%d %d %d\n",i,j,panels[i][j]); my_printf("--- ANALOG ---\n"); for(i=0;i<NUMSYSTEMS;i++) for(j=0;j<systems[i].in_ch_an;j++) if(analogTable[deviceToid[0][i][j]].id_analog!=-1) my_printf("%d %d %d %s %d\n",analogTable[deviceToid[0][i][j]].id_analog, analogTable[deviceToid[0][i][j]].device_num, analogTable[deviceToid[0][i][j]].ch_num, analogTable[deviceToid[0][i][j]].description, analogTable[deviceToid[0][i][j]].enabled); my_printf("--- DIGITAL ---\n"); for(i=0;i<NUMSYSTEMS;i++) for(j=0;j<systems[i].in_ch_d;j++) if(digitalTable[deviceToid[1][i][j]].id_digital!=-1) my_printf("%d %d %s %d\n",digitalTable[deviceToid[1][i][j]].device_num, digitalTable[deviceToid[1][i][j]].ch_num, digitalTable[deviceToid[1][i][j]].description, digitalTable[deviceToid[1][i][j]].enabled); my_printf("--- DIGITALOUT ---\n"); for(i=0;i<NUMSYSTEMS;i++) for(j=0;j<systems[i].out_ch_d;j++) if(digitalOutTable[deviceToid[2][i][j]].id_digital_out!=-1) my_printf("%d %d %d %s %d %d - %d %d\n", digitalOutTable[deviceToid[2][i][j]].id_digital_out, digitalOutTable[deviceToid[2][i][j]].device_num, digitalOutTable[deviceToid[2][i][j]].ch_num, digitalOutTable[deviceToid[2][i][j]].description, digitalOutTable[deviceToid[2][i][j]].def, digitalOutTable[deviceToid[2][i][j]].value, digitalOutTable[deviceToid[2][i][j]].po_delay, digitalOutTable[deviceToid[2][i][j]].on_time); my_printf("--- MM ---\n"); for(i=0;i<NUMMULTIMETERS;i++) for(j=0;j<multimeters[i].out_ch_1+multimeters[i].out_ch_2;j++) if(readingTable[deviceToid[3][i][j]].id_reading!=-1) my_printf("%d %d %d %s %d\n",readingTable[deviceToid[3][i][j]].id_reading, readingTable[deviceToid[3][i][j]].multimeter_num, readingTable[deviceToid[3][i][j]].ch_num, readingTable[deviceToid[3][i][j]].description, readingTable[deviceToid[3][i][j]].enabled); my_printf("--- KNX IN ---\n"); for(i=0;i<NUMKNXGATEWAYS;i++) for(j=0;j<knxGateways[i].ch_in;j++) if(knxTable[deviceToid[4][i][j]].id_knx_line!=-1) my_printf("%d %d %s %c %s %d\n",knxTable[deviceToid[4][i][j]].id_knx_line, knxTable[deviceToid[4][i][j]].id_knx_gateway, knxTable[deviceToid[4][i][j]].group_address, knxTable[deviceToid[4][i][j]].data_type, knxTable[deviceToid[4][i][j]].description, knxTable[deviceToid[4][i][j]].enabled); my_printf("--- KNX ALL ---\n"); for(i=0;i<NUMKNXGATEWAYS;i++) for(j=0;j<knxGateways[i].ch_in+knxGateways[i].ch_out;j++) my_printf("%d %d %s %c %s %d\n",knxTable[j].id_knx_line, knxTable[j].id_knx_gateway, knxTable[j].group_address, knxTable[j].data_type, knxTable[j].description, knxTable[j].enabled); my_printf("--- KNX OUT ---\n"); for(i=0;i<NUMKNXGATEWAYS;i++) for(j=0;j<knxGateways[i].ch_out;j++) if(knxTable[deviceToid[5][i][j]].id_knx_line!=-1) my_printf("%d %d %s %c %s\n",knxTable[deviceToid[5][i][j]].id_knx_line, knxTable[deviceToid[5][i][j]].id_knx_gateway, knxTable[deviceToid[5][i][j]].group_address, knxTable[deviceToid[5][i][j]].data_type, knxTable[deviceToid[5][i][j]].description); my_printf("--- SCENARIPRESENZE ---\n"); for(i=0;i<SCENARIPRESENZECOUNT;i++) my_printf("%d %d %d %d %d %d %d\n",scenariPresenzeTable[i].id_digital_out, scenariPresenzeTable[i].attivo, scenariPresenzeTable[i].ciclico, scenariPresenzeTable[i].tempo_on, scenariPresenzeTable[i].tempo_off, scenariPresenzeTable[i].ora_ini, scenariPresenzeTable[i].ora_fine); my_printf("--- SCENARIBGBN ---\n"); for(i=0;i<SCENARIBGBNCOUNT;i++) my_printf("%d %d %d %d\n",scenariBgBnTable[i].id_digital_out, scenariBgBnTable[i].attivo, scenariBgBnTable[i].ritardo, scenariBgBnTable[i].bg); my_printf("--- IRRIGAZIONE ---\n"); for(i=0;i<IRRIGAZIONESYSTEMS;i++) my_printf("%d %d %d %d %d %d %d\n", irrigazioneTable[i].id_irrigazione, irrigazioneTable[i].ora_start, irrigazioneTable[i].ripetitivita, irrigazioneTable[i].tempo_off, irrigazioneTable[i].id_digital_out, irrigazioneTable[i].num_circuiti, IRRIGAZIONECIRCUITS); for(i=0;i<IRRIGAZIONECIRCUITS;i++) { if(irrigazioneCircuitiTable[i].id_irrigazione!=-1) my_printf("%d %d %d %d %d\n", irrigazioneCircuitiTable[i].id_irrigazione, irrigazioneCircuitiTable[i].circuito, irrigazioneCircuitiTable[i].id_digital_out, irrigazioneCircuitiTable[i].durata, irrigazioneCircuitiTable[i].validita); } my_printf("--- SMS ---\n"); for(i=0;i<NUMSMSDEVICES;i++) my_printf("%d %s %d %s\n", sms_devices[i].id_sms_device, sms_devices[i].address, sms_devices[i].port, sms_devices[i].description); for(i=0;i<NUMSMSNUMBERS;i++) my_printf("%d %s %s\n", sms_numbers[i].id_sms_number, sms_numbers[i].name, sms_numbers[i].number); my_printf("--- BACNET ---\n"); for(i=0;i<NUMBACNETDEVICES;i++) my_printf("%d %s %d %s %d %d %d %d\n", bacnetDevices[i].id, bacnetDevices[i].address, bacnetDevices[i].port, bacnetDevices[i].description, bacnetDevices[i].enabled, bacnetDevices[i].status, bacnetDevices[i].sockfd, bacnetDevices[i].failures); my_printf("--- BACNET_INPUT ---\n"); for(i=0;i<NUMBACNETLINES;i++) my_printf("%d %d %d %d %s %s %s %d %s %d\n", bacnetTable[i].id, bacnetTable[i].id_bacnet_device, bacnetTable[i].object_type, bacnetTable[i].object_instance, bacnetTable[i].description, bacnetTable[i].hi_low_msg, bacnetTable[i].low_hi_msg, bacnetTable[i].is_alarm, bacnetTable[i].alarm_msg, bacnetTable[i].value); */ my_printf("pid: %d\n",getpid()); gettimeofday(&tim, NULL); my_printf("%.6f seconds to initialise\n",(tim.tv_sec+(tim.tv_usec/1000000.0))-t1); //FINE MYSQL STUFF }
void die(char *text) { my_perror(text); termination_handler(2); }
int main(int argc, char *argv[]) { struct sigaction sa; time_t db_counter; time_t db_counter_now; struct msgform msg; char message[160]; bool notAllProcessesOn=0; int k; argv0size = strlen(argv[0]); if (signal (SIGUSR1, kill_handler) == SIG_IGN) signal (SIGUSR1, SIG_IGN); if (signal (SIGINT, termination_handler) == SIG_IGN) signal (SIGINT, SIG_IGN); if (signal (SIGSEGV, termination_handler) == SIG_IGN) signal (SIGSEGV, SIG_IGN); if (signal (SIGHUP, termination_handler) == SIG_IGN) signal (SIGHUP, SIG_IGN); if (signal (SIGTERM, termination_handler) == SIG_IGN) signal (SIGTERM, SIG_IGN); sa.sa_handler = sigchld_handler; // reap all dead processes sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; if (sigaction(SIGCHLD, &sa, NULL) == -1) { my_perror("sigaction"); termination_handler(2); } msg_alarm_id=msgget(MSGKEY,0777|IPC_CREAT); /* ottiene un descrittore per la chiave KEY; coda nuova */ msg.mtype=1; //not sms mypid=getpid(); /* if(getenv("HOME")!=NULL) sprintf(logPath,"%s/log/",getenv("HOME")); else strcpy(logPath,"./log/");*/ my_printf("get_shared_memory_segment: reloadCommand\n"); reloadCommand=(bool *)get_shared_memory_segment(1, &SHMRELOADCOMMAND, "/dev/zero"); if(!reloadCommand) die("reloadCommand - get_shared_memory_segment\n"); // *reloadCommand=0; //così all'inizio parte server while(1) { loadAllSystems(); startAllSystems(argv); notAllProcessesOn=0; *reloadCommand=0; db_counter=time(NULL); do { // fa qualcosa qui *buonGiornoAttivo=checkBuonGiornoAttivo(); *buonaNotteAttivo=checkBuonaNotteAttivo(); // ora attendo solo la morte dei figli usleep(1000); //salvo valori storici ad intervalli regolari /* db_counter_now=time(NULL); if((db_counter_now - db_counter >= RECORDDATATIME) && ((db_counter_now % RECORDDATATIME) <50)) { storeTables(); db_counter=time(NULL); } */ if(checkSystems(pid)!=TOTALSYSTEMS) { my_printf("Respawning dead process\n"); for(k=0;k<TOTALSYSTEMS;k++) if(pid[k]==-1) forkSystem(k,argv); /* if(notAllProcessesOn==0) { my_printf("Not all children are alive\nYou had better restart\n"); notAllProcessesOn=1; }*/ } } while(*reloadCommand==0); my_printf("reload required\n"); killAllSystems(); freeshm(); } // }
void forkSystem(int k,char **argv) { int l; pid[k]=-1; char processName[255]; switch(pid[k]=fork()) // fork for every system or multimeter or knx or bacnet { case -1: my_perror("fork!"); termination_handler(2); break; case 0: pid[k]=getpid(); if(k<NUMSYSTEMS) // tabella system { sprintf(processName,"sys_%d",k); strncpy(argv[0],processName,argv0size); doSystem(k); } else { if(k<NUMSYSTEMS+NUMMULTIMETERS)//multimetro { l=k-NUMSYSTEMS; sprintf(processName,"mm_%d",l); strncpy(argv[0],processName,argv0size); doMultimeter(l); } else { if(k<NUMSYSTEMS+NUMMULTIMETERS+NUMKNXGATEWAYS)//knx { l=k-NUMSYSTEMS-NUMMULTIMETERS; sprintf(processName,"knx_%d",l); strncpy(argv[0],processName,argv0size); doKNX(l); } else { if(k<NUMSYSTEMS+NUMMULTIMETERS+NUMKNXGATEWAYS+NUMBACNETDEVICES)//bacnet { l=k-NUMSYSTEMS-NUMMULTIMETERS-NUMKNXGATEWAYS; sprintf(processName,"bac_%d",l); strncpy(argv[0],processName,argv0size); doBacnet(l); } else//ceiabi { l=k-NUMSYSTEMS-NUMMULTIMETERS-NUMKNXGATEWAYS-NUMBACNETDEVICES; sprintf(processName,"cei_%d",l); strncpy(argv[0],processName,argv0size); doCEIABI(l); } } } } exit(0); break; default: // my_printf("padre :%d\n",getpid()); if(k<NUMSYSTEMS) // tabella system my_printf("system pid %d\n",pid[k]); else { if(k<NUMSYSTEMS+NUMMULTIMETERS)//multimetro my_printf("multimeter pid %d\n",pid[k]); else { if(k<NUMSYSTEMS+NUMMULTIMETERS+NUMKNXGATEWAYS)//knx my_printf("knx pid %d\n",pid[k]); else { if(k<NUMSYSTEMS+NUMMULTIMETERS+NUMKNXGATEWAYS+NUMBACNETDEVICES)//bacnet my_printf("bacnet pid %d\n",pid[k]); else//ceiabi my_printf("ceiabi pid %d\n",pid[k]); } } } break; } }