gint main(gint argc, gchar **argv) { gint i,r; gchar *s; g_assert(qm == NULL); g_assert(q == NULL); memset(&opts, 0, sizeof(struct _opts_s)); setlocale(LC_ALL, ""); r = opts_new(argc, argv); if (r != EXIT_SUCCESS) return (r); q = quvi_new(); examples_exit_if_error(); if (opts.autoproxy == TRUE) examples_enable_autoproxy(); if (opts.verbose == TRUE) examples_enable_verbose(); quvi_set(q, QUVI_OPTION_CALLBACK_STATUS, (qcs) examples_status); for (i=0; opts.url[i] != NULL; ++i) { qm = quvi_media_new(q, opts.url[i]); examples_exit_if_error(); quvi_media_get(qm, QUVI_MEDIA_PROPERTY_TITLE, &s); g_print("[%s]\n title='%s'\n", __func__, s); if (opts.best == TRUE) { quvi_media_stream_choose_best(qm); dump_stream(); } else if (opts.stream != NULL) { quvi_media_stream_select(qm, opts.stream); examples_exit_if_error(); dump_stream(); } else dump_streams(); quvi_media_free(qm); qm = NULL; } opts_free(); examples_cleanup(); g_assert(qm == NULL); g_assert(q == NULL); return (r); }
int tc_api_task_uninit(tc_api_task task) { if (task->last_info != NULL) free_info(task->last_info); opts_free(task->opts); free_safe_mem(task); return TC_OK; }
int main(int argc, char **argv) { FILE* cfiles[BUFSIZ]; FILE *asmfile = NULL; char errstr[BUFSIZ]; char line[BUFSIZ]; int i; handle_args(argc, argv); for (i = 0; i < opts.c_fcount; ++i) { printf("C file[%d]: '%s'\n", i + 1, opts.c_fname[i]); cfiles[i] = fopen(opts.c_fname[i], "r"); if (cfiles[i] == NULL) { sprintf(errstr, "couldn't open '%s'", opts.c_fname[i]); error(errstr); error("perhaps it doesn't exist?"); opts.c_fcount = i; goto exit; } } if (opts.asm_name_spec) printf("asm file: '%s'\n", opts.asm_fname); else printf("asm file: '%s'\n", defout); for (i = 0; i < opts.c_fcount; ++i) { cfiles[i] = comment_preprocessor_notes(cfiles[i], opts.c_fname[i]); } for (i = 0; i < opts.c_fcount; ++i) { while (fgets(line, BUFSIZ, cfiles[i]) != NULL) printf("%s", line); rewind(cfiles[i]); } for (i = 0; i < opts.c_fcount; ++i) { yyin = cfiles[i]; yyparse(); } if (scc_error == 0) { asmfile = fopen(opts.asm_fname, "w"); if (asmfile == NULL) { sprintf(errstr, "couldn't open '%s' for output", opts.asm_fname); error(errstr); } else { fclose(asmfile); } } exit: close_files(cfiles, opts.c_fcount); opts_free(); exit(EXIT_SUCCESS); }
END_TEST START_TEST(opts_debug_01) { opts_t *opts; opts = opts_new(); opts->debug = 0; fail_unless(!opts->debug, "plain 0"); fail_unless(!OPTS_DEBUG(opts), "macro 0"); opts->debug = 1; fail_unless(!!opts->debug, "plain 1"); fail_unless(!!OPTS_DEBUG(opts), "macro 1"); opts_free(opts); }
tc_api_task tc_api_task_init(const char *op) { tc_api_task task = NULL; int fail = 1; if ((task = alloc_safe_mem(sizeof(*task))) == NULL) { errno = ENOMEM; goto out; } if ((task->opts = opts_init()) == NULL) { errno = ENOMEM; goto out; } if (_match(op, "create")) { task->op = TC_OP_CREATE; } else if (_match(op, "map")) { task->op = TC_OP_MAP; } else if (_match(op, "unmap")) { task->op = TC_OP_UNMAP; } else if (_match(op, "info")) { task->op = TC_OP_INFO; } else if (_match(op, "info_mapped")) { task->op = TC_OP_INFO_MAPPED; } else if (_match(op, "modify")) { task->op = TC_OP_MODIFY; } else if (_match(op, "restore")) { task->op = TC_OP_RESTORE; } else { errno = EINVAL; goto out; } tc_set_iteration_count(0); fail = 0; out: if (fail && task != NULL) { if (task->opts != NULL) opts_free(task->opts); free_safe_mem(task); } return fail ? NULL : task; }
/* * Parse the given command-line arguments into an opts_t object, handling * "help", "license" and "version" options internally. * * Returns an opts_t, or 0 on error. * * Note that the contents of *argv[] (i.e. the command line parameters) * aren't copied anywhere, just the pointers are copied, so make sure the * command line data isn't overwritten or argv[1] free()d or whatever. */ opts_t opts_parse(int argc, char **argv) { #ifdef HAVE_GETOPT_LONG struct option long_options[] = { {"help", 0, 0, 'h'}, {"version", 0, 0, 'V'}, {"progress", 0, 0, 'p'}, {"timer", 0, 0, 't'}, {"eta", 0, 0, 'e'}, {"rate", 0, 0, 'r'}, {"average-rate", 0, 0, 'a'}, {"bytes", 0, 0, 'b'}, {"force", 0, 0, 'f'}, {"numeric", 0, 0, 'n'}, {"quiet", 0, 0, 'q'}, {"cursor", 0, 0, 'c'}, {"wait", 0, 0, 'W'}, {"size", 1, 0, 's'}, {"line-mode", 0, 0, 'l'}, {"null", 0, 0, '0'}, {"interval", 1, 0, 'i'}, {"width", 1, 0, 'w'}, {"height", 1, 0, 'H'}, {"name", 1, 0, 'N'}, {"format", 1, 0, 'F'}, {"rate-limit", 1, 0, 'L'}, {"buffer-size", 1, 0, 'B'}, {"skip-errors", 0, 0, 'E'}, {"stop-at-size", 0, 0, 'S'}, {"remote", 1, 0, 'R'}, {"pidfile", 1, 0, 'P'}, {0, 0, 0, 0} }; int option_index = 0; #endif char *short_options = "hVpterabfnqcWs:l0i:w:H:N:F:L:B:ESR:P:"; int c, numopts; opts_t opts; opts = calloc(1, sizeof(*opts)); if (!opts) { fprintf(stderr, /* RATS: ignore */ _("%s: option structure allocation failed (%s)"), argv[0], strerror(errno)); fprintf(stderr, "\n"); return 0; } opts->program_name = argv[0]; opts->argc = 0; opts->argv = calloc(argc + 1, sizeof(char *)); if (!opts->argv) { fprintf(stderr, /* RATS: ignore */ _ ("%s: option structure argv allocation failed (%s)"), argv[0], strerror(errno)); fprintf(stderr, "\n"); opts_free(opts); return 0; } numopts = 0; opts->interval = 1; do { #ifdef HAVE_GETOPT_LONG c = getopt_long(argc, argv, /* RATS: ignore */ short_options, long_options, &option_index); #else c = getopt(argc, argv, short_options); /* RATS: ignore */ #endif if (c < 0) continue; /* * Check that any numeric arguments are of the right type. */ switch (c) { case 's': case 'w': case 'H': case 'L': case 'B': case 'R': if (pv_getnum_check(optarg, PV_NUMTYPE_INTEGER) != 0) { fprintf(stderr, "%s: -%c: %s\n", argv[0], c, _("integer argument expected")); opts_free(opts); return 0; } break; case 'i': if (pv_getnum_check(optarg, PV_NUMTYPE_DOUBLE) != 0) { fprintf(stderr, "%s: -%c: %s\n", argv[0], c, _("numeric argument expected")); opts_free(opts); return 0; } break; default: break; } /* * Parse each command line option. */ switch (c) { case 'h': display_help(); opts->do_nothing = 1; return opts; break; case 'V': display_version(); opts->do_nothing = 1; return opts; break; case 'p': opts->progress = 1; numopts++; break; case 't': opts->timer = 1; numopts++; break; case 'e': opts->eta = 1; numopts++; break; case 'r': opts->rate = 1; numopts++; break; case 'a': opts->average_rate = 1; numopts++; break; case 'b': opts->bytes = 1; numopts++; break; case 'f': opts->force = 1; break; case 'n': opts->numeric = 1; numopts++; break; case 'q': opts->no_op = 1; numopts++; break; case 'c': opts->cursor = 1; break; case 'W': opts->wait = 1; break; case 's': opts->size = pv_getnum_ll(optarg); break; case 'l': opts->linemode = 1; break; case '0': opts->null = 1; opts->linemode = 1; break; case 'i': opts->interval = pv_getnum_d(optarg); break; case 'w': opts->width = pv_getnum_i(optarg); break; case 'H': opts->height = pv_getnum_i(optarg); break; case 'N': opts->name = optarg; break; case 'L': opts->rate_limit = pv_getnum_ll(optarg); break; case 'B': opts->buffer_size = pv_getnum_ll(optarg); break; case 'E': opts->skip_errors++; break; case 'S': opts->stop_at_size = 1; break; case 'R': opts->remote = pv_getnum_i(optarg); break; case 'P': opts->pidfile = optarg; break; case 'F': opts->format = optarg; break; default: #ifdef HAVE_GETOPT_LONG fprintf(stderr, /* RATS: ignore (OK) */ _("Try `%s --help' for more information."), argv[0]); #else fprintf(stderr, /* RATS: ignore (OK) */ _("Try `%s -h' for more information."), argv[0]); #endif fprintf(stderr, "\n"); opts_free(opts); return 0; break; } } while (c != -1); /* * Default options: -pterb */ if (0 == numopts) { opts->progress = 1; opts->timer = 1; opts->eta = 1; opts->rate = 1; opts->bytes = 1; } /* * Store remaining command-line arguments. */ while (optind < argc) { opts->argv[opts->argc++] = argv[optind++]; } return opts; }
/* * Main entry point. */ int main(int argc, char *argv[]) { const char *argv0; int ch; opts_t *opts; char *natengine; int pidfd = -1; int rv = EXIT_FAILURE; argv0 = argv[0]; opts = opts_new(); natengine = strdup(nat_getdefaultname()); while ((ch = getopt(argc, argv, OPT_g OPT_G OPT_Z "k:c:C:K:t:OPs:e:Eu:j:p:l:L:S:dDVh")) != -1) { switch (ch) { case 'c': if (opts->cacrt) X509_free(opts->cacrt); opts->cacrt = ssl_x509_load(optarg); if (!opts->cacrt) { fprintf(stderr, "%s: error loading CA " "cert from '%s':\n", argv0, optarg); if (errno) { fprintf(stderr, "%s\n", strerror(errno)); } else { ERR_print_errors_fp(stderr); } exit(EXIT_FAILURE); } ssl_x509_refcount_inc(opts->cacrt); sk_X509_insert(opts->chain, opts->cacrt, 0); if (!opts->cakey) { opts->cakey = ssl_key_load(optarg); } #ifndef OPENSSL_NO_DH if (!opts->dh) { opts->dh = ssl_dh_load(optarg); } #endif /* !OPENSSL_NO_DH */ break; case 'k': if (opts->cakey) EVP_PKEY_free(opts->cakey); opts->cakey = ssl_key_load(optarg); if (!opts->cakey) { fprintf(stderr, "%s: error loading CA " "key from '%s':\n", argv0, optarg); if (errno) { fprintf(stderr, "%s\n", strerror(errno)); } else { ERR_print_errors_fp(stderr); } exit(EXIT_FAILURE); } if (!opts->cacrt) { opts->cacrt = ssl_x509_load(optarg); if (opts->cacrt) { ssl_x509_refcount_inc( opts->cacrt); sk_X509_insert(opts->chain, opts->cacrt, 0); } } #ifndef OPENSSL_NO_DH if (!opts->dh) { opts->dh = ssl_dh_load(optarg); } #endif /* !OPENSSL_NO_DH */ break; case 'C': if (ssl_x509chain_load(NULL, &opts->chain, optarg) == -1) { fprintf(stderr, "%s: error loading " "chain from '%s':\n", argv0, optarg); if (errno) { fprintf(stderr, "%s\n", strerror(errno)); } else { ERR_print_errors_fp(stderr); } exit(EXIT_FAILURE); } break; case 'K': if (opts->key) EVP_PKEY_free(opts->key); opts->key = ssl_key_load(optarg); if (!opts->key) { fprintf(stderr, "%s: error loading lea" "f key from '%s':\n", argv0, optarg); if (errno) { fprintf(stderr, "%s\n", strerror(errno)); } else { ERR_print_errors_fp(stderr); } exit(EXIT_FAILURE); } #ifndef OPENSSL_NO_DH if (!opts->dh) { opts->dh = ssl_dh_load(optarg); } #endif /* !OPENSSL_NO_DH */ break; case 't': if (!sys_isdir(optarg)) { fprintf(stderr, "%s: '%s' is not a " "directory\n", argv0, optarg); exit(EXIT_FAILURE); } if (opts->tgcrtdir) free(opts->tgcrtdir); opts->tgcrtdir = strdup(optarg); break; case 'O': opts->deny_ocsp = 1; break; case 'P': opts->passthrough = 1; break; #ifndef OPENSSL_NO_DH case 'g': if (opts->dh) DH_free(opts->dh); opts->dh = ssl_dh_load(optarg); if (!opts->dh) { fprintf(stderr, "%s: error loading DH " "params from '%s':\n", argv0, optarg); if (errno) { fprintf(stderr, "%s\n", strerror(errno)); } else { ERR_print_errors_fp(stderr); } exit(EXIT_FAILURE); } break; #endif /* !OPENSSL_NO_DH */ #ifndef OPENSSL_NO_ECDH case 'G': { EC_KEY *ec; if (opts->ecdhcurve) free(opts->ecdhcurve); if (!(ec = ssl_ec_by_name(optarg))) { fprintf(stderr, "%s: unknown curve " "'%s'\n", argv0, optarg); exit(EXIT_FAILURE); } EC_KEY_free(ec); opts->ecdhcurve = strdup(optarg); break; } #endif /* !OPENSSL_NO_ECDH */ #ifdef SSL_OP_NO_COMPRESSION case 'Z': opts->sslcomp = 0; break; #endif /* SSL_OP_NO_COMPRESSION */ case 's': if (opts->ciphers) free(opts->ciphers); opts->ciphers = strdup(optarg); break; case 'e': free(natengine); natengine = strdup(optarg); break; case 'E': nat_list_engines(); exit(EXIT_SUCCESS); break; case 'u': if (opts->dropuser) free(opts->dropuser); opts->dropuser = strdup(optarg); break; case 'p': if (opts->pidfile) free(opts->pidfile); opts->pidfile = strdup(optarg); break; case 'j': if (opts->jaildir) free(opts->jaildir); opts->jaildir = strdup(optarg); break; case 'l': if (opts->connectlog) free(opts->connectlog); opts->connectlog = strdup(optarg); break; case 'L': if (opts->contentlog) free(opts->contentlog); opts->contentlog = strdup(optarg); opts->contentlogdir = 0; break; case 'S': if (opts->contentlog) free(opts->contentlog); opts->contentlog = strdup(optarg); opts->contentlogdir = 1; break; case 'd': opts->detach = 1; break; case 'D': log_dbg_mode(LOG_DBG_MODE_ERRLOG); opts->debug = 1; break; case 'V': main_version(); exit(EXIT_SUCCESS); case 'h': main_usage(); exit(EXIT_SUCCESS); case '?': exit(EXIT_FAILURE); default: main_usage(); exit(EXIT_FAILURE); } } argc -= optind; argv += optind; opts->spec = proxyspec_parse(&argc, &argv, natengine); /* usage checks */ if (opts->detach && OPTS_DEBUG(opts)) { fprintf(stderr, "%s: -d and -D are mutually exclusive.\n", argv0); exit(EXIT_FAILURE); } if (!opts->spec) { fprintf(stderr, "%s: no proxyspec specified.\n", argv0); exit(EXIT_FAILURE); } for (proxyspec_t *spec = opts->spec; spec; spec = spec->next) { if (spec->connect_addrlen || spec->sni_port) continue; if (!spec->natengine) { fprintf(stderr, "%s: no supported NAT engines " "on this platform.\n" "Only static addr and SNI proxyspecs " "supported.\n", argv0); exit(EXIT_FAILURE); } if (spec->listen_addr.ss_family == AF_INET6 && !nat_ipv6ready(spec->natengine)) { fprintf(stderr, "%s: IPv6 not supported by '%s'\n", argv0, spec->natengine); exit(EXIT_FAILURE); } spec->natlookup = nat_getlookupcb(spec->natengine); spec->natsocket = nat_getsocketcb(spec->natengine); } if (opts_has_ssl_spec(opts)) { if ((opts->cacrt || !opts->tgcrtdir) && !opts->cakey) { fprintf(stderr, "%s: no CA key specified (-k).\n", argv0); exit(EXIT_FAILURE); } if (opts->cakey && !opts->cacrt) { fprintf(stderr, "%s: no CA cert specified (-c).\n", argv0); exit(EXIT_FAILURE); } if (opts->cakey && opts->cacrt && (X509_check_private_key(opts->cacrt, opts->cakey) != 1)) { fprintf(stderr, "%s: CA cert does not match key.\n", argv0); ERR_print_errors_fp(stderr); exit(EXIT_FAILURE); } } /* prevent multiple instances running */ if (opts->pidfile) { pidfd = sys_pidf_open(opts->pidfile); if (pidfd == -1) { fprintf(stderr, "%s: cannot open PID file '%s' " "- process already running?\n", argv0, opts->pidfile); exit(EXIT_FAILURE); } } /* dynamic defaults */ if (!opts->ciphers) { opts->ciphers = strdup("ALL:-aNULL"); if (!opts->ciphers) { fprintf(stderr, "%s: out of memory.\n", argv0); exit(EXIT_FAILURE); } } if (!opts->jaildir && (geteuid() == 0) && !opts->contentlogdir) { opts->jaildir = strdup("/var/empty"); } if (!opts->dropuser && !geteuid() && !getuid() && !opts->contentlogdir) { opts->dropuser = strdup("nobody"); } if (opts_has_ssl_spec(opts) && !opts->key) { opts->key = ssl_key_genrsa(1024); if (!opts->key) { fprintf(stderr, "%s: error generating RSA key:\n", argv0); ERR_print_errors_fp(stderr); exit(EXIT_FAILURE); } if (OPTS_DEBUG(opts)) { log_dbg_printf("Generated RSA key for leaf certs.\n"); } } /* debugging */ if (OPTS_DEBUG(opts)) { main_version(); log_dbg_printf("proxyspecs:\n"); for (proxyspec_t *spec = opts->spec; spec; spec = spec->next) { char *lbuf, *cbuf = NULL; lbuf = sys_sockaddr_str((struct sockaddr *) &spec->listen_addr, spec->listen_addrlen); if (spec->connect_addrlen) { cbuf = sys_sockaddr_str((struct sockaddr *) &spec->connect_addr, spec->connect_addrlen); } if (spec->sni_port) { asprintf(&cbuf, "sni %i", spec->sni_port); } log_dbg_printf("- %s %s %s %s\n", lbuf, (spec->ssl ? "ssl" : "tcp"), (spec->http ? "http" : "plain"), (spec->natengine ? spec->natengine : cbuf)); if (lbuf) free(lbuf); if (cbuf) free(cbuf); } if (opts->cacrt) { char *subj = ssl_x509_subject(opts->cacrt); log_dbg_printf("Loaded CA: '%s'\n", subj); free(subj); #ifdef DEBUG_CERTIFICATE log_dbg_print_free(ssl_x509_to_str(opts->cacrt)); log_dbg_print_free(ssl_x509_to_pem(opts->cacrt)); #endif /* DEBUG_CERTIFICATE */ } else { log_dbg_printf("No CA loaded.\n"); } } /* * Initialize as much as possible before daemon() in order to be * able to provide direct feedback to the user when failing. */ if (cachemgr_preinit() == -1) { fprintf(stderr, "%s: failed to preinit cachemgr.\n", argv0); exit(EXIT_FAILURE); } if (log_preinit(opts) == -1) { fprintf(stderr, "%s: failed to preinit logging.\n", argv0); exit(EXIT_FAILURE); } if (nat_preinit() == -1) { fprintf(stderr, "%s: failed to preinit NAT lookup.\n", argv0); exit(EXIT_FAILURE); } /* Bind listeners before dropping privileges */ proxy_ctx_t *proxy = proxy_new(opts); if (!proxy) { fprintf(stderr, "%s: failed to initialize proxy.\n", argv0); exit(EXIT_FAILURE); } /* Drop privs, chroot, detach from TTY */ if (sys_privdrop(opts->dropuser, opts->jaildir) == -1) { fprintf(stderr, "%s: failed to drop privileges: %s\n", argv0, strerror(errno)); exit(EXIT_FAILURE); } if (opts->detach) { if (OPTS_DEBUG(opts)) { log_dbg_printf("Detaching from TTY, see syslog for " "errors after this point\n"); } if (daemon(1, 0) == -1) { fprintf(stderr, "%s: failed to detach from TTY: %s\n", argv0, strerror(errno)); exit(EXIT_FAILURE); } log_err_mode(LOG_ERR_MODE_SYSLOG); ssl_reinit(); } /* Post-privdrop/chroot/detach initialization, thread spawning */ if (log_init(opts) == -1) { fprintf(stderr, "%s: failed to init log facility.\n", argv0); goto out_log_failed; } if (opts->pidfile && (sys_pidf_write(pidfd) == -1)) { log_err_printf("Failed to write PID to PID file '%s': %s\n", opts->pidfile, strerror(errno)); goto out_pidwrite_failed; } if (cachemgr_init() == -1) { log_err_printf("Failed to init cache manager.\n"); goto out_cachemgr_failed; } if (nat_init() == -1) { log_err_printf("Failed to init NAT state table lookup.\n"); goto out_nat_failed; } if (opts->tgcrtdir) { sys_dir_eachfile(opts->tgcrtdir, main_loadtgcrt, opts); } rv = EXIT_SUCCESS; proxy_run(proxy); proxy_free(proxy); nat_fini(); out_nat_failed: cachemgr_fini(); out_cachemgr_failed: if (opts->pidfile) { sys_pidf_close(pidfd, opts->pidfile); } out_pidwrite_failed: log_fini(); out_log_failed: opts_free(opts); ssl_fini(); return rv; }
struct obj_conf *conf_init( int argc, char **argv ) { struct obj_conf *conf = (struct obj_conf *) myalloc( sizeof(struct obj_conf) ); BEN *opts = opts_init(); BEN *value = NULL; /* Parse command line */ opts_load( opts, argc, argv ); /* Mode */ if( ben_searchDictStr( opts, "-d" ) != NULL ) { conf->mode = CONF_DAEMON; } else { conf->mode = CONF_CONSOLE; } /* Verbosity */ if( ben_searchDictStr( opts, "-v" ) != NULL ) { conf->verbosity = CONF_VERBOSE; } else if ( ben_searchDictStr( opts, "-q" ) != NULL ) { conf->verbosity = CONF_BEQUIET; } else { /* Be verbose in the console and quiet while running as a daemon. */ conf->verbosity = ( conf->mode == CONF_CONSOLE ) ? CONF_VERBOSE : CONF_BEQUIET; } /* Port */ value = ben_searchDictStr( opts, "-p" ); if( value != NULL && ben_str_size( value ) >= 1 ) { conf->port = atoi( (char *)value->v.s->s ); } else { conf->port = CONF_PORT; } if( conf->port < CONF_PORTMIN || conf->port > CONF_PORTMAX ) { conf->port = CONF_PORT; } /* Cores */ conf->cores = ( unix_cpus() > 2 ) ? unix_cpus() : CONF_CORES; if( conf->cores < 1 || conf->cores > 128 ) { fail( "Invalid number of CPU cores" ); } /* HOME */ conf_home( conf, opts ); #ifdef TUMBLEWEED /* HTML index */ value = ben_searchDictStr( opts, "-i" ); if( value != NULL && ben_str_size( value ) >= 1 ) { snprintf( conf->file, BUF_SIZE, "%s", (char *)value->v.s->s ); } else { snprintf( conf->file, BUF_SIZE, "%s", CONF_INDEX_NAME ); } if( !str_isValidFilename( conf->file ) ) { fail( "Index %s looks suspicious", conf->file ); } #endif #ifdef TORRENTKINO /* Hostname */ conf_hostname( conf, opts ); /* Realm */ value = ben_searchDictStr( opts, "-r" ); if( value != NULL && ben_str_size( value ) >= 1 ) { snprintf( conf->realm, BUF_SIZE, "%s", (char *)value->v.s->s ); conf->bool_realm = TRUE; } else { snprintf( conf->realm, BUF_SIZE, "%s", CONF_REALM ); conf->bool_realm = FALSE; } /* Compute host_id. Respect the realm. */ conf_hostid( conf->host_id, conf->hostname, conf->realm, conf->bool_realm ); /* Announce this port */ value = ben_searchDictStr( opts, "-b" ); if( value != NULL && ben_str_size( value ) >= 1 ) { conf->announce_port = atoi( (char *)value->v.s->s ); } else { conf->announce_port = CONF_ANNOUNCED_PORT; } if( conf->announce_port < CONF_PORTMIN || conf->announce_port > CONF_PORTMAX ) { fail( "Invalid announce port number. (-a)" ); } if( getuid() == 0 ) { snprintf( conf->file, BUF_SIZE, "%s/%s", conf->home, CONF_FILE ); } else { snprintf( conf->file, BUF_SIZE, "%s/.%s", conf->home, CONF_FILE ); } /* Node ID */ value = ben_searchDictStr( opts, "-n" ); if( value != NULL && ben_str_size( value ) >= 1 ) { sha1_hash( conf->node_id, (char *)value->v.s->s, ben_str_size( value ) ); } else { rand_urandom( conf->node_id, SHA1_SIZE ); } memset( conf->null_id, '\0', SHA1_SIZE ); /* Bootstrap node */ value = ben_searchDictStr( opts, "-x" ); if( value != NULL && ben_str_size( value ) >= 1 ) { snprintf( conf->bootstrap_node, BUF_SIZE, "%s", (char *)value->v.s->s ); } else { snprintf( conf->bootstrap_node, BUF_SIZE, "%s", CONF_MULTICAST ); } /* Bootstrap port */ value = ben_searchDictStr( opts, "-y" ); if( value != NULL && ben_str_size( value ) >= 1 ) { snprintf( conf->bootstrap_port, CONF_PORT_SIZE+1, "%s", value->v.s->s ); } else { snprintf( conf->bootstrap_port, CONF_PORT_SIZE+1, "%i", CONF_PORT ); } if( str_isSafePort( conf->bootstrap_port) < 0 ) { fail( "Invalid bootstrap port number. (-y)" ); } #ifdef POLARSSL /* Secret key */ value = ben_searchDictStr( opts, "-k" ); if( value != NULL && ben_str_size( value ) >= 1 ) { snprintf( conf->key, BUF_SIZE, "%s", (char *)value->v.s->s ); conf->bool_encryption = TRUE; } else { memset( conf->key, '\0', BUF_SIZE ); conf->bool_encryption = FALSE; } #endif #endif opts_free( opts ); return conf; }
static void handle_args(int argc, char **argv) { char opt = 0; int longind = 0; int outcount = 0; char **hdata = NULL; char *c_file = NULL; static const char *optstring = "ho:"; static const struct option longopts[] = { {"help", no_argument, NULL, 0}, {"version", no_argument, NULL, 0}, }; opts.c_fname = NULL; opts.asm_fname = NULL; opts.asm_name_spec = 0; opts.c_fcount = 0; opt = getopt_long(argc, argv, optstring, longopts, &longind); while (opt != -1) { switch (opt) { case 'o': if (outcount == 0) { opts.asm_name_spec = 1; opts.asm_fname = optarg; outcount++; } else { error("output file name already defined"); exit(EXIT_FAILURE); } break; case 'h': display_usage(); exit(EXIT_FAILURE); break; case '?': suggest_help(); exit(EXIT_FAILURE); case 0: if (strcmp("help", longopts[longind].name) == 0) { display_usage(); exit(EXIT_FAILURE); } else if (strcmp("version", longopts[longind].name) == 0) { display_version(); exit(EXIT_FAILURE); } break; } opt = getopt_long(argc, argv, optstring, longopts, &longind); } if (optind == argc) { error("no input files specified"); suggest_help(); exit(EXIT_FAILURE); } else { while (optind < argc) { hdata = realloc(opts.c_fname, sizeof (char*) * (opts.c_fcount + 1)); if (hdata == NULL) { error("memory error."); opts_free(); exit(EXIT_FAILURE); } opts.c_fname = hdata; opts.c_fname[opts.c_fcount] = malloc(sizeof (char) * strlen(argv[optind]) + 1); if (opts.c_fname[opts.c_fcount] == NULL) { error("memory error."); opts_free(); exit(EXIT_FAILURE); } strcpy(opts.c_fname[opts.c_fcount], argv[optind]); opts.c_fcount++; optind++; } } if (opts.asm_name_spec == 0) { opts.asm_fname = defout; } }
/*--------------------------------------------------------- */ int main(int argc, char **argv) { int retval = -1; struct options *opts = NULL; int pidfd = -1; unsigned int interval; /* Signal vars */ struct sigaction sig_act; sigset_t sig_set; /* IRQ list. It contain all found IRQs. */ lub_list_t *irqs; /* IRQs need to be balanced */ lub_list_t *balance_irqs; /* CPU list. It contain all found CPUs. */ lub_list_t *cpus; /* NUMA list. It contain all found NUMA nodes. */ lub_list_t *numas; /* Proximity list. */ lub_list_t *pxms; /* Parse command line options */ opts = opts_init(); if (opts_parse(argc, argv, opts)) goto err; /* Initialize syslog */ openlog(argv[0], LOG_CONS, opts->log_facility); syslog(LOG_ERR, "Start daemon.\n"); /* Fork the daemon */ if (!opts->debug) { /* Daemonize */ if (daemon(0, 0) < 0) { syslog(LOG_ERR, "Can't daemonize\n"); goto err; } /* Write pidfile */ if ((pidfd = open(opts->pidfile, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < 0) { syslog(LOG_WARNING, "Can't open pidfile %s: %s", opts->pidfile, strerror(errno)); } else { char str[20]; snprintf(str, sizeof(str), "%u\n", getpid()); str[sizeof(str) - 1] = '\0'; if (write(pidfd, str, strlen(str)) < 0) syslog(LOG_WARNING, "Can't write to %s: %s", opts->pidfile, strerror(errno)); close(pidfd); } } /* Set signal handler */ sigemptyset(&sig_set); sigaddset(&sig_set, SIGTERM); sigaddset(&sig_set, SIGINT); sigaddset(&sig_set, SIGQUIT); sig_act.sa_flags = 0; sig_act.sa_mask = sig_set; sig_act.sa_handler = &sighandler; sigaction(SIGTERM, &sig_act, NULL); sigaction(SIGINT, &sig_act, NULL); sigaction(SIGQUIT, &sig_act, NULL); /* Randomize */ srand(time(NULL)); /* Scan NUMA nodes */ numas = lub_list_new(numa_list_compare); scan_numas(numas); if (opts->verbose) show_numas(numas); /* Scan CPUs */ cpus = lub_list_new(cpu_list_compare); scan_cpus(cpus, opts->ht); if (opts->verbose) show_cpus(cpus); /* Prepare data structures */ irqs = lub_list_new(irq_list_compare); balance_irqs = lub_list_new(irq_list_compare); /* Parse proximity file */ pxms = lub_list_new(NULL); if (opts->pxm) parse_pxm_config(opts->pxm, pxms, numas); if (opts->verbose) show_pxms(pxms); /* Main loop */ while (!sigterm) { lub_list_node_t *node; char outstr[10]; time_t t; struct tm *tmp; t = time(NULL); tmp = localtime(&t); if (tmp) { strftime(outstr, sizeof(outstr), "%H:%M:%S", tmp); printf("----[ %s ]----------------------------------------------------------------\n", outstr); } /* Rescan PCI devices for new IRQs. */ scan_irqs(irqs, balance_irqs, pxms); if (opts->verbose) irq_list_show(irqs); /* Link IRQs to CPUs due to real current smp affinity. */ link_irqs_to_cpus(cpus, irqs); /* Gather statistics on CPU load and number of interrupts. */ gather_statistics(cpus, irqs); show_statistics(cpus, opts->verbose); /* Choose IRQ to move to another CPU. */ choose_irqs_to_move(cpus, balance_irqs, opts->threshold, opts->strategy); /* If nothing to balance */ if (lub_list_len(balance_irqs) != 0) { /* Set short interval to make balancing faster. */ interval = opts->short_interval; /* Choose new CPU for IRQs need to be balanced. */ balance(cpus, balance_irqs, opts->threshold); /* Write new values to /proc/irq/<IRQ>/smp_affinity */ apply_affinity(balance_irqs); /* Free list of balanced IRQs */ while ((node = lub_list__get_tail(balance_irqs))) { lub_list_del(balance_irqs, node); lub_list_node_free(node); } } else { /* If nothing to balance */ interval = opts->long_interval; } /* Wait before next iteration */ sleep(interval); } /* Free data structures */ irq_list_free(irqs); lub_list_free(balance_irqs); cpu_list_free(cpus); numa_list_free(numas); pxm_list_free(pxms); retval = 0; err: /* Remove pidfile */ if (pidfd >= 0) { if (unlink(opts->pidfile) < 0) { syslog(LOG_ERR, "Can't remove pid-file %s: %s\n", opts->pidfile, strerror(errno)); } } /* Free command line options */ opts_free(opts); syslog(LOG_ERR, "Stop daemon.\n"); return retval; }