/** * Bail.... */ static void error_exit( /* RETURN: nothing */ const char *format, /* IN: msg format */ ...) /* IN: varadic args */ { char buffer[4096]; va_list ap; va_start(ap, format); vsnprintf(buffer, sizeof(buffer), format, ap); va_end(ap); #ifndef NO_DAEMON if (params->detached!=0) { unlink(params->pid_file); syslog(LOG_INFO, "%s: %s", params->daemon, buffer); } else #endif { fprintf(stderr, "%s: %s\n", params->daemon, buffer); if (0 !=(params->setup & RUN_AS_APP) && 0 != handle) { if (havege_status_dump(handle, H_SD_TOPIC_TEST, buffer, sizeof(buffer))>0) fprintf(stderr, "%s\n", buffer); if (havege_status_dump(handle, H_SD_TOPIC_SUM, buffer, sizeof(buffer))>0) fprintf(stderr, "%s\n", buffer); } } havege_destroy(handle); exit(params->exit_code); }
int main(void) { int rc; H_UINT* buf; H_PARAMS havege_parameters; H_PTR havege_state = NULL; const int status_buf_size = 8192; char status_buf[status_buf_size]; int i, size; memset(&havege_parameters, 0, sizeof(H_PARAMS)); //havege_parameters.msg_out = print_msg; havege_state = havege_create(&havege_parameters); buf = havege_state->io_buf; size = havege_state->i_readSz /sizeof(H_UINT); rc = havege_state==NULL? H_NOHANDLE : havege_state->error; switch(rc) { case H_NOERR: fprintf(stderr, "havege_create: buffer size is %d\n", havege_state->i_readSz); break; case H_NOTESTSPEC: fprintf(stderr, "ERROR: havege_create: unrecognized test setup: %s", havege_parameters.testSpec); break; default: fprintf(stderr, "ERROR: havege_create has returned %d\n",rc); return 1; } rc = havege_run(havege_state); if ( rc ) { fprintf(stderr, "ERROR: havege_create has returned %d\n", havege_state->error); return 1; } if ( my_status_dump(havege_state, status_buf, status_buf_size) > 0 ) fprintf(stderr,"%s\n", status_buf); for (i=0;i<1024;i++) { rc = havege_rng(havege_state, buf, size); if ( rc != (int) size ) { fprintf(stderr, "ERROR: havege_rng has returned %d\n", havege_state->error); return 1; } rc = fwrite(buf, 1, size, stdout); if ( rc < size ) { fprintf(stderr, "ERROR: fwrite\n"); return 1; } } if ( my_status_dump(havege_state, status_buf, status_buf_size) > 0 ) fprintf(stderr,"%s\n", status_buf); havege_destroy(havege_state); return 0; }
/** * Entry point */ int main(int argc, char **argv) { static const char* cmds[] = { "b", "buffer", "1", SETTINGR("Buffer size [KW], default: ",COLLECT_BUFSIZE), "d", "data", "1", SETTINGR("Data cache size [KB], with fallback to: ", GENERIC_DCACHE ), "i", "inst", "1", SETTINGR("Instruction cache size [KB], with fallback to: ", GENERIC_ICACHE), "f", "file", "1", "Sample output file, default: '" OUTPUT_DEFAULT "', '-' for stdout", "F", "Foreground", "0", "Run daemon in foreground", "r", "run", "1", "0=daemon, 1=config info, >1=<r>KB sample", "n", "number", "1", "Output size in [k|m|g|t] bytes, 0 = unlimited to stdout", "o", "onlinetest", "1", "[t<x>][c<x>] x=[a[n][w]][b[w]] 't'ot, 'c'ontinuous, default: ta8b", "p", "pidfile", "1", "daemon pidfile, default: " PID_DEFAULT , "s", "source", "1", "Injection source file, default: '" INPUT_DEFAULT "', '-' for stdin", "t", "threads", "1", "Number of threads", "v", "verbose", "1", "Verbose mask 0=none,1=summary,2=retries,4=timing,8=loop,16=code,32=test", "w", "write", "1", "Set write_wakeup_threshold [bits]", "h", "help", "0", "This help" }; static int nopts = sizeof(cmds)/(4*sizeof(char *)); struct option long_options[nopts+1]; char short_options[1+nopts*2]; int c,i,j; H_UINT bufct, bufrem, ierr; H_PARAMS cmd; if (havege_version(HAVEGE_PREP_VERSION)==NULL) error_exit("version conflict %s!=%s", HAVEGE_PREP_VERSION, havege_version(NULL)); #if NO_DAEMON==1 params->setup |= RUN_AS_APP; #endif #ifdef RAW_IN_ENABLE #define DIAG_USAGE2 SETTINGL("=inject ticks,", DIAG_RUN_INJECT)\ SETTINGL("=inject data", DIAG_RUN_TEST) params->setup |= INJECT | RUN_AS_APP; #else #define DIAG_USAGE2 "" #endif #ifdef RAW_OUT_ENABLE #define DIAG_USAGE1 SETTINGL("=capture,", DIAG_RUN_CAPTURE) params->setup |= CAPTURE | RUN_AS_APP; #else #define DIAG_USAGE1 "" #endif #if NUMBER_CORES>1 params->setup |= MULTI_CORE; #endif #ifdef SIGHUP signal(SIGHUP, tidy_exit); #endif signal(SIGINT, tidy_exit); signal(SIGTERM, tidy_exit); strcpy(short_options,""); bufct = bufrem = 0; /** * Build options */ for(i=j=0;j<(nopts*4);j+=4) { switch(cmds[j][0]) { case 'o': #ifdef ONLINE_TESTS_ENABLE break; #else continue; #endif case 'r': #if defined(RAW_IN_ENABLE) || defined (RAW_OUT_ENABLE) if (0!=(params->setup & (INJECT|CAPTURE))) { params->daemon = "havege_diagnostic"; cmds[j+3] = "run level, 0=diagnostic off,1=config info," DIAG_USAGE1 DIAG_USAGE2 ; } else #endif if (0!=(params->setup & RUN_AS_APP)) continue; break; case 's': if (0 == (params->setup & INJECT)) continue; break; case 't': if (0 == (params->setup & MULTI_CORE)) continue; break; case 'p': case 'w': case 'F': if (0 !=(params->setup & RUN_AS_APP)) continue; break; } long_options[i].name = cmds[j+1]; long_options[i].has_arg = atoi(cmds[j+2]); long_options[i].flag = NULL; long_options[i].val = cmds[j][0]; strcat(short_options,cmds[j]); if (long_options[i].has_arg!=0) strcat(short_options,":"); i += 1; } memset(&long_options[i], 0, sizeof(struct option)); do { c = getopt_long (argc, argv, short_options, long_options, NULL); switch(c) { case 'F': params->setup |= RUN_IN_FG; params->foreground = 1; break; case 'b': params->buffersz = ATOU(optarg) * 1024; if (params->buffersz<4) error_exit("invalid size %s", optarg); break; case 'd': params->d_cache = ATOU(optarg); break; case 'i': params->i_cache = ATOU(optarg); break; case 'f': params->sample_out = optarg; if (strcmp(optarg,"-") == 0 ) params->setup |= USE_STDOUT; break; case 'n': if (get_runsize(&bufct, &bufrem, optarg)) error_exit("invalid count: %s", optarg); params->setup |= RUN_AS_APP|RANGE_SPEC; if (bufct==0 && bufrem==0) params->setup |= USE_STDOUT; /* ugly but documented behavior! */ break; case 'o': params->tests_config = optarg; break; case 'p': params->pid_file = optarg; break; case 'r': params->run_level = ATOU(optarg); if (params->run_level != 0) params->setup |= RUN_AS_APP; break; case 's': params->sample_in = optarg; break; case 't': params->ncores = ATOU(optarg); if (params->ncores > NUMBER_CORES) error_exit("invalid thread count: %s", optarg); break; case 'v': params->verbose = ATOU(optarg); break; case 'w': params->setup |= SET_LWM; params->low_water = ATOU(optarg); break; case '?': case 'h': usage(0, nopts, long_options, cmds); case -1: break; } } while (c!=-1); if (params->tests_config == 0) params->tests_config = (0 != (params->setup & RUN_AS_APP))? TESTS_DEFAULT_APP : TESTS_DEFAULT_RUN; memset(&cmd, 0, sizeof(H_PARAMS)); cmd.collectSize = params->buffersz; cmd.icacheSize = params->i_cache; cmd.dcacheSize = params->d_cache; cmd.options = params->verbose & 0xff; cmd.nCores = params->ncores; cmd.testSpec = params->tests_config; cmd.msg_out = print_msg; if (0 != (params->setup & RUN_AS_APP)) { cmd.ioSz = APP_BUFF_SIZE * sizeof(H_UINT); if (params->verbose!=0 && 0==(params->setup & RANGE_SPEC)) params->run_level = 1; } #ifndef NO_DAEMON else { poolSize = get_poolsize(); i = (poolSize + 7)/8 * sizeof(H_UINT); cmd.ioSz = sizeof(struct rand_pool_info) + i *sizeof(H_UINT); } #endif if (0 != (params->verbose & H_DEBUG_TIME)) cmd.metering = show_meterInfo; if (0 !=(params->setup & CAPTURE) && 0 != (params->run_level == DIAG_RUN_CAPTURE)) cmd.options |= H_DEBUG_RAW_OUT; #ifdef RAW_IN_ENABLE if (0 !=(params->setup & INJECT) && 0 != (params->run_level & (DIAG_RUN_INJECT|DIAG_RUN_TEST))) { if (strcmp(params->sample_in,"-") == 0 ) fd_in = stdin; else fd_in = fopen(params->sample_in, "rb"); if (NULL == fd_in) error_exit("Unable to open: %s", params->sample_in); cmd.injection = injectFile; if (params->run_level==DIAG_RUN_INJECT) cmd.options |= H_DEBUG_RAW_IN; else if (params->run_level==DIAG_RUN_TEST) cmd.options |= H_DEBUG_TEST_IN; else usage(1, nopts, long_options, cmds); } #endif handle = havege_create(&cmd); ierr = handle==NULL? H_NOHANDLE : handle->error; switch(ierr) { case H_NOERR: break; case H_NOTESTSPEC: error_exit("unrecognized test setup: %s", cmd.testSpec); break; default: error_exit("Couldn't initialize haveged (%d)", ierr); } if (0 != (params->setup & RUN_AS_APP)) { if (params->run_level==1) anchor_info(handle); else if (0==(params->setup&(INJECT|CAPTURE))) { /* must specify range with --nunber or --run > 1 but not both */ if (params->run_level>1) { if (0==(params->setup&RANGE_SPEC)) { /* --run specified */ bufct = params->run_level/sizeof(H_UINT); bufrem = (params->run_level%sizeof(H_UINT))*1024; } else usage(2, nopts, long_options, cmds); /* both specified */ } else if (0==(params->setup&RANGE_SPEC)) usage(3,nopts, long_options, cmds); /* neither specified */ else if (0==(params->setup&USE_STDOUT)&&(bufct+bufrem)==0) usage(4, nopts, long_options, cmds); /* only with stdout */ run_app(handle, bufct, bufrem); } else if (0==(params->setup&USE_STDOUT)&&(bufct+bufrem)==0) usage(5, nopts, long_options, cmds); /* only with stdout */ else run_app(handle, bufct, bufrem); } #ifndef NO_DAEMON else run_daemon(handle); #endif havege_destroy(handle); exit(0); }