Esempio n. 1
0
static void usage()
{
  version_print();
  printf("(Multicasts All-Kinds of Updating Operation for Servers on Administered Network)\n\n");
  printf("usage: makuosan [OPTION]\n");
  printf("  -d num       # loglevel(0-9)\n");
  printf("  -u uid       # user\n");
  printf("  -g gid       # group\n");
  printf("  -G gid,..    # groups\n");
  printf("  -b dir       # base dir\n");
  printf("  -p port      # port number       (default: 5000)\n");
  printf("  -m addr      # multicast address (default: 224.0.0.108)\n");
  printf("  -i addr      # interface address (default: 0.0.0.0)\n");
  printf("  -l addr      # listen address    (default: 127.0.0.1)\n");
  printf("  -U path      # unix domain socket\n");
  printf("  -k file      # key file (encrypt password)\n");
  printf("  -K file      # key file (console password)\n");
  printf("  -f num       # parallel send count(default: 5) \n");
  printf("  -R num       # recv buffer size [bytes]\n");
  printf("  -S num       # send buffer size [bytes]\n");
  printf("  -T num       # traffic rate     [Mbps]\n");
  printf("  -n           # don't fork\n");
  printf("  -r           # don't recv\n");
  printf("  -s           # don't send\n");
  printf("  -o           # don't listen (console off mode)\n");
  printf("  -O           # owner match limitation mode\n");
  printf("  -c --chroot  # chroot to base dir\n");
  printf("  -C --core    # enable core\n");
  printf("  -V --version # version\n"); 
  printf("  -h --help    # help\n\n"); 
  exit(0);
}
Esempio n. 2
0
static void
dump_drcov_data(void *drcontext, per_thread_t *data)
{
    if (data->log == INVALID_FILE) {
        /* It is possible that failure on log file creation is caused by the
         * running process not having enough privilege, so this is not a
         * release-build fatal error
         */
        ASSERT(false, "invalid log file");
        return;
    }
    version_print(data->log);
    drmodtrack_dump(data->log);
    bb_table_print(drcontext, data);
}
Esempio n. 3
0
int main(int argc, char* argv[])
{
	yyscan_t scanner;
	FILE* file;
	
	version_print(bautofree(bfromcstr("Preprocessor")));
	file = fopen(argv[1], "r");
	assert(file != NULL);
	ppfind_add_autopath(bautofree(bfromcstr(argv[1])));
	pp_yylex_init(&scanner);
	pp_yyset_out(stdout, scanner);
	pp_yyset_in(file, scanner);
	pp_yyparse(scanner);
	pp_yylex_destroy(scanner);
	return 0;
}
Esempio n. 4
0
int main(int argc, char* argv[])
{
    // Define our variables.
    FILE* load;
    uint16_t flash[0x10000];
    char leading[0x100];
    unsigned int i;
    bool uread = true;
    vm_t* vm;
    int nerrors;
    bstring ss, st;
    host_context_t* dtemu = malloc(sizeof(host_context_t));
    const char* warnprefix = "no-";

    // Define arguments.
    struct arg_lit* show_help = arg_lit0("h", "help", "Show this help.");
    struct arg_file* input_file = arg_file1(NULL, NULL, "<file>", "The input file, or - to read from standard input.");
    struct arg_file* execution_dump_file = arg_file0("e", "execution-dump", "<file>", "Produce a very large execution dump file.");
    struct arg_lit* debug_mode = arg_lit0("d", "debug", "Show each executed instruction.");
    struct arg_lit* terminate_mode = arg_lit0("t", "show-on-terminate", "Show state of machine when program is terminated.");
    struct arg_lit* headless_mode = arg_lit0("h", "headless", "Run machine witout displaying monitor and SPED output");
    struct arg_lit* legacy_mode = arg_lit0("l", "legacy", "Automatically initialize hardware to legacy values.");
    struct arg_str* warning_policies = arg_strn("W", NULL, "policy", 0, _WARN_COUNT * 2 + 10, "Modify warning policies.");
    struct arg_lit* little_endian_mode = arg_lit0(NULL, "little-endian", "Use little endian serialization (for compatibility with older versions).");
    struct arg_lit* verbose = arg_litn("v", NULL, 0, LEVEL_EVERYTHING - LEVEL_DEFAULT, "Increase verbosity.");
    struct arg_lit* quiet = arg_litn("q", NULL,  0, LEVEL_DEFAULT - LEVEL_SILENT, "Decrease verbosity.");
    struct arg_int* radiation = arg_intn("r", NULL, "<n>", 0, 1, "Radiation factor (higher is less radiation)");
    struct arg_lit* catch_fire = arg_lit0("c", "catch-fire", "The virtual machine should catch fire instead of halting.");
    struct arg_end* end = arg_end(20);
    void* argtable[] = { input_file, warning_policies, debug_mode, execution_dump_file, terminate_mode, headless_mode, legacy_mode, little_endian_mode, radiation, catch_fire, verbose, quiet, end };

    // Parse arguments.
    nerrors = arg_parse(argc, argv, argtable);

    if (nerrors != 0 || show_help->count != 0)
    {
        if (show_help->count != 0)
            arg_print_errors(stdout, end, "emulator");

        printd(LEVEL_DEFAULT, "syntax:\n    dtemu");
        arg_print_syntax(stderr, argtable, "\n");
        printd(LEVEL_DEFAULT, "options:\n");
        arg_print_glossary(stderr, argtable, "      %-25s %s\n");
        arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0]));
        return 1;
    }

    // Set verbosity level.
    debug_setlevel(LEVEL_DEFAULT + verbose->count - quiet->count);
    
    // Show version information.
    version_print(bautofree(bfromcstr("Emulator")));

    // Set global path variable.
    osutil_setarg0(bautofree(bfromcstr(argv[0])));

    // Set endianness.
    isetmode(little_endian_mode->count == 0 ? IMODE_BIG : IMODE_LITTLE);

    // Set up warning policies.
    dsetwarnpolicy(warning_policies);
    
    // Set up error handling.
    if (dsethalt())
    {
        // Handle the error.
        dautohandle();
        printd(LEVEL_ERROR, "emulator: error occurred.\n");

        arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0]));
        return 1;
    }

    // Zero out the flash space.
    for (i = 0; i < 0x10000; i++)
        flash[i] = 0x0;

    // Zero out the leading space.
    for (i = 0; i < 0x100; i++)
        leading[i] = 0x0;

    // Load from either file or stdin.
    if (strcmp(input_file->filename[0], "-") != 0)
    {
        // Open file.
        load = fopen(input_file->filename[0], "rb");

        if (load == NULL)
            dhalt(ERR_EMU_LOAD_FILE_FAILED, input_file->filename[0]);
    }
    else
    {
        // Windows needs stdin in binary mode.
#ifdef _WIN32
        _setmode(_fileno(stdin), _O_BINARY);
#endif

        // Set load to stdin.
        load = stdin;
    }
    
    // Read leading component.
    for (i = 0; i < strlen(ldata_objfmt); i++)
        leading[i] = fgetc(load);
    fseek(load, 0, SEEK_SET);

    // Read up to 0x10000 words.
    for (i = 0; i < 0x10000 && !feof(load); i++)
        iread(&flash[i], load);
    fclose(load);

    // Check to see if the first X bytes matches the header
    // for intermediate code and stop if it does.
    ss = bfromcstr("");
    st = bfromcstr(ldata_objfmt);
    for (i = 0; i < strlen(ldata_objfmt); i++)
        bconchar(ss, leading[i]);
    if (biseq(ss, st))
        dhalt(ERR_INTERMEDIATE_EXECUTION, NULL);

    // Set up the host context.
    glfwInit();
    dtemu->create_context = &dtemu_create_context;
    dtemu->activate_context = &dtemu_activate_context;
    dtemu->swap_buffers = &dtemu_swap_buffers;
    dtemu->destroy_context = &dtemu_destroy_context;
    dtemu->get_ud = &dtemu_get_ud;

    // And then use the VM.
    vm = vm_create();
    vm->debug = (debug_mode->count > 0);
    vm_flash(vm, flash);

    // Set radiation and catch fire settings.
    if (radiation->count == 1)
        vm->radiation_factor = radiation->ival[0];
    if (catch_fire->count == 1)
        vm->can_fire = true;

    // Init hardware.
    vm_hw_clock_init(vm);

    if (headless_mode->count < 1)
        vm->host = dtemu;

    vm_hw_sped3_init(vm);
    vm_hw_lem1802_init(vm);
    vm_hw_m35fd_init(vm);
    vm_hw_lua_init(vm);

    if (legacy_mode->count > 0)
    {
        for (i = 0; i < vm_hw_count(vm); i++) {

            hw_t* device = vm_hw_get_device(vm, i);
            if (device == NULL)
                continue;

            if (device->id == 0x7349F615 && device->manufacturer == 0x1C6C8B36)
            {
                vm_hw_lem1802_mem_set_screen((struct lem1802_hardware*)device->userdata, 0x8000);
                break;
            }
        }
    }

    vm_execute(vm, execution_dump_file->count > 0 ? execution_dump_file->filename[0] : NULL);

    if (terminate_mode->count > 0)
    {
        fprintf(stderr, "\n");
        fprintf(stderr, "A:   0x%04X     [A]:    0x%04X\n", vm->registers[REG_A], vm->ram[vm->registers[REG_A]]);
        fprintf(stderr, "B:   0x%04X     [B]:    0x%04X\n", vm->registers[REG_B], vm->ram[vm->registers[REG_B]]);
        fprintf(stderr, "C:   0x%04X     [C]:    0x%04X\n", vm->registers[REG_C], vm->ram[vm->registers[REG_C]]);
        fprintf(stderr, "X:   0x%04X     [X]:    0x%04X\n", vm->registers[REG_X], vm->ram[vm->registers[REG_X]]);
        fprintf(stderr, "Y:   0x%04X     [Y]:    0x%04X\n", vm->registers[REG_Y], vm->ram[vm->registers[REG_Y]]);
        fprintf(stderr, "Z:   0x%04X     [Z]:    0x%04X\n", vm->registers[REG_Z], vm->ram[vm->registers[REG_Z]]);
        fprintf(stderr, "I:   0x%04X     [I]:    0x%04X\n", vm->registers[REG_I], vm->ram[vm->registers[REG_I]]);
        fprintf(stderr, "J:   0x%04X     [J]:    0x%04X\n", vm->registers[REG_J], vm->ram[vm->registers[REG_J]]);
        fprintf(stderr, "PC:  0x%04X     SP:    0x%04X\n", vm->pc, vm->sp);
        fprintf(stderr, "EX:  0x%04X     IA:    0x%04X\n", vm->ex, vm->ia);
    }

    vm_hw_lua_free(vm);
    vm_free(vm);

    arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0]));
    glfwTerminate();
    return 0;
}
Esempio n. 5
0
int main(int argc, char* argv[])
{
    CURL* curl;
    bstring command;
    bstring name;
    bstring modpath;
    int all;

    // Define arguments.
    struct arg_lit* show_help = arg_lit0("h", "help", "Show this help.");
    struct arg_str* cmdopt = arg_str1(NULL, NULL, "<command>", "The command; either 'search', 'install', 'uninstall', 'enable' or 'disable'.");
    struct arg_str* nameopt = arg_str0(NULL, NULL, "<name>", "The name of the module to search for, install, uninstall, enable or disable.");
    struct arg_lit* all_flag = arg_lit0("a", "all", "Apply this command to all available / installed modules.");
    struct arg_lit* verbose = arg_litn("v", NULL, 0, LEVEL_EVERYTHING - LEVEL_DEFAULT, "Increase verbosity.");
    struct arg_lit* quiet = arg_litn("q", NULL,  0, LEVEL_DEFAULT - LEVEL_SILENT, "Decrease verbosity.");
    struct arg_end* end = arg_end(20);
    void* argtable[] = { show_help, cmdopt, all_flag, nameopt, verbose, quiet, end };

    // Parse arguments.
    int nerrors = arg_parse(argc, argv, argtable);

    if (nerrors != 0 || show_help->count != 0 || (all_flag->count == 0 && nameopt->count == 0))
    {
        if (all_flag->count == 0 && nameopt->count == 0)
            printd(LEVEL_ERROR, "error: must have either module name or -a.");
        if (show_help->count != 0)
            arg_print_errors(stderr, end, "mm");

        fprintf(stderr, "syntax:\n    dtmm");
        arg_print_syntax(stderr, argtable, "\n");
        fprintf(stderr, "options:\n");
        arg_print_glossary(stderr, argtable, "    %-25s %s\n");
        arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0]));
        return 1;
    }

    // Set verbosity level.
    debug_setlevel(LEVEL_DEFAULT + verbose->count - quiet->count);
    
    // Show version information.
    version_print(bautofree(bfromcstr("Module Manager")));

    // Set argument 0 and convert parameters.
    osutil_setarg0(bautofree(bfromcstr(argv[0])));
    command = bfromcstr(cmdopt->sval[0]);
    name = bfromcstr(nameopt->sval[0]);

    // Initialize curl or exit.
    curl = curl_easy_init();
    if (!curl)
    {
        printd(LEVEL_ERROR, "unable to initialize curl.\n");
        return 1;
    }

    // Ensure module path exists.
    modpath = osutil_getmodulepath();
    if (modpath == NULL)
    {
        printd(LEVEL_ERROR, "module path does not exist (searched TOOLCHAIN_MODULES and modules/).\n");
        return 1;
    }
    bdestroy(modpath);

    // Convert all flag.
    all = (all_flag->count > 0);

    // If all is set, set the name back to "".
    if (all)
        bassigncstr(name, "");

    // If the name is "all" or "*", handle this as the all
    // boolean flag.
    if (biseqcstr(name, "all") || biseqcstr(name, "*"))
    {
        bassigncstr(name, "");
        all = 1;
        printd(LEVEL_WARNING, "treating name as -a (all) flag");
    }

    if (biseqcstrcaseless(command, "search") || biseqcstrcaseless(command, "se"))
        return do_search(curl, name, all);
    else if (biseqcstrcaseless(command, "install") || biseqcstrcaseless(command, "in"))
    {
        if (all)
            return do_install_all(curl);
        else
            return do_install(curl, name);
    }
    else if (biseqcstrcaseless(command, "uninstall") || biseqcstrcaseless(command, "rm"))
    {
        if (all)
            return do_uninstall_all(curl);
        else
            return do_uninstall(curl, name);
    }
    else if (biseqcstrcaseless(command, "enable") || biseqcstrcaseless(command, "en"))
    {
        if (all)
            return do_enable_all(curl);
        else
            return do_enable(curl, name);
    }
    else if (biseqcstrcaseless(command, "disable") || biseqcstrcaseless(command, "di") || biseqcstrcaseless(command, "dis"))
    {
        if (all)
            return do_disable_all(curl);
        else
            return do_disable(curl, name);
    }
    else
    {
        printd(LEVEL_ERROR, "unknown command (must be search, install, uninstall, enable or disable).");
        return 1;
    }

    return 0;
}
Esempio n. 6
0
int main(int argc, char* argv[])
{
	// Define arguments.
	struct arg_lit* show_help = arg_lit0("h", "help", "Show this help.");
	struct arg_str* type_assembler = arg_str0("t", NULL, "<type>", "The type of assembler to output for.");
	struct arg_file* input_file = arg_file1(NULL, NULL, "<file>", "The input file (or - to read from standard input).");
	struct arg_file* output_file = arg_file1("o", "output", "<file>", "The output file (or - to send to standard output).");
	struct arg_end* end = arg_end(20);
	void* argtable[] = { output_file, show_help, type_assembler, input_file, end };

	// Parse arguments.
	int nerrors = arg_parse(argc, argv, argtable);

	version_print(bautofree(bfromcstr("Compiler")));
	if (nerrors != 0 || show_help->count != 0)
	{
		if (show_help->count != 0)
			arg_print_errors(stdout, end, "compiler");

		fprintf(stderr, "syntax:\n    compiler");
		arg_print_syntax(stdout, argtable, "\n");
		fprintf(stderr, "options:\n");
		arg_print_glossary(stdout, argtable, "	  %-25s %s\n");
		return 1;
	}

	fprintf(stderr, "Preprocessing...\n");

	// Run the preprocessor.
	ppfind_add_path(bautofree(bfromcstr(".")));
	ppfind_add_path(bautofree(bfromcstr("include")));
	ppfind_add_autopath(bautofree(bfromcstr(input_file->filename[0])));
	bstring pp_result_name = pp_do(bautofree(bfromcstr(input_file->filename[0])));

	if (pp_result_name == NULL)
	{
		fprintf(stderr, "compiler: invalid result returned from preprocessor.\n");
		pp_cleanup(bautofree(pp_result_name));
		return 1;
	}

	fprintf(stderr, "Parsing C...\n");

	// Parse C.
	yyout = stderr;
	yyin = fopen((const char*)(pp_result_name->data), "r");

	if (yyin == NULL)
	{
		pp_cleanup(bautofree(pp_result_name));
		return 1;
	}

	yyparse();

	if (yyin != stdin)
		fclose(yyin);

	pp_cleanup(bautofree(pp_result_name));

	if (program == NULL)
	{
		std::cerr << "An error occurred while compiling." << std::endl;
		return 1;
	}

	// Assembler type.
	const char* asmtype = "dcpu16toolchain";

	if (type_assembler->count > 0)
		asmtype = type_assembler->sval[0];

	// Spacing.
	std::cerr << std::endl;

	fprintf(stderr, "Generating assembly...\n");

	// Generate assembly using the AST.
	try
	{
		AsmGenerator generator(asmtype);
		AsmBlock* block = program->compile(generator);

		if (strcmp(output_file->filename[0], "-") == 0)
		{
			std::cout << generator.m_Preassembly << std::endl;
			std::cout << *block << std::endl;
			std::cout << generator.m_Postassembly << std::endl;
		}
		else
		{
			std::ofstream output(output_file->filename[0], std::ios::out | std::ios::trunc);
			output << generator.m_Preassembly << std::endl;
			output << *block << std::endl;
			output << generator.m_Postassembly << std::endl;
			output.close();
		}

		delete block;
	}
	catch (CompilerException* ex)
	{
		std::string msg = ex->getMessage();
		std::cerr << "An error occurred while compiling." << std::endl;
		std::cerr << msg << std::endl;
		return 1;
	}

	return 0;
}
Esempio n. 7
0
int main(int argc, char* argv[])
{
	// Define our variables.
	FILE* load;
	uint16_t flash[0x10000];
	char leading[0x100];
	unsigned int i;
	bool uread = true;
	vm_t* vm;
	int nerrors;
	bstring ss, st;

	// Define arguments.
	struct arg_lit* show_help = arg_lit0("h", "help", "Show this help.");
	struct arg_file* input_file = arg_file1(NULL, NULL, "<file>", "The input file, or - to read from standard input.");
	struct arg_file* execution_dump_file = arg_file0("e", "execution-dump", "<file>", "Produce a very large execution dump file.");
	struct arg_lit* debug_mode = arg_lit0("d", "debug", "Show each executed instruction.");
	struct arg_lit* terminate_mode = arg_lit0("t", "show-on-terminate", "Show state of machine when program is terminated.");
	struct arg_lit* legacy_mode = arg_lit0("l", "legacy", "Automatically initialize hardware to legacy values.");
	struct arg_lit* little_endian_mode = arg_lit0(NULL, "little-endian", "Use little endian serialization (for compatibility with older versions).");
	struct arg_lit* verbose = arg_litn("v", NULL, 0, LEVEL_EVERYTHING - LEVEL_DEFAULT, "Increase verbosity.");
	struct arg_lit* quiet = arg_litn("q", NULL,  0, LEVEL_DEFAULT - LEVEL_SILENT, "Decrease verbosity.");
	struct arg_end* end = arg_end(20);
	void* argtable[] = { input_file, debug_mode, execution_dump_file, terminate_mode, legacy_mode, little_endian_mode, verbose, quiet, end };

	// Parse arguments.
	nerrors = arg_parse(argc, argv, argtable);

	version_print(bautofree(bfromcstr("Emulator")));
	if (nerrors != 0 || show_help->count != 0)
	{
		if (show_help->count != 0)
			arg_print_errors(stdout, end, "emulator");

		printd(LEVEL_DEFAULT, "syntax:\n    dtemu");
		arg_print_syntax(stderr, argtable, "\n");
		printd(LEVEL_DEFAULT, "options:\n");
		arg_print_glossary(stderr, argtable, "	  %-25s %s\n");
		arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0]));
		return 1;
	}

	// Set verbosity level.
	debug_setlevel(LEVEL_DEFAULT + verbose->count - quiet->count);

	// Set global path variable.
	osutil_setarg0(bautofree(bfromcstr(argv[0])));

	// Set endianness.
	isetmode(little_endian_mode->count == 0 ? IMODE_BIG : IMODE_LITTLE);

	// Zero out the flash space.
	for (i = 0; i < 0x10000; i++)
		flash[i] = 0x0;

	// Zero out the leading space.
	for (i = 0; i < 0x100; i++)
		leading[i] = 0x0;

	// Load from either file or stdin.
	if (strcmp(input_file->filename[0], "-") != 0)
	{
		// Open file.
		load = fopen(input_file->filename[0], "rb");

		if (load == NULL)
		{
			fprintf(stderr, "emulator: unable to load %s from disk.\n", argv[1]);
			arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0]));
			return 1;
		}
	}
	else
	{
		// Windows needs stdin in binary mode.
#ifdef _WIN32
		_setmode(_fileno(stdin), _O_BINARY);
#endif

		// Set load to stdin.
		load = stdin;
	}

	// Read up to 0x10000 words.
	for (i = 0; i < 0x10000 && !feof(load); i++)
		iread(&flash[i], load);
	fclose(load);

	// Check to see if the first X bytes matches the header
	// for intermediate code and stop if it does.
	ss = bfromcstr("");
	st = bfromcstr(ldata_objfmt);
	for (i = 0; i < strlen(ldata_objfmt); i++)
		bconchar(ss, leading[i]);
	if (biseq(ss, st))
	{
		fprintf(stderr, "emulator: it appears you passed intermediate code for execution.  link\n");
		fprintf(stderr, "	   the input code with the toolchain linker to execute it.\n");
		arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0]));
		return 1;
	}

	// And then use the VM.
	vm = vm_create();
	vm->debug = (debug_mode->count > 0);
	vm_flash(vm, flash);
	vm_hw_timer_init(vm);
	vm_hw_io_init(vm);
	vm_hw_lem1802_init(vm);
	vm_hw_lua_init(vm);
	if (legacy_mode->count > 0)
	{
		vm_hw_lem1802_mem_set_screen(vm, 0x8000);
		vm_hw_io_set_legacy(true);
	}
	vm_execute(vm, execution_dump_file->count > 0 ? execution_dump_file->filename[0] : NULL);

#ifdef __EMSCRIPTEN__
	printd(LEVEL_WARNING, "warning: not cleaning up resources in Emscripten.\n");
#else
	if (terminate_mode->count > 0)
	{
		fprintf(stderr, "\n");
		fprintf(stderr, "A:   0x%04X	 [A]:	0x%04X\n", vm->registers[REG_A], vm->ram[vm->registers[REG_A]]);
		fprintf(stderr, "B:   0x%04X	 [B]:	0x%04X\n", vm->registers[REG_B], vm->ram[vm->registers[REG_B]]);
		fprintf(stderr, "C:   0x%04X	 [C]:	0x%04X\n", vm->registers[REG_C], vm->ram[vm->registers[REG_C]]);
		fprintf(stderr, "X:   0x%04X	 [X]:	0x%04X\n", vm->registers[REG_X], vm->ram[vm->registers[REG_X]]);
		fprintf(stderr, "Y:   0x%04X	 [Y]:	0x%04X\n", vm->registers[REG_Y], vm->ram[vm->registers[REG_Y]]);
		fprintf(stderr, "Z:   0x%04X	 [Z]:	0x%04X\n", vm->registers[REG_Z], vm->ram[vm->registers[REG_Z]]);
		fprintf(stderr, "I:   0x%04X	 [I]:	0x%04X\n", vm->registers[REG_I], vm->ram[vm->registers[REG_I]]);
		fprintf(stderr, "J:   0x%04X	 [J]:	0x%04X\n", vm->registers[REG_J], vm->ram[vm->registers[REG_J]]);
		fprintf(stderr, "PC:  0x%04X	 SP:	0x%04X\n", vm->pc, vm->sp);
		fprintf(stderr, "EX:  0x%04X	 IA:	0x%04X\n", vm->ex, vm->ia);
	}

	vm_hw_lua_free(vm);
	vm_hw_timer_free(vm);
	vm_hw_io_free(vm);
	vm_hw_lem1802_free(vm);
	vm_free(vm);

	arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0]));
	return 0;
#endif
}
Esempio n. 8
0
int main(int argc, char** argv)
{
	char* buf;
	yyscan_t scanner;
	int nerrors;

	// Define arguments.
	struct arg_lit* show_help = arg_lit0("h", "help", "Show this help.");
	struct arg_str* command_arg = arg_str0("c", NULL, "<command>", "Run a single debugger command and exit with the result.");
	struct arg_file* symbols_file = arg_file0("s", "symbols", "<file>", "The file to load symbols from.");
	struct arg_file* input_file = arg_file0(NULL, NULL, "<file>", "The file to initially load.");
	struct arg_lit* little_endian_mode = arg_lit0(NULL, "little-endian", "Use little endian serialization (for compatibility with older versions).");
	struct arg_lit* no_attach_mode = arg_lit0("n", "no-attachment", "Do not attach default devices when launched.");
	struct arg_lit* verbose = arg_litn("v", NULL, 0, LEVEL_EVERYTHING - LEVEL_DEFAULT, "Increase verbosity.");
	struct arg_lit* quiet = arg_litn("q", NULL,  0, LEVEL_DEFAULT - LEVEL_SILENT, "Decrease verbosity.");
	struct arg_end* end = arg_end(20);
	void* argtable[] = { show_help, no_attach_mode, command_arg, symbols_file, input_file, little_endian_mode, verbose, quiet, end };

	// Parse arguments.
	nerrors = arg_parse(argc, argv, argtable);

	version_print(bautofree(bfromcstr("Debugger")));
	if (nerrors != 0 || show_help->count != 0)
	{
		if (show_help->count != 0)
			arg_print_errors(stdout, end, "Debugger");

		printf("syntax:\n    dtdb");
		arg_print_syntax(stderr, argtable, "\n");
		printf("options:\n");
		arg_print_glossary(stderr, argtable, "	  %-25s %s\n");
		arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0]));
		return 1;
	}

	// Set verbosity level.
	debug_setlevel(LEVEL_DEFAULT + verbose->count - quiet->count);

	// Set global path variable.
	osutil_setarg0(bautofree(bfromcstr(argv[0])));

	// Set endianness.
	isetmode(little_endian_mode->count == 0 ? IMODE_BIG : IMODE_LITTLE);

	// Register signal handler.
	signal(SIGINT, ddbg_sigint);

	// Initialize debugger.
	ddbg_init();

	// Initialize devices unless not requested.
	if (no_attach_mode->count == 0)
	{
		ddbg_attach(bfromcstr("clock"));
		ddbg_attach(bfromcstr("keyboard"));
		ddbg_attach(bfromcstr("lem1802"));
	}

	// Load file if filename is specified.
	if (input_file->count > 0)
	{
		ddbg_load(bfromcstr(input_file->filename[0]));
		ddbg_flash_vm();
	}
	if (symbols_file->count > 0)
		ddbg_load_symbols(bfromcstr(symbols_file->filename[0]));

	// If the user specified a command, execute only that
	// command and then continue.
	if (command_arg->count > 0)
	{
		ddbg_return_code = 1; // Default is failure.
		dbg_yylex_init(&scanner);
		dbg_yy_scan_string(command_arg->sval[0], scanner);
		dbg_yyparse(scanner);
		dbg_yylex_destroy(scanner);
		return ddbg_return_code;
	}

	// Create SDP thread if supported.
#ifdef FEATURE_SDP
	pthread_create(&sdp_thread, NULL, (void*)ddbg_sdp_thread, vm);
#endif

	// We always want to show the debugger start message.
	debug_setlevel(LEVEL_VERBOSE + verbose->count - quiet->count);
	version_print(bautofree(bfromcstr("Debugger")));
	debug_setlevel(LEVEL_DEFAULT + verbose->count - quiet->count);

	for (;;)
	{
		buf = readline("> ");
		add_history(buf);

		dbg_yylex_init(&scanner);
		dbg_yy_scan_string(buf, scanner);
		dbg_yyparse(scanner);
		dbg_yylex_destroy(scanner);
	}

	free(buf);

	return 0;
}
Esempio n. 9
0
void bootstrap(void)
{
	mmu_start();
	version_print();
	
	printf("\nMemory statistics\n");
	printf(" %p|%p: bootstrap stack\n", &boot_stack, &boot_stack);
	printf(" %p|%p: bootstrap page table\n", &boot_pt, &boot_pt);
	printf(" %p|%p: boot info structure\n", &bootinfo, &bootinfo);
	printf(" %p|%p: kernel entry point\n",
	    (void *) PA2KA(BOOT_OFFSET), (void *) BOOT_OFFSET);
	
	size_t i;
	for (i = 0; i < COMPONENTS; i++)
		printf(" %p|%p: %s image (%u/%u bytes)\n", components[i].start,
		    components[i].start, components[i].name, components[i].inflated,
		    components[i].size);
	
	void *dest[COMPONENTS];
	size_t top = 0;
	size_t cnt = 0;
	bootinfo.cnt = 0;
	for (i = 0; i < min(COMPONENTS, TASKMAP_MAX_RECORDS); i++) {
		top = ALIGN_UP(top, PAGE_SIZE);
		
		if (i > 0) {
			bootinfo.tasks[bootinfo.cnt].addr = TOP2ADDR(top);
			bootinfo.tasks[bootinfo.cnt].size = components[i].inflated;
			
			str_cpy(bootinfo.tasks[bootinfo.cnt].name,
			    BOOTINFO_TASK_NAME_BUFLEN, components[i].name);
			
			bootinfo.cnt++;
		}
		
		dest[i] = TOP2ADDR(top);
		top += components[i].inflated;
		cnt++;
	}
	
	printf("\nInflating components ... ");
	
	for (i = cnt; i > 0; i--) {
		void *tail = components[i - 1].start + components[i - 1].size;
		if (tail >= dest[i - 1]) {
			printf("\n%s: Image too large to fit (%p >= %p), halting.\n",
			    components[i].name, tail, dest[i - 1]);
			halt();
		}
		
		printf("%s ", components[i - 1].name);
		
		int err = inflate(components[i - 1].start, components[i - 1].size,
		    dest[i - 1], components[i - 1].inflated);
		
		if (err != EOK) {
			printf("\n%s: Inflating error %d\n", components[i - 1].name, err);
			halt();
		}
	}
	
	printf(".\n");
	
	printf("Booting the kernel... \n");
	jump_to_kernel((void *) PA2KA(BOOT_OFFSET), &bootinfo);
}
Esempio n. 10
0
int main ( int argc, char *argv[] )
{
/***********************************************************************
 * Local variables
 ***********************************************************************/
    int ierr    = 0;    // Flag errors
    char *error = NULL; // Error message string

    double t1, t2, t3, t4, t5; // Variables to track runtime

    /* File in/out handling variables */
    char *inputFile = NULL, *outputFile = NULL;
    FILE *fp_in     = NULL, *fp_out     = NULL;

    input_data input_vars;               // Struct to store input variables
    input_data_init ( &input_vars );     // Set variables to initial values

    para_data para_vars;                 // Struct to store parallel variables
    para_data_init ( &para_vars );       // Set variables to initial values

    time_data time_vars;                 // Struct to store time variables
    time_data_init ( &time_vars );       // Set variables to initial values

    geom_data geom_vars;                 // Struct to store geometry variables
    geom_data_init ( &geom_vars );       // Set variables to initial values

    sn_data sn_vars;                     // Struct to store sn variables
    sn_data_init ( &sn_vars );           // Set variables to initial values

    data_data data_vars;                 // Struct to store data variables
    data_data_init ( &data_vars );       // Set variables to initial values

    control_data control_vars;           // Struct to store control variables
    control_data_init ( &control_vars ); // Set variables to initial values

    mms_data mms_vars;                   // Struct to store mms variables
    mms_data_init ( &mms_vars );         // Set variables to initial values

    solvar_data solvar_vars;             // Struct to store solvar variables
    solvar_data_init ( &solvar_vars );   // Set variables to initial values

    sweep_data sweep_vars;               // Struct to store sweep variables
    sweep_data_init ( &sweep_vars );     // Set variables to initial values

    dim_sweep_data dim_sweep_vars;

/***********************************************************************
 * Perform calls that set up the parallel environment in MPI and
 * OpenMP. Also starts the timer. Update parallel setup time.
 ***********************************************************************/
    /* Initialize the parallel environment */
    pinit ( argc, argv, &para_vars, &t1, &ierr );

    t2 = wtime(); // Get the MPI walltime

    /* Calc parallel setup time */
    time_vars.tparset = time_vars.tparset + t2 - t1;


/***********************************************************************
 * Read the command line arguments to get i/o file names.
 * Open the two files.
 ***********************************************************************/
    ierr = cmdarg ( argc, argv, &inputFile, &outputFile, &error,
             para_vars.iproc, para_vars.root );

    bcast_i_scalar ( &ierr, para_vars.comm_snap, para_vars.root, para_vars.nproc );

    /* Ensure arguments are valid */
    if ( ierr != 0 )
    {
        print_error ( NULL, error, para_vars.iproc, para_vars.root );

        FREE ( inputFile );
        FREE ( outputFile );
        FREE ( error );

        stop_run ( 0, 0, 0, &para_vars, &sn_vars, &data_vars, &mms_vars,
                   &geom_vars, &solvar_vars, &control_vars );
    }

    /* Open the input file to read in initial values */
    ierr = open_file ( &fp_in, inputFile, "r", &error, para_vars.iproc, para_vars.root );

    bcast_i_scalar ( &ierr, para_vars.comm_snap, para_vars.root, para_vars.nproc);

    /* Ensure input file is found */
    if ( ierr != 0 )
    {
        print_error ( NULL, error, para_vars.iproc, para_vars.root );

        FREE ( inputFile );
        FREE ( outputFile );
        FREE ( error );

        stop_run ( 0, 0, 0, &para_vars, &sn_vars, &data_vars, &mms_vars,
                   &geom_vars, &solvar_vars, &control_vars );
    }

    /* Open the output file to write results and error messages */
    ierr = open_file ( &fp_out, outputFile, "w", &error, para_vars.iproc, para_vars.root );

    bcast_i_scalar ( &ierr, para_vars.comm_snap, para_vars.root, para_vars.nproc );

    /* Ensure output file can be created */
    if ( ierr != 0 )
    {
        print_error ( NULL, error, para_vars.iproc, para_vars.root );

        FREE ( inputFile );
        FREE ( outputFile );
        FREE ( error );

        stop_run ( 0, 0, 0, &para_vars, &sn_vars, &data_vars, &mms_vars,
                   &geom_vars, &solvar_vars, &control_vars );
    }

/***********************************************************************
 * Write code version and execution time to output.
 ***********************************************************************/
    if ( para_vars.iproc == para_vars.root ) version_print ( fp_out );

/***********************************************************************
 * Read input
 ***********************************************************************/
    ierr = read_input ( fp_in, fp_out, &input_vars, &para_vars, &time_vars );

    ierr = close_file ( fp_in, inputFile, &error, para_vars.iproc,
                        para_vars.root );

    FREE ( inputFile );

    bcast_i_scalar ( &ierr, para_vars.comm_snap, para_vars.root, para_vars.nproc );

    if ( ierr != 0 )
    {
        print_error ( fp_out, error, para_vars.iproc, para_vars.root );

        FREE ( outputFile );
        FREE ( error );

        stop_run ( 0, 0, 0, &para_vars, &sn_vars, &data_vars, &mms_vars,
                   &geom_vars, &solvar_vars, &control_vars );
    }

/***********************************************************************
 * Get nthreads for each proc. Print the warning about resetting
 * nthreads if necessary. Don't stop run. Set up the SDD MPI topology.
 ***********************************************************************/
    t3 = wtime();

    pinit_omp ( para_vars.comm_snap, &input_vars.nthreads, input_vars.nnested,
                &para_vars.do_nested, &ierr, &error );

    if ( ierr != 0 ) print_error ( NULL, error, para_vars.iproc,
                                   para_vars.root );

    pcomm_set ( input_vars.npey, input_vars.npez, &para_vars, &ierr );

    t4 = wtime();

    time_vars.tparset = time_vars.tparset + t4 - t3;

/***********************************************************************
 * Setup problem
 ***********************************************************************/
    setup ( &input_vars, &para_vars, &time_vars, &geom_vars, &sn_vars,
            &data_vars, &solvar_vars, &control_vars, &mms_vars, fp_out,
            &ierr, &error );

/***********************************************************************
 * Call for the problem solution
 ***********************************************************************/
    translv ( &input_vars, &para_vars, &time_vars, &geom_vars, &sn_vars,
              &data_vars, &control_vars, &solvar_vars, &mms_vars,
              &sweep_vars, &dim_sweep_vars, fp_out, &ierr, &error );

/***********************************************************************
 * Output the results. Print the timing summary
 ***********************************************************************/
    output ( &input_vars, &para_vars, &time_vars, &geom_vars, &data_vars,
             &sn_vars, &control_vars, &mms_vars, &solvar_vars, &sweep_vars,
             fp_out, &ierr, &error );

    if ( para_vars.iproc == para_vars.root ) time_summ ( fp_out, &time_vars );

/***********************************************************************
 * Final cleanup: deallocate, close output file, end the program
 ***********************************************************************/
    dealloc_input ( 3, &sn_vars, &data_vars, &mms_vars );
    dealloc_solve ( 3, &geom_vars, &solvar_vars, &control_vars );

    t5 = wtime();
    time_vars.tsnap = t5 - t1;

    if ( para_vars.iproc == para_vars.root )
    {
        fprintf ( fp_out, "  Total Execution time"
                  "                   %.4E\n\n", time_vars.tsnap );
        fprintf ( fp_out, "  Grind Time (nanoseconds)"
                  "         %.4E\n\n", time_vars.tgrind );
        fprintf ( fp_out,
                  "****************************************"
                  "****************************************\n" );
    }

    ierr = close_file ( fp_out, outputFile, &error, para_vars.iproc, para_vars.root );

    FREE ( outputFile );

    bcast_i_scalar ( &ierr, para_vars.comm_snap, para_vars.root, para_vars.nproc );

    if ( ierr != 0 )
    {
        print_error ( 0, error, para_vars.iproc, para_vars.root );

        FREE ( error );

        stop_run ( 0, 0, 0, &para_vars, &sn_vars, &data_vars, &mms_vars,
                   &geom_vars, &solvar_vars, &control_vars );
    }


    if ( control_vars.otrdone )
    {
        FREE ( error );

        stop_run ( 0, 0, 1, &para_vars, &sn_vars, &data_vars, &mms_vars,
                   &geom_vars, &solvar_vars, &control_vars );
    }
    else
    {
        FREE ( error );

        stop_run ( 0, 0, 2, &para_vars, &sn_vars, &data_vars, &mms_vars,
                   &geom_vars, &solvar_vars, &control_vars );
    }

    return 0;
}
Esempio n. 11
0
int main(int argc, char* argv[])
{
	// Define our variables.
	FILE* in;
	FILE* out;
	int nerrors, i;
	char* test;
	uint16_t offset, current, store, mem_index;
	struct lprov_entry* required = NULL;
	struct lprov_entry* provided = NULL;
	struct lprov_entry* adjustment = NULL;
	struct lprov_entry* temp = NULL;

	// Define arguments.
	struct arg_lit* show_help = arg_lit0("h", "help", "Show this help.");
	struct arg_file* input_files = arg_filen(NULL, NULL, "<file>", 1, 100, "The input object files.");
	struct arg_file* output_file = arg_file1("o", "output", "<file>", "The output file (or - to send to standard output).");
	struct arg_end* end = arg_end(20);
	void* argtable[] = { show_help, input_files, output_file, end };

	// Parse arguments.
	nerrors = arg_parse(argc, argv, argtable);
	
	version_print(bautofree(bfromcstr("Linker")));
	if (nerrors != 0 || show_help->count != 0)
	{
		if (show_help->count != 0)
			arg_print_errors(stdout, end, "linker");

		printf("syntax:\n    linker");
		arg_print_syntax(stdout, argtable, "\n");
		printf("options:\n");
		arg_print_glossary(stdout, argtable, "	  %-25s %s\n");
		return 1;
	}

	// Open the output file for writing.
	out = fopen(output_file->filename[0], "wb");

	if (out == NULL)
	{
		// Handle the error.
		fprintf(stderr, "linker: unable to write to output file.\n");
		return 1;
	}

	// We initially need to get a list of ALL provided
	// labels before we can start replacing them.
	offset = 0;

	for (i = 0; i < input_files->count; i++)
	{
		// Open the input file.
		in = fopen(input_files->filename[i], "rb");

		if (in == NULL)
		{
			// Handle the error.
			fprintf(stderr, "linker: unable to read input file '%s'.\n", input_files->filename[i]);
			fclose(out);
			return 1;
		}

		// Is this the object format?
		test = malloc(strlen(ldata_objfmt) + 1);
		memset(test, 0, strlen(ldata_objfmt) + 1);
		fread(test, 1, strlen(ldata_objfmt), in);
		fseek(in, 1, SEEK_CUR);

		if (strcmp(test, ldata_objfmt) != 0)
		{
			// Handle the error.
			fprintf(stderr, "linker: input file '%s' is not in object format 1.0.\n", input_files->filename[i]);
			fclose(in);
			fclose(out);
			return 1;
		}

		free(test);

		// Load only the provided label entries into memory.
		objfile_load(input_files->filename[i], in, &offset, &provided, NULL, NULL);

		// Close the file.
		fclose(in);
	}

	// Now we can start replacing the labels with the provided values
	// since we have ALL of the provided labels available.
	offset = 0;

	for (i = 0; i < input_files->count; i++)
	{
		// Open the input file.
		in = fopen(input_files->filename[i], "rb");

		if (in == NULL)
		{
			// Handle the error.
			fprintf(stderr, "linker: unable to read input file '%s'.\n", input_files->filename[i]);
			fclose(out);
			return 1;
		}

		// Skip over the object format label; we already tested
		// for this in phase 1.
		fseek(in, strlen(ldata_objfmt) + 1, SEEK_CUR);

		// Load only the required and adjustment entries into memory.
		current = offset;
		objfile_load(input_files->filename[i], in, &offset, NULL, &required, &adjustment);

		// Copy all of the input file's data into the output
		// file, word by word.
		mem_index = 0;
		fprintf(stderr, "BEGIN %s\n", input_files->filename[i]);

		while (!feof(in))
		{
			// Read a word.
			fread(&store, sizeof(uint16_t), 1, in);

			// For some strange reason, the last two bytes get
			// written twice, as if it's only EOF after you
			// attempt to read past the end again.	I'm not sure
			// why the semantics are like this, but checking again
			// for EOF here prevents us writing double.
			if (feof(in))
				break;

			// Check to see if we need to do something with this
			// word, such as adjusting it.
			if (lprov_find_by_address(adjustment, mem_index) != NULL)
			{
				// We need to adjust this word by the offset.
				store += current;
				fprintf(stderr, "ADJUSTED 0x%04X: 0x%04X -> 0x%04X\n", mem_index, store - current, store);
			}

			// Check to see if we need to resolve this word into
			// an actual address because it was imported.
			temp = lprov_find_by_address(required, mem_index);

			if (temp != NULL)
			{
				// Find the position we should change this to.
				temp = lprov_find_by_label(provided, temp->label);

				// We need to set this word to the proper location.
				fprintf(stderr, "RESOLVED 0x%04X: 0x%04X -> 0x%04X\n", mem_index, store, temp->address);
				store = temp->address;
			}

			// Now write the (potentially modified) word to the
			// output.
			fprintf(stderr, " >> WRITE 0x%04X\n", store);
			fwrite(&store, sizeof(uint16_t), 1, out);

			// Increment memory position.
			mem_index++;
		}

		// Close the file.
		fclose(in);

		// Reset and free the required and adjustment linked list.
		// FIXME: Actually free the lists!
		required = NULL;
		adjustment = NULL;
	}

	// Close file.
	fprintf(stderr, "linker: completed successfully.\n", input_files->filename[i]);
	fclose(out);

	return 0;
}
Esempio n. 12
0
void bootstrap(void)
{
	version_print();
	ofw_memmap(&bootinfo.memmap);
	
	void *bootinfo_pa = ofw_translate(&bootinfo);
	void *real_mode_pa = ofw_translate(&real_mode);
	void *loader_address_pa = ofw_translate((void *) LOADER_ADDRESS);
	
	printf("\nMemory statistics (total %llu MB)\n", bootinfo.memmap.total >> 20);
	printf(" %p|%p: real mode trampoline\n", &real_mode, real_mode_pa);
	printf(" %p|%p: boot info structure\n", &bootinfo, bootinfo_pa);
	printf(" %p|%p: kernel entry point\n",
	    (void *) PA2KA(BOOT_OFFSET), (void *) BOOT_OFFSET);
	printf(" %p|%p: loader entry point\n",
	    (void *) LOADER_ADDRESS, loader_address_pa);
	
	size_t i;
	for (i = 0; i < COMPONENTS; i++)
		printf(" %p|%p: %s image (%zu/%zu bytes)\n", components[i].start,
		    ofw_translate(components[i].start), components[i].name,
		    components[i].inflated, components[i].size);
	
	size_t dest[COMPONENTS];
	size_t top = 0;
	size_t cnt = 0;
	bootinfo.taskmap.cnt = 0;
	for (i = 0; i < min(COMPONENTS, TASKMAP_MAX_RECORDS); i++) {
		top = ALIGN_UP(top, PAGE_SIZE);
		
		if (i > 0) {
			bootinfo.taskmap.tasks[bootinfo.taskmap.cnt].addr =
			    (void *) PA2KA(top);
			bootinfo.taskmap.tasks[bootinfo.taskmap.cnt].size =
			    components[i].inflated;
			
			str_cpy(bootinfo.taskmap.tasks[bootinfo.taskmap.cnt].name,
			    BOOTINFO_TASK_NAME_BUFLEN, components[i].name);
			
			bootinfo.taskmap.cnt++;
		}
		
		dest[i] = top;
		top += components[i].inflated;
		cnt++;
	}
	
	void *balloc_base;
	void *balloc_base_pa;
	ofw_alloc("boot allocator area", &balloc_base, &balloc_base_pa,
	    BALLOC_MAX_SIZE, loader_address_pa);
	printf(" %p|%p: boot allocator area\n", balloc_base, balloc_base_pa);
	
	void *inflate_base;
	void *inflate_base_pa;
	ofw_alloc("inflate area", &inflate_base, &inflate_base_pa, top,
	    loader_address_pa);
	printf(" %p|%p: inflate area\n", inflate_base, inflate_base_pa);
	
	uintptr_t balloc_start = ALIGN_UP(top, PAGE_SIZE);
	size_t pages = (balloc_start + ALIGN_UP(BALLOC_MAX_SIZE, PAGE_SIZE))
	    >> PAGE_WIDTH;
	void *transtable;
	void *transtable_pa;
	ofw_alloc("translate table", &transtable, &transtable_pa,
	    pages * sizeof(void *), loader_address_pa);
	printf(" %p|%p: translate table\n", transtable, transtable_pa);
	
	check_overlap("boot allocator area", balloc_base_pa, pages);
	check_overlap("inflate area", inflate_base_pa, pages);
	check_overlap("translate table", transtable_pa, pages);
	
	printf("\nInflating components ... ");
	
	for (i = cnt; i > 0; i--) {
		printf("%s ", components[i - 1].name);
		
		int err = inflate(components[i - 1].start, components[i - 1].size,
		    inflate_base + dest[i - 1], components[i - 1].inflated);
		
		if (err != EOK) {
			printf("\n%s: Inflating error %d, halting.\n",
			    components[i - 1].name, err);
			halt();
		}
	}
	
	printf(".\n");
	
	printf("Setting up boot allocator ...\n");
	balloc_init(&bootinfo.ballocs, balloc_base, PA2KA(balloc_start),
	    BALLOC_MAX_SIZE);
	
	printf("Setting up screens ...\n");
	ofw_setup_screens();
	
	printf("Canonizing OpenFirmware device tree ...\n");
	bootinfo.ofw_root = ofw_tree_build();
	
	printf("Setting up translate table ...\n");
	for (i = 0; i < pages; i++) {
		uintptr_t off = i << PAGE_WIDTH;
		void *phys;
		
		if (off < balloc_start)
			phys = ofw_translate(inflate_base + off);
		else
			phys = ofw_translate(balloc_base + off - balloc_start);
		
		((void **) transtable)[i] = phys;
	}
	
	printf("Booting the kernel...\n");
	jump_to_kernel(bootinfo_pa, transtable_pa, pages, real_mode_pa);
}
Esempio n. 13
0
int main(int argc, char* argv[])
{
    bstring ldargs = bfromcstr("");
    int i, result;
    unsigned int match = 0, unmatch = 0;
    char ca, ce;
    BFILE* expect;
    BFILE* actual;

    // Define arguments.
    struct arg_lit* show_help = arg_lit0("h", "help", "Show this help.");
    struct arg_lit* gen_relocatable = arg_lit0("r", "relocatable", "Generate relocatable code.");
    struct arg_lit* gen_intermediate = arg_lit0("i", "intermediate", "Generate intermediate code for use with the linker.");
    struct arg_lit* little_endian_mode = arg_lit0(NULL, "little-endian", "Use little endian serialization.");
    struct arg_file* input_file = arg_file1(NULL, NULL, "<file>", "The input assembly file.");
    struct arg_file* expect_file = arg_file0("e", "expect", "<file>", "The output file that contains expected output.");
    struct arg_file* actual_file = arg_file1("a", "actual", "<file>", "The output file where actual output will be placed.");
    struct arg_file* symbols_file = arg_file0("s", "debug-symbols", "<file>", "The debugging symbol output file.");
    struct arg_lit* fail_opt = arg_lit0("f", "fail", "The assembler is expected to fail and the actual output file should not exist on completion.");
    struct arg_file* path = arg_file1("p", NULL, "<path>", "The path to the assembler.");
    struct arg_lit* verbose = arg_litn("v", NULL, 0, LEVEL_EVERYTHING - LEVEL_DEFAULT, "Increase verbosity.");
    struct arg_lit* quiet = arg_litn("q", NULL,  0, LEVEL_DEFAULT - LEVEL_SILENT, "Decrease verbosity.");
    struct arg_end* end = arg_end(20);
    void* argtable[] = { show_help, gen_relocatable, gen_intermediate, little_endian_mode, symbols_file, input_file, expect_file, actual_file, fail_opt, path, verbose, quiet, end };

    // Parse arguments.
    int nerrors = arg_parse(argc, argv, argtable);

    version_print(bautofree(bfromcstr("Assembler Test Driver")));
    if (nerrors != 0 || show_help->count != 0 || (fail_opt->count == 0 && (expect_file->count == 0 || actual_file->count == 0)))
    {
        if (show_help->count != 0 && fail_opt->count == 0 && (expect_file->count == 0 || actual_file->count == 0))
            printd(LEVEL_ERROR, "error: you must provide either -f or -e and -a.\n");
        if (show_help->count != 0)
            arg_print_errors(stderr, end, "testasm");

        printd(LEVEL_DEFAULT, "syntax:\n    testasm");
        arg_print_syntax(stderr, argtable, "\n");
        printd(LEVEL_DEFAULT, "options:\n");
        arg_print_glossary(stderr, argtable, "    %-25s %s\n");
        arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0]));
        return 1;
    }

    // Set verbosity level.
    debug_setlevel(LEVEL_DEFAULT + verbose->count - quiet->count);

    // Set global path variable.
    osutil_setarg0(bautofree(bfromcstr(argv[0])));

    // Generate the argument list for the assembler.
    ldargs = bfromcstr(path->filename[0]);
    binsertch(ldargs, 0, 1, '"');
    bconchar(ldargs, '"');
    bconchar(ldargs, ' ');

    // Verbosity options.
    if (verbose->count > 0)
    {
        bconchar(ldargs, '-');
        for (i = 0; i < verbose->count; i++) bconchar(ldargs, 'v');
        bconchar(ldargs, ' ');
    }
    if (quiet->count > 0)
    {
        bconchar(ldargs, '-');
        for (i = 0; i < quiet->count; i++) bconchar(ldargs, 'q');
        bconchar(ldargs, ' ');
    }

    // Literal options.
    if (gen_relocatable->count > 0)
    {
        bconchar(ldargs, '-');
        for (i = 0; i < gen_relocatable->count; i++) bconchar(ldargs, 'r');
        bconchar(ldargs, ' ');
    }
    if (gen_intermediate->count > 0)
    {
        bconchar(ldargs, '-');
        for (i = 0; i < gen_intermediate->count; i++) bconchar(ldargs, 'i');
        bconchar(ldargs, ' ');
    }
    if (little_endian_mode->count > 0)
    {
        for (i = 0; i < little_endian_mode->count; i++)
            bcatcstr(ldargs, "--little-endian ");
    }

    // Unlink the actual file so that if we are expecting
    // failure, we won't return incorrectly.
    unlink(actual_file->filename[0]);

    // Output file.
    bcatcstr(ldargs, "-o \"");
    bcatcstr(ldargs, actual_file->filename[0]);
    bcatcstr(ldargs, "\" ");

    // Input file.
    bcatcstr(ldargs, "\"");
    bcatcstr(ldargs, input_file->filename[0]);
    bcatcstr(ldargs, "\" ");

    // Windows needs the whole command wrapped in quotes and slashes to be correct.
    // See http://stackoverflow.com/questions/2642551/windows-c-system-call-with-spaces-in-command.
#ifdef _WIN32
    binsertch(ldargs, 0, 1, '"');
    bconchar(ldargs, '"');
#endif

    // Now run the assembler!
    result = system(ldargs->data);
    if (result != 0 && fail_opt->count == 0)
    {
        // Assembler returned error exit code.
        printd(LEVEL_ERROR, "error: expected success but assembler returned non-zero exit code (%i).\n", result);
        return 1;
    }
    else if (result == 0 && fail_opt->count >= 1)
    {
        // Assembler returned zero when failure was expected.
        printd(LEVEL_ERROR, "error: expected failure but assembler returned zero exit code.\n");
        return 1;
    }
    else if (result != 0 && fail_opt->count >= 1)
    {
        // Assembler failed and we expected it to.  Return success only
        // if the output file does not exist.
        actual = bfopen(actual_file->filename[0], "rb");
        if (actual != NULL)
        {
            printd(LEVEL_ERROR, "error: expected failure but actual output file exists.\n");
            bfclose(actual);
            return 1;
        }
        return 0;
    }

    // Open expect data.
    expect = bfopen(expect_file->filename[0], "rb");
    if (expect == NULL)
    {
        // The expect file was not provided.
        printd(LEVEL_ERROR, "error: path to expect file does not exist.\n");
        return 1;
    }

    // Open actual data.
    actual = bfopen(actual_file->filename[0], "rb");
    if (actual == NULL)
    {
        // The expect file was not provided.
        bfclose(expect);
        printd(LEVEL_ERROR, "error: expected data but actual output file does not exist after running assembler.\n");
        return 1;
    }

    // Now compare raw bytes.
    while (true)
    {
        if (!bfeof(actual) && !bfeof(expect))
        {
            ca = bfgetc(actual);
            ce = bfgetc(expect);
            if (ca == ce)
                match++;
            else
            {
                printd(LEVEL_WARNING, "warning: byte at 0x%04X is different (got 0x%02X, expected 0x%02X)!\n", bftell(actual), ca, ce);
                unmatch++;
            }
        }
        else if (!bfeof(actual))
        {
            ca = bfgetc(actual);
            printd(LEVEL_ERROR, "error: actual output contained trailing byte 0x%02X.\n", (unsigned char)ca);
            unmatch++;
        }
        else if (!bfeof(expect))
        {
            ce = bfgetc(expect);
            printd(LEVEL_ERROR, "error: expected actual output to contain 0x%02X.\n", (unsigned char)ce);
            unmatch++;
        }
        else
            break;
    }
    if (unmatch > 0)
    {
        printd(LEVEL_ERROR, "error: actual output differs from expected output in content (%f%%, %i bytes different).\n", 100.f / (unmatch + match) * unmatch, unmatch);
        if (bftell(actual) != bftell(expect))
            printd(LEVEL_ERROR, "error: actual output differs from expected output in length (%i bytes larger).\n", bftell(actual) - bftell(expect));
        bfclose(actual);
        bfclose(expect);
        return 1;
    }

    // Close files and delete actual because we have
    // succeeded.
    bfclose(actual);
    bfclose(expect);
    unlink(actual_file->filename[0]);

    return 0;
}
Esempio n. 14
0
int wtpinfo_print(char *str, struct wtpinfo * wtpinfo)
{
	char hstr[64];

	char *s = str;




	s+=sprintf (s,"\tWTP Name: %s\n", (!wtpinfo->name ? (uint8_t*)"Not set" : wtpinfo->name) );
	s+=sprintf (s,"\tLocation: %s\n", (!wtpinfo->location ? (uint8_t*)"Not set" : wtpinfo->location) );

	s+=sprintf (s,"\tMAC Adress: ");
	if (wtpinfo->macaddress){
		sock_hwaddrtostr(wtpinfo->macaddress,wtpinfo->macaddress_len,hstr,":");
		s+=sprintf(s,"%s\n",hstr);

	}
	else
		s+=sprintf(s,"Not set\n");

	char disctypestr[32];
	switch(wtpinfo->discovery_type){
		case CW_DISCOVERY_TYPE_STATIC:
			sprintf(disctypestr,"Static");
			break;
			
		case CW_DISCOVERY_TYPE_DHCP:
			sprintf(disctypestr,"DHCP");
			break;
			
		case CW_DISCOVERY_TYPE_DNS:
			sprintf(disctypestr,"DNS");
			break;

		case CW_DISCOVERY_TYPE_AC_REFERRAL:
			sprintf(disctypestr,"AC Referral");
			break;

		default:
			sprintf(disctypestr,"Unknown");
			break;

	}
	s+=sprintf (s,"\tDiscovery Type: %s\n",disctypestr);



//	sock_addrtostr((struct sockaddr*)&wtpinfo->local_ip,hstr,64);

/*
int i0;
for (i0=0; i0<10; i0++){
	printf("%d\n", ((char*)(&wtpinfo->local_ip))[i0]  );
}

*/	s+=sprintf (s,"\tLocal IP: %s\n",sock_addr2str(&(wtpinfo->local_ip)));



	s+=sprintf (s,"\tVendor ID: %d, %s\n", wtpinfo->vendor_id,lw_vendor_id_to_str(wtpinfo->vendor_id) );

	s+=sprintf (s,"\tModel No.: "); //, (!wtpinfo->model_no ? (uint8_t*)"Not set" : wtpinfo->model_no) );
	s+=bstr_to_str(s,wtpinfo->model_no,0);
	s+=sprintf(s,"\n");
	

//	s+=sprintf (s,"\tSerial No.: %s\n", (!wtpinfo->serial_no ? (uint8_t*)"Not set" : wtpinfo->serial_no) );



	s+=sprintf (s,"\tSerial No.: "); 
	s+=bstr_to_str(s,wtpinfo->serial_no,0);
	s+=sprintf(s,"\n");

	s+=sprintf (s,"\tBoard ID: "); 
	s+=bstr_to_str(s,wtpinfo->board_id,0);
	s+=sprintf(s,"\n");

	s+=sprintf (s,"\tBoard Revision: "); 
	s+=bstr_to_str(s,wtpinfo->board_revision,0);
	s+=sprintf(s,"\n");


//	s+=sprintf (s,"\tBoard Id: %s\n", (!wtpinfo->board_id ? (uint8_t*)"Not set" : wtpinfo->board_id) );



	s+=sprintf (s,"\tSoftware Version: ");
//	s+=version_print(s,wtpinfo->software_version,wtpinfo->software_version_len,wtpinfo->software_vendor_id);
	s+=cw_format_version(s,wtpinfo->software_version,wtpinfo->software_vendor_id,"Not set");
	s+=sprintf (s,"\n");


	s+=sprintf (s,"\tHardware Version: ");
	s+=version_print(s,wtpinfo->hardware_version,wtpinfo->hardware_version_len,wtpinfo->hardware_vendor_id);
	s+=sprintf (s,"\tBootloader Version: ");
	s+=version_print(s,wtpinfo->bootloader_version,wtpinfo->bootloader_version_len,wtpinfo->bootloader_vendor_id);
		



//, (!wtpinfo->software_version ? (uint8_t*)"Not set" : wtpinfo->software_version) );



//	s+=sprintf (s,"\tHardware Version: %s\n", (!wtpinfo->hardware_version ? (uint8_t*)"Not set" : wtpinfo->hardware_version) );


	s+=sprintf (s,"\tMax Radios: %d\n",wtpinfo->max_radios);
	s+=sprintf (s,"\tRadios in use: %d\n",wtpinfo->radios_in_use);


	s+=sprintf (s,"\tSession ID: ");
	if (wtpinfo->session_id) {
		int i;
		for (i=0; i<bstr_len(wtpinfo->session_id); i++)
			s+=sprintf(s,"%02X",bstr_data(wtpinfo->session_id)[i]);
	}
	else 
		s+=sprintf(s,"Not set");
		s+=sprintf(s,"\n");

	s+=sprintf (s,"\tMAC Type: ");
	switch (wtpinfo->mac_type){
		case WTP_MAC_TYPE_LOCAL:
			s+=sprintf(s,"local");
			break;
		case WTP_MAC_TYPE_SPLIT:
			s+=sprintf(s,"split");
			break;
		case WTP_MAC_TYPE_BOTH:
			s+=sprintf(s,"local, split");
			break;
	}
	s+=sprintf(s,"\n");

	s+=sprintf (s,"\tFrame Tunnel Mode: ");
	s+=sprintf(s,"(%08X)",wtpinfo->frame_tunnel_mode);
	char * c="";
	if (wtpinfo->frame_tunnel_mode & WTP_FRAME_TUNNEL_MODE_N){
		s+=printf (s,"%snative",c);c=", ";
	}

	if (wtpinfo->frame_tunnel_mode & WTP_FRAME_TUNNEL_MODE_E){
		s+=sprintf (s,"%s802.3",c);c=", ";
	}

	if (wtpinfo->frame_tunnel_mode & WTP_FRAME_TUNNEL_MODE_L){
		s+=sprintf (s,"%sLocal bridging",c);c=", ";
	}
	if (wtpinfo->frame_tunnel_mode == 0)
		s+=sprintf(s," None");

	s+=sprintf(s,"\n");

	s+=sprintf(s,"\tRadios: %d\n",wtpinfo->max_radios);	
	int i;

	char ristr[2048];
	char *r = ristr;
	for (i=0; i<wtpinfo->max_radios; i++){
		if (wtpinfo->radioinfo[i].set)
			r+=radioinfo_print(r,&wtpinfo->radioinfo[i]);
	}

	s+=sprintf(s,"%s",ristr);


	s+=sprintf(s,"Encryption: %08x\n",wtpinfo->encryption_cap);

	s+=wtp_reboot_statistics_print(s,&wtpinfo->reboot_statistics);
	return s-str;


}
Esempio n. 15
0
/**
 * Main entry point.
 *
 * @param argc The argument count.
 * @param argv The argument vector.
 * @return The exit code.
 */
int main(int argc, char *argv[]) {
  if (argc == 1) {
    printf("\nThis program needs some arguments ...  \n Try add_list -h \n\n");
  }

  int option = 0;
  int start = -1;
  int end = 0;

  // Handle command line arguments.
  while ((option = getopt(argc, argv, "hvs:e:")) != -1) {
    switch (option) {
      case 's':
        start = atoi(optarg);
        break;

      case 'e':
        end = atoi(optarg);
        break;

      case 'v':
        version_print();
        exit(EXIT_FAILURE);

       case 'h':
        help_print();
        exit(EXIT_FAILURE);

       default:
        usage_print();
        exit(EXIT_FAILURE);
    }
  }

  // Validate our input.
  validate_input(start, end);

  // Create an arrays for threading.
  int threadCount = find_number_of_threads(start, end);
  ThreadData data[threadCount];
  pthread_t threadIds[threadCount];
  int i = 0;

  // Spawn threads.
  for (i = 0; i < threadCount; i++) {
    data[i].start = start + (i * CHUNK_SIZE);
    data[i].stop = data[i].start + CHUNK_SIZE - 1;
    data[i].result = 0;

    // If we've exceeded the end amount or reached our maximum threads then set the stop to the actual end.
    if ((data[i].stop > end) || (data[i].stop < end && i + 1 == threadCount)) {
      data[i].stop = end;
    }

    //// NOTE: Uncomment to view what ranges each thread is responsible for.
    //printf("%d: %d to %d\n", i + 1, data[i].start, data[i].stop);

    if (pthread_create(&threadIds[i], NULL, &gaussian_add, (void *)&data[i]) != 0) {
      printf("Could not create thread #%d.", i);
    }
  }

  // Wait for the threads to finish.
  unsigned long long sum = 0;
  for (i = 0; i < threadCount; i++) {
    if (pthread_join(threadIds[i], NULL) != 0) {
      printf("Could not join thread #%d\n", i + 1);
    }

    sum += data[i].result;
  }

  // Inform the user of the results and of the short cut.
  summary_print(threadCount, sum, start, end);

  return 0;
}
Esempio n. 16
0
int main(int argc, char* argv[])
{
	// Define arguments.
	struct arg_lit* show_help = arg_lit0("h", "help", "Show this help.");
	struct arg_str* type_assembler = arg_str0("t", NULL, "<type>", "The type of assembler to output for.");
	struct arg_file* input_file = arg_file1(NULL, NULL, "<file>", "The input file (or - to read from standard input).");
	struct arg_file* output_file = arg_file1("o", "output", "<file>", "The output file (or - to send to standard output).");
	// 20 is maxcount for include directories, this has to be set to some constant number.
	struct arg_file* include_dirs = arg_filen("I", NULL, "<directory>", 0, 20, "Adds the directory <dir> to the directories to be searched for header files.");
	struct arg_lit* verbose = arg_litn("v", NULL, 0, LEVEL_EVERYTHING - LEVEL_DEFAULT, "Increase verbosity.");
	struct arg_lit* quiet = arg_litn("q", NULL,  0, LEVEL_DEFAULT - LEVEL_SILENT, "Decrease verbosity.");
	struct arg_end* end = arg_end(20);
	void* argtable[] = { output_file, show_help, type_assembler, include_dirs, input_file, verbose, quiet, end };

	// Parse arguments.
	int nerrors = arg_parse(argc, argv, argtable);

	version_print(bautofree(bfromcstr("Compiler")));
	if (nerrors != 0 || show_help->count != 0)
	{
		if (nerrors != 0)
			arg_print_errors(stderr, end, "compiler");

		fprintf(stderr, "syntax:\n    dtcc");
		arg_print_syntax(stderr, argtable, "\n");
		fprintf(stderr, "options:\n");
		arg_print_glossary(stderr, argtable, "	  %-25s %s\n");
		arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0]));
		return 1;
	}

	// Set verbosity level.
	debug_setlevel(LEVEL_DEFAULT + verbose->count - quiet->count);

	// Set global path variable.
	osutil_setarg0(bautofree(bfromcstr(argv[0])));

	// Run the preprocessor.
	ppfind_add_path(bautofree(bfromcstr(".")));
	ppfind_add_path(bautofree(bfromcstr("include")));
	ppfind_add_autopath(bautofree(bfromcstr(input_file->filename[0])));
	for (int i = 0; i < include_dirs->count; ++i)
		ppfind_add_path(bautofree(bfromcstr(include_dirs->filename[i])));
	bstring pp_result_name = pp_do(bautofree(bfromcstr(input_file->filename[0])));

	if (pp_result_name == NULL)
	{
		fprintf(stderr, "compiler: invalid result returned from preprocessor.\n");
		pp_cleanup(bautofree(pp_result_name));
		arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0]));
		return 1;
	}

	// Parse C.
	yyout = stderr;
	yyin = fopen((const char*)(pp_result_name->data), "r");

	if (yyin == NULL)
	{
		pp_cleanup(bautofree(pp_result_name));
		arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0]));
		return 1;
	}

	yyparse();

	if (yyin != stdin)
		fclose(yyin);

	pp_cleanup(bautofree(pp_result_name));

	if (program == NULL)
	{
		std::cerr << "An error occurred while compiling." << std::endl;
		arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0]));
		return 1;
	}

	// Assembler type.
	const char* asmtype = "toolchain";

	if (type_assembler->count > 0)
		asmtype = type_assembler->sval[0];

	// Initially save to a temporary file.
	std::string temp = std::string(tempnam(".", "cc."));

	// Generate assembly using the AST.
	try
	{
		AsmGenerator generator(asmtype);
		AsmBlock* block = program->compile(generator);

		std::ofstream output(temp.c_str(), std::ios::out | std::ios::trunc);
		if (output.bad() || output.fail())
		{
			printd(LEVEL_ERROR, "compiler: temporary file not writable.\n");
			arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0]));
			return 1;
		}
		output << *block << std::endl;
		output.close();

		delete block;
	}
	catch (CompilerException* ex)
	{
		std::string msg = ex->getMessage();
		std::cerr << "An error occurred while compiling." << std::endl;
		std::cerr << msg << std::endl;
		arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0]));
		return 1;
	}

	// Re-open the temporary file for reading.
	std::ifstream input(temp.c_str(), std::ios::in);
	if (input.bad() || input.fail())
	{
		printd(LEVEL_ERROR, "compiler: temporary file not readable.\n");
		arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0]));
		return 1;
	}

	// Open the output file.
	std::ostream* output;
	if (strcmp(output_file->filename[0], "-") != 0)
	{
		// Write to file.
		output = new std::ofstream(output_file->filename[0], std::ios::out | std::ios::trunc);

		if (output->bad() || output->fail())
		{
			printd(LEVEL_ERROR, "compiler: output file not readable.\n");
			arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0]));
			return 1;
		}
	}
	else
	{
		// Set output to cout.
		output = &std::cout;
	}

	// Copy data.
	std::copy(std::istreambuf_iterator<char>(input), std::istreambuf_iterator<char>(), std::ostreambuf_iterator<char>(*output));

	// Close files and delete temporary.
	if (strcmp(output_file->filename[0], "-") != 0)
	{
		((std::ofstream*)output)->close();
		delete output;
	}
	input.close();
	unlink(temp.c_str());

	arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0]));
	return 0;
}
Esempio n. 17
0
/*
 *	The main guy.
 */
int main(int argc, char *argv[])
{
	int rcode = EXIT_SUCCESS;
	int argval;
	const char *input_file = NULL;
	const char *output_file = NULL;
	const char *filter_file = NULL;
	FILE *fp;
	REQUEST *request = NULL;
	VALUE_PAIR *vp;
	VALUE_PAIR *filter_vps = NULL;
	bool xlat_only = false;
	fr_state_tree_t *state = NULL;

	fr_talloc_fault_setup();

	/*
	 *	If the server was built with debugging enabled always install
	 *	the basic fatal signal handlers.
	 */
#ifndef NDEBUG
	if (fr_fault_setup(getenv("PANIC_ACTION"), argv[0]) < 0) {
		fr_perror("unittest");
		exit(EXIT_FAILURE);
	}
#endif

	rad_debug_lvl = 0;
	set_radius_dir(NULL, RADIUS_DIR);

	/*
	 *	Ensure that the configuration is initialized.
	 */
	memset(&main_config, 0, sizeof(main_config));
	main_config.name = "unittest";

	/*
	 *	The tests should have only IPs, not host names.
	 */
	fr_hostname_lookups = false;

	/*
	 *	We always log to stdout.
	 */
	fr_log_fp = stdout;
	default_log.dst = L_DST_STDOUT;
	default_log.fd = STDOUT_FILENO;

	/*  Process the options.  */
	while ((argval = getopt(argc, argv, "d:D:f:hi:mMn:o:O:xX")) != EOF) {

		switch (argval) {
			case 'd':
				set_radius_dir(NULL, optarg);
				break;

			case 'D':
				main_config.dictionary_dir = talloc_typed_strdup(NULL, optarg);
				break;

			case 'f':
				filter_file = optarg;
				break;

			case 'h':
				usage(0);
				break;

			case 'i':
				input_file = optarg;
				break;

			case 'm':
				main_config.debug_memory = true;
				break;

			case 'M':
				memory_report = true;
				main_config.debug_memory = true;
				break;

			case 'n':
				main_config.name = optarg;
				break;

			case 'o':
				output_file = optarg;
				break;

			case 'O':
				if (strcmp(optarg, "xlat_only") == 0) {
					xlat_only = true;
					break;
				}

				fprintf(stderr, "Unknown option '%s'\n", optarg);
				exit(EXIT_FAILURE);

			case 'X':
				rad_debug_lvl += 2;
				main_config.log_auth = true;
				main_config.log_auth_badpass = true;
				main_config.log_auth_goodpass = true;
				break;

			case 'x':
				rad_debug_lvl++;
				break;

			default:
				usage(1);
				break;
		}
	}

	if (rad_debug_lvl) version_print();
	fr_debug_lvl = rad_debug_lvl;

	/*
	 *	Mismatch between the binary and the libraries it depends on
	 */
	if (fr_check_lib_magic(RADIUSD_MAGIC_NUMBER) < 0) {
		fr_perror("%s", main_config.name);
		exit(EXIT_FAILURE);
	}

	/*
	 *  Initialising OpenSSL once, here, is safer than having individual modules do it.
	 */
#ifdef HAVE_OPENSSL_CRYPTO_H
	if (tls_global_init() < 0) {
		rcode = EXIT_FAILURE;
		goto finish;
	}
#endif

	if (xlat_register(NULL, "poke", xlat_poke, NULL, NULL, 0, XLAT_DEFAULT_BUF_LEN) < 0) {
		rcode = EXIT_FAILURE;
		goto finish;
	}

	if (map_proc_register(NULL, "test-fail", mod_map_proc, NULL,  NULL, 0) < 0) {
		rcode = EXIT_FAILURE;
		goto finish;
	}


	/*  Read the configuration files, BEFORE doing anything else.  */
	if (main_config_init() < 0) {
	exit_failure:
		rcode = EXIT_FAILURE;
		goto finish;
	}

	/*
	 *	Setup dummy virtual server
	 */
	cf_section_add(main_config.config, cf_section_alloc(main_config.config, "server", "unit_test"));

	/*
	 *	Initialize Auth-Type, etc. in the virtual servers
	 *	before loading the modules.  Some modules need those
	 *	to be defined.
	 */
	if (virtual_servers_bootstrap(main_config.config) < 0) goto exit_failure;

	/*
	 *	Bootstrap the modules.  This links to them, and runs
	 *	their "bootstrap" routines.
	 *
	 *	After this step, all dynamic attributes, xlats, etc. are defined.
	 */
	if (modules_bootstrap(main_config.config) < 0) exit(EXIT_FAILURE);

	/*
	 *	Load the modules
	 */
	if (modules_init(main_config.config) < 0) goto exit_failure;

	/*
	 *	And then load the virtual servers.
	 */
	if (virtual_servers_init(main_config.config) < 0) goto exit_failure;

	state = fr_state_tree_init(NULL, main_config.max_requests * 2, 10);

	/*
	 *  Set the panic action (if required)
	 */
	{
		char const *panic_action = NULL;

		panic_action = getenv("PANIC_ACTION");
		if (!panic_action) panic_action = main_config.panic_action;

		if (panic_action && (fr_fault_setup(panic_action, argv[0]) < 0)) {
			fr_perror("%s", main_config.name);
			exit(EXIT_FAILURE);
		}
	}

	setlinebuf(stdout); /* unbuffered output */

	if (!input_file || (strcmp(input_file, "-") == 0)) {
		fp = stdin;
	} else {
		fp = fopen(input_file, "r");
		if (!fp) {
			fprintf(stderr, "Failed reading %s: %s\n",
				input_file, strerror(errno));
			rcode = EXIT_FAILURE;
			goto finish;
		}
	}

	/*
	 *	For simplicity, read xlat's.
	 */
	if (xlat_only) {
		if (!do_xlats(input_file, fp)) rcode = EXIT_FAILURE;
		if (input_file) fclose(fp);
		goto finish;
	}

	/*
	 *	Grab the VPs from stdin, or from the file.
	 */
	request = request_setup(fp);
	if (!request) {
		fprintf(stderr, "Failed reading input: %s\n", fr_strerror());
		rcode = EXIT_FAILURE;
		goto finish;
	}

	/*
	 *	No filter file, OR there's no more input, OR we're
	 *	reading from a file, and it's different from the
	 *	filter file.
	 */
	if (!filter_file || filedone ||
	    ((input_file != NULL) && (strcmp(filter_file, input_file) != 0))) {
		if (output_file) {
			fclose(fp);
			fp = NULL;
		}
		filedone = false;
	}

	/*
	 *	There is a filter file.  If necessary, open it.  If we
	 *	already are reading it via "input_file", then we don't
	 *	need to re-open it.
	 */
	if (filter_file) {
		if (!fp) {
			fp = fopen(filter_file, "r");
			if (!fp) {
				fprintf(stderr, "Failed reading %s: %s\n", filter_file, strerror(errno));
				rcode = EXIT_FAILURE;
				goto finish;
			}
		}


		if (fr_pair_list_afrom_file(request, &filter_vps, fp, &filedone) < 0) {
			fprintf(stderr, "Failed reading attributes from %s: %s\n",
				filter_file, fr_strerror());
			rcode = EXIT_FAILURE;
			goto finish;
		}

		/*
		 *	FIXME: loop over input packets.
		 */
		fclose(fp);
	}

	rad_virtual_server(request);

	if (!output_file || (strcmp(output_file, "-") == 0)) {
		fp = stdout;
	} else {
		fp = fopen(output_file, "w");
		if (!fp) {
			fprintf(stderr, "Failed writing %s: %s\n",
				output_file, strerror(errno));
			exit(EXIT_FAILURE);
		}
	}

	print_packet(fp, request->reply);

	if (output_file) fclose(fp);

	/*
	 *	Update the list with the response type.
	 */
	vp = radius_pair_create(request->reply, &request->reply->vps,
			       PW_RESPONSE_PACKET_TYPE, 0);
	vp->vp_integer = request->reply->code;

	{
		VALUE_PAIR const *failed[2];

		if (filter_vps && !fr_pair_validate(failed, filter_vps, request->reply->vps)) {
			fr_pair_validate_debug(request, failed);
			fr_perror("Output file %s does not match attributes in filter %s (%s)",
				  output_file ? output_file : input_file, filter_file, fr_strerror());
			rcode = EXIT_FAILURE;
			goto finish;
		}
	}

	INFO("Exiting normally");

finish:
	talloc_free(request);
	talloc_free(state);

	/*
	 *	Free the configuration items.
	 */
	main_config_free();

	/*
	 *	Detach any modules.
	 */
	modules_free();

	xlat_unregister(NULL, "poke", xlat_poke);

	xlat_free();		/* modules may have xlat's */

	if (memory_report) {
		INFO("Allocated memory at time of report:");
		fr_log_talloc_report(NULL);
	}

	return rcode;
}
Esempio n. 18
0
static void minit_getopt(int argc, char *argv[])
{
  int r;
  struct option opt[]={
    {"chroot",  0, NULL, 'c'},
    {"core",    0, NULL, 'C'},
    {"help",    0, NULL, 'h'},
    {"version", 0, NULL, 'V'},
    {0, 0, 0, 0}
  };

  while((r=getopt_long(argc, argv, "T:R:S:f:u:g:G:d:b:p:m:i:l:U:k:K:VhnsroOcC", opt, NULL)) != -1){
    switch(r){
      case 'V':
        version_print();
        exit(0);

      case 'h':
        usage();
        exit(0);

      case 'T':
        moption.sendrate = atoi(optarg) * 1024 * 1024 / 8;
        break;

      case 'R':
        moption.recvsize = atoi(optarg);
        break;

      case 'S':
        moption.sendsize = atoi(optarg);
        break;

      case 'f':
        moption.parallel = atoi(optarg);
        if(moption.parallel < 1){
          moption.parallel = 1;
        }
        if(moption.parallel >= MAKUO_PARALLEL_MAX){
          moption.parallel = MAKUO_PARALLEL_MAX - 1;
        }
        break;

      case 'n':
        moption.dontfork = 1;
        break;

      case 's':
        moption.dontsend = 1;
        break;

      case 'r':
        moption.dontrecv = 1;
        break;

      case 'o':
        moption.comm_ena = 0;
        break;

      case 'C':
        moption.core_ena = 1;
        break;

      case 'c':
        moption.chroot = 1;
        break;

      case 'd':
        moption.loglevel = atoi(optarg);
        break;

      case 'u':
        if(minit_option_setuid(optarg)){
          exit(1);
        }
        break;

      case 'g':
        if(minit_option_setgid(optarg)){
          exit(1);
        }
        break;

      case 'G':
        if(minit_option_setgids(optarg)){
          exit(1);
        }
        break;

      case 'b':
        realpath(optarg, moption.base_dir);
        break;

      case 'm':
        moption.maddr.sin_addr.s_addr = inet_addr(optarg);
        break;

      case 'i':
        moption.iaddr.sin_addr.s_addr = inet_addr(optarg);
        break;

      case 'l':
        moption.laddr.sin_addr.s_addr = inet_addr(optarg);
        break;

      case 'U':
        strcpy(moption.uaddr.sun_path, optarg);
        break;

      case 'p':
        moption.laddr.sin_port = htons(atoi(optarg));
        moption.maddr.sin_port = htons(atoi(optarg));
        break;

      case 'K':
        moption.commpass = 1;
        minit_password(optarg, 0);
        break;

      case 'k':
        moption.cryptena = 1;
        minit_password(optarg, 1);
        break;

      case 'O':
        moption.ownmatch = 1;
        break;
  
      case '?':
        exit(1);
    }
  }
  log_level = moption.loglevel;
}
Esempio n. 19
0
int main(int argc, char *argv[])
{
	argv++;
	argc--;
	if (argc < 4) {
		usage();
		return 1;
	}
	
	char *term = *argv;
	argv++;
	argc--;
	
	char *locfs = *argv;
	argv++;
	argc--;
	
	bool print_msg = false;
	bool wait = false;
	
	while ((argc > 0) && (str_cmp(*argv, "--") != 0)) {
		if (str_cmp(*argv, "--msg") == 0) {
			print_msg = true;
		} else if (str_cmp(*argv, "--wait") == 0) {
			wait = true;
		} else {
			usage();
			return 2;
		}
		
		argv++;
		argc--;
	}
	
	if (argc < 1) {
		usage();
		return 3;
	}
	
	/* Skip "--" */
	argv++;
	argc--;
	
	char *cmd = *argv;
	char **args = argv;
	
	if (wait) {
		/* Wait for the terminal service to be ready */
		service_id_t service_id;
		int rc = loc_service_get_id(term, &service_id, IPC_FLAG_BLOCKING);
		if (rc != EOK) {
			printf("%s: Error waiting on %s (%s)\n", APP_NAME, term,
			    str_error(rc));
			return rc;
		}
	}
	
	char term_node[LOC_NAME_MAXLEN];
	snprintf(term_node, LOC_NAME_MAXLEN, "%s/%s", locfs, term);
	
	reopen(&stdin, 0, term_node, O_RDONLY, "r");
	reopen(&stdout, 1, term_node, O_WRONLY, "w");
	reopen(&stderr, 2, term_node, O_WRONLY, "w");
	
	if (stdin == NULL)
		return 4;
	
	if (stdout == NULL)
		return 5;
	
	if (stderr == NULL)
		return 6;
	
	/*
	 * FIXME: fdopen() should actually detect that we are opening a console
	 * and it should set line-buffering mode automatically.
	 */
	setvbuf(stdout, NULL, _IOLBF, BUFSIZ);
	
	version_print(term);
	if (print_msg)
		welcome_msg_print();
	
	task_id_t id;
	task_wait_t twait;
	
	int rc = task_spawnv(&id, &twait, cmd, (const char * const *) args);
	if (rc != EOK) {
		printf("%s: Error spawning %s (%s)\n", APP_NAME, cmd,
		    str_error(rc));
		return rc;
	}
	
	task_exit_t texit;
	int retval;
	rc = task_wait(&twait, &texit, &retval);
	if (rc != EOK) {
		printf("%s: Error waiting for %s (%s)\n", APP_NAME, cmd,
		    str_error(rc));
		return rc;
	}
	
	return 0;
}
Esempio n. 20
0
int main(int argc, char* argv[])
{
    // Define our variables.
    int nerrors, i;
    int32_t saved = 0; // The number of words saved during compression and optimization.
    struct errinfo* errval;
    const char* prepend = "error: ";
    const char* warnprefix = "no-";
    int msglen;
    char* msg;
    int target;

    // Define arguments.
    struct arg_lit* show_help = arg_lit0("h", "help", "Show this help.");
    struct arg_str* target_arg = arg_str0("l", "link-as", "target", "Link as the specified object, can be 'image', 'static' or 'kernel'.");
    struct arg_file* symbol_file = arg_file0("s", "symbols", "<file>", "Produce a combined symbol file (~triples memory usage!).");
    struct arg_str* symbol_ext = arg_str0(NULL, "symbol-extension", "ext", "When -s is used, specifies the extension for symbol files.  Defaults to \"dsym16\".");
    struct arg_file* input_files = arg_filen(NULL, NULL, "<file>", 1, 100, "The input object files.");
    struct arg_file* output_file = arg_file1("o", "output", "<file>", "The output file (or - to send to standard output).");
    struct arg_file* kernel_file = arg_file0("k", "kernel", "<file>", "Directly link in the specified kernel.");
    struct arg_file* jumplist_file = arg_file0("j", "jumplist", "<file>", "Link against the specified jumplist.");
    struct arg_str* warning_policies = arg_strn("W", NULL, "policy", 0, _WARN_COUNT * 2 + 10, "Modify warning policies.");
    struct arg_lit* keep_output_arg = arg_lit0(NULL, "keep-outputs", "Keep the .OUTPUT entries in the final static library (used for stdlib).");
    struct arg_lit* little_endian_mode = arg_lit0(NULL, "little-endian", "Use little endian serialization (for compatibility with older versions).");
    struct arg_lit* no_short_literals_arg = arg_lit0(NULL, "no-short-literals", "Do not compress literals to short literals.");
    struct arg_int* opt_level = arg_int0("O", NULL, "<level>", "The optimization level.");
    struct arg_lit* opt_mode = arg_lit0("S", NULL, "Favour runtime speed over size when optimizing.");
    struct arg_lit* verbose = arg_litn("v", NULL, 0, LEVEL_EVERYTHING - LEVEL_DEFAULT, "Increase verbosity.");
    struct arg_lit* quiet = arg_litn("q", NULL,  0, LEVEL_DEFAULT - LEVEL_SILENT, "Decrease verbosity.");
    struct arg_end* end = arg_end(20);
    void* argtable[] = { show_help, target_arg, keep_output_arg, little_endian_mode, opt_level, opt_mode, no_short_literals_arg,
                         symbol_ext, symbol_file, kernel_file, jumplist_file, warning_policies, output_file, input_files, verbose, quiet, end
                       };

    // Parse arguments.
    nerrors = arg_parse(argc, argv, argtable);

    version_print(bautofree(bfromcstr("Linker")));
    if (nerrors != 0 || show_help->count != 0)
    {
        if (show_help->count != 0)
            arg_print_errors(stdout, end, "linker");

        printd(LEVEL_DEFAULT, "syntax:\n    dtld");
        arg_print_syntax(stderr, argtable, "\n");
        printd(LEVEL_DEFAULT, "options:\n");
        arg_print_glossary(stderr, argtable, "    %-25s %s\n");
        arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0]));
        return 1;
    }

    // Set verbosity level.
    debug_setlevel(LEVEL_DEFAULT + verbose->count - quiet->count);

    // Set global path variable.
    osutil_setarg0(bautofree(bfromcstr(argv[0])));

    // Set endianness.
    isetmode(little_endian_mode->count == 0 ? IMODE_BIG : IMODE_LITTLE);

    // Set up warning policies.
    dsetwarnpolicy(warning_policies);

    // Set up error handling.
    if (dsethalt())
    {
        errval = derrinfo();

        // FIXME: Use bstrings here.
        msglen = strlen(derrstr[errval->errid]) + strlen(prepend) + 1;
        msg = malloc(msglen);
        memset(msg, '\0', msglen);
        strcat(msg, prepend);
        strcat(msg, derrstr[errval->errid]);
        printd(LEVEL_ERROR, msg, errval->errdata);

        // Handle the error.
        printd(LEVEL_ERROR, "linker: error occurred.\n");

        arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0]));
        return 1;
    }

    // Check to make sure target is correct.
    if (target_arg->count == 0)
        target = IMAGE_APPLICATION;
    else
    {
        if (strcmp(target_arg->sval[0], "image") == 0)
            target = IMAGE_APPLICATION;
        else if (strcmp(target_arg->sval[0], "static") == 0)
            target = IMAGE_STATIC_LIBRARY;
        else if (strcmp(target_arg->sval[0], "kernel") == 0)
            target = IMAGE_KERNEL;
        else
        {
            // Invalid option.
            dhalt(ERR_INVALID_TARGET_NAME, NULL);
        }
    }

    // Load all passed objects and use linker bin system to
    // produce result.
    bins_init();
    for (i = 0; i < input_files->count; i++)
        if (!bins_load(bautofree(bfromcstr(input_files->filename[i])), symbol_file->count > 0, (symbol_file->count > 0 && symbol_ext->count > 0) ? symbol_ext->sval[0] : "dsym16"))
            // Failed to load one of the input files.
            dhalt(ERR_BIN_LOAD_FAILED, input_files->filename[i]);
    bins_associate();
    bins_sectionize();
    bins_flatten(bautofree(bfromcstr("output")));
    if (target == IMAGE_KERNEL)
        bins_write_jump();
    saved = bins_optimize(
                opt_mode->count == 0 ? OPTIMIZE_SIZE : OPTIMIZE_SPEED,
                opt_level->count == 0 ? OPTIMIZE_NONE : opt_level->ival[0]);
    if (no_short_literals_arg->count == 0 && target != IMAGE_STATIC_LIBRARY)
        saved += bins_compress();
    else if (no_short_literals_arg->count == 0)
        dwarn(WARN_SKIPPING_SHORT_LITERALS_TYPE, NULL);
    else
        dwarn(WARN_SKIPPING_SHORT_LITERALS_REQUEST, NULL);
    bins_resolve(
        target == IMAGE_STATIC_LIBRARY,
        target == IMAGE_STATIC_LIBRARY);
    bins_save(
        bautofree(bfromcstr("output")),
        bautofree(bfromcstr(output_file->filename[0])),
        target,
        keep_output_arg->count > 0,
        symbol_file->count > 0 ? symbol_file->filename[0] : NULL,
        jumplist_file->count > 0 ? jumplist_file->filename[0] : NULL);
    bins_free();
    if (saved > 0)
        printd(LEVEL_DEFAULT, "linker: saved %i words during optimization.\n", saved);
    else if (saved < 0)
        printd(LEVEL_DEFAULT, "linker: increased by %i words during optimization.\n", -saved);

    arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0]));
    return 0;
}
Esempio n. 21
0
/*
 *	The main guy.
 */
int main(int argc, char *argv[])
{
	int rcode = EXIT_SUCCESS;
	int status;
	int argval;
	bool spawn_flag = true;
	bool write_pid = false;
	bool display_version = false;
	int flag = 0;
	int from_child[2] = {-1, -1};
	fr_state_t *state = NULL;

	/*
	 *  We probably don't want to free the talloc autofree context
	 *  directly, so we'll allocate a new context beneath it, and
	 *  free that before any leak reports.
	 */
	TALLOC_CTX *autofree = talloc_init("main");

#ifdef OSFC2
	set_auth_parameters(argc, argv);
#endif

	if ((progname = strrchr(argv[0], FR_DIR_SEP)) == NULL)
		progname = argv[0];
	else
		progname++;

#ifdef WIN32
	{
		WSADATA wsaData;
		if (WSAStartup(MAKEWORD(2, 0), &wsaData)) {
			fprintf(stderr, "%s: Unable to initialize socket library.\n", progname);
			exit(EXIT_FAILURE);
		}
	}
#endif

	rad_debug_lvl = 0;
	set_radius_dir(autofree, RADIUS_DIR);

	/*
	 *	Ensure that the configuration is initialized.
	 */
	memset(&main_config, 0, sizeof(main_config));
	main_config.myip.af = AF_UNSPEC;
	main_config.port = 0;
	main_config.name = "radiusd";
	main_config.daemonize = true;

	/*
	 *	Don't put output anywhere until we get told a little
	 *	more.
	 */
	default_log.dst = L_DST_NULL;
	default_log.fd = -1;
	main_config.log_file = NULL;

	/*  Process the options.  */
	while ((argval = getopt(argc, argv, "Cd:D:fhi:l:mMn:p:PstvxX")) != EOF) {

		switch (argval) {
			case 'C':
				check_config = true;
				spawn_flag = false;
				main_config.daemonize = false;
				break;

			case 'd':
				set_radius_dir(autofree, optarg);
				break;

			case 'D':
				main_config.dictionary_dir = talloc_typed_strdup(autofree, optarg);
				break;

			case 'f':
				main_config.daemonize = false;
				break;

			case 'h':
				usage(0);
				break;

			case 'l':
				if (strcmp(optarg, "stdout") == 0) {
					goto do_stdout;
				}
				main_config.log_file = strdup(optarg);
				default_log.dst = L_DST_FILES;
				default_log.fd = open(main_config.log_file,
							    O_WRONLY | O_APPEND | O_CREAT, 0640);
				if (default_log.fd < 0) {
					fprintf(stderr, "radiusd: Failed to open log file %s: %s\n", main_config.log_file, fr_syserror(errno));
					exit(EXIT_FAILURE);
				}
				fr_log_fp = fdopen(default_log.fd, "a");
				break;

			case 'i':
				if (ip_hton(&main_config.myip, AF_UNSPEC, optarg, false) < 0) {
					fprintf(stderr, "radiusd: Invalid IP Address or hostname \"%s\"\n", optarg);
					exit(EXIT_FAILURE);
				}
				flag |= 1;
				break;

			case 'n':
				main_config.name = optarg;
				break;

			case 'm':
				main_config.debug_memory = true;
				break;

			case 'M':
				main_config.memory_report = true;
				main_config.debug_memory = true;
				break;

			case 'p':
			{
				unsigned long port;

				port = strtoul(optarg, 0, 10);
				if ((port == 0) || (port > UINT16_MAX)) {
					fprintf(stderr, "radiusd: Invalid port number \"%s\"\n", optarg);
					exit(EXIT_FAILURE);
				}

				main_config.port = (uint16_t) port;
				flag |= 2;
			}
				break;

			case 'P':
				/* Force the PID to be written, even in -f mode */
				write_pid = true;
				break;

			case 's':	/* Single process mode */
				spawn_flag = false;
				main_config.daemonize = false;
				break;

			case 't':	/* no child threads */
				spawn_flag = false;
				break;

			case 'v':
				display_version = true;
				break;

			case 'X':
				spawn_flag = false;
				main_config.daemonize = false;
				rad_debug_lvl += 2;
				main_config.log_auth = true;
				main_config.log_auth_badpass = true;
				main_config.log_auth_goodpass = true;
		do_stdout:
				fr_log_fp = stdout;
				default_log.dst = L_DST_STDOUT;
				default_log.fd = STDOUT_FILENO;
				break;

			case 'x':
				rad_debug_lvl++;
				break;

			default:
				usage(1);
				break;
		}
	}

	/*
	 *  Mismatch between the binary and the libraries it depends on.
	 */
	if (fr_check_lib_magic(RADIUSD_MAGIC_NUMBER) < 0) {
		fr_perror("radiusd");
		exit(EXIT_FAILURE);
	}

	if (rad_check_lib_magic(RADIUSD_MAGIC_NUMBER) < 0) exit(EXIT_FAILURE);

	/*
	 *  Mismatch between build time OpenSSL and linked SSL, better to die
	 *  here than segfault later.
	 */
#ifdef HAVE_OPENSSL_CRYPTO_H
	if (ssl_check_consistency() < 0) exit(EXIT_FAILURE);
#endif

	if (flag && (flag != 0x03)) {
		fprintf(stderr, "radiusd: The options -i and -p cannot be used individually.\n");
		exit(EXIT_FAILURE);
	}

	/*
	 *  According to the talloc peeps, no two threads may modify any part of
	 *  a ctx tree with a common root without synchronisation.
	 *
	 *  So we can't run with a null context and threads.
	 */
	if (main_config.memory_report) {
		if (spawn_flag) {
			fprintf(stderr, "radiusd: The server cannot produce memory reports (-M) in threaded mode\n");
			exit(EXIT_FAILURE);
		}
		talloc_enable_null_tracking();
	} else {
		talloc_disable_null_tracking();
	}

	/*
	 *  Better here, so it doesn't matter whether we get passed -xv or -vx.
	 */
	if (display_version) {
		/* Don't print timestamps */
		rad_debug_lvl += 2;
		fr_log_fp = stdout;
		default_log.dst = L_DST_STDOUT;
		default_log.fd = STDOUT_FILENO;

		INFO("%s: %s", progname, radiusd_version);
		version_print();
		exit(EXIT_SUCCESS);
	}

	if (rad_debug_lvl) version_print();

	/*
	 *  Under linux CAP_SYS_PTRACE is usually only available before setuid/setguid,
	 *  so we need to check whether we can attach before calling those functions
	 *  (in main_config_init()).
	 */
	fr_store_debug_state();

	/*
	 *  Initialising OpenSSL once, here, is safer than having individual modules do it.
	 */
#ifdef HAVE_OPENSSL_CRYPTO_H
	tls_global_init();
#endif

	/*
	 *  Read the configuration files, BEFORE doing anything else.
	 */
	if (main_config_init() < 0) exit(EXIT_FAILURE);

	/*
	 *  This is very useful in figuring out why the panic_action didn't fire.
	 */
	INFO("%s", fr_debug_state_to_msg(fr_debug_state));

	/*
	 *  Check for vulnerabilities in the version of libssl were linked against.
	 */
#if defined(HAVE_OPENSSL_CRYPTO_H) && defined(ENABLE_OPENSSL_VERSION_CHECK)
	if (tls_global_version_check(main_config.allow_vulnerable_openssl) < 0) exit(EXIT_FAILURE);
#endif

	fr_talloc_fault_setup();

	/*
	 *  Set the panic action (if required)
	 */
	{
		char const *panic_action = NULL;

		panic_action = getenv("PANIC_ACTION");
		if (!panic_action) panic_action = main_config.panic_action;

		if (panic_action && (fr_fault_setup(panic_action, argv[0]) < 0)) {
			fr_perror("radiusd");
			exit(EXIT_FAILURE);
		}
	}

#ifndef __MINGW32__
	/*
	 *  Disconnect from session
	 */
	if (main_config.daemonize) {
		pid_t pid;
		int devnull;

		/*
		 *  Really weird things happen if we leave stdin open and call things like
		 *  system() later.
		 */
		devnull = open("/dev/null", O_RDWR);
		if (devnull < 0) {
			ERROR("Failed opening /dev/null: %s", fr_syserror(errno));
			exit(EXIT_FAILURE);
		}
		dup2(devnull, STDIN_FILENO);

		close(devnull);

		if (pipe(from_child) != 0) {
			ERROR("Couldn't open pipe for child status: %s", fr_syserror(errno));
			exit(EXIT_FAILURE);
		}

		pid = fork();
		if (pid < 0) {
			ERROR("Couldn't fork: %s", fr_syserror(errno));
			exit(EXIT_FAILURE);
		}

		/*
		 *  The parent exits, so the child can run in the background.
		 *
		 *  As the child can still encounter an error during initialisation
		 *  we do a blocking read on a pipe between it and the parent.
		 *
		 *  Just before entering the event loop the child will send a success
		 *  or failure message to the parent, via the pipe.
		 */
		if (pid > 0) {
			uint8_t ret = 0;
			int stat_loc;

			/* So the pipe is correctly widowed if the child exits */
			close(from_child[1]);

			/*
			 *  The child writes a 0x01 byte on success, and closes
			 *  the pipe on error.
			 */
			if ((read(from_child[0], &ret, 1) < 0)) {
				ret = 0;
			}

			/* For cleanliness... */
			close(from_child[0]);

			/* Don't turn children into zombies */
			if (!ret) {
				waitpid(pid, &stat_loc, WNOHANG);
				exit(EXIT_FAILURE);
			}

			exit(EXIT_SUCCESS);
		}

		/* so the pipe is correctly widowed if the parent exits?! */
		close(from_child[0]);
#  ifdef HAVE_SETSID
		setsid();
#  endif
	}
#endif

	/*
	 *  Ensure that we're using the CORRECT pid after forking, NOT the one
	 *  we started with.
	 */
	radius_pid = getpid();

	/*
	 *  Initialize any event loops just enough so module instantiations can
	 *  add fd/event to them, but do not start them yet.
	 *
	 *  This has to be done post-fork in case we're using kqueue, where the
	 *  queue isn't inherited by the child process.
	 */
	if (!radius_event_init(autofree)) exit(EXIT_FAILURE);

	/*
	 *   Load the modules
	 */
	if (modules_init(main_config.config) < 0) exit(EXIT_FAILURE);

	/*
	 *  Redirect stderr/stdout as appropriate.
	 */
	if (radlog_init(&default_log, main_config.daemonize) < 0) {
		ERROR("%s", fr_strerror());
		exit(EXIT_FAILURE);
	}

	event_loop_started = true;

	/*
	 *  Start the event loop(s) and threads.
	 */
	radius_event_start(main_config.config, spawn_flag);

	/*
	 *  Now that we've set everything up, we can install the signal
	 *  handlers.  Before this, if we get any signal, we don't know
	 *  what to do, so we might as well do the default, and die.
	 */
#ifdef SIGPIPE
	signal(SIGPIPE, SIG_IGN);
#endif

	if ((fr_set_signal(SIGHUP, sig_hup) < 0) ||
	    (fr_set_signal(SIGTERM, sig_fatal) < 0)) {
		ERROR("%s", fr_strerror());
		exit(EXIT_FAILURE);
	}

	/*
	 *  If we're debugging, then a CTRL-C will cause the server to die
	 *  immediately.  Use SIGTERM to shut down the server cleanly in
	 *  that case.
	 */
	if (main_config.debug_memory || (rad_debug_lvl == 0)) {
		if ((fr_set_signal(SIGINT, sig_fatal) < 0)
#ifdef SIGQUIT
		|| (fr_set_signal(SIGQUIT, sig_fatal) < 0)
#endif
		) {
			ERROR("%s", fr_strerror());
			exit(EXIT_FAILURE);
		}
	}

	/*
	 *  Everything seems to have loaded OK, exit gracefully.
	 */
	if (check_config) {
		DEBUG("Configuration appears to be OK");

		/* for -C -m|-M */
		if (main_config.debug_memory) goto cleanup;

		exit(EXIT_SUCCESS);
	}

#ifdef WITH_STATS
	radius_stats_init(0);
#endif

	/*
	 *  Write the PID always if we're running as a daemon.
	 */
	if (main_config.daemonize) write_pid = true;

	/*
	 *  Write the PID after we've forked, so that we write the correct one.
	 */
	if (write_pid) {
		FILE *fp;

		fp = fopen(main_config.pid_file, "w");
		if (fp != NULL) {
			/*
			 *  @fixme What about following symlinks,
			 *  and having it over-write a normal file?
			 */
			fprintf(fp, "%d\n", (int) radius_pid);
			fclose(fp);
		} else {
			ERROR("Failed creating PID file %s: %s", main_config.pid_file, fr_syserror(errno));
			exit(EXIT_FAILURE);
		}
	}

	exec_trigger(NULL, NULL, "server.start", false);

	/*
	 *  Inform the parent (who should still be waiting) that the rest of
	 *  initialisation went OK, and that it should exit with a 0 status.
	 *  If we don't get this far, then we just close the pipe on exit, and the
	 *  parent gets a read failure.
	 */
	if (main_config.daemonize) {
		if (write(from_child[1], "\001", 1) < 0) {
			WARN("Failed informing parent of successful start: %s",
			     fr_syserror(errno));
		}
		close(from_child[1]);
	}

	/*
	 *  Clear the libfreeradius error buffer.
	 */
	fr_strerror();

	/*
	 *  Initialise the state rbtree (used to link multiple rounds of challenges).
	 */
	state = fr_state_init(NULL, 0);

	/*
	 *  Process requests until HUP or exit.
	 */
	while ((status = radius_event_process()) == 0x80) {
#ifdef WITH_STATS
		radius_stats_init(1);
#endif
		main_config_hup();
	}
	if (status < 0) {
		ERROR("Exiting due to internal error: %s", fr_strerror());
		rcode = EXIT_FAILURE;
	} else {
		INFO("Exiting normally");
	}

	/*
	 *  Ignore the TERM signal: we're about to die.
	 */
	signal(SIGTERM, SIG_IGN);

	/*
	 *   Fire signal and stop triggers after ignoring SIGTERM, so handlers are
	 *   not killed with the rest of the process group, below.
	 */
	if (status == 2) exec_trigger(NULL, NULL, "server.signal.term", true);
	exec_trigger(NULL, NULL, "server.stop", false);

	/*
	 *  Send a TERM signal to all associated processes
	 *  (including us, which gets ignored.)
	 */
#ifndef __MINGW32__
	if (spawn_flag) kill(-radius_pid, SIGTERM);
#endif

	/*
	 *  We're exiting, so we can delete the PID file.
	 *  (If it doesn't exist, we can ignore the error returned by unlink)
	 */
	if (main_config.daemonize) unlink(main_config.pid_file);

	radius_event_free();

cleanup:
	/*
	 *  Detach any modules.
	 */
	modules_free();

	xlat_free();		/* modules may have xlat's */

	fr_state_delete(state);

	/*
	 *  Free the configuration items.
	 */
	main_config_free();

#ifdef WIN32
	WSACleanup();
#endif

#ifdef HAVE_OPENSSL_CRYPTO_H
	tls_global_cleanup();
#endif
	/*
	 *  So we don't see autofreed memory in the talloc report
	 */
	talloc_free(autofree);

	if (main_config.memory_report) {
		INFO("Allocated memory at time of report:");
		fr_log_talloc_report(NULL);
	}

	return rcode;
}