void add_topic(xmlNode * a_node,char *login, char *topic, char *post, char *text, char *id) { xmlNode *cur_node = NULL; char buf[256]; bzero(buf,256); for (cur_node = a_node; cur_node; cur_node = cur_node->next) { if (cur_node->type == XML_ELEMENT_NODE) { if((!xmlStrcmp(cur_node->name,(const xmlChar *)"topic"))) if((!xmlStrcmp(xmlGetProp(cur_node,"name"),(const xmlChar *)topic))) { xmlNodePtr nNode = xmlNewNode(0,(const xmlChar *)"post"); xmlSetProp(nNode,(const xmlChar *)"id",(const xmlChar *)id); xmlSetProp(nNode,(const xmlChar *)"name",(const xmlChar *)post); xmlSetProp(nNode,(const xmlChar *)"autor",(const xmlChar *)login); xmlSetProp(nNode,(const xmlChar *)"text",(const xmlChar *)text); xmlAddChild(cur_node,nNode); return; } } add_topic(cur_node->children,login, topic, post, text, id); } }
void add_new_topic(xmlNode * a_node,int newsockfd,char *login) { int i; char buffer[256]; char topic_name[256]; char post_name[256]; char post_message[256]; char id[6]; write(newsockfd,"Print topic name\n ",18); bzero(buffer,256); bzero(topic_name,256); read( newsockfd,buffer,255 ); strcpy(topic_name,buffer); topic_name[strlen(topic_name)-1]=0; write(newsockfd,"Print post name\n ",18); bzero(buffer,256); bzero(post_name,256); read( newsockfd,buffer,255 ); strcpy(post_name,buffer); post_name[strlen(post_name)-1]=0; write(newsockfd,"Print message\n ",18); bzero(buffer,256); bzero(post_message,256); read( newsockfd,buffer,255 ); strcpy(post_message,buffer); post_message[strlen(post_message)-1]=0; bzero(id,6); for(i=0;i<5;i++) id[i]=(rand()%10+'0'); add_topic(a_node,login,topic_name,post_name,post_message,id); }
/* * Program entry point. */ int main(int argc, char** argv) { /* * Standard command-line parsing. */ const HASH_T *options = parse_cmdline(argc, argv, arg_opts); if(options == NULL || hash_get(options, "help") != NULL) { show_usage(argc, argv, arg_opts); return EXIT_FAILURE; } const char *url = hash_get(options, "url"); const char *principal = hash_get(options, "principal"); CREDENTIALS_T *credentials = NULL; const char *password = hash_get(options, "credentials"); if(password != NULL) { credentials = credentials_create_password(password); } const char *topic_name = hash_get(options, "topic"); const long seconds = atol(hash_get(options, "seconds")); /* * Setup for condition variable. */ apr_initialize(); apr_pool_create(&pool, NULL); apr_thread_mutex_create(&mutex, APR_THREAD_MUTEX_UNNESTED, pool); apr_thread_cond_create(&cond, pool); /* * Create a session with the Diffusion server. */ SESSION_T *session; DIFFUSION_ERROR_T error = { 0 }; session = session_create(url, principal, credentials, NULL, NULL, &error); if(session == NULL) { fprintf(stderr, "TEST: Failed to create session\n"); fprintf(stderr, "ERR : %s\n", error.message); return EXIT_FAILURE; } /* * Create a topic holding simple string content. */ TOPIC_DETAILS_T *string_topic_details = create_topic_details_single_value(M_DATA_TYPE_STRING); const ADD_TOPIC_PARAMS_T add_topic_params = { .topic_path = topic_name, .details = string_topic_details, .on_topic_added = on_topic_added, .on_topic_add_failed = on_topic_add_failed, .on_discard = on_topic_add_discard, }; apr_thread_mutex_lock(mutex); add_topic(session, add_topic_params); apr_thread_cond_wait(cond, mutex); apr_thread_mutex_unlock(mutex); topic_details_free(string_topic_details); /* * Define the handlers for add_update_source() */ const UPDATE_SOURCE_REGISTRATION_PARAMS_T update_reg_params = { .topic_path = topic_name, .on_init = on_update_source_init, .on_registered = on_update_source_registered, .on_active = on_update_source_active, .on_standby = on_update_source_standby, .on_close = on_update_source_closed }; /* * Register an updater. */ apr_thread_mutex_lock(mutex); CONVERSATION_ID_T *updater_id = register_update_source(session, update_reg_params); apr_thread_cond_wait(cond, mutex); apr_thread_mutex_unlock(mutex); /* * Define default parameters for an update source. */ UPDATE_SOURCE_PARAMS_T update_source_params_base = { .updater_id = updater_id, .topic_path = topic_name, .on_success = on_update_success, .on_failure = on_update_failure }; time_t end_time = time(NULL) + seconds; while(time(NULL) < end_time) { if(active) { /* * Create an update structure containing the current time. */ BUF_T *buf = buf_create(); const time_t time_now = time(NULL); buf_write_string(buf, ctime(&time_now)); CONTENT_T *content = content_create(CONTENT_ENCODING_NONE, buf); UPDATE_T *upd = update_create(UPDATE_ACTION_REFRESH, UPDATE_TYPE_CONTENT, content); UPDATE_SOURCE_PARAMS_T update_source_params = update_source_params_base; update_source_params.update = upd; /* * Update the topic. */ update(session, update_source_params); content_free(content); update_free(upd); buf_free(buf); } sleep(1); } if(active) { UPDATE_SOURCE_DEREGISTRATION_PARAMS_T update_dereg_params = { .updater_id = updater_id, .on_deregistered = on_update_source_deregistered }; apr_thread_mutex_lock(mutex); deregister_update_source(session, update_dereg_params); apr_thread_cond_wait(cond, mutex); apr_thread_mutex_unlock(mutex); } /* * Close session and free resources. */ session_close(session, NULL); session_free(session); conversation_id_free(updater_id); credentials_free(credentials); apr_thread_mutex_destroy(mutex); apr_thread_cond_destroy(cond); apr_pool_destroy(pool); apr_terminate(); return EXIT_SUCCESS; }
int main(int argc, char** argv) { /* * Standard command-line parsing. */ HASH_T *options = parse_cmdline(argc, argv, arg_opts); if(options == NULL || hash_get(options, "help") != NULL) { show_usage(argc, argv, arg_opts); return EXIT_FAILURE; } char *url = hash_get(options, "url"); const char *principal = hash_get(options, "principal"); CREDENTIALS_T *credentials = NULL; const char *password = hash_get(options, "credentials"); if(password != NULL) { credentials = credentials_create_password(password); } // Setup for condition variable apr_initialize(); apr_pool_create(&pool, NULL); apr_thread_mutex_create(&mutex, APR_THREAD_MUTEX_UNNESTED, pool); apr_thread_cond_create(&cond, pool); // Setup for session SESSION_T *session; DIFFUSION_ERROR_T error = { 0 }; session = session_create(url, principal, credentials, NULL, NULL, &error); if(session == NULL) { fprintf(stderr, "TEST: Failed to create session\n"); fprintf(stderr, "ERR : %s\n", error.message); return EXIT_FAILURE; } // Common params for all add_topic() functions. ADD_TOPIC_PARAMS_T common_params = { .on_topic_added = on_topic_added, .on_topic_add_failed = on_topic_add_failed, .on_discard = on_topic_add_discard }; /* * Create a stateless topic. */ TOPIC_DETAILS_T *topic_details = create_topic_details_stateless(); ADD_TOPIC_PARAMS_T stateless_params = common_params; stateless_params.topic_path = "stateless"; stateless_params.details = topic_details; apr_thread_mutex_lock(mutex); add_topic(session, stateless_params); apr_thread_cond_wait(cond, mutex); apr_thread_mutex_unlock(mutex); /* * Create a topic with single value string data, but with * containing no default data. */ TOPIC_DETAILS_T *string_topic_details = create_topic_details_single_value(M_DATA_TYPE_STRING); ADD_TOPIC_PARAMS_T string_params = common_params; string_params.topic_path = "string"; string_params.details = string_topic_details; apr_thread_mutex_lock(mutex); add_topic(session, string_params); apr_thread_cond_wait(cond, mutex); apr_thread_mutex_unlock(mutex); /* * Create a topic with single value string data and containing * some default data. */ ADD_TOPIC_PARAMS_T string_data_params = common_params; string_data_params.topic_path = "string-data"; string_data_params.details = string_topic_details; BUF_T *sample_data_buf = buf_create(); buf_write_string(sample_data_buf, "Hello, world"); string_data_params.content = content_create(CONTENT_ENCODING_NONE, sample_data_buf); apr_thread_mutex_lock(mutex); add_topic(session, string_data_params); apr_thread_cond_wait(cond, mutex); apr_thread_mutex_unlock(mutex); /* * Create a topic with single value integer data, and with a * default value. */ TOPIC_DETAILS_T *integer_topic_details = create_topic_details_single_value(M_DATA_TYPE_INTEGER_STRING); integer_topic_details->topic_details_params.integer.default_value = 999; ADD_TOPIC_PARAMS_T integer_params = common_params; integer_params.topic_path = "integer"; integer_params.details = integer_topic_details; apr_thread_mutex_lock(mutex); add_topic(session, integer_params); apr_thread_cond_wait(cond, mutex); apr_thread_mutex_unlock(mutex); /* * Create a topic with integer data, but using a CONTENT_T to * specify the initial data. */ ADD_TOPIC_PARAMS_T integer_data_params = common_params; integer_data_params.topic_path = "integer-data"; integer_data_params.details = integer_topic_details; BUF_T *integer_data_buf = buf_create(); buf_sprintf(integer_data_buf, "%d", 123); integer_data_params.content = content_create(CONTENT_ENCODING_NONE, integer_data_buf); apr_thread_mutex_lock(mutex); add_topic(session, integer_data_params); apr_thread_cond_wait(cond, mutex); apr_thread_mutex_unlock(mutex); /* * Create a topic with single value decimal data, with a * default value and specifying the scale (i.e. positions * after the decimal place). */ TOPIC_DETAILS_T *decimal_topic_details = create_topic_details_single_value(M_DATA_TYPE_DECIMAL_STRING); decimal_topic_details->topic_details_params.decimal.default_value = 123.456; decimal_topic_details->topic_details_params.decimal.scale = 4; ADD_TOPIC_PARAMS_T decimal_params = common_params; decimal_params.topic_path = "decimal"; decimal_params.details = decimal_topic_details; apr_thread_mutex_lock(mutex); add_topic(session, decimal_params); apr_thread_cond_wait(cond, mutex); apr_thread_mutex_unlock(mutex); /* * Create a topic with decimal data, using a CONTENT_T to * specify the initial data. */ ADD_TOPIC_PARAMS_T decimal_data_params = common_params; decimal_data_params.topic_path = "decimal-data"; decimal_data_params.details = decimal_topic_details; BUF_T *decimal_data_buf = buf_create(); buf_sprintf(decimal_data_buf, "%f", 987.654); decimal_data_params.content = content_create(CONTENT_ENCODING_NONE, decimal_data_buf); apr_thread_mutex_lock(mutex); add_topic(session, decimal_data_params); apr_thread_cond_wait(cond, mutex); apr_thread_mutex_unlock(mutex); /* * Record topic data. * * The C API does not have the concept of "builders" for * creating record topic data, but requires you to build a * string containing XML that describes the structure of the * messages. */ /* * First of all, this adds a topic equivalent to single-value * strings, but defined with XML. */ BUF_T *manual_schema = buf_create(); buf_write_string(manual_schema, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"); buf_write_string(manual_schema, "<field name=\"x\" type=\"string\" default=\"xyzzy\" allowsEmpty=\"true\"/>"); TOPIC_DETAILS_T *manual_topic_details = create_topic_details_single_value(M_DATA_TYPE_STRING); manual_topic_details->user_defined_schema = manual_schema; ADD_TOPIC_PARAMS_T string_manual_params = common_params; string_manual_params.topic_path = "string-manual"; string_manual_params.details = manual_topic_details; apr_thread_mutex_lock(mutex); add_topic(session, string_manual_params); apr_thread_cond_wait(cond, mutex); apr_thread_mutex_unlock(mutex); /* * This adds a topic with a record containing multiple fields * of different types. */ BUF_T *record_schema = buf_create(); buf_write_string(record_schema, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"); buf_write_string(record_schema, "<message topicDataType=\"record\" name=\"MyContent\">"); buf_write_string(record_schema, "<record name=\"Record1\">"); buf_write_string(record_schema, "<field type=\"string\" default=\"\" allowsEmpty=\"true\" name=\"Field1\"/>"); buf_write_string(record_schema, "<field type=\"integerString\" default=\"0\" allowsEmpty=\"false\" name=\"Field2\"/>"); buf_write_string(record_schema, "<field type=\"decimalString\" default=\"0.00\" scale=\"2\" allowsEmpty=\"false\" name=\"Field3\"/>"); buf_write_string(record_schema, "</record>"); buf_write_string(record_schema, "</message>"); TOPIC_DETAILS_T *record_topic_details = create_topic_details_record(); record_topic_details->user_defined_schema = record_schema; ADD_TOPIC_PARAMS_T record_params = common_params; record_params.topic_path = "record"; record_params.details = record_topic_details; apr_thread_mutex_lock(mutex); add_topic(session, record_params); apr_thread_cond_wait(cond, mutex); apr_thread_mutex_unlock(mutex); /* * We can also remove topics. First, add a couple of topics * and then remove their parent topic. All child topics are * removed with the parent. */ puts("Adding topics remove_me/1 and remove_me/2"); ADD_TOPIC_PARAMS_T topic_params = common_params; topic_params.details = topic_details; topic_params.topic_path = "remove_me/1"; apr_thread_mutex_lock(mutex); add_topic(session, topic_params); apr_thread_cond_wait(cond, mutex); apr_thread_mutex_unlock(mutex); topic_params.topic_path = "remove_me/2"; apr_thread_mutex_lock(mutex); add_topic(session, topic_params); apr_thread_cond_wait(cond, mutex); apr_thread_mutex_unlock(mutex); puts("Removing topics in 5 seconds..."); sleep(5); REMOVE_TOPICS_PARAMS_T remove_params = { .on_removed = on_topic_removed, .on_discard = on_topic_remove_discard, .topic_selector = ">remove_me" }; apr_thread_mutex_lock(mutex); remove_topics(session, remove_params); apr_thread_cond_wait(cond, mutex); apr_thread_mutex_unlock(mutex); /* * Close our session, and release resources and memory. */ session_close(session, NULL); session_free(session); apr_thread_mutex_destroy(mutex); apr_thread_cond_destroy(cond); apr_pool_destroy(pool); apr_terminate(); return EXIT_SUCCESS; }