void ICACHE_FLASH_ATTR config_parse(serverConnData *conn, char *buf, int len) { char *lbuf = (char *)os_malloc(len + 1), **argv; uint8_t i, argc; // we need a '\0' end of the string os_memcpy(lbuf, buf, len); lbuf[len] = '\0'; DBG_MSG("parse %d[%s]\r\n", len, lbuf); // remove any CR / LF for (i = 0; i < len; ++i) if (lbuf[i] == '\n' || lbuf[i] == '\r') lbuf[i] = '\0'; // verify the command prefix if (os_strncmp(lbuf, "+++AT", 5) != 0) { DBG_MSG("Not a command\r\n"); return; } // parse out buffer into arguments argv = config_parse_args(&lbuf[5], &argc); DBG_MSG("argc: %d, argv[0]: %s.\r\n", argc, argv[0]); if (argc == 0) { espbuffsentstring(conn, MSG_OK); } else { argc--; // to mimic C main() argc argv for (i = 0; config_commands[i].command; ++i) { if (os_strncmp(argv[0], config_commands[i].command, strlen(argv[0])) == 0) { config_commands[i].function(conn, argc, argv); break; } } if (!config_commands[i].command) espbuffsentprintf(conn, "%s - buf: %s\r\n", MSG_INVALID_CMD, argv[0]); } config_parse_args_free(argc, argv); os_free(lbuf); }
PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) { abl_args *args; abl_info *info; abl_context *context; DB *utdb; DB *usdb; DB *htdb; DB *hsdb; int err = PAM_SUCCESS; /*log_debug(args, "pam_sm_authenticate(), flags=%08x", flags);*/ if (args = malloc(sizeof(abl_args)), NULL == args) { return PAM_BUF_ERR; } if (info = malloc(sizeof(abl_info)), NULL == info) { return PAM_BUF_ERR; } if (context = malloc(sizeof(abl_context)), NULL == context) { return PAM_BUF_ERR; } memset(info,0,sizeof(abl_info)); memset(context,0,sizeof(abl_context)); if (err = config_parse_args(pamh, argc, argv, args), PAM_SUCCESS == err) { /* We now keep the database open from the beginning to avoid the cost * of opening them repeatedly. */ err = dbopen(args, args->user_db, DB_TIME, &utdb); if (err) goto psa_fail; info->utdb = utdb; err = dbopen(args, args->user_db, DB_STATE, &usdb); if (err) goto psa_fail; info->usdb = usdb; err = dbopen(args, args->host_db, DB_TIME, &htdb); if (err) goto psa_fail; info->htdb = htdb; err = dbopen(args, args->host_db, DB_STATE, &hsdb); if (err) goto psa_fail; info->hsdb = hsdb; context->args = args; context->info = info; if (err = pam_set_data(pamh, DATA_NAME, context, cleanup), PAM_SUCCESS != err) { log_pam_error(args,err,"setting PAM data"); goto psa_fail; } if (err = pam_get_item(args->pamh, PAM_USER, (const void **) &info->user), PAM_SUCCESS != err) { log_pam_error(args, err, "getting PAM_USER"); goto psa_fail; } if (err = pam_get_item(args->pamh, PAM_SERVICE, (const void **) &info->service), PAM_SUCCESS != err) { log_pam_error(args, err, "getting PAM_SERVICE"); goto psa_fail; } if (err = pam_get_item(args->pamh, PAM_RHOST, (const void **) &info->host), PAM_SUCCESS != err) { log_pam_error(args, err, "getting PAM_RHOST"); goto psa_fail; } check_attempt(args, info); if (info->state == BLOCKED) { log_info("Blocking access from %s to service %s, user %s", info->host, info->service, info->user); return PAM_AUTH_ERR; } else { return PAM_SUCCESS; } } psa_fail: config_free(args); utdb->close(utdb,0); usdb->close(usdb,0); htdb->close(htdb,0); hsdb->close(hsdb,0); free(args); free(info); free(context); return err; }
int main(int argc, char *argv[]) { struct benchmark_config cfg; memset(&cfg, 0, sizeof(struct benchmark_config)); if (config_parse_args(argc, argv, &cfg) < 0) { usage(); } config_init_defaults(&cfg); log_level = cfg.debug; if (cfg.show_config) { fprintf(stderr, "============== Configuration values: ==============\n"); config_print(stdout, &cfg); fprintf(stderr, "===================================================\n"); } struct rlimit rlim; if (getrlimit(RLIMIT_NOFILE, &rlim) != 0) { benchmark_error_log("error: getrlimit failed: %s\n", strerror(errno)); exit(1); } if (cfg.unix_socket != NULL && (cfg.server != NULL || cfg.port > 0)) { benchmark_error_log("error: UNIX domain socket and TCP cannot be used together.\n"); exit(1); } unsigned int fds_needed = (cfg.threads * cfg.clients) + (cfg.threads * 10) + 10; if (fds_needed > rlim.rlim_cur) { if (fds_needed > rlim.rlim_max && getuid() != 0) { benchmark_error_log("error: running the tool with this number of connections requires 'root' privilegs.\n"); exit(1); } rlim.rlim_cur = rlim.rlim_max = fds_needed; if (setrlimit(RLIMIT_NOFILE, &rlim) != 0) { benchmark_error_log("error: setrlimit failed: %s\n", strerror(errno)); exit(1); } } // create and configure object generator object_generator* obj_gen = NULL; imported_keylist* keylist = NULL; if (!cfg.data_import) { if (cfg.data_verify) { fprintf(stderr, "error: use data-verify only with data-import\n"); exit(1); } if (cfg.no_expiry) { fprintf(stderr, "error: use no-expiry only with data-import\n"); exit(1); } obj_gen = new object_generator(); assert(obj_gen != NULL); } else { // check paramters if (cfg.data_size || cfg.data_size_list.is_defined() || cfg.data_size_range.is_defined()) { fprintf(stderr, "error: data size cannot be specified when importing.\n"); exit(1); } if (cfg.random_data) { fprintf(stderr, "error: random-data cannot be specified when importing.\n"); exit(1); } if (!cfg.generate_keys && (cfg.key_maximum || cfg.key_minimum || cfg.key_prefix)) { fprintf(stderr, "error: use key-minimum, key-maximum and key-prefix only with generate-keys.\n"); exit(1); } if (!cfg.generate_keys) { // read keys fprintf(stderr, "Reading keys from %s...", cfg.data_import); keylist = new imported_keylist(cfg.data_import); assert(keylist != NULL); if (!keylist->read_keys()) { fprintf(stderr, "\nerror: failed to read keys.\n"); exit(1); } else { fprintf(stderr, " %u keys read.\n", keylist->size()); } } obj_gen = new import_object_generator(cfg.data_import, keylist, cfg.no_expiry); assert(obj_gen != NULL); if (dynamic_cast<import_object_generator*>(obj_gen)->open_file() != true) { fprintf(stderr, "error: %s: failed to open.\n", cfg.data_import); exit(1); } } if (cfg.authenticate) { if (strcmp(cfg.protocol, "redis") != 0 && strcmp(cfg.protocol, "memcache_binary") != 0) { fprintf(stderr, "error: authenticate can only be used with redis or memcache_binary.\n"); usage(); } if (strcmp(cfg.protocol, "memcache_binary") == 0 && strchr(cfg.authenticate, ':') == NULL) { fprintf(stderr, "error: binary_memcache credentials must be in the form of USER:PASSWORD.\n"); usage(); } } if (cfg.select_db > 0 && strcmp(cfg.protocol, "redis")) { fprintf(stderr, "error: select-db can only be used with redis protocol.\n"); usage(); } if (cfg.data_offset > 0) { if (cfg.data_offset > (1<<29)-1) { fprintf(stderr, "error: data-offset too long\n"); usage(); } if (cfg.expiry_range.min || cfg.expiry_range.max || strcmp(cfg.protocol, "redis")) { fprintf(stderr, "error: data-offset can only be used with redis protocol, and cannot be used with expiry\n"); usage(); } } if (cfg.data_size) { if (cfg.data_size_list.is_defined() || cfg.data_size_range.is_defined()) { fprintf(stderr, "error: data-size cannot be used with data-size-list or data-size-range.\n"); usage(); } obj_gen->set_data_size_fixed(cfg.data_size); } else if (cfg.data_size_list.is_defined()) { if (cfg.data_size_range.is_defined()) { fprintf(stderr, "error: data-size-list cannot be used with data-size-range.\n"); usage(); } obj_gen->set_data_size_list(&cfg.data_size_list); } else if (cfg.data_size_range.is_defined()) { obj_gen->set_data_size_range(cfg.data_size_range.min, cfg.data_size_range.max); obj_gen->set_data_size_pattern(cfg.data_size_pattern); } else if (!cfg.data_import) { fprintf(stderr, "error: data-size, data-size-list or data-size-range must be specified.\n"); usage(); } if (!cfg.data_import) { obj_gen->set_random_data(cfg.random_data); } if (!cfg.data_import || cfg.generate_keys) { obj_gen->set_key_prefix(cfg.key_prefix); obj_gen->set_key_range(cfg.key_minimum, cfg.key_maximum); } if (cfg.key_stddev>0 || cfg.key_median>0) { if (cfg.key_pattern[0]!='G' && cfg.key_pattern[2]!='G') { fprintf(stderr, "error: key-stddev and key-median are only allowed together with key-pattern set to G.\n"); usage(); } if (cfg.key_median!=0 && (cfg.key_median<cfg.key_minimum || cfg.key_median>cfg.key_maximum)) { fprintf(stderr, "error: key-median must be between key-minimum and key-maximum.\n"); usage(); } obj_gen->set_key_distribution(cfg.key_stddev, cfg.key_median); } obj_gen->set_expiry_range(cfg.expiry_range.min, cfg.expiry_range.max); // Prepare output file FILE *outfile; if (cfg.out_file != NULL) { fprintf(stderr, "Writing results to %s...\n", cfg.out_file); outfile = fopen(cfg.out_file, "w"); if (!outfile) { perror(cfg.out_file); } } else { outfile = stdout; } if (!cfg.verify_only) { std::vector<run_stats> all_stats; for (unsigned int run_id = 1; run_id <= cfg.run_count; run_id++) { if (run_id > 1) sleep(1); // let connections settle run_stats stats = run_benchmark(run_id, &cfg, obj_gen); all_stats.push_back(stats); } // Print some run information fprintf(outfile, "%-9u Threads\n" "%-9u Connections per thread\n" "%-9u %s\n", cfg.threads, cfg.clients, cfg.requests > 0 ? cfg.requests : cfg.test_time, cfg.requests > 0 ? "Requests per thread" : "Seconds"); // If more than 1 run was used, compute best, worst and average if (cfg.run_count > 1) { unsigned int min_ops_sec = (unsigned int) -1; unsigned int max_ops_sec = 0; run_stats* worst = NULL; run_stats* best = NULL; for (std::vector<run_stats>::iterator i = all_stats.begin(); i != all_stats.end(); i++) { unsigned long usecs = i->get_duration_usec(); unsigned int ops_sec = (int)(((double)i->get_total_ops() / (usecs > 0 ? usecs : 1)) * 1000000); if (ops_sec < min_ops_sec || worst == NULL) { min_ops_sec = ops_sec; worst = &(*i); } if (ops_sec > max_ops_sec || best == NULL) { max_ops_sec = ops_sec; best = &(*i); } } fprintf(outfile, "\n\n" "BEST RUN RESULTS\n" "========================================================================\n"); best->print(outfile, !cfg.hide_histogram); fprintf(outfile, "\n\n" "WORST RUN RESULTS\n" "========================================================================\n"); worst->print(outfile, !cfg.hide_histogram); fprintf(outfile, "\n\n" "AGGREGATED AVERAGE RESULTS (%u runs)\n" "========================================================================\n", cfg.run_count); run_stats average; average.aggregate_average(all_stats); average.print(outfile, !cfg.hide_histogram); } else { all_stats.begin()->print(outfile, !cfg.hide_histogram); } } // If needed, data verification is done now... if (cfg.data_verify) { struct event_base *verify_event_base = event_base_new(); abstract_protocol *verify_protocol = protocol_factory(cfg.protocol); verify_client *client = new verify_client(verify_event_base, &cfg, verify_protocol, obj_gen); fprintf(outfile, "\n\nPerforming data verification...\n"); // Run client in verification mode client->prepare(); event_base_dispatch(verify_event_base); fprintf(outfile, "Data verification completed:\n" "%-10llu keys verified successfuly.\n" "%-10llu keys failed.\n", client->get_verified_keys(), client->get_errors()); // Clean up... delete client; delete verify_protocol; event_base_free(verify_event_base); } if (outfile != stdout) { fclose(outfile); } delete obj_gen; if (keylist != NULL) delete keylist; }
/* service_main */ static VOID WINAPI service_main(DWORD argc, LPTSTR *argv) { config_t conf; void* net; void* threads; void* pipe; h_service = RegisterServiceCtrlHandler(LDMSVC_SERVICE_NAME, handler); if(h_service == NULL) { return; } set_state1(SERVICE_START_PENDING); // SERVICE_START_PENDING // open the heap if(!heap_start()) { dout("Failed to create the heap\n"); set_state2(SERVICE_STOPPED, 1); return; } // parse configuration if(!config_parse_args(&conf, argc, argv)) { heap_stop(); set_state2(SERVICE_STOPPED, 1); return; } if(0) { dout(va("PORT: %u\n", conf.port)); dout(va("PIPE: %s\n", conf.pipe)); dout(va("MAXC: %u\n", conf.maxconn)); } // open network if((net = net_start()) == NULL) { heap_stop(); set_state2(SERVICE_STOPPED, 1); return; } // open the pipe if((pipe = pipe_start(conf.pipe)) == NULL) { net_stop(net); heap_stop(); set_state2(SERVICE_STOPPED, 1); return; } // connect the pipe if(!pipe_open(pipe)) { pipe_stop(pipe); net_stop(net); heap_stop(); set_state2(SERVICE_STOPPED, 1); return; } // start threads if((threads = threads_start(net, pipe, conf.maxconn)) == NULL) { pipe_stop(pipe); net_stop(net); heap_stop(); set_state2(SERVICE_STOPPED, 1); return; } set_state1(SERVICE_RUNNING); // SERVICE_RUNNING while(svc_state == SERVICE_RUNNING) { if(!net_is_ready(net)) { net_bind(net, NULL, conf.port); } if(!threads_think(threads)) { break; } Sleep(1); } set_state1(SERVICE_STOP_PENDING); // SERVICE_STOP_PENDING // close everything here threads_stop(threads); pipe_stop(pipe); net_stop(net); heap_stop(); set_state2(SERVICE_STOPPED, 0); // SERVICE_STOPPED }