char * __mod_ssl_sni_common_handler (MyQttCtx * myqtt_ctx, MyQttConn * conn, const char * serverName, axlPointer user_data, const char * attr_name) { MyQttdCtx * ctx = user_data; axlNode * node; /* find certificate node by Name */ node = __mod_ssl_get_certificate_node_by_name (ctx, serverName); if (! node) { wrn ("No certificate was found for serverName=%s, requested by connecting ip=%s", serverName, myqtt_conn_get_host_ip (conn)); return NULL; /* no node certificate was found, finish * here */ } /* end if */ if (! HAS_ATTR (node, attr_name)) { wrn ("No certificate was found for serverName=%s, requested by connecting ip=%s, node %s attribute was not defined", serverName, myqtt_conn_get_host_ip (conn), attr_name); return NULL; /* no crt attr was found, finish here */ } /* end if */ /* ok, now report certificate location */ if (__mod_ssl_debug) msg ("Reporting certificate %s=%s for serverName=%s", attr_name, ATTR_VALUE (node, attr_name), serverName); /* report certificate */ return axl_strdup (ATTR_VALUE (node, attr_name)); }
void CClientInfo::Config(const string& fileName) { ifstream inFile(fileName.c_str(), ifstream::in); string inXml, inLine; while (getline(inFile, inLine)) inXml += inLine; XmlVec confData(inXml.begin(), inXml.end()); confData.push_back('\0'); XmlDoc xmlDoc; try { xmlDoc.parse<0>(&confData[0]); } catch (...) { LOG("ERROR: failed to load the server config file."); return; } XmlNodePtr pNode = NULL; if ((pNode = xmlDoc.first_node("server_list"))) { XmlNodePtr pItem = pNode->first_node("server"); while (pItem) { int pId = HAS_ATTR(pItem, "id") ? atoi(ATTR_VALUE(pItem, "id")) : -1; string ipStr = HAS_ATTR(pItem, "ip") ? ATTR_VALUE(pItem, "ip") : "127.0.0.1"; int port = HAS_ATTR(pItem, "port") ? atoi(ATTR_VALUE(pItem, "port")) : 12345; m_svrMap[pId] = pair<string, int>(ipStr, port); pItem = pItem->next_sibling("server"); } } if ((pNode = xmlDoc.first_node("parameters"))) { m_connNum = HAS_NODE(pNode, "conn_num") ? atoi(NODE_VALUE(pNode, "conn_num")) : 1; m_fixRate = HAS_NODE(pNode, "fix_rate") ? atoi(NODE_VALUE(pNode, "fix_rate")) : 0; m_initTimeout = HAS_NODE(pNode, "init_timeout") ? atoi(NODE_VALUE(pNode, "init_timeout")) : 20; m_videoLen = HAS_NODE(pNode, "video_len") ? atoi(NODE_VALUE(pNode, "video_len")) : 278; m_initBufferSize = HAS_NODE(pNode, "init_buffer_size") ? atoi(NODE_VALUE(pNode, "init_buffer_size")) : 10; } LOG("--------------------------------------------------"); svrMap_t::const_iterator cIt = m_svrMap.begin(); for (; cIt != m_svrMap.end(); ++cIt) { LOG("|server: id=%d, %s:%d.", (*cIt).first, (*cIt).second.first.c_str(), (*cIt).second.second); } LOG("|number of connections: %d.", m_connNum); LOG("|video length: %d.", m_videoLen); LOG("|fix rate: %d.", m_fixRate); LOG("|init buffer timeout: %d.", m_initTimeout); LOG("|init buffer size: %d.", m_initBufferSize); LOG("--------------------------------------------------"); xmlDoc.clear(); m_rateVec.push_back(350); m_rateVec.push_back(470); m_rateVec.push_back(630); m_rateVec.push_back(845); m_rateVec.push_back(1130); m_rateVec.push_back(1520); m_rateVec.push_back(2040); }
/** * @brief Allows to send a SMTP message using the configuration found * on the provided smtp_conf declaration. This smtp_conf declaration * is found at the turbulence configuration file. See \ref * turbulence_smtp_notifications * * @param ctx The turbulence context where the operation will be * implemented. * * @param smtp_conf_id The string identifying the smtp configuration (id * declaration inside <smtp-server> node) or NULL. If NULL is used, * then the first smtp server with is-default=yes declared is used. * * @param subject Optional subject to be configured on mail body * message. * * @param body The message body to be configured. If NULL is provided * no body will be sent. * * @param body_file Optional reference to a file that contains the * body of the message. * * @return axl_true if the mail message was submited or axl_false if * something failed. */ axl_bool turbulence_support_simple_smtp_send (TurbulenceCtx * ctx, const char * smtp_conf_id, const char * subject, const char * body, const char * body_file) { axlNode * node; axlNode * default_node; if (ctx == NULL) return axl_false; /* find smtp mail notification conf */ node = axl_doc_get (turbulence_config_get (ctx), "/turbulence/global-settings/notify-failures/smtp-server"); default_node = NULL; while (node) { /* check for declaration with the smtp conf requested */ if (HAS_ATTR_VALUE (node, "id", smtp_conf_id)) break; /* check for default node declaration */ if (HAS_ATTR_VALUE (node, "is-default", "yes") && default_node == NULL) default_node = node; /* node not found, go next */ node = axl_node_get_next_called (node, "smtp-server"); } /* end while */ /* set to default node found (if any) when node is null */ if (node == NULL) node = default_node; /* check if the smtp configuration was found */ if (node == NULL) { error ("Failed to send mail notification, unable to find default smtp configuration or smtp configuration associated to id '%s'", smtp_conf_id ? smtp_conf_id : "NULL"); return axl_false; } /* now use SMTP send values */ return turbulence_support_smtp_send (ctx, ATTR_VALUE (node, "mail-from"), ATTR_VALUE (node, "mail-to"), subject, body, body_file, ATTR_VALUE (node, "server"), ATTR_VALUE (node, "port")); }
MyQttConn * __mod_ssl_start_listener (MyQttdCtx * ctx, MyQttCtx * my_ctx, axlNode * port_node, const char * bind_addr, const char * port, axlPointer user_data) { MyQttConn * listener; axlNode * node; const char * crt, * key, * chain; /* create listener on the port indicated */ listener = myqtt_tls_listener_new ( /* the context where the listener will * be started */ my_ctx, /* listener name */ bind_addr ? bind_addr : "0.0.0.0", /* port to use */ port, /* opts */ NULL, /* on ready callbacks */ NULL, NULL); /* configure default certificates from store */ node = __mod_ssl_get_default_certificate (ctx, my_ctx); if (node) { /* configure certificates */ crt = ATTR_VALUE (node, "crt"); key = ATTR_VALUE (node, "key"); chain = ATTR_VALUE (node, "chain"); msg ("mod-ssl: configuring default crt=%s, key=%s, chain=%s", crt, key, chain); if (! myqtt_tls_set_certificate (listener, crt, key, chain)) { error ("unable to configure certificates for TLS mqtt (myqtt_tls_set_certificate failed).."); return NULL; } /* end if */ } else { wrn ("Unable to configure any certificate. No default certificate was found. __mod_ssl_get_default_certificate() reported NULL"); } /* end if */ return listener; /* basic configuration done */ }
/** * @internal Init function, perform all the necessary code to register * profiles, configure Vortex, and any other init task. The function * must return true to signal that the module was properly initialized * Otherwise, false must be returned. */ static int slm_init (ValvuladCtx * _ctx) { axlNode * node; const char * mode; /* configure the module */ ctx = _ctx; msg ("Valvulad slm module: init"); /* get node */ node = axl_doc_get (_ctx->config, "/valvula/enviroment/sender-login-mismatch"); mode = ATTR_VALUE (node, "mode"); /* configure module */ if (axl_cmp (mode, "full")) __slm_mode = VALVULA_MOD_SLM_FULL; else if (axl_cmp (mode, "same-domain")) __slm_mode = VALVULA_MOD_SLM_SAME_DOMAIN; else if (axl_cmp (mode, "valid-mail-from")) __slm_mode = VALVULA_MOD_SLM_VALID_MAIL_FROM; else if (axl_cmp (mode, "disabled")) __slm_mode = VALVULA_MOD_SLM_DISABLED; /* get allow empty mail from */ if (HAS_ATTR_VALUE (node, "allow-empty-mail-from", "no")) __slm_allow_empty_mail_from = axl_false; /* ensure tables */ if (! valvulad_db_ensure_table (ctx, "slm_exception", /* attributes */ "id", "autoincrement int", "is_active", "int", "description", "text", "mail_from", "text", "sasl_username", "text", NULL)) { printf ("ERROR: unable to create slm_exception table..\n"); return axl_false; } /* end if */ return axl_true; }
axlNode * __mod_ssl_get_certificate_node_by_name (MyQttdCtx * ctx, const char * serverName) { axlNode * node; node = axl_doc_get (mod_ssl_conf, "/mod-ssl/certificates/cert"); if (node == NULL) return NULL; while (node) { if (axl_cmp (serverName, ATTR_VALUE (node, "serverName"))) { /* node found, report it */ return node; } /* end if */ /* get next <cert> node */ node = axl_node_get_next_called (node, "cert"); } /* end while */ /* reached this point no certificate was found, so report NULL */ return NULL; }
axl_bool mod_sasl_mysql_load_auth_db (TurbulenceCtx * ctx, SaslAuthBackend * sasl_backend, axlNode * auth_db_node_conf, axlError ** err) { MYSQL * conn; const char * location; char * basedir = NULL; axlDoc * doc; axlError * local_err = NULL; /* check if location is defined */ if (! HAS_ATTR (auth_db_node_conf, "location")) { axl_error_report (err, -1, "Unable to open auth mysql database, 'location' attribute is not defined"); return axl_false; } /* end if */ /* find the node that holds the connection configuration */ location = ATTR_VALUE (auth_db_node_conf, "location"); /* check if the location is relative or not */ if (! turbulence_file_is_fullpath (location)) { /* get base dir of the sasl.conf that represents this backend */ basedir = turbulence_base_dir (common_sasl_get_file_path (sasl_backend)); /* now build a new path */ location = axl_strdup_printf ("%s%s%s", basedir, VORTEX_FILE_SEPARATOR, location); msg ("Found relative file to auth mysql db settings, resolved to: %s", location); } /* end if */ /* now load the file */ doc = axl_doc_parse_from_file (location, &local_err); /* check for error and report */ if (doc == NULL) { axl_error_report (err, -1, "Failed to open auth mysql db at %s error was %s", location, axl_error_get (local_err)); axl_error_free (local_err); } /* end if */ /* dealloc some variables */ if (basedir) { axl_free (basedir); axl_free ((char *) location); } /* end if */ /* return if error */ if (doc == NULL) { return axl_false; } /* end if */ /* do DTD validation */ if (! axl_dtd_validate (doc, mysql_sasl_dtd, &local_err)) { axl_error_report (err, -1, "Failed to open auth mysql db at %s, found DTD error %s", location, axl_error_get (local_err)); axl_error_free (local_err); axl_doc_free (doc); return axl_false; } /* end if */ /* link the document to this node so we can reuse it later */ axl_node_annotate_data_full (auth_db_node_conf, "mysql-conf", NULL, doc, (axlDestroyFunc) axl_doc_free); /* request to load msyql database */ conn = mod_sasl_mysql_get_connection (ctx, auth_db_node_conf, err); if (conn == NULL) return axl_false; msg ("load database ok"); /* connection ok, this means we have loaded the database */ return axl_true; }
axl_bool mod_sasl_mysql_do_auth (TurbulenceCtx * ctx, VortexConnection * conn, axlNode * auth_db_node_conf, const char * auth_id, const char * authorization_id, const char * formated_password, const char * password, const char * serverName, const char * sasl_method, axlError ** err) { char * query; axlDoc * doc; axlNode * node; axl_bool _result = axl_false; /* check import parameters without doing anything */ if (! mod_sasl_mysql_check_unallowed_sequence (ctx, conn, auth_id)) return axl_false; if (! mod_sasl_mysql_check_unallowed_sequence (ctx, conn, password)) return axl_false; if (! mod_sasl_mysql_check_unallowed_sequence (ctx, conn, formated_password)) return axl_false; if (! mod_sasl_mysql_check_unallowed_sequence (ctx, conn, serverName)) return axl_false; if (! mod_sasl_mysql_check_unallowed_sequence (ctx, conn, authorization_id)) return axl_false; if (! mod_sasl_mysql_check_unallowed_sequence (ctx, conn, sasl_method)) return axl_false; if (! mod_sasl_mysql_check_unallowed_sequence (ctx, conn, auth_id)) return axl_false; if (! mod_sasl_mysql_check_unallowed_sequence (ctx, conn, vortex_connection_get_host (conn))) return axl_false; /* get the auth query */ doc = axl_node_annotate_get (auth_db_node_conf, "mysql-conf", axl_false); if (doc == NULL) { axl_error_report (err, -1, "Found no xml document defining MySQL settings to connect to the database"); return axl_false; } /* end if */ /* check for ip filter reference */ node = axl_doc_get (doc, "/sasl-auth-db/ip-filter"); if (node && HAS_ATTR (node, "query")) { /* ip filter defined, get query */ query = axl_strdup (ATTR_VALUE (node, "query")); /* replace query with recognized tokens */ axl_replace (query, "%u", auth_id); axl_replace (query, "%n", serverName); axl_replace (query, "%i", authorization_id); axl_replace (query, "%m", sasl_method); msg ("Checking IP filter for auth id [%s], query [%s]", auth_id, query); if (! mod_sasl_mysql_check_ip_filter_query (ctx, query, conn, auth_db_node_conf)) { error ("login failure: %s, ip filtered by defined expression associated to user: %s denied connection from %s", auth_id, auth_id, vortex_connection_get_host_ip (conn)); axl_free (query); return 0; } msg ("IP not filtered by defined expression associated to user: %s allowed connection from %s", auth_id, vortex_connection_get_host_ip (conn)); /* ip not filtered, now let the auth continue */ axl_free (query); } /* end if */ /***** ALT AUTHENTICATION *****/ /* get alt password if defined <get-password-alt> */ node = axl_doc_get (doc, "/sasl-auth-db/get-password-alt"); if (node) { /* get query */ query = (char *) ATTR_VALUE_TRANS (node, "query"); /* call to do auth operation */ _result = __mod_sasl_mysql_prepare_query_and_auth (ctx, query, conn, auth_db_node_conf, auth_id, authorization_id, formated_password, password, serverName, sasl_method, axl_false, /* skip login error reporting */ axl_true, err); /* clean for cleanup node <get-password-alt-cleanup> */ node = axl_doc_get (doc, "/sasl-auth-db/get-password-alt-cleanup"); if (node) { /* get query */ query = (char *) ATTR_VALUE_TRANS (node, "query"); /* call and skip getting value reported */ if (! __mod_sasl_mysql_prepare_query_and_auth (ctx, query, conn, auth_db_node_conf, auth_id, authorization_id, formated_password, password, serverName, sasl_method, axl_true, /* skip login error reporting */ axl_true, err)) error ("Cleanup query failed, please, review <get-password-alt-cleanup>.."); } /* end if */ } /* end if */ /**** MAIN AUTHENTICATION ****/ /* if authentication failed, try with main table */ if (! _result) { /* get the node that contains the configuration */ node = axl_doc_get (doc, "/sasl-auth-db/get-password"); query = (char *) ATTR_VALUE (node, "query"); /* call to do auth operation */ _result = __mod_sasl_mysql_prepare_query_and_auth (ctx, query, conn, auth_db_node_conf, auth_id, authorization_id, formated_password, password, serverName, sasl_method, axl_false, /* skip login error reporting */ axl_false, err); } /* end if */ /* now check for auth-log declaration to report it */ node = axl_doc_get (doc, "/sasl-auth-db/auth-log"); if (node) { /* log auth defined */ query = axl_strdup (ATTR_VALUE (node, "query")); /* replace query with recognized tokens */ axl_replace (query, "%t", _result ? "ok" : "failed"); axl_replace (query, "%u", auth_id); axl_replace (query, "%n", serverName); axl_replace (query, "%i", authorization_id); axl_replace (query, "%m", sasl_method); axl_replace (query, "%p", vortex_connection_get_host (conn)); msg ("Trying to auth-log %s:%s with query string %s", auth_id, _result ? "ok" : "failed", query); /* exec query */ if (! mod_sasl_mysql_do_query (ctx, auth_db_node_conf, query, axl_true, err)) { error ("Unable to auth-log, failed query configured, error was: %d:%s", axl_error_get_code (*err), axl_error_get (*err)); axl_error_free (*err); } axl_free (query); } /* end if */ if (!_result) error ("login failure: %s, failed from: %s", auth_id, vortex_connection_get_host_ip (conn)); return _result ? 1 : 0; }
/** * @internal Function that creates a connection to the MySQL database * configured on the xml node. */ MYSQL * mod_sasl_mysql_get_connection (TurbulenceCtx * ctx, axlNode * auth_db_node_conf, axlError ** err) { MYSQL * conn; int port = 0; int reconnect = 1; axlDoc * doc; axlNode * node; if (ctx == NULL || auth_db_node_conf == NULL) { axl_error_report (err, -1, "Received null ctx, auth db node or sql query, failed to run SQL command"); return NULL; } /* end if */ /* check if the connection is already defined */ conn = axl_node_annotate_get (auth_db_node_conf, "mysql-conn", axl_false); if (conn) { /* reuse connection */ return conn; } /* end if */ /* get document containing MySQL settings */ doc = axl_node_annotate_get (auth_db_node_conf, "mysql-conf", axl_false); if (doc == NULL) { axl_error_report (err, -1, "Found no xml document defining MySQL settings to connect to the database"); return NULL; } /* end if */ /* get the node that contains the configuration */ node = axl_doc_get (doc, "/sasl-auth-db/connection-settings"); /* create a mysql connection */ conn = mysql_init (NULL); /* get port */ if (HAS_ATTR (node, "port") && strlen (ATTR_VALUE (node, "port")) > 0) { /* get port configured by the user */ port = atoi (ATTR_VALUE (node, "port")); } /* create a connection */ if (mysql_real_connect (conn, /* get host */ ATTR_VALUE (node, "host"), /* get user */ ATTR_VALUE (node, "user"), /* get password */ ATTR_VALUE (node, "password"), /* get database */ ATTR_VALUE (node, "database"), port, NULL, 0) == NULL) { axl_error_report (err, mysql_errno (conn), "Mysql connect error: %s, failed to run SQL command", mysql_error (conn)); return NULL; } /* end if */ /* flag here to reconnect in case of lost connection */ mysql_options (conn, MYSQL_OPT_RECONNECT, (const char *) &reconnect); /* record connection */ axl_node_annotate_data_full (auth_db_node_conf, "mysql-conn", NULL, conn, (axlDestroyFunc) mysql_close); return conn; }
/** * @internal Places current process identifier into the file provided * by the user. */ void valvulad_place_pidfile (ValvuladCtx * ctx) { FILE * pid_file = NULL; int pid = getpid (); char buffer[20]; int size; axlNode * node; int gid, uid; /* check if pid file exists */ if (! exarg_is_defined ("skip-pid-check")) { if (valvula_support_file_test (pid_file_path, FILE_EXISTS)) { abort_error ("Unable to start server, found pid file in place %s. There is a valvula server running. If not, remove file %s", pid_file_path, pid_file_path); exit (-1); return; } /* end if */ } else { wrn ("Skipping pid file checking.."); } /* end if */ /* open pid file or create it to place the pid file */ pid_file = fopen (pid_file_path, "w"); if (pid_file == NULL) { abort_error ("Unable to open pid file at: %s", pid_file_path); return; } /* end if */ /* stringfy pid */ size = axl_stream_printf_buffer (buffer, 20, NULL, "%d", pid); msg ("signaling PID %d at %s", pid, pid_file_path); if (fwrite (buffer, size, 1, pid_file) <= 0) { abort_error ("Unable to write pid file content at %s, error was: errno=%d : %s", pid_file, errno, strerror (errno)); return; } fclose (pid_file); pid_file = fopen (valvula_status, "w"); if (pid_file == NULL) { abort_error ("Unable to open valvula status file at: %s (errno=%d)", valvula_status, errno); return; } /* end if */ fprintf (pid_file, "<valvula-state>\n"); fprintf (pid_file, " <attr name='valvula pid' value='%d' />\n", getpid ()); fprintf (pid_file, "</valvula-state>\n"); fclose (pid_file); /* now change permissions (if required) */ node = axl_doc_get (ctx->config, "/valvula/global-settings/running"); if (node && ATTR_VALUE (node, "user") && ATTR_VALUE (node, "group") && HAS_ATTR_VALUE (node, "enabled", "yes")) { /* change group first */ gid = valvulad_get_system_id (ctx, ATTR_VALUE (node, "group"), axl_false); uid = valvulad_get_system_id (ctx, ATTR_VALUE (node, "user"), axl_true); msg ("Attempting to update pid ownership to %d:%d", uid, gid); if (gid > 0 && uid > 0) { if (chown (valvula_status, uid, gid) != 0) { error ("Unable to change permissions to file %s (%d:%d), error was errno=%d (%s)", valvula_status, uid, gid, errno, strerror (errno)); } /* end if */ /**** do no change pid file ownership is a security problem ****/ } /* end if */ } /* end if */ return; }
void valvulad_ping_server (void) { axl_bool result; axlNode * node; VALVULA_SOCKET _socket; int timeout = 10; char buffer[20]; const char * host; const char * port; int event; /* init here valvula library and valvulaD context */ if (! valvulad_init (&ctx)) { error ("Failed to initialize ValvulaD context, unable to start server"); exit (-1); } /* end if */ /* parse configuration file */ if (exarg_is_defined ("config")) result = valvulad_config_load (ctx, exarg_get_string ("config")); else result = valvulad_config_load (ctx, "/etc/valvula/valvula.conf"); if (! result) { printf ("ERROR: unable to load valvula configuration, failed to locate server to ping it\n"); exit (-1); } /* end if */ /* get node */ node = axl_doc_get (ctx->config, "/valvula/general/listen"); if (! node ) { printf ("ERROR: nothing to test, no listener was found defined\n"); exit (-1); } /* end if */ while (node) { /* connect to the server */ port = ATTR_VALUE (node, "port"); host = ATTR_VALUE (node, "host"); if (! port) continue; if (! host) host = "127.0.0.1"; /* ensure that in 10 seconds we get called */ event = valvula_thread_pool_new_event (ctx->ctx, 10000000, catch_ping_server_timeout, NULL, NULL); _socket = valvula_connection_sock_connect (ctx->ctx, host, port, &timeout, NULL); if (_socket <= 0) { printf ("ERROR: unable to connect to %s:%s, _socket=%d, error=%d\n", host, port, _socket, errno); exit (-1); } /* end if */ valvula_connection_set_sock_block (_socket, axl_true); /* send check server request */ if (send (_socket, "checkserver\n", 12, 0) != 12) { printf ("ERROR: failed to send checkserver request, bytes expected weren't 11, errno=%d\n", errno); exit (-1); } /* end if */ /* ensure that in 10 seconds we get called */ valvula_thread_pool_remove (ctx->ctx, event); event = valvula_thread_pool_new_event (ctx->ctx, 10000000, catch_ping_server_timeout, NULL, NULL); /* wait for reply */ memset (buffer, 0, 20); if (recv (_socket, buffer, 17, 0) != 17) { printf ("ERROR: expected to receive 20 bytes but found: %s, errno=%d : %s\n", buffer, errno, strerror (errno)); exit (-1); } /* end if */ /* check content here */ valvula_close_socket (_socket); if (! axl_cmp (buffer, "I'm running right")) { printf ("ERROR: expected to receive different values but found: %s\n", buffer); exit (-1); } /* end if */ printf ("%s:%s working right!\n", host, port); /* get next <listen /> node */ node = axl_node_get_next_called (node, "listen"); } /* end while */ printf ("Valvula server working OK\n"); exit (0); }
void valvulad_show_current_server_status (void) { axlDoc * doc; axlError * err = NULL; axlNode * node; int pid = -1; doc = axl_doc_parse_from_file (valvula_status, &err); if (doc == NULL) { printf ("ERROR: unable to open file %s, error was: %s\n", valvula_status, axl_error_get (err)); axl_error_free (err); exit (-1); } /* end if */ /* find the pid file to send the signal */ node = axl_doc_get (doc, "/valvula-state/attr"); while (node) { if (HAS_ATTR_VALUE (node, "name", "valvula pid")) { /* get pid */ pid = valvula_support_strtod (ATTR_VALUE (node, "value"), NULL); break; } /* get next node */ node = axl_node_get_next_called (node, "attr"); } /* end while */ /* release document */ axl_doc_free (doc); if (pid == -1) { printf ("ERROR: unable to find running pid..\n"); exit (-1); } /* end if */ printf ("--== Found pid %d, sending signal..==--\n", pid); kill (pid, SIGUSR1); sleep (1); /* reparse file */ doc = axl_doc_parse_from_file (valvula_status, &err); if (doc == NULL) { printf ("ERROR: unable to open file %s, error was: %s\n", valvula_status, axl_error_get (err)); axl_error_free (err); exit (-1); } /* end if */ /* find the pid file to send the signal */ node = axl_doc_get (doc, "/valvula-state"); node = axl_node_get_first_child (node); while (node) { /* show values */ if (NODE_CMP_NAME (node, "attr")) printf ("%s: %s\n", ATTR_VALUE (node, "name"), ATTR_VALUE (node, "value")); else if (NODE_CMP_NAME (node, "section")) printf ("\n--== %s ==--\n\n", ATTR_VALUE (node, "title")); /* get next node */ node = axl_node_get_next (node); } printf ("\n"); exit (0); return; }
/** * @internal Terminates the myqttd excution, returing the exit signal * provided as first parameter. This function is used to notify a * context that a signal was received. * * @param ctx The myqttd context to terminate. * @param _signal The exit code to return. */ void myqttd_signal_exit (MyQttdCtx * ctx, int _signal) { /* get myqttd context */ axlDoc * doc; axlNode * node; MyQttAsyncQueue * queue; char * backtrace_file; /* lock the mutex and check */ myqtt_mutex_lock (&ctx->exit_mutex); if (ctx->is_exiting) { msg ("process already existing, signal received=%d, doing nothing...", _signal); /* other thread is already cleaning */ myqtt_mutex_unlock (&ctx->exit_mutex); return; } /* end if */ msg ("received termination signal (%d) on PID %d, preparing exit process", _signal, getpid ()); /* flag that myqttd is existing and do all cleanup * operations */ ctx->is_exiting = axl_true; myqtt_mutex_unlock (&ctx->exit_mutex); switch (_signal) { case SIGINT: msg ("caught SIGINT, terminating myqttd.."); break; case SIGTERM: msg ("caught SIGTERM, terminating myqttd.."); break; #if defined(AXL_OS_UNIX) case SIGKILL: msg ("caught SIGKILL, terminating myqttd.."); break; case SIGQUIT: msg ("caught SIGQUIT, terminating myqttd.."); break; #endif case SIGSEGV: case SIGABRT: error ("caught %s, anomalous termination (this is an internal myqttd or module error)", _signal == SIGSEGV ? "SIGSEGV" : "SIGABRT"); /* check current termination option */ doc = myqttd_config_get (ctx); node = axl_doc_get (doc, "/myqtt/global-settings/on-bad-signal"); error ("applying configured action %s", (node && HAS_ATTR (node, "action")) ? ATTR_VALUE (node, "action") : "not defined"); if (HAS_ATTR_VALUE (node, "action", "ignore")) { /* do notify if enabled */ CHECK_AND_REPORT_MAIL_TO ("Bad signal received at myqttd process, default action: ignore", "Received termination signal but it was ignored.", NULL); /* ignore the signal emision */ return; } else if (HAS_ATTR_VALUE (node, "action", "hold")) { /* lock the process */ error ("Bad signal found, locking process, now you can attach or terminate pid: %d", getpid ()); CHECK_AND_REPORT_MAIL_TO ("Bad signal received a myqttd process, default action: hold", "Received termination signal and the process was hold for examination", NULL); queue = myqtt_async_queue_new (); myqtt_async_queue_pop (queue); return; } else if (HAS_ATTR_VALUE (node, "action", "backtrace")) { /* create temporal file */ error ("Bad signal found, creating backtrace for current process: %d", getpid ()); backtrace_file = myqttd_support_get_backtrace (ctx, getpid ()); if (backtrace_file == NULL) error ("..backtrace error, unable to produce backtrace.."); else error ("..backtrace created at: %s", backtrace_file); /* check if we have to do a mail notification */ CHECK_AND_REPORT_MAIL_TO ("Bad signal received a myqttd process, default action: backtrace", NULL, backtrace_file); /* release backtrace */ axl_free (backtrace_file); } /* signal myqtt to not terminate threads (to avoid * deadlocks) */ exit (-1); break; default: msg ("terminating myqttd.."); break; } /* end if */ /* Unlock the listener here. Do not perform any deallocation * operation here because we are in the middle of a signal * handler execution. By unlocking the listener, the * myqttd_cleanup is called cleaning the room. */ msg ("Unlocking myqttd listener: %p", ctx); /* unlock the current listener */ myqtt_listener_unlock (MYQTTD_MYQTT_CTX (ctx)); return; } /* end if */
int tbc_mod_gen_compile () { axlDtd * dtd; axlDoc * doc; axlError * error; axlNode * node; axlNode * moddef; char * mod_name; char * tolower; char * toupper; char * description; /* parse DTD document */ dtd = axl_dtd_parse (TBC_MOD_GEN_DTD, -1, &error); if (dtd == NULL) { /* report error and dealloc resources */ error ("Failed to parse DTD, error found: %s", axl_error_get (error)); axl_error_free (error); return axl_false; } /* end if */ /* nice, now parse the xml file */ doc = axl_doc_parse_from_file (exarg_get_string ("compile"), &error); if (doc == NULL) { /* report error and dealloc resources */ error ("unable to parse file: %s, error found: %s", exarg_get_string ("compile"), axl_error_get (error)); axl_error_free (error); axl_dtd_free (dtd); } /* end if */ /* nice, now validate content */ if (! axl_dtd_validate (doc, dtd, &error)) { /* report error and dealloc */ error ("failed to validate module description provided: %s, error found: %s", exarg_get_string ("compile"), axl_error_get (error)); axl_error_free (error); axl_doc_free (doc); axl_dtd_free (dtd); return axl_false; } /* end if */ /* ok, now produce source code */ axl_dtd_free (dtd); /* open file */ moddef = axl_doc_get_root (doc); node = axl_doc_get (doc, "/mod-def/name"); mod_name = (char *) axl_node_get_content (node, NULL); mod_name = support_clean_name (mod_name); tolower = support_to_lower (mod_name); toupper = support_to_upper (mod_name); /* out dir */ support_open_file (ctx, "%s%s.c", get_out_dir (), mod_name); /* place copyright if found */ node = axl_doc_get (doc, "/mod-def/copyright"); if (node != NULL) { /* place the copyright */ } /* end if */ write ("/* %s implementation */\n", mod_name); write ("#include <turbulence.h>\n\n"); write ("/* use this declarations to avoid c++ compilers to mangle exported\n"); write (" * names. */\n"); write ("BEGIN_C_DECLS\n\n"); write ("/* global turbulence context reference */\n"); write ("TurbulenceCtx * ctx = NULL;\n\n"); /* place here additional content */ node = axl_doc_get (doc, "/mod-def/source-code/additional-content"); if (node != NULL) { write ("%s\n", axl_node_get_content (node, NULL)); } /* end if */ /* init handler */ write ("/* %s init handler */\n", mod_name); write ("static int %s_init (TurbulenceCtx * _ctx) {\n", tolower); push_indent (); write ("/* configure the module */\n"); write ("TBC_MOD_PREPARE (_ctx);\n\n"); pop_indent (); node = axl_doc_get (doc, "/mod-def/source-code/init"); if (axl_node_get_content (node, NULL)) { /* write the content defined */ write ("%s\n", axl_node_get_content (node, NULL)); } write ("} /* end %s_init */\n\n", tolower); /* close handler */ write ("/* %s close handler */\n", mod_name); write ("static void %s_close (TurbulenceCtx * _ctx) {\n", tolower); node = axl_doc_get (doc, "/mod-def/source-code/close"); if (axl_node_get_content (node, NULL)) { /* write the content defined */ write ("%s\n", axl_node_get_content (node, NULL)); } write ("} /* end %s_close */\n\n", tolower); /* reconf handler */ write ("/* %s reconf handler */\n", mod_name); write ("static void %s_reconf (TurbulenceCtx * _ctx) {\n", tolower); node = axl_doc_get (doc, "/mod-def/source-code/reconf"); if (axl_node_get_content (node, NULL)) { /* write the content defined */ write ("%s\n", axl_node_get_content (node, NULL)); } write ("} /* end %s_reconf */\n\n", tolower); /* unload handler */ write ("/* %s unload handler */\n", mod_name); write ("static void %s_unload (TurbulenceCtx * _ctx) {\n", tolower); node = axl_doc_get (doc, "/mod-def/source-code/unload"); if (axl_node_get_content (node, NULL)) { /* write the content defined */ write ("%s\n", axl_node_get_content (node, NULL)); } write ("} /* end %s_unload */\n\n", tolower); /* ppath_selected handler */ write ("/* %s ppath-selected handler */\n", mod_name); write ("static axl_bool %s_ppath_selected (TurbulenceCtx * _ctx, TurbulencePPathDef * ppath_selected, VortexConnection * conn) {\n", tolower); node = axl_doc_get (doc, "/mod-def/source-code/ppath-selected"); if (axl_node_get_content (node, NULL)) { /* write the content defined */ write ("%s\n", axl_node_get_content (node, NULL)); } write ("} /* end %s_ppath_selected */\n\n", tolower); /* write handler description */ write ("/* Entry point definition for all handlers included in this module */\n"); write ("TurbulenceModDef module_def = {\n"); push_indent (); write ("\"%s\",\n", mod_name); node = axl_doc_get (doc, "/mod-def/description"); description = (char *) axl_node_get_content (node, NULL); write ("\"%s\",\n", description ? description : ""); write ("%s_init,\n", tolower); write ("%s_close,\n", tolower); write ("%s_reconf,\n", tolower); write ("%s_unload,\n", tolower); write ("%s_ppath_selected\n", tolower); pop_indent (); write ("};\n\n"); write ("END_C_DECLS\n\n"); /* close content */ support_close_file (ctx); /* create the makefile required */ support_open_file (ctx, "%sMakefile.am", get_out_dir ()); write ("# Module definition\n"); write ("EXTRA_DIST = %s\n\n", exarg_get_string ("compile")); write ("INCLUDES = -Wall -g -ansi $(TURBULENCE_CFLAGS) -I../../src -DCOMPILATION_DATE=`date +%%s` \\\n"); push_indent (); write ("-DVERSION=\\\"$(VERSION)\\\" \\\n"); write ("$(AXL_CFLAGS) $(VORTEX_CFLAGS) $(EXARG_CFLAGS)\n\n"); pop_indent (); write ("# configure module binary\n"); write ("lib_LTLIBRARIES = %s.la\n", mod_name); write ("%s_la_SOURCES = %s.c %s\n", mod_name, mod_name, HAS_ATTR (moddef, "sources") ? ATTR_VALUE (moddef, "sources") : ""); write ("%s_la_LDFLAGS = -module -ldl\n\n", mod_name); write ("# reconfigure module installation directory\n"); write ("libdir = `turbulence-config --mod-dir`\n\n"); write ("# configure site module installation\n"); write ("modconfdir = `turbulence-config --mod-xml`\n"); write ("modconf_DATA = %s.xml %s.win32.xml\n\n", mod_name, mod_name); write ("%s.xml %s.win32.xml:\n", mod_name, mod_name); push_indent (); write ("echo \"<mod-turbulence location=\\\"`turbulence-config --mod-dir`/%s.so\\\"/>\" > %s.xml\n", mod_name, mod_name); write ("echo \"<mod-turbulence location=\\\"../modules/%s.dll\\\"/>\" > %s.win32.xml\n", mod_name, mod_name); pop_indent (); support_close_file (ctx); /* create autoconf if defined */ if (exarg_is_defined ("enable-autoconf")) { msg ("found autoconf support files request.."); /* create the autogen.sh */ support_open_file (ctx, "%sautogen.sh", get_out_dir ()); write ("# autogen.sh file created by tbc-mod-gen\n"); write ("PACKAGE=\"%s: %s\"\n\n", mod_name, description); write ("(automake --version) < /dev/null > /dev/null 2>&1 || {\n"); push_indent (); write ("echo;\n"); write ("echo \"You must have automake installed to compile $PACKAGE\";\n"); write ("echo;\n"); write ("exit;\n"); pop_indent (); write ("}\n\n"); write ("(autoconf --version) < /dev/null > /dev/null 2>&1 || {\n"); push_indent (); write ("echo;\n"); write ("echo \"You must have autoconf installed to compile $PACKAGE\";\n"); write ("echo;\n"); write ("exit;\n"); pop_indent (); write ("}\n\n"); write ("echo \"Generating configuration files for $PACKAGE, please wait....\"\n"); write ("echo;\n\n"); write ("touch NEWS README AUTHORS ChangeLog\n"); write ("libtoolize --force;\n"); write ("aclocal $ACLOCAL_FLAGS;\n"); write ("autoheader;\n"); write ("automake --add-missing;\n"); write ("autoconf;\n\n"); write ("./configure $@ --enable-maintainer-mode --enable-compile-warnings\n"); support_close_file (ctx); support_make_executable (ctx, "%sautogen.sh", get_out_dir ()); /* now create the configure.ac file */ support_open_file (ctx, "%sconfigure.ac", get_out_dir ()); write ("dnl configure.ac template file created by tbc-mod-gen\n"); write ("AC_INIT(%s.c)\n\n", mod_name); write ("dnl declare a global version value\n"); write ("%s_VERSION=\"0.0.1\"\n", toupper); write ("AC_SUBST(%s_VERSION)\n\n", toupper); write ("AC_CONFIG_AUX_DIR(.)\n"); write ("AM_INIT_AUTOMAKE(%s, $%s_VERSION)\n\n", mod_name, toupper); write ("AC_CONFIG_HEADER(config.h)\n"); write ("AM_MAINTAINER_MODE\n"); write ("AC_PROG_CC\n"); write ("AC_ISC_POSIX\n"); write ("AC_HEADER_STDC\n"); write ("AM_PROG_LIBTOOL\n\n"); write ("dnl external dependencies\n"); write ("PKG_CHECK_MODULES(AXL, axl >= %s)\n\n", AXL_VERSION); write ("dnl general libries subsitution\n"); write ("AC_SUBST(AXL_CFLAGS)\n"); write ("AC_SUBST(AXL_LIBS)\n\n"); write ("dnl external dependencies\n"); write ("PKG_CHECK_MODULES(VORTEX, vortex >= %s) \n\n", VORTEX_VERSION); write ("dnl general libries subsitution\n"); write ("AC_SUBST(VORTEX_CFLAGS)\n"); write ("AC_SUBST(VORTEX_LIBS)\n\n"); write ("dnl external dependencies\n"); write ("PKG_CHECK_MODULES(EXARG, exarg)\n\n"); write ("dnl general libries subsitution\n"); write ("AC_SUBST(EXARG_CFLAGS)\n"); write ("AC_SUBST(EXARG_LIBS)\n\n"); write ("dnl external dependencies\n"); write ("PKG_CHECK_MODULES(TURBULENCE, turbulence >= %s)\n\n", VERSION); write ("dnl general libries subsitution\n"); write ("AC_SUBST(TURBULENCE_CFLAGS)\n"); write ("AC_SUBST(TURBULENCE_LIBS)\n\n"); write ("AC_OUTPUT([\n"); write ("Makefile\n"); write ("])\n\n"); write ("echo \"------------------------------------------\"\n"); write ("echo \"-- mod_template Settings --\"\n"); write ("echo \"------------------------------------------\"\n"); write ("echo \"------------------------------------------\"\n"); write ("echo \"-- Let it BEEP! --\"\n"); write ("echo \"-- --\"\n"); write ("echo \"-- NOW TYPE: make; make install --\"\n"); write ("echo \"------------------------------------------\"\n"); support_close_file (ctx); } /* end if */ /* dealloc */ axl_free (tolower); axl_free (toupper); axl_doc_free (doc); /* create the script file */ support_open_file (ctx, "%sgen-code", get_out_dir ()); write ("#!/bin/sh\n\n"); /* write the mod gen */ write ("tbc-mod-gen --compile %s --out-dir %s\n", exarg_get_string ("compile"), exarg_get_string ("out-dir")); support_close_file (ctx); support_make_executable (ctx, "%sgen-code", get_out_dir ()); msg ("%s created!", mod_name); axl_free (mod_name); return axl_true; }