Beispiel #1
0
/**
 * Second half of command line parsing. See ParseCommandLineEarly() for
 * the first half. Note that render mode must come before resolution flag.
 * \param argc number of arguments given
 * \param argv string array of the arguments
 * \return Returns true on success, false on error */
bool ParseCommandLine(int argc, const char **argv)
{
	poptContext poptCon = poptGetContext(nullptr, argc, argv, getOptionsTable(), 0);
	int iOption;

	/* loop through command line */
	while ((iOption = poptGetNextOpt(poptCon)) > 0)
	{
		const char *token;
		CLI_OPTIONS option = (CLI_OPTIONS)iOption;

		switch (option)
		{
		case CLI_DEBUG:
		case CLI_DEBUGFILE:
		case CLI_FLUSHDEBUGSTDERR:
		case CLI_CONFIGDIR:
		case CLI_HELP:
		case CLI_HELP_ALL:
		case CLI_VERSION:
			// These options are parsed in ParseCommandLineEarly() already, so ignore them
			break;

		case CLI_NOASSERT:
			kf_NoAssert();
			break;

		// NOTE: The sole purpose of this is to test the crash handler.
		case CLI_CRASH:
			CauseCrash = true;
			NetPlay.bComms = false;
			sstrcpy(aLevelName, "CAM_3A");
			SetGameMode(GS_NORMAL);
			break;

		case CLI_DATADIR:
			// retrieve the quoted path name
			token = poptGetOptArg(poptCon);
			if (token == nullptr)
			{
				qFatal("Unrecognised datadir");
			}
			sstrcpy(datadir, token);
			break;

		case CLI_FULLSCREEN:
			war_setFullscreen(true);
			break;
		case CLI_CONNECTTOIP:
			//get the ip we want to connect with, and go directly to join screen.
			token = poptGetOptArg(poptCon);
			if (token == nullptr)
			{
				qFatal("No IP/hostname given");
			}
			sstrcpy(iptoconnect, token);
			break;
		case CLI_HOSTLAUNCH:
			// go directly to host screen, bypass all others.
			hostlaunch = 1;
			break;
		case CLI_GAME:
			// retrieve the game name
			token = poptGetOptArg(poptCon);
			if (token == nullptr
			    || (strcmp(token, "CAM_1A") && strcmp(token, "CAM_2A") && strcmp(token, "CAM_3A")
			        && strcmp(token, "TUTORIAL3") && strcmp(token, "FASTPLAY")))
			{
				qFatal("The game parameter requires one of the following keywords:"
				       "CAM_1A, CAM_2A, CAM_3A, TUTORIAL3, or FASTPLAY.");
			}
			NetPlay.bComms = false;
			bMultiPlayer = false;
			bMultiMessages = false;
			for (int i = 0; i < MAX_PLAYERS; i++)
			{
				NET_InitPlayer(i, true, false);
			}

			//NET_InitPlayer deallocates Player 0, who must be allocated so that a later invocation of processDebugMappings does not trigger DEBUG mode
			NetPlay.players[0].allocated = true;

			if (!strcmp(token, "CAM_1A") || !strcmp(token, "CAM_2A") || !strcmp(token, "CAM_3A"))
			{
				game.type = CAMPAIGN;
			}
			else
			{
				game.type = SKIRMISH; // tutorial is skirmish for some reason
			}
			sstrcpy(aLevelName, token);
			SetGameMode(GS_NORMAL);
			break;
		case CLI_MOD_GLOB:
			{
				// retrieve the file name
				token = poptGetOptArg(poptCon);
				if (token == nullptr)
				{
					qFatal("Missing mod name?");
				}

				global_mods.push_back(token);
				break;
			}
		case CLI_MOD_CA:
			{
				// retrieve the file name
				token = poptGetOptArg(poptCon);
				if (token == nullptr)
				{
					qFatal("Missing mod name?");
				}

				campaign_mods.push_back(token);
				break;
			}
		case CLI_MOD_MP:
			{
				// retrieve the file name
				token = poptGetOptArg(poptCon);
				if (token == nullptr)
				{
					qFatal("Missing mod name?");
				}

				multiplay_mods.push_back(token);
				break;
			}
		case CLI_RESOLUTION:
			{
				unsigned int width, height;

				token = poptGetOptArg(poptCon);
				if (sscanf(token, "%ix%i", &width, &height) != 2)
				{
					qFatal("Invalid parameter specified (format is WIDTHxHEIGHT, e.g. 800x600)");
				}
				if (width < 640)
				{
					debug(LOG_ERROR, "Screen width < 640 unsupported, using 640");
					width = 640;
				}
				if (height < 480)
				{
					debug(LOG_ERROR, "Screen height < 480 unsupported, using 480");
					height = 480;
				}
				// tell the display system of the desired resolution
				pie_SetVideoBufferWidth(width);
				pie_SetVideoBufferHeight(height);
				// and update the configuration
				war_SetWidth(width);
				war_SetHeight(height);
				break;
			}
		case CLI_LOADSKIRMISH:
			// retrieve the game name
			token = poptGetOptArg(poptCon);
			if (token == nullptr)
			{
				qFatal("Unrecognised skirmish savegame name");
			}
			snprintf(saveGameName, sizeof(saveGameName), "%s/skirmish/%s.gam", SaveGamePath, token);
			SPinit();
			bMultiPlayer = true;
			game.type = SKIRMISH; // tutorial is skirmish for some reason
			SetGameMode(GS_SAVEGAMELOAD);
			break;
		case CLI_LOADCAMPAIGN:
			// retrieve the game name
			token = poptGetOptArg(poptCon);
			if (token == nullptr)
			{
				qFatal("Unrecognised campaign savegame name");
			}
			snprintf(saveGameName, sizeof(saveGameName), "%s/campaign/%s.gam", SaveGamePath, token);
			SPinit();
			SetGameMode(GS_SAVEGAMELOAD);
			break;

		case CLI_WINDOW:
			war_setFullscreen(false);
			break;

		case CLI_SHADOWS:
			setDrawShadows(true);
			break;

		case CLI_NOSHADOWS:
			setDrawShadows(false);
			break;

		case CLI_SOUND:
			war_setSoundEnabled(true);
			break;

		case CLI_NOSOUND:
			war_setSoundEnabled(false);
			break;

		case CLI_TEXTURECOMPRESSION:
			wz_texture_compression = true;
			break;

		case CLI_NOTEXTURECOMPRESSION:
			wz_texture_compression = false;
			break;

		case CLI_AUTOGAME:
			wz_autogame = true;
			break;

		case CLI_SAVEANDQUIT:
			token = poptGetOptArg(poptCon);
			if (token == nullptr || !strchr(token, '/'))
			{
				qFatal("Bad savegame name (needs to be a full path)");
			}
			wz_saveandquit = token;
			break;

		case CLI_SKIRMISH:
			hostlaunch = 2;
			token = poptGetOptArg(poptCon);
			if (token == nullptr)
			{
				qFatal("Bad test key");
			}
			wz_test = token;
			break;
		};
	}

	return true;
}
Beispiel #2
0
/*
 * The 'destroy <options>' first level command
 */
int cmd_destroy(int argc, const char **argv)
{
	int opt;
	int ret = CMD_SUCCESS , i, command_ret = CMD_SUCCESS, success = 1;
	static poptContext pc;
	char *session_name = NULL;

	struct lttng_session *sessions;
	int count;
	int found;

	pc = poptGetContext(NULL, argc, argv, long_options, 0);
	poptReadDefaultConfig(pc, 0);

	while ((opt = poptGetNextOpt(pc)) != -1) {
		switch (opt) {
		case OPT_HELP:
			usage(stdout);
			break;
		case OPT_LIST_OPTIONS:
			list_cmd_options(stdout, long_options);
			break;
		default:
			usage(stderr);
			ret = CMD_UNDEFINED;
			break;
		}
		goto end;
	}

	/* Mi preparation */
	if (lttng_opt_mi) {
		writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi);
		if (!writer) {
			ret = -LTTNG_ERR_NOMEM;
			goto end;
		}

		/* Open command element */
		ret = mi_lttng_writer_command_open(writer,
				mi_lttng_element_command_destroy);
		if (ret) {
			ret = CMD_ERROR;
			goto end;
		}

		/* Open output element */
		ret = mi_lttng_writer_open_element(writer,
				mi_lttng_element_command_output);
		if (ret) {
			ret = CMD_ERROR;
			goto end;
		}

		/* For validation and semantic purpose we open a sessions element */
		ret = mi_lttng_sessions_open(writer);
		if (ret) {
			ret = CMD_ERROR;
			goto end;
		}
	}

	/* Recuperate all sessions for further operation */
	count = lttng_list_sessions(&sessions);
	if (count < 0) {
		command_ret = count;
		success = 0;
		goto mi_closing;
	}

	/* Ignore session name in case all sessions are to be destroyed */
	if (opt_destroy_all) {
		command_ret = destroy_all_sessions(sessions, count);
		if (command_ret) {
			success = 0;
		}
	} else {
		opt_session_name = (char *) poptGetArg(pc);

		if (opt_session_name == NULL) {
			/* No session name specified, lookup default */
			session_name = get_session_name();
			if (session_name == NULL) {
				command_ret = CMD_ERROR;
				success = 0;
				goto mi_closing;
			}
		} else {
			session_name = opt_session_name;
		}

		/* Find the corresponding lttng_session struct */
		found = 0;
		for (i = 0; i < count; i++) {
			if (strncmp(sessions[i].name, session_name, NAME_MAX) == 0) {
				found = 1;
				command_ret = destroy_session(&sessions[i]);
				if (command_ret) {
					success = 0;
				}

			}
		}

		if (!found) {
			ERR("Session name %s not found", session_name);
			command_ret = LTTNG_ERR_SESS_NOT_FOUND;
			success = 0;
			goto mi_closing;
		}
	}

mi_closing:
	/* Mi closing */
	if (lttng_opt_mi) {
		/* Close sessions and output element element */
		ret = mi_lttng_close_multi_element(writer, 2);
		if (ret) {
			ret = CMD_ERROR;
			goto end;
		}

		/* Success ? */
		ret = mi_lttng_writer_write_element_bool(writer,
				mi_lttng_element_command_success, success);
		if (ret) {
			ret = CMD_ERROR;
			goto end;
		}

		/* Command element close */
		ret = mi_lttng_writer_command_close(writer);
		if (ret) {
			ret = CMD_ERROR;
			goto end;
		}
	}
end:
	/* Mi clean-up */
	if (writer && mi_lttng_writer_destroy(writer)) {
		/* Preserve original error code */
		ret = ret ? ret : -LTTNG_ERR_MI_IO_FAIL;
	}

	if (opt_session_name == NULL) {
		free(session_name);
	}

	/* Overwrite ret if an error occurred during destroy_session/all */
	ret = command_ret ? command_ret : ret;

	poptFreeContext(pc);
	return ret;
}
Beispiel #3
0
/**
 * Parse %patch line.
 * This supports too many crazy syntaxes:
 * - %patchN is equal to %patch -P<N>
 * - -P<N> -P<N+1>... can be used to apply several patch on a single line
 * - Any trailing arguments are treated as patch numbers
 * - Any combination of the above, except unless at least one -P is specified,
 *   %patch is treated as %patch -P0 so that "%patch 1" is actually
 *   equal to "%patch -P0 -P1".
 *
 * @param spec		build info
 * @param line		current line from spec file
 * @return		RPMRC_OK on success
 */
static rpmRC doPatchMacro(rpmSpec spec, const char *line)
{
    char *opt_b, *opt_P, *opt_d;
    char *buf = NULL;
    int opt_p, opt_R, opt_E, opt_F;
    int argc, c;
    const char **argv = NULL;
    ARGV_t patch, patchnums = NULL;
    rpmRC rc = RPMRC_FAIL; /* assume failure */
    
    struct poptOption const patchOpts[] = {
	{ NULL, 'P', POPT_ARG_STRING, &opt_P, 'P', NULL, NULL },
	{ NULL, 'p', POPT_ARG_INT, &opt_p, 'p', NULL, NULL },
	{ NULL, 'R', POPT_ARG_NONE, &opt_R, 'R', NULL, NULL },
	{ NULL, 'E', POPT_ARG_NONE, &opt_E, 'E', NULL, NULL },
	{ NULL, 'b', POPT_ARG_STRING, &opt_b, 'b', NULL, NULL },
	{ NULL, 'z', POPT_ARG_STRING, &opt_b, 'z', NULL, NULL },
	{ NULL, 'F', POPT_ARG_INT, &opt_F, 'F', NULL, NULL },
	{ NULL, 'd', POPT_ARG_STRING, &opt_d, 'd', NULL, NULL },
	{ NULL, 0, 0, NULL, 0, NULL, NULL }
    };
    poptContext optCon = NULL;

    opt_p = opt_R = opt_E = 0;
    opt_F = rpmExpandNumeric("%{_default_patch_fuzz}");		/* get default fuzz factor for %patch */
    opt_b = opt_d = NULL;

    /* Convert %patchN to %patch -PN to simplify further processing */
    if (! strchr(" \t\n", line[6])) {
	rasprintf(&buf, "%%patch -P %s", line + 6);
    } else {
	if (strstr(line+6, " -P") == NULL)
	    rasprintf(&buf, "%%patch -P %d %s", INT_MAX, line + 6); /* INT_MAX denotes not numbered %patch */
	else
	    buf = xstrdup(line); /* it is not numberless patch because -P is present */
    }
    poptParseArgvString(buf, &argc, &argv);
    free(buf);

    /* 
     * Grab all -P<N> numbers for later processing. Stored as strings
     * at this point so we only have to worry about conversion in one place.
     */
    optCon = poptGetContext(NULL, argc, argv, patchOpts, 0);
    while ((c = poptGetNextOpt(optCon)) > 0) {
	switch (c) {
	case 'P': {
	    char *arg = poptGetOptArg(optCon);
	    if (arg) {
	    	argvAdd(&patchnums, arg);
	    	free(arg);
	    }
	    break;
	}
	default:
	    break;
	}
    }

    if (c < -1) {
	rpmlog(RPMLOG_ERR, _("%s: %s: %s\n"), poptStrerror(c), 
		poptBadOption(optCon, POPT_BADOPTION_NOALIAS), line);
	goto exit;
    }

    /* Any trailing arguments are treated as patch numbers */
    argvAppend(&patchnums, (ARGV_const_t) poptGetArgs(optCon));

    /* Convert to number, generate patch command and append to %prep script */
    for (patch = patchnums; *patch; patch++) {
	uint32_t pnum;
	char *s;
	if (parseUnsignedNum(*patch, &pnum)) {
	    rpmlog(RPMLOG_ERR, _("Invalid patch number %s: %s\n"),
		     *patch, line);
	    goto exit;
	}
	s = doPatch(spec, pnum, opt_p, opt_b, opt_R, opt_E, opt_F, opt_d);
	if (s == NULL) {
	    goto exit;
	}
	appendLineStringBuf(spec->prep, s);
	free(s);
    }
	
    rc = RPMRC_OK;

exit:
    argvFree(patchnums);
    free(argv);
    poptFreeContext(optCon);
    return rc;
}
Beispiel #4
0
/**
 * First half of the command line parsing. Also see ParseCommandLine()
 * below. The parameters here are needed early in the boot process,
 * while the ones in ParseCommandLine can benefit from debugging being
 * set up first.
 * \param argc number of arguments given
 * \param argv string array of the arguments
 * \return Returns true on success, false on error */
bool ParseCommandLineEarly(int argc, const char **argv)
{
	poptContext poptCon = poptGetContext(nullptr, argc, argv, getOptionsTable(), 0);
	int iOption;

#if defined(WZ_OS_MAC) && defined(DEBUG)
	debug_enable_switch("all");
#endif /* WZ_OS_MAC && DEBUG */

	/* loop through command line */
	while ((iOption = poptGetNextOpt(poptCon)) > 0 || iOption == POPT_ERROR_BADOPT)
	{
		CLI_OPTIONS option = (CLI_OPTIONS)iOption;
		const char *token;

		if (iOption == POPT_ERROR_BADOPT)
		{
			qFatal("Unrecognized option: %s", poptBadOption(poptCon, 0));
		}

		switch (option)
		{
		case CLI_DEBUG:
			// retrieve the debug section name
			token = poptGetOptArg(poptCon);
			if (token == nullptr)
			{
				qFatal("Usage: --debug=<flag>");
			}

			// Attempt to enable the given debug section
			if (!debug_enable_switch(token))
			{
				qFatal("Debug flag \"%s\" not found!", token);
			}
			break;

		case CLI_DEBUGFILE:
			// find the file name
			token = poptGetOptArg(poptCon);
			if (token == nullptr)
			{
				qFatal("Missing debugfile filename?");
			}
			debug_register_callback(debug_callback_file, debug_callback_file_init, debug_callback_file_exit, (void *)token);
			customDebugfile = true;
			break;

		case CLI_FLUSHDEBUGSTDERR:
			// Tell the debug stderr output callback to always flush its output
			debugFlushStderr();
			break;

		case CLI_CONFIGDIR:
			// retrieve the configuration directory
			token = poptGetOptArg(poptCon);
			if (token == nullptr)
			{
				qFatal("Unrecognised configuration directory");
			}
			if (strlen(token) >= (sizeof(configdir) / sizeof(configdir[0])))
			{
				qFatal("Configuration directory exceeds maximum supported length on this platform");
			}
			sstrcpy(configdir, token);
			break;

		case CLI_HELP:
		case CLI_HELP_ALL:
			poptPrintHelp(poptCon, stdout, option == CLI_HELP_ALL);
			return false;

		case CLI_VERSION:
			printf("Warzone 2100 - %s\n", version_getFormattedVersionString());
			return false;

		default:
			break;
		};
	}

	return true;
}
Beispiel #5
0
 int main(int argc,const char *argv[])
{
	/* shall I run as a daemon */
	bool is_daemon = false;
	bool interactive = false;
	bool Fork = true;
	bool no_process_group = false;
	bool log_stdout = false;
	char *ports = NULL;
	char *profile_level = NULL;
	int opt;
	poptContext pc;
	bool print_build_options = False;
        enum {
		OPT_DAEMON = 1000,
		OPT_INTERACTIVE,
		OPT_FORK,
		OPT_NO_PROCESS_GROUP,
		OPT_LOG_STDOUT
	};
	struct poptOption long_options[] = {
	POPT_AUTOHELP
	{"daemon", 'D', POPT_ARG_NONE, NULL, OPT_DAEMON, "Become a daemon (default)" },
	{"interactive", 'i', POPT_ARG_NONE, NULL, OPT_INTERACTIVE, "Run interactive (not a daemon)"},
	{"foreground", 'F', POPT_ARG_NONE, NULL, OPT_FORK, "Run daemon in foreground (for daemontools, etc.)" },
	{"no-process-group", '\0', POPT_ARG_NONE, NULL, OPT_NO_PROCESS_GROUP, "Don't create a new process group" },
	{"log-stdout", 'S', POPT_ARG_NONE, NULL, OPT_LOG_STDOUT, "Log to stdout" },
	{"build-options", 'b', POPT_ARG_NONE, NULL, 'b', "Print build options" },
	{"port", 'p', POPT_ARG_STRING, &ports, 0, "Listen on the specified ports"},
	{"profiling-level", 'P', POPT_ARG_STRING, &profile_level, 0, "Set profiling level","PROFILE_LEVEL"},
	POPT_COMMON_SAMBA
	POPT_COMMON_DYNCONFIG
	POPT_TABLEEND
	};
	struct smbd_parent_context *parent = NULL;
	TALLOC_CTX *frame;
	NTSTATUS status;
	uint64_t unique_id;
	struct tevent_context *ev_ctx;
	struct messaging_context *msg_ctx;
	struct tevent_signal *se;

	/*
	 * Do this before any other talloc operation
	 */
	talloc_enable_null_tracking();
	frame = talloc_stackframe();

	setup_logging(argv[0], DEBUG_DEFAULT_STDOUT);

	load_case_tables();

	smbd_init_globals();

	TimeInit();

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

	pc = poptGetContext("smbd", argc, argv, long_options, 0);
	while((opt = poptGetNextOpt(pc)) != -1) {
		switch (opt)  {
		case OPT_DAEMON:
			is_daemon = true;
			break;
		case OPT_INTERACTIVE:
			interactive = true;
			break;
		case OPT_FORK:
			Fork = false;
			break;
		case OPT_NO_PROCESS_GROUP:
			no_process_group = true;
			break;
		case OPT_LOG_STDOUT:
			log_stdout = true;
			break;
		case 'b':
			print_build_options = True;
			break;
		default:
			d_fprintf(stderr, "\nInvalid option %s: %s\n\n",
				  poptBadOption(pc, 0), poptStrerror(opt));
			poptPrintUsage(pc, stderr, 0);
			exit(1);
		}
	}
	poptFreeContext(pc);

	if (interactive) {
		Fork = False;
		log_stdout = True;
	}

	if (log_stdout) {
		setup_logging(argv[0], DEBUG_STDOUT);
	} else {
		setup_logging(argv[0], DEBUG_FILE);
	}

	if (print_build_options) {
		build_options(True); /* Display output to screen as well as debug */
		exit(0);
	}

#ifdef HAVE_SETLUID
	/* needed for SecureWare on SCO */
	setluid(0);
#endif

	set_remote_machine_name("smbd", False);

	if (interactive && (DEBUGLEVEL >= 9)) {
		talloc_enable_leak_report();
	}

	if (log_stdout && Fork) {
		DEBUG(0,("ERROR: Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n"));
		exit(1);
	}

	/* we want to re-seed early to prevent time delays causing
           client problems at a later date. (tridge) */
	generate_random_buffer(NULL, 0);

	/* get initial effective uid and gid */
	sec_init();

	/* make absolutely sure we run as root - to handle cases where people
	   are crazy enough to have it setuid */
	gain_root_privilege();
	gain_root_group_privilege();

	fault_setup();
	dump_core_setup("smbd", lp_logfile());

	/* we are never interested in SIGPIPE */
	BlockSignals(True,SIGPIPE);

#if defined(SIGFPE)
	/* we are never interested in SIGFPE */
	BlockSignals(True,SIGFPE);
#endif

#if defined(SIGUSR2)
	/* We are no longer interested in USR2 */
	BlockSignals(True,SIGUSR2);
#endif

	/* POSIX demands that signals are inherited. If the invoking process has
	 * these signals masked, we will have problems, as we won't recieve them. */
	BlockSignals(False, SIGHUP);
	BlockSignals(False, SIGUSR1);
	BlockSignals(False, SIGTERM);

	/* Ensure we leave no zombies until we
	 * correctly set up child handling below. */

	CatchChild();

	/* we want total control over the permissions on created files,
	   so set our umask to 0 */
	umask(0);

	reopen_logs();

	DEBUG(0,("smbd version %s started.\n", samba_version_string()));
	DEBUGADD(0,("%s\n", COPYRIGHT_STARTUP_MESSAGE));

	DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
		 (int)getuid(),(int)getgid(),(int)geteuid(),(int)getegid()));

	/* Output the build options to the debug log */ 
	build_options(False);

	if (sizeof(uint16) < 2 || sizeof(uint32) < 4) {
		DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
		exit(1);
	}

	if (!lp_load_initial_only(get_dyn_CONFIGFILE())) {
		DEBUG(0, ("error opening config file '%s'\n", get_dyn_CONFIGFILE()));
		exit(1);
	}

	/* Init the security context and global current_user */
	init_sec_ctx();

	/*
	 * Initialize the event context. The event context needs to be
	 * initialized before the messaging context, cause the messaging
	 * context holds an event context.
	 * FIXME: This should be s3_tevent_context_init()
	 */
	ev_ctx = server_event_context();
	if (ev_ctx == NULL) {
		exit(1);
	}

	/*
	 * Init the messaging context
	 * FIXME: This should only call messaging_init()
	 */
	msg_ctx = server_messaging_context();
	if (msg_ctx == NULL) {
		exit(1);
	}

	/*
	 * Reloading of the printers will not work here as we don't have a
	 * server info and rpc services set up. It will be called later.
	 */
	if (!reload_services(NULL, NULL, false)) {
		exit(1);
	}

	/* ...NOTE... Log files are working from this point! */

	DEBUG(3,("loaded services\n"));

	init_structs();

#ifdef WITH_PROFILE
	if (!profile_setup(msg_ctx, False)) {
		DEBUG(0,("ERROR: failed to setup profiling\n"));
		return -1;
	}
	if (profile_level != NULL) {
		int pl = atoi(profile_level);
		struct server_id src;

		DEBUG(1, ("setting profiling level: %s\n",profile_level));
		src.pid = getpid();
		set_profile_level(pl, src);
	}
#endif

	if (!is_daemon && !is_a_socket(0)) {
		if (!interactive)
			DEBUG(0,("standard input is not a socket, assuming -D option\n"));

		/*
		 * Setting is_daemon here prevents us from eventually calling
		 * the open_sockets_inetd()
		 */

		is_daemon = True;
	}

	if (is_daemon && !interactive) {
		DEBUG( 3, ( "Becoming a daemon.\n" ) );
		become_daemon(Fork, no_process_group, log_stdout);
	}

        generate_random_buffer((uint8_t *)&unique_id, sizeof(unique_id));
        set_my_unique_id(unique_id);

#if HAVE_SETPGID
	/*
	 * If we're interactive we want to set our own process group for
	 * signal management.
	 */
	if (interactive && !no_process_group)
		setpgid( (pid_t)0, (pid_t)0);
#endif

	if (!directory_exist(lp_lockdir()))
		mkdir(lp_lockdir(), 0755);

	if (is_daemon)
		pidfile_create("smbd");

	status = reinit_after_fork(msg_ctx,
				   ev_ctx,
				   false);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0,("reinit_after_fork() failed\n"));
		exit(1);
	}

	smbd_server_conn->msg_ctx = msg_ctx;

	parent = talloc_zero(ev_ctx, struct smbd_parent_context);
	if (!parent) {
		exit_server("talloc(struct smbd_parent_context) failed");
	}
	parent->interactive = interactive;
	parent->ev_ctx = ev_ctx;
	parent->msg_ctx = msg_ctx;
	am_parent = parent;

	se = tevent_add_signal(parent->ev_ctx,
			       parent,
			       SIGTERM, 0,
			       smbd_parent_sig_term_handler,
			       parent);
	if (!se) {
		exit_server("failed to setup SIGTERM handler");
	}
	se = tevent_add_signal(parent->ev_ctx,
			       parent,
			       SIGHUP, 0,
			       smbd_parent_sig_hup_handler,
			       parent);
	if (!se) {
		exit_server("failed to setup SIGHUP handler");
	}

	/* Setup all the TDB's - including CLEAR_IF_FIRST tdb's. */

	if (smbd_memcache() == NULL) {
		exit(1);
	}

	memcache_set_global(smbd_memcache());

	/* Initialise the password backed before the global_sam_sid
	   to ensure that we fetch from ldap before we make a domain sid up */

	if(!initialize_password_db(false, ev_ctx))
		exit(1);

	if (!secrets_init()) {
		DEBUG(0, ("ERROR: smbd can not open secrets.tdb\n"));
		exit(1);
	}

	if (lp_server_role() == ROLE_DOMAIN_BDC || lp_server_role() == ROLE_DOMAIN_PDC) {
		struct loadparm_context *lp_ctx = loadparm_init_s3(NULL, loadparm_s3_context());
		if (!open_schannel_session_store(NULL, lp_ctx)) {
			DEBUG(0,("ERROR: Samba cannot open schannel store for secured NETLOGON operations.\n"));
			exit(1);
		}
		TALLOC_FREE(lp_ctx);
	}

	if(!get_global_sam_sid()) {
		DEBUG(0,("ERROR: Samba cannot create a SAM SID.\n"));
		exit(1);
	}

	if (!sessionid_init()) {
		exit(1);
	}

	if (!connections_init(True))
		exit(1);

	if (!locking_init())
		exit(1);

	if (!messaging_tdb_parent_init(ev_ctx)) {
		exit(1);
	}

	if (!notify_internal_parent_init(ev_ctx)) {
		exit(1);
	}

	if (!serverid_parent_init(ev_ctx)) {
		exit(1);
	}

	if (!W_ERROR_IS_OK(registry_init_full()))
		exit(1);

	/* Open the share_info.tdb here, so we don't have to open
	   after the fork on every single connection.  This is a small
	   performance improvment and reduces the total number of system
	   fds used. */
	if (!share_info_db_init()) {
		DEBUG(0,("ERROR: failed to load share info db.\n"));
		exit(1);
	}

	status = init_system_info();
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(1, ("ERROR: failed to setup system user info: %s.\n",
			  nt_errstr(status)));
		return -1;
	}

	if (!init_guest_info()) {
		DEBUG(0,("ERROR: failed to setup guest info.\n"));
		return -1;
	}

	if (!file_init(smbd_server_conn)) {
		DEBUG(0, ("ERROR: file_init failed\n"));
		return -1;
	}

	/* This MUST be done before start_epmd() because otherwise
	 * start_epmd() forks and races against dcesrv_ep_setup() to
	 * call directory_create_or_exist() */
	if (!directory_create_or_exist(lp_ncalrpc_dir(), geteuid(), 0755)) {
		DEBUG(0, ("Failed to create pipe directory %s - %s\n",
			  lp_ncalrpc_dir(), strerror(errno)));
		return -1;
	}

	if (is_daemon && !interactive) {
		if (rpc_epmapper_daemon() == RPC_DAEMON_FORK) {
			start_epmd(ev_ctx, msg_ctx);
		}
	}

	if (!dcesrv_ep_setup(ev_ctx, msg_ctx)) {
		exit(1);
	}

	/* only start other daemons if we are running as a daemon
	 * -- bad things will happen if smbd is launched via inetd
	 *  and we fork a copy of ourselves here */
	if (is_daemon && !interactive) {

		if (rpc_lsasd_daemon() == RPC_DAEMON_FORK) {
			start_lsasd(ev_ctx, msg_ctx);
		}

		if (!_lp_disable_spoolss() &&
		    (rpc_spoolss_daemon() != RPC_DAEMON_DISABLED)) {
			bool bgq = lp_parm_bool(-1, "smbd", "backgroundqueue", true);

			if (!printing_subsystem_init(ev_ctx, msg_ctx, true, bgq)) {
				exit(1);
			}
		}
	} else if (!_lp_disable_spoolss() &&
		   (rpc_spoolss_daemon() != RPC_DAEMON_DISABLED)) {
		if (!printing_subsystem_init(ev_ctx, msg_ctx, false, false)) {
			exit(1);
		}
	}

	if (!is_daemon) {
		/* inetd mode */
		TALLOC_FREE(frame);

		/* Started from inetd. fd 0 is the socket. */
		/* We will abort gracefully when the client or remote system
		   goes away */
		smbd_server_conn->sock = dup(0);

		/* close our standard file descriptors */
		if (!debug_get_output_is_stdout()) {
			close_low_fds(False); /* Don't close stderr */
		}

#ifdef HAVE_ATEXIT
		atexit(killkids);
#endif

	        /* Stop zombies */
		smbd_setup_sig_chld_handler(parent);

		smbd_process(ev_ctx, smbd_server_conn);

		exit_server_cleanly(NULL);
		return(0);
	}

	if (!open_sockets_smbd(parent, ev_ctx, msg_ctx, ports))
		exit_server("open_sockets_smbd() failed");

	/* do a printer update now that all messaging has been set up,
	 * before we allow clients to start connecting */
	printing_subsystem_update(ev_ctx, msg_ctx, false);

	TALLOC_FREE(frame);
	/* make sure we always have a valid stackframe */
	frame = talloc_stackframe();

	smbd_parent_loop(ev_ctx, parent);

	exit_server_cleanly(NULL);
	TALLOC_FREE(frame);
	return(0);
}
Beispiel #6
0
/**
 * Parse %setup macro.
 * @todo FIXME: Option -q broken when not immediately after %setup.
 * @param spec		build info
 * @param line		current line from spec file
 * @return		RPMRC_OK on success
 */
static int doSetupMacro(rpmSpec spec, const char *line)
{
    char *buf = NULL;
    StringBuf before = newStringBuf();
    StringBuf after = newStringBuf();
    poptContext optCon = NULL;
    int argc;
    const char ** argv = NULL;
    int arg;
    const char * optArg;
    int xx;
    rpmRC rc = RPMRC_FAIL;
    uint32_t num;
    int leaveDirs = 0, skipDefaultAction = 0;
    int createDir = 0, quietly = 0;
    const char * dirName = NULL;
    struct poptOption optionsTable[] = {
	    { NULL, 'a', POPT_ARG_STRING, NULL, 'a',	NULL, NULL},
	    { NULL, 'b', POPT_ARG_STRING, NULL, 'b',	NULL, NULL},
	    { NULL, 'c', 0, &createDir, 0,		NULL, NULL},
	    { NULL, 'D', 0, &leaveDirs, 0,		NULL, NULL},
	    { NULL, 'n', POPT_ARG_STRING, &dirName, 0,	NULL, NULL},
	    { NULL, 'T', 0, &skipDefaultAction, 0,	NULL, NULL},
	    { NULL, 'q', 0, &quietly, 0,		NULL, NULL},
	    { 0, 0, 0, 0, 0,	NULL, NULL}
    };

    if ((xx = poptParseArgvString(line, &argc, &argv))) {
	rpmlog(RPMLOG_ERR, _("Error parsing %%setup: %s\n"), poptStrerror(xx));
	goto exit;
    }

    optCon = poptGetContext(NULL, argc, argv, optionsTable, 0);
    while ((arg = poptGetNextOpt(optCon)) > 0) {
	optArg = poptGetOptArg(optCon);

	/* We only parse -a and -b here */

	if (parseUnsignedNum(optArg, &num)) {
	    rpmlog(RPMLOG_ERR, _("line %d: Bad arg to %%setup: %s\n"),
		     spec->lineNum, (optArg ? optArg : "???"));
	    goto exit;
	}

	{   char *chptr = doUntar(spec, num, quietly);
	    if (chptr == NULL)
		goto exit;

	    appendLineStringBuf((arg == 'a' ? after : before), chptr);
	    free(chptr);
	}
    }

    if (arg < -1) {
	rpmlog(RPMLOG_ERR, _("line %d: Bad %%setup option %s: %s\n"),
		 spec->lineNum,
		 poptBadOption(optCon, POPT_BADOPTION_NOALIAS), 
		 poptStrerror(arg));
	goto exit;
    }

    if (dirName) {
	spec->buildSubdir = xstrdup(dirName);
    } else {
	rasprintf(&spec->buildSubdir, "%s-%s", 
		  headerGetString(spec->packages->header, RPMTAG_NAME),
		  headerGetString(spec->packages->header, RPMTAG_VERSION));
    }
    addMacro(spec->macros, "buildsubdir", NULL, spec->buildSubdir, RMIL_SPEC);
    
    /* cd to the build dir */
    {	char * buildDir = rpmGenPath(spec->rootDir, "%{_builddir}", "");

	rasprintf(&buf, "cd '%s'", buildDir);
	appendLineStringBuf(spec->prep, buf);
	free(buf);
	free(buildDir);
    }
    
    /* delete any old sources */
    if (!leaveDirs) {
	rasprintf(&buf, "rm -rf '%s'", spec->buildSubdir);
	appendLineStringBuf(spec->prep, buf);
	free(buf);
    }

    /* if necessary, create and cd into the proper dir */
    if (createDir) {
	rasprintf(&buf, RPM_MKDIR_P " %s\ncd '%s'",
		spec->buildSubdir, spec->buildSubdir);
	appendLineStringBuf(spec->prep, buf);
	free(buf);
    }

    /* do the default action */
   if (!createDir && !skipDefaultAction) {
	char *chptr = doUntar(spec, 0, quietly);
	if (!chptr)
	    goto exit;
	appendLineStringBuf(spec->prep, chptr);
	free(chptr);
    }

    appendStringBuf(spec->prep, getStringBuf(before));

    if (!createDir) {
	rasprintf(&buf, "cd '%s'", spec->buildSubdir);
	appendLineStringBuf(spec->prep, buf);
	free(buf);
    }

    if (createDir && !skipDefaultAction) {
	char *chptr = doUntar(spec, 0, quietly);
	if (chptr == NULL)
	    goto exit;
	appendLineStringBuf(spec->prep, chptr);
	free(chptr);
    }
    
    appendStringBuf(spec->prep, getStringBuf(after));

    /* Fix the permissions of the setup build tree */
    {	char *fix = rpmExpand("%{_fixperms} .", NULL);
	if (fix && *fix != '%') {
	    appendLineStringBuf(spec->prep, fix);
	}
	free(fix);
    }
    rc = RPMRC_OK;

exit:
    freeStringBuf(before);
    freeStringBuf(after);
    poptFreeContext(optCon);
    free(argv);

    return rc;
}
Beispiel #7
0
/*
 * Add event to trace session
 */
int cmd_enable_events(int argc, const char **argv)
{
	int opt, ret = CMD_SUCCESS, command_ret = CMD_SUCCESS, success = 1;
	static poptContext pc;
	char *session_name = NULL;
	int event_type = -1;

	pc = poptGetContext(NULL, argc, argv, long_options, 0);
	poptReadDefaultConfig(pc, 0);

	/* Default event type */
	opt_event_type = LTTNG_EVENT_ALL;

	while ((opt = poptGetNextOpt(pc)) != -1) {
		switch (opt) {
		case OPT_HELP:
			usage(stdout);
			goto end;
		case OPT_TRACEPOINT:
			opt_event_type = LTTNG_EVENT_TRACEPOINT;
			break;
		case OPT_PROBE:
			opt_event_type = LTTNG_EVENT_PROBE;
			break;
		case OPT_FUNCTION:
			opt_event_type = LTTNG_EVENT_FUNCTION;
			break;
		case OPT_SYSCALL:
			opt_event_type = LTTNG_EVENT_SYSCALL;
			break;
		case OPT_USERSPACE:
			opt_userspace = 1;
			break;
		case OPT_LOGLEVEL:
			opt_loglevel_type = LTTNG_EVENT_LOGLEVEL_RANGE;
			opt_loglevel = poptGetOptArg(pc);
			break;
		case OPT_LOGLEVEL_ONLY:
			opt_loglevel_type = LTTNG_EVENT_LOGLEVEL_SINGLE;
			opt_loglevel = poptGetOptArg(pc);
			break;
		case OPT_LIST_OPTIONS:
			list_cmd_options(stdout, long_options);
			goto end;
		case OPT_FILTER:
			break;
		case OPT_EXCLUDE:
			break;
		default:
			usage(stderr);
			ret = CMD_UNDEFINED;
			goto end;
		}

		/* Validate event type. Multiple event type are not supported. */
		if (event_type == -1) {
			event_type = opt_event_type;
		} else {
			if (event_type != opt_event_type) {
				ERR("Multiple event type not supported.");
				ret = CMD_ERROR;
				goto end;
			}
		}
	}

	ret = print_missing_or_multiple_domains(
		opt_kernel + opt_userspace + opt_jul + opt_log4j + opt_python);
	if (ret) {
		ret = CMD_ERROR;
		goto end;
	}

	/* Mi check */
	if (lttng_opt_mi) {
		writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi);
		if (!writer) {
			ret = -LTTNG_ERR_NOMEM;
			goto end;
		}

		/* Open command element */
		ret = mi_lttng_writer_command_open(writer,
				mi_lttng_element_command_enable_event);
		if (ret) {
			ret = CMD_ERROR;
			goto end;
		}

		/* Open output element */
		ret = mi_lttng_writer_open_element(writer,
				mi_lttng_element_command_output);
		if (ret) {
			ret = CMD_ERROR;
			goto end;
		}
	}

	opt_event_list = (char*) poptGetArg(pc);
	if (opt_event_list == NULL && opt_enable_all == 0) {
		ERR("Missing event name(s).\n");
		usage(stderr);
		ret = CMD_ERROR;
		goto end;
	}

	if (!opt_session_name) {
		session_name = get_session_name();
		if (session_name == NULL) {
			command_ret = CMD_ERROR;
			success = 0;
			goto mi_closing;
		}
	} else {
		session_name = opt_session_name;
	}

	command_ret = enable_events(session_name);
	if (command_ret) {
		success = 0;
		goto mi_closing;
	}

mi_closing:
	/* Mi closing */
	if (lttng_opt_mi) {
		/* Close  output element */
		ret = mi_lttng_writer_close_element(writer);
		if (ret) {
			ret = CMD_ERROR;
			goto end;
		}

		ret = mi_lttng_writer_write_element_bool(writer,
				mi_lttng_element_command_success, success);
		if (ret) {
			ret = CMD_ERROR;
			goto end;
		}

		/* Command element close */
		ret = mi_lttng_writer_command_close(writer);
		if (ret) {
			ret = CMD_ERROR;
			goto end;
		}
	}

end:
	/* Mi clean-up */
	if (writer && mi_lttng_writer_destroy(writer)) {
		/* Preserve original error code */
		ret = ret ? ret : LTTNG_ERR_MI_IO_FAIL;
	}

	if (opt_session_name == NULL) {
		free(session_name);
	}

	/* Overwrite ret if an error occurred in enable_events */
	ret = command_ret ? command_ret : ret;

	poptFreeContext(pc);
	return ret;
}
Beispiel #8
0
/* Command line parser */
static void
parse_cmdline(int argc, char **argv)
{
	poptContext context;
	char *option_arg = NULL;
	int c;

	struct poptOption options_table[] = {
		{"version", 'v', POPT_ARG_NONE, NULL, 'v'},
		{"help", 'h', POPT_ARG_NONE, NULL, 'h'},
		{"log-console", 'l', POPT_ARG_NONE, NULL, 'l'},
		{"log-detail", 'D', POPT_ARG_NONE, NULL, 'D'},
		{"log-facility", 'S', POPT_ARG_STRING, &option_arg, 'S'},
		{"dont-release-vrrp", 'V', POPT_ARG_NONE, NULL, 'V'},
		{"dont-release-ipvs", 'I', POPT_ARG_NONE, NULL, 'I'},
		{"dont-fork", 'n', POPT_ARG_NONE, NULL, 'n'},
		{"dump-conf", 'd', POPT_ARG_NONE, NULL, 'd'},
		{"use-file", 'f', POPT_ARG_STRING, &option_arg, 'f'},
		{"vrrp", 'P', POPT_ARG_NONE, NULL, 'P'},
		{"check", 'C', POPT_ARG_NONE, NULL, 'C'},
		{"pid", 'p', POPT_ARG_STRING, &option_arg, 'p'},
		{"checkers_pid", 'c', POPT_ARG_STRING, &option_arg, 'c'},
		{"vrrp_pid", 'r', POPT_ARG_STRING, &option_arg, 'r'},
#ifdef _WITH_SNMP_
		{"snmp", 'x', POPT_ARG_NONE, NULL, 'x'},
#endif
		{NULL, 0, 0, NULL, 0}
	};

	context =
	    poptGetContext(PROG, argc, (const char **) argv, options_table, 0);
	if ((c = poptGetNextOpt(context)) < 0) {
		return;
	}

	/* The first option car */
	switch (c) {
	case 'v':
		fprintf(stderr, VERSION_STRING);
		exit(0);
		break;
	case 'h':
		usage(argv[0]);
		exit(0);
		break;
	case 'l':
		debug |= 1;
		break;
	case 'n':
		debug |= 2;
		break;
	case 'd':
		debug |= 4;
		break;
	case 'V':
		debug |= 8;
		break;
	case 'I':
		debug |= 16;
		break;
	case 'D':
		debug |= 32;
		break;
	case 'S':
		log_facility = LOG_FACILITY[atoi(option_arg)].facility;
		break;
	case 'f':
		conf_file = option_arg;
		break;
	case 'P':
		daemon_mode |= 1;
		break;
	case 'C':
		daemon_mode |= 2;
		break;
	case 'p':
		main_pidfile = option_arg;
		break;
	case 'c':
		checkers_pidfile = option_arg;
		break;
	case 'r':
		vrrp_pidfile = option_arg;
		break;
#ifdef _WITH_SNMP_
	case 'x':
		snmp = 1;
		break;
#endif
	}

	/* the others */
	/* fixme: why is this duplicated? */
	while ((c = poptGetNextOpt(context)) >= 0) {
		switch (c) {
		case 'l':
			debug |= 1;
			break;
		case 'n':
			debug |= 2;
			break;
		case 'd':
			debug |= 4;
			break;
		case 'V':
			debug |= 8;
			break;
		case 'I':
			debug |= 16;
			break;
		case 'D':
			debug |= 32;
			break;
		case 'S':
			log_facility = LOG_FACILITY[atoi(option_arg)].facility;
			break;
		case 'f':
			conf_file = option_arg;
			break;
		case 'P':
			daemon_mode |= 1;
			break;
		case 'C':
			daemon_mode |= 2;
			break;
		case 'p':
			main_pidfile = option_arg;
			break;
		case 'c':
			checkers_pidfile = option_arg;
			break;
		case 'r':
			vrrp_pidfile = option_arg;
			break;
#ifdef _WITH_SNMP_
		case 'x':
			snmp = 1;
			break;
#endif
		}
	}

	/* check unexpected arguments */
	if ((option_arg = (char *) poptGetArg(context))) {
		fprintf(stderr, "unexpected argument %s\n", option_arg);
		return;
	}

	/* free the allocated context */
	poptFreeContext(context);
}
Beispiel #9
0
int
main(int argc, const char **argv)
{
    poptContext poptContext;
    int poptResult;
    uid_t uid;
    int kq;
    HANDLE lsaConnection = (HANDLE) NULL;
    PVOID pUserInfo = NULL;
    struct kevent event = { 0 };
    int numChanges = 1;
    krb5_context krb5Context = NULL;
    char krb5FileCachePath[PATH_MAX];
    krb5_ccache krb5FileCache = NULL;
    krb5_ccache krb5MemoryCache = NULL;
    krb5_cc_cursor krb5Cursor = NULL;
    krb5_creds krb5Credentials = { 0 };
    krb5_principal krb5Principal = NULL;
    krb5_error_code krb5Error;
    int exitStatus = 0;
    DWORD dwError = LW_ERROR_SUCCESS;

    poptContext = poptGetContext(NULL, argc, argv, Options, 0);
    while ((poptResult = poptGetNextOpt(poptContext)) >= 0)
    {
        /* All options are processed automatically. */
    }

    if (poptResult < -1)
    {
        fprintf(stderr, "%s: %s: %s\n", getprogname(),
                poptBadOption(poptContext, POPT_BADOPTION_NOALIAS),
                poptStrerror(poptResult));
        exitStatus = 1;
        goto error;
    }

    uid = getuid();

    /* Make sure we're running as an AD user. */
    dwError = LsaOpenServer(&lsaConnection);
    BAIL_ON_LSA_ERROR(dwError);

    dwError = LsaFindUserById(
                  lsaConnection,
                  uid,
                  0,
                  &pUserInfo);
    if (dwError == LW_ERROR_NO_SUCH_USER)
    {
        /*
         * Running as a non-AD user; exit 0 so launchd doesn't restart
         * the ticketcopy program (see com.beyondtrust.pbis.ticketcopy.plist).
         */
        LSA_LOG_DEBUG(
            "uid %lu is not an AD user; exiting",
            (unsigned long) uid);
        dwError = LW_ERROR_SUCCESS;
        goto cleanup;
    }
    BAIL_ON_LSA_ERROR(dwError);

    kq = kqueue();
    BAIL_ON_UNIX_ERROR(kq == -1);

    krb5Error = krb5_init_context(&krb5Context);
    BAIL_ON_KRB5_ERROR(krb5Context, krb5Error, dwError);

    krb5Error = krb5_cc_default(krb5Context, &krb5MemoryCache);
    BAIL_ON_KRB5_ERROR(krb5Context, krb5Error, dwError);

    snprintf(
        krb5FileCachePath,
        sizeof(krb5FileCachePath),
        "FILE:/tmp/krb5cc_%lu",
        (unsigned long) uid);

    while (1) /* Forever (or until an error occurs) */
    {
        while ((event.ident = open(krb5FileCachePath + 5, O_RDONLY)) == -1)
        {
            sleep(5);
        }

        event.filter = EVFILT_VNODE;
        event.flags = EV_ADD | EV_ENABLE | EV_CLEAR;
        event.fflags = NOTE_DELETE | NOTE_WRITE;
        numChanges = 1;

        krb5Error = krb5_cc_resolve(
                        krb5Context,
                        krb5FileCachePath,
                        &krb5FileCache);
        BAIL_ON_KRB5_ERROR(krb5Context, krb5Error, dwError);

        while (1) /* While the file continues to exist. */
        {
            /*
             * Turn off KRB5_TC_OPENCLOSE so the file will be opened once
             * and kept open.  This causes it to actually attempt to open
             * the file, so this is where we check for the file not
             * existing and retry after sleeping a bit.
             */
            krb5Error = krb5_cc_set_flags(krb5Context, krb5FileCache, 0);
            if (krb5Error == KRB5_FCC_NOFILE)
            {
                break;
            }
            BAIL_ON_KRB5_ERROR(krb5Context, krb5Error, dwError);

            /* Copy all credentials from the file to the memory cache. */
            krb5Error = krb5_cc_start_seq_get(
                            krb5Context,
                            krb5FileCache,
                            &krb5Cursor);
            BAIL_ON_KRB5_ERROR(krb5Context, krb5Error, dwError);

            while ((krb5Error = krb5_cc_next_cred(
                                    krb5Context,
                                    krb5FileCache,
                                    &krb5Cursor,
                                    &krb5Credentials)) == 0)
            {
                krb5Error = krb5_cc_store_cred(
                                krb5Context,
                                krb5MemoryCache,
                                &krb5Credentials);
                if (krb5Error == KRB5_FCC_NOFILE)
                {
                    krb5Error = krb5_cc_get_principal(
                                    krb5Context,
                                    krb5FileCache,
                                    &krb5Principal);
                    BAIL_ON_KRB5_ERROR(krb5Context, krb5Error, dwError);

                    /* The memory cache was destroyed; re-create it. */
                    krb5Error = krb5_cc_initialize(
                                    krb5Context,
                                    krb5MemoryCache,
                                    krb5Principal);
                    BAIL_ON_KRB5_ERROR(krb5Context, krb5Error, dwError);

                    krb5_free_principal(krb5Context, krb5Principal);
                    krb5Principal = NULL;

                    krb5Error = krb5_cc_store_cred(
                                    krb5Context,
                                    krb5MemoryCache,
                                    &krb5Credentials);
                }
                BAIL_ON_KRB5_ERROR(krb5Context, krb5Error, dwError);

                krb5_free_cred_contents(krb5Context, &krb5Credentials);
            }

            if (krb5Error != KRB5_CC_END)
            {
                BAIL_ON_KRB5_ERROR(krb5Context, krb5Error, dwError);
            }

            krb5Error = krb5_cc_end_seq_get(
                            krb5Context,
                            krb5FileCache,
                            &krb5Cursor);
            krb5Cursor = NULL;
            BAIL_ON_KRB5_ERROR(krb5Context, krb5Error, dwError);

            /*
             * Turn KRB5_TC_OPENCLOSE back on; this will cause
             * the file to be closed and any locks to be
             * released.
             */
            krb5Error = krb5_cc_set_flags(
                            krb5Context,
                            krb5FileCache,
                            KRB5_TC_OPENCLOSE);
            BAIL_ON_KRB5_ERROR(krb5Context, krb5Error, dwError);

            /*
             * Wait for the file to be modified or deleted.  The first
             * time this is called after the file is opened, numChanges
             * will be 1, which will install the fd into the event
             * list.  After that numChanges is changed to 0, so it will
             * just report events from the existing list.
             */
            if (kevent(kq, &event, numChanges, &event, 1, NULL) != 1)
            {
                fprintf(stderr, "kevent failed\n");
                exitStatus = 1;
                goto cleanup;
            }

            if (event.fflags & NOTE_DELETE)
            {
                break;
            }

            numChanges = 0;
        }

        krb5Error = krb5_cc_close(krb5Context, krb5FileCache);
        BAIL_ON_KRB5_ERROR(krb5Context, krb5Error, dwError);
        krb5FileCache = NULL;

        close(event.ident);
        event.ident = -1;

        /*
         * The cache file is usually removed as part of a
         * rename(2) system call, so only wait a short
         * time before the first attempt to re-open it.
         */
        usleep(100000);
    }

error:
cleanup:
    krb5_free_cred_contents(krb5Context, &krb5Credentials);

    if (krb5Cursor)
    {
        krb5_cc_end_seq_get(krb5Context, krb5FileCache, &krb5Cursor);
    }

    if (krb5FileCache)
    {
        krb5_cc_close(krb5Context, krb5FileCache);
    }

    if (krb5Principal)
    {
        krb5_free_principal(krb5Context, krb5Principal);
    }

    if (krb5Context)
    {
        krb5_free_context(krb5Context);
    }

    if (event.ident != -1)
    {
        close(event.ident);
    }

    if (pUserInfo)
    {
        LsaFreeUserInfo(0, pUserInfo);
    }

    if (lsaConnection != (HANDLE) NULL)
    {
        LsaCloseServer(lsaConnection);
    }

    if (dwError)
    {
        exitStatus = 1;
    }

    return exitStatus;
}
Beispiel #10
0
/*
 main server.
*/
static int binary_smbd_main(const char *binary_name, int argc, const char *argv[])
{
	bool opt_daemon = false;
	bool opt_interactive = false;
	int opt;
	poptContext pc;
#define _MODULE_PROTO(init) extern NTSTATUS init(void);
	STATIC_service_MODULES_PROTO;
	init_module_fn static_init[] = { STATIC_service_MODULES };
	init_module_fn *shared_init;
	struct tevent_context *event_ctx;
	uint16_t stdin_event_flags;
	NTSTATUS status;
	const char *model = "standard";
	int max_runtime = 0;
	struct stat st;
	enum {
		OPT_DAEMON = 1000,
		OPT_INTERACTIVE,
		OPT_PROCESS_MODEL,
		OPT_SHOW_BUILD
	};
	struct poptOption long_options[] = {
		POPT_AUTOHELP
		{"daemon", 'D', POPT_ARG_NONE, NULL, OPT_DAEMON,
		 "Become a daemon (default)", NULL },
		{"interactive",	'i', POPT_ARG_NONE, NULL, OPT_INTERACTIVE,
		 "Run interactive (not a daemon)", NULL},
		{"model", 'M', POPT_ARG_STRING,	NULL, OPT_PROCESS_MODEL, 
		 "Select process model", "MODEL"},
		{"maximum-runtime",0, POPT_ARG_INT, &max_runtime, 0, 
		 "set maximum runtime of the server process, till autotermination", "seconds"},
		{"show-build", 'b', POPT_ARG_NONE, NULL, OPT_SHOW_BUILD, "show build info", NULL },
		POPT_COMMON_SAMBA
		POPT_COMMON_VERSION
		{ NULL }
	};

	pc = poptGetContext(binary_name, argc, argv, long_options, 0);
	while((opt = poptGetNextOpt(pc)) != -1) {
		switch(opt) {
		case OPT_DAEMON:
			opt_daemon = true;
			break;
		case OPT_INTERACTIVE:
			opt_interactive = true;
			break;
		case OPT_PROCESS_MODEL:
			model = poptGetOptArg(pc);
			break;
		case OPT_SHOW_BUILD:
			show_build();
			break;
		default:
			fprintf(stderr, "\nInvalid option %s: %s\n\n",
				  poptBadOption(pc, 0), poptStrerror(opt));
			poptPrintUsage(pc, stderr, 0);
			return 1;
		}
	}

	if (opt_daemon && opt_interactive) {
		fprintf(stderr,"\nERROR: "
			  "Option -i|--interactive is not allowed together with -D|--daemon\n\n");
		poptPrintUsage(pc, stderr, 0);
		return 1;
	} else if (!opt_interactive) {
		/* default is --daemon */
		opt_daemon = true;
	}

	poptFreeContext(pc);

	talloc_enable_null_tracking();

	setup_logging(binary_name, opt_interactive?DEBUG_STDOUT:DEBUG_FILE);
	setup_signals();

	/* we want total control over the permissions on created files,
	   so set our umask to 0 */
	umask(0);

	DEBUG(0,("%s version %s started.\n", binary_name, SAMBA_VERSION_STRING));
	DEBUGADD(0,("Copyright Andrew Tridgell and the Samba Team 1992-2015\n"));

	if (sizeof(uint16_t) < 2 || sizeof(uint32_t) < 4 || sizeof(uint64_t) < 8) {
		DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
		DEBUGADD(0,("sizeof(uint16_t) = %u, sizeof(uint32_t) %u, sizeof(uint64_t) = %u\n",
			    (unsigned int)sizeof(uint16_t), (unsigned int)sizeof(uint32_t), (unsigned int)sizeof(uint64_t)));
		return 1;
	}

	if (opt_daemon) {
		DEBUG(3,("Becoming a daemon.\n"));
		become_daemon(true, false, false);
	}

	cleanup_tmp_files(cmdline_lp_ctx);

	if (!directory_exist(lpcfg_lock_directory(cmdline_lp_ctx))) {
		mkdir(lpcfg_lock_directory(cmdline_lp_ctx), 0755);
	}

	pidfile_create(lpcfg_pid_directory(cmdline_lp_ctx), binary_name);

	if (lpcfg_server_role(cmdline_lp_ctx) == ROLE_ACTIVE_DIRECTORY_DC) {
		if (!open_schannel_session_store(talloc_autofree_context(), cmdline_lp_ctx)) {
			exit_daemon("Samba cannot open schannel store for secured NETLOGON operations.", EACCES);
		}
	}

	/* make sure we won't go through nss_winbind */
	if (!winbind_off()) {
		exit_daemon("Samba failed to disable recusive winbindd calls.", EACCES);
	}

	gensec_init(); /* FIXME: */

	ntptr_init();	/* FIXME: maybe run this in the initialization function 
						of the spoolss RPC server instead? */

	ntvfs_init(cmdline_lp_ctx); 	/* FIXME: maybe run this in the initialization functions 
						of the SMB[,2] server instead? */

	process_model_init(cmdline_lp_ctx); 

	shared_init = load_samba_modules(NULL, "service");

	run_init_functions(static_init);
	run_init_functions(shared_init);

	talloc_free(shared_init);
	
	/* the event context is the top level structure in smbd. Everything else
	   should hang off that */
	event_ctx = s4_event_context_init(talloc_autofree_context());

	if (event_ctx == NULL) {
		exit_daemon("Initializing event context failed", EACCES);
	}

	if (opt_interactive) {
		/* terminate when stdin goes away */
		stdin_event_flags = TEVENT_FD_READ;
	} else {
		/* stay alive forever */
		stdin_event_flags = 0;
	}

	/* catch EOF on stdin */
#ifdef SIGTTIN
	signal(SIGTTIN, SIG_IGN);
#endif

	if (fstat(0, &st) != 0) {
		exit_daemon("Samba failed to set standard input handler", ENOTTY);
	}

	if (S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode)) {
		tevent_add_fd(event_ctx,
				event_ctx,
				0,
				stdin_event_flags,
				server_stdin_handler,
				discard_const(binary_name));
	}

	if (max_runtime) {
		DEBUG(0,("Called with maxruntime %d - current ts %llu\n",
		      max_runtime, (unsigned long long) time(NULL)));
		tevent_add_timer(event_ctx, event_ctx,
				 timeval_current_ofs(max_runtime, 0),
				 max_runtime_handler,
				 discard_const(binary_name));
	}

	if (lpcfg_server_role(cmdline_lp_ctx) != ROLE_ACTIVE_DIRECTORY_DC
	    && !lpcfg_parm_bool(cmdline_lp_ctx, NULL, "server role check", "inhibit", false)
	    && !str_list_check_ci(lpcfg_server_services(cmdline_lp_ctx), "smb") 
	    && !str_list_check_ci(lpcfg_dcerpc_endpoint_servers(cmdline_lp_ctx), "remote")
	    && !str_list_check_ci(lpcfg_dcerpc_endpoint_servers(cmdline_lp_ctx), "mapiproxy")) {
		DEBUG(0, ("At this time the 'samba' binary should only be used for either:\n"));
		DEBUGADD(0, ("'server role = active directory domain controller' or to access the ntvfs file server with 'server services = +smb' or the rpc proxy with 'dcerpc endpoint servers = remote'\n"));
		DEBUGADD(0, ("You should start smbd/nmbd/winbindd instead for domain member and standalone file server tasks\n"));
		exit_daemon("Samba detected misconfigured 'server role' and exited. Check logs for details", EINVAL);
	};

	prime_ldb_databases(event_ctx);

	status = setup_parent_messaging(event_ctx, cmdline_lp_ctx);
	if (!NT_STATUS_IS_OK(status)) {
		exit_daemon("Samba failed to setup parent messaging", NT_STATUS_V(status));
	}

	DEBUG(0,("%s: using '%s' process model\n", binary_name, model));

	status = server_service_startup(event_ctx, cmdline_lp_ctx, model, 
					lpcfg_server_services(cmdline_lp_ctx));
	if (!NT_STATUS_IS_OK(status)) {
		exit_daemon("Samba failed to start services", NT_STATUS_V(status));
	}

	if (opt_daemon) {
		daemon_ready("samba");
	}

	/* wait for events - this is where smbd sits for most of its
	   life */
	tevent_loop_wait(event_ctx);

	/* as everything hangs off this event context, freeing it
	   should initiate a clean shutdown of all services */
	talloc_free(event_ctx);

	return 0;
}
Beispiel #11
0
int main(int argc, const char **argv)
{
    gid_t pc_gid = 0;
    int pc_debug = SSSDBG_DEFAULT;
    struct poptOption long_options[] = {
        POPT_AUTOHELP
        { "debug",'\0', POPT_ARG_INT | POPT_ARGFLAG_DOC_HIDDEN, &pc_debug,
            0, _("The debug level to run with"), NULL },
        { "gid",   'g', POPT_ARG_INT, &pc_gid,
            0, _("The GID of the group"), NULL },
        POPT_TABLEEND
    };
    poptContext pc = NULL;
    struct tools_ctx *tctx = NULL;
    int ret = EXIT_SUCCESS;
    errno_t sret;
    const char *pc_groupname = NULL;
    bool in_transaction = false;

    debug_prg_name = argv[0];

    ret = set_locale();
    if (ret != EOK) {
        DEBUG(1, ("set_locale failed (%d): %s\n", ret, strerror(ret)));
        ERROR("Error setting the locale\n");
        ret = EXIT_FAILURE;
        goto fini;
    }

    /* parse params */
    pc = poptGetContext(NULL, argc, argv, long_options, 0);
    poptSetOtherOptionHelp(pc, "GROUPNAME");
    if ((ret = poptGetNextOpt(pc)) < -1) {
        BAD_POPT_PARAMS(pc, poptStrerror(ret), ret, fini);
    }

    DEBUG_INIT(pc_debug);

    /* groupname is an argument, not option */
    pc_groupname = poptGetArg(pc);
    if (pc_groupname == NULL) {
        BAD_POPT_PARAMS(pc, _("Specify group to add\n"), ret, fini);
    }

    CHECK_ROOT(ret, debug_prg_name);

    ret = init_sss_tools(&tctx);
    if (ret != EOK) {
        DEBUG(1, ("init_sss_tools failed (%d): %s\n", ret, strerror(ret)));
        if (ret == ENOENT) {
            ERROR("Error initializing the tools - no local domain\n");
        } else {
            ERROR("Error initializing the tools\n");
        }
        ret = EXIT_FAILURE;
        goto fini;
    }

    /* if the domain was not given as part of FQDN, default to local domain */
    ret = parse_name_domain(tctx, pc_groupname);
    if (ret != EOK) {
        ERROR("Invalid domain specified in FQDN\n");
        ret = EXIT_FAILURE;
        goto fini;
    }

    tctx->octx->gid = pc_gid;

    /* arguments processed, go on to actual work */
    if (id_in_range(tctx->octx->gid, tctx->octx->domain) != EOK) {
        ERROR("The selected GID is outside the allowed range\n");
        ret = EXIT_FAILURE;
        goto fini;
    }

    tctx->error = sysdb_transaction_start(tctx->sysdb);
    if (tctx->error != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to start transaction\n"));
        goto done;
    }
    in_transaction = true;

    /* groupadd */
    tctx->error = groupadd(tctx->sysdb, tctx->octx);
    if (tctx->error) {
        goto done;
    }

    tctx->error = sysdb_transaction_commit(tctx->sysdb);
    if (tctx->error != EOK) {
        DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to commit transaction\n"));
        goto done;
    }
    in_transaction = false;

done:
    if (in_transaction) {
        sret = sysdb_transaction_cancel(tctx->sysdb);
        if (sret != EOK) {
            DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to cancel transaction\n"));
        }
    }

    if (tctx->error) {
        ret = tctx->error;
        switch (ret) {
            case ERANGE:
                ERROR("Could not allocate ID for the group - domain full?\n");
                break;

            case EEXIST:
                ERROR("A group with the same name or GID already exists\n");
                break;

            default:
                DEBUG(1, ("sysdb operation failed (%d)[%s]\n", ret, strerror(ret)));
                ERROR("Transaction error. Could not add group.\n");
                break;
        }
        ret = EXIT_FAILURE;
        goto fini;
    }

    ret = EXIT_SUCCESS;
fini:
    talloc_free(tctx);
    poptFreeContext(pc);
    exit(ret);
}
Beispiel #12
0
int
main (int argc, char **argv)
{
  static int want_my_version = 0;
  static int want_version = 0;
  static int want_libs = 0;
  static int want_cflags = 0;
  static int want_l_libs = 0;
  static int want_L_libs = 0;
  static int want_other_libs = 0;
  static int want_I_cflags = 0;
  static int want_other_cflags = 0;
  static int want_list = 0;
  static int want_static_lib_list = ENABLE_INDIRECT_DEPS;
  static int want_short_errors = 0;
  static int want_uninstalled = 0;
  static char *variable_name = NULL;
  static int want_exists = 0;
  static int want_provides = 0;
  static int want_requires = 0;
  static int want_requires_private = 0;
  static char *required_atleast_version = NULL;
  static char *required_exact_version = NULL;
  static char *required_max_version = NULL;
  static char *required_pkgconfig_version = NULL;
  static int want_silence_errors = 0;
  static int want_variable_list = 0;
  int result;
  GString *str;
  GSList *packages = NULL;
  char *search_path;
  char *pcbuilddir;
  gboolean need_newline;
  FILE *log = NULL;
  const char *pkgname;

  poptContext opt_context;

  struct poptOption options_table[] = {
    { NULL, 0, POPT_ARG_CALLBACK, popt_callback, 0, NULL, NULL },
    { "version", 0, POPT_ARG_NONE, &want_my_version, 0,
      "output version of pkg-config" },
    { "modversion", 0, POPT_ARG_NONE, &want_version, 0,
      "output version for package" },
    { "atleast-pkgconfig-version", 0, POPT_ARG_STRING, &required_pkgconfig_version, 0,
      "require given version of pkg-config", "VERSION" },
    { "libs", 0, POPT_ARG_NONE, &want_libs, 0,
      "output all linker flags" },
    { "static", 0, POPT_ARG_NONE, &want_static_lib_list, 0,
      "output linker flags for static linking" },
    { "short-errors", 0, POPT_ARG_NONE, &want_short_errors, 0,
      "print short errors" },
    { "libs-only-l", 0, POPT_ARG_NONE, &want_l_libs, 0,
      "output -l flags" },
    { "libs-only-other", 0, POPT_ARG_NONE, &want_other_libs, 0,
      "output other libs (e.g. -pthread)" },
    { "libs-only-L", 0, POPT_ARG_NONE, &want_L_libs, 0,
      "output -L flags" },
    { "cflags", 0, POPT_ARG_NONE, &want_cflags, 0,
      "output all pre-processor and compiler flags" },
    { "cflags-only-I", 0, POPT_ARG_NONE, &want_I_cflags, 0,
      "output -I flags" },
    { "cflags-only-other", 0, POPT_ARG_NONE, &want_other_cflags, 0,
      "output cflags not covered by the cflags-only-I option"},
    { "variable", 0, POPT_ARG_STRING, &variable_name, 0,
      "get the value of variable named NAME", "NAME" },
    { "define-variable", 0, POPT_ARG_STRING, NULL, DEFINE_VARIABLE,
      "set variable NAME to VALUE", "NAME=VALUE" },
    { "exists", 0, POPT_ARG_NONE, &want_exists, 0,
      "return 0 if the module(s) exist" },
    { "print-variables", 0, POPT_ARG_NONE, &want_variable_list, 0,
      "output list of variables defined by the module" },
    { "uninstalled", 0, POPT_ARG_NONE, &want_uninstalled, 0,
      "return 0 if the uninstalled version of one or more module(s) or their dependencies will be used" },
    { "atleast-version", 0, POPT_ARG_STRING, &required_atleast_version, 0,
      "return 0 if the module is at least version VERSION", "VERSION" },
    { "exact-version", 0, POPT_ARG_STRING, &required_exact_version, 0,
      "return 0 if the module is at exactly version VERSION", "VERSION" },
    { "max-version", 0, POPT_ARG_STRING, &required_max_version, 0,
      "return 0 if the module is at no newer than version VERSION", "VERSION" },
    { "list-all", 0, POPT_ARG_NONE, &want_list, 0,
      "list all known packages" },
    { "debug", 0, POPT_ARG_NONE, &want_debug_spew, 0,
      "show verbose debug information" },
    { "print-errors", 0, POPT_ARG_NONE, &want_verbose_errors, 0,
      "show verbose information about missing or conflicting packages,"
      "default if --cflags or --libs given on the command line" },
    { "silence-errors", 0, POPT_ARG_NONE, &want_silence_errors, 0,
      "be silent about errors (default unless --cflags or --libs"
      "given on the command line)" },
    { "errors-to-stdout", 0, POPT_ARG_NONE, &want_stdout_errors, 0,
      "print errors from --print-errors to stdout not stderr" },
    { "print-provides", 0, POPT_ARG_NONE, &want_provides, 0,
      "print which packages the package provides" },
    { "print-requires", 0, POPT_ARG_NONE, &want_requires, 0,
      "print which packages the package requires" },
    { "print-requires-private", 0, POPT_ARG_NONE, &want_requires_private, 0,
      "print which packages the package requires for static linking" },
#ifdef G_OS_WIN32
    { "dont-define-prefix", 0, POPT_ARG_NONE, &dont_define_prefix, 0,
      "don't try to override the value of prefix for each .pc file found with "
      "a guesstimated value based on the location of the .pc file" },
    { "prefix-variable", 0, POPT_ARG_STRING, &prefix_variable, 0,
      "set the name of the variable that pkg-config automatically sets", "PREFIX" },
    { "msvc-syntax", 0, POPT_ARG_NONE, &msvc_syntax, 0,
      "output -l and -L flags for the Microsoft compiler (cl)" },
#endif
    POPT_AUTOHELP
    { NULL, 0, 0, NULL, 0 }
  };

  /* This is here so that we get debug spew from the start,
   * during arg parsing
   */
  if (getenv ("PKG_CONFIG_DEBUG_SPEW"))
    {
      want_debug_spew = TRUE;
      want_verbose_errors = TRUE;
      want_silence_errors = FALSE;
      debug_spew ("PKG_CONFIG_DEBUG_SPEW variable enabling debug spew\n");
    }

  search_path = getenv ("PKG_CONFIG_PATH");
  if (search_path) 
    {
      add_search_dirs(search_path, G_SEARCHPATH_SEPARATOR_S);
    }
  if (getenv("PKG_CONFIG_LIBDIR") != NULL) 
    {
      add_search_dirs(getenv("PKG_CONFIG_LIBDIR"), G_SEARCHPATH_SEPARATOR_S);
    }
  else
    {
      add_search_dirs(PKG_CONFIG_PC_PATH, G_SEARCHPATH_SEPARATOR_S);
    }

  pcsysrootdir = getenv ("PKG_CONFIG_SYSROOT_DIR");
  if (pcsysrootdir)
    {
      define_global_variable ("pc_sysrootdir", pcsysrootdir);
    }
  else
    {
      define_global_variable ("pc_sysrootdir", "/");
    }

  pcbuilddir = getenv ("PKG_CONFIG_TOP_BUILD_DIR");
  if (pcbuilddir)
    {
      define_global_variable ("pc_top_builddir", pcbuilddir);
    }
  else
    {
      /* Default appropriate for automake */
      define_global_variable ("pc_top_builddir", "$(top_builddir)");
    }

  if (getenv ("PKG_CONFIG_DISABLE_UNINSTALLED"))
    {
      debug_spew ("disabling auto-preference for uninstalled packages\n");
      disable_uninstalled = TRUE;
    }

  opt_context = poptGetContext (NULL, argc, argv,
                                options_table, 0);

  result = poptGetNextOpt (opt_context);
  if (result != -1)
    {
      fprintf(stderr, "%s: %s\n",
	      poptBadOption(opt_context, POPT_BADOPTION_NOALIAS),
	      poptStrerror(result));
      return 1;
    }


  /* Error printing is determined as follows:
   *     - for --cflags, --libs, etc. it's on by default
   *       and --silence-errors can turn it off
   *     - for --exists, --max-version, etc. and no options
   *       at all, it's off by default and --print-errors
   *       will turn it on
   */

  if (want_my_version ||
      want_version ||
      want_libs ||
      want_cflags ||
      want_l_libs ||
      want_L_libs ||
      want_other_libs ||
      want_I_cflags ||
      want_other_cflags ||
      want_list ||
      want_variable_list)
    {
      debug_spew ("Error printing enabled by default due to use of --version, --libs, --cflags, --libs-only-l, --libs-only-L, --libs-only-other, --cflags-only-I, --cflags-only-other or --list. Value of --silence-errors: %d\n", want_silence_errors);

      if (want_silence_errors && getenv ("PKG_CONFIG_DEBUG_SPEW") == NULL)
        want_verbose_errors = FALSE;
      else
        want_verbose_errors = TRUE;
    }
  else
    {
      debug_spew ("Error printing disabled by default, value of --print-errors: %d\n",
                  want_verbose_errors);

      /* Leave want_verbose_errors unchanged, reflecting --print-errors */
    }

  if (want_verbose_errors)
    debug_spew ("Error printing enabled\n");
  else
    debug_spew ("Error printing disabled\n");

  if (want_static_lib_list)
    enable_private_libs();
  else
    disable_private_libs();

  /* honor Requires.private if any Cflags are requested or any static
   * libs are requested */

  if (want_I_cflags || want_other_cflags || want_cflags ||
      want_requires_private ||
      (want_static_lib_list && (want_libs || want_l_libs || want_L_libs)))
    enable_requires_private();

  /* ignore Requires if no Cflags or Libs are requested */

  if (!want_I_cflags && !want_other_cflags && !want_cflags &&
      !want_libs && !want_l_libs && !want_L_libs && !want_requires)
    disable_requires();

  if (want_my_version)
    {
      printf ("%s\n", VERSION);
      return 0;
    }

  if (required_pkgconfig_version)
    {
      if (compare_versions (VERSION, required_pkgconfig_version) >= 0)
        return 0;
      else
        return 1;
    }

  package_init ();

  if (want_list)
    {
      print_package_list ();
      return 0;
    }

  str = g_string_new ("");
  while (1)
    {
      pkgname = poptGetArg (opt_context);
      if (pkgname == NULL)
	break;

      g_string_append (str, pkgname);
      g_string_append (str, " ");
    }

  poptFreeContext (opt_context);

  g_strstrip (str->str);

  if (getenv("PKG_CONFIG_LOG") != NULL)
    {
      log = fopen (getenv ("PKG_CONFIG_LOG"), "a");
      if (log == NULL)
	{
	  fprintf (stderr, "Cannot open log file: %s\n",
		   getenv ("PKG_CONFIG_LOG"));
	  exit (1);
	}
    }

  {
    gboolean failed = FALSE;
    GSList *reqs;
    GSList *iter;

    reqs = parse_module_list (NULL, str->str,
                              "(command line arguments)");

    iter = reqs;

    while (iter != NULL)
      {
        Package *req;
        RequiredVersion *ver = iter->data;

        if (want_short_errors)
          req = get_package_quiet (ver->name);
        else
          req = get_package (ver->name);

	if (log != NULL)
	  {
	    if (req == NULL)
	      fprintf (log, "%s NOT-FOUND", ver->name);
	    else
	      fprintf (log, "%s %s %s", ver->name,
		       comparison_to_str (ver->comparison),
		       (ver->version == NULL) ? "(null)" : ver->version);
	    fprintf (log, "\n");
	  }

        if (req == NULL)
          {
            failed = TRUE;
            verbose_error ("No package '%s' found\n", ver->name);
            goto nextiter;
          }

        if (!version_test (ver->comparison, req->version, ver->version))
          {
            failed = TRUE;
            verbose_error ("Requested '%s %s %s' but version of %s is %s\n",
                           ver->name,
                           comparison_to_str (ver->comparison),
                           ver->version,
                           req->name,
                           req->version);

	    if (req->url)
	      verbose_error ("You may find new versions of %s at %s\n",
			     req->name, req->url);

            goto nextiter;
          }

        packages = g_slist_prepend (packages, req);

      nextiter:
        iter = g_slist_next (iter);
      }

    if (log != NULL)
      {
	fclose (log);
      }

    if (failed) {
      return 1;
    }

  if (want_variable_list)
    {
      GSList *tmp;
      tmp = packages;
      while (tmp != NULL)
        {
          Package *pkg = tmp->data;
          g_hash_table_foreach(pkg->vars,
                               &print_hashtable_key,
                               NULL);
          tmp = g_slist_next (tmp);
          if (tmp) printf ("\n");
        }
      need_newline = FALSE;
    }

  }

  g_string_free (str, TRUE);

  packages = g_slist_reverse (packages);

  if (packages == NULL)
    {
      fprintf (stderr, "Must specify package names on the command line\n");

      exit (1);
    }

  if (want_exists)
    return 0; /* if we got here, all the packages existed. */

  if (want_uninstalled)
    {
      /* See if > 0 pkgs (including dependencies recursively) were uninstalled */
      GSList *tmp;
      tmp = packages;
      while (tmp != NULL)
        {
          Package *pkg = tmp->data;

          if (pkg_uninstalled (pkg))
            return 0;

          tmp = g_slist_next (tmp);
        }

      return 1;
    }

  if (want_version)
    {
      GSList *tmp;
      tmp = packages;
      while (tmp != NULL)
        {
          Package *pkg = tmp->data;

          printf ("%s\n", pkg->version);

          tmp = g_slist_next (tmp);
        }
    }

 if (want_provides)
   {
     GSList *tmp;
     tmp = packages;
     while (tmp != NULL)
       {
         Package *pkg = tmp->data;
         char *key;
         key = pkg->key;
         while (*key == '/')
           key++;
         if (strlen(key) > 0)
           printf ("%s = %s\n", key, pkg->version);
         tmp = g_slist_next (tmp);
       }
   }

  if (want_requires)
    {
      GSList *pkgtmp;
      for (pkgtmp = packages; pkgtmp != NULL; pkgtmp = g_slist_next (pkgtmp))
        {
          Package *pkg = pkgtmp->data;
          GSList *reqtmp;

          /* process Requires: */
          for (reqtmp = pkg->requires; reqtmp != NULL; reqtmp = g_slist_next (reqtmp))
            {
              Package *deppkg = reqtmp->data;
              RequiredVersion *req;
              req = g_hash_table_lookup(pkg->required_versions, deppkg->key);
              if ((req == NULL) || (req->comparison == ALWAYS_MATCH))
                printf ("%s\n", deppkg->key);
              else
                printf ("%s %s %s\n", deppkg->key,
                  comparison_to_str(req->comparison),
                  req->version);
            }
        }
    }
  if (want_requires_private)
    {
      GSList *pkgtmp;
      for (pkgtmp = packages; pkgtmp != NULL; pkgtmp = g_slist_next (pkgtmp))
        {
          Package *pkg = pkgtmp->data;
          GSList *reqtmp;
          /* process Requires.private: */
          for (reqtmp = pkg->requires_private; reqtmp != NULL; reqtmp = g_slist_next (reqtmp))
            {

              Package *deppkg = reqtmp->data;
              RequiredVersion *req;

              if (g_slist_find (pkg->requires, reqtmp->data))
                continue;

              req = g_hash_table_lookup(pkg->required_versions, deppkg->key);
              if ((req == NULL) || (req->comparison == ALWAYS_MATCH))
                printf ("%s\n", deppkg->key);
              else
                printf ("%s %s %s\n", deppkg->key,
                  comparison_to_str(req->comparison),
                  req->version);
            }
        }
    }
  
  if (required_exact_version)
    {
      Package *pkg = packages->data;

      if (compare_versions (pkg->version, required_exact_version) == 0)
        return 0;
      else
        return 1;
    }
  else if (required_atleast_version)
    {
      Package *pkg = packages->data;

      if (compare_versions (pkg->version, required_atleast_version) >= 0)
        return 0;
      else
        return 1;
    }
  else if (required_max_version)
    {
      Package *pkg = packages->data;

      if (compare_versions (pkg->version, required_max_version) <= 0)
        return 0;
      else
        return 1;
    }

  /* Print all flags; then print a newline at the end. */
  need_newline = FALSE;

  if (variable_name)
    {
      char *str = packages_get_var (packages, variable_name);
      printf ("%s", str);
      g_free (str);
      need_newline = TRUE;
    }

  if (want_I_cflags)
    {
      char *str = packages_get_I_cflags (packages);
      printf ("%s ", str);
      g_free (str);
      need_newline = TRUE;
    }
  else if (want_other_cflags)
    {
      char *str = packages_get_other_cflags (packages);
      printf ("%s ", str);
      g_free (str);
      need_newline = TRUE;
    }
  else if (want_cflags)
    {
      char *str = packages_get_all_cflags (packages);
      printf ("%s ", str);
      g_free (str);
      need_newline = TRUE;
    }

  if (want_l_libs)
    {
      char *str = packages_get_l_libs (packages);
      printf ("%s ", str);
      g_free (str);
      need_newline = TRUE;
    }
  else if (want_L_libs)
    {
      char *str = packages_get_L_libs (packages);
      printf ("%s ", str);
      g_free (str);
      need_newline = TRUE;
    }
  else if (want_other_libs)
    {
      char *str = packages_get_other_libs (packages);
      printf ("%s ", str);
      g_free (str);
      need_newline = TRUE;
    }
  else if (want_libs)
    {
      char *str = packages_get_all_libs (packages);
      printf ("%s ", str);
      g_free (str);
      need_newline = TRUE;
    }

  if (need_newline)
#ifdef G_OS_WIN32
    printf ("\r\n");
#else
    printf ("\n");
#endif

  return 0;
}
int main(int argc, const char *argv[]) {
  printf("Running %s version %s\n", argv[0], version_identifier());
  for (int i=0; argv[i]; i++) {
    printf("%s ", argv[i]);
  }
  printf("\n");
  took("Starting program");
  // ----------------------------------------------------------------------------
  // Define "Constants" -- set from arguments then unchanged
  // ----------------------------------------------------------------------------

  // NOTE: debug can slow things down VERY much
  int debug = false;

  sw_simulation sw;

  sw.sticky_wall = 0;
  sw.len[0] = sw.len[1] = sw.len[2] = 1;
  sw.walls = 0;
  sw.N = 10;
  sw.translation_scale = 0.05;

  unsigned long int seed = 0;

  char *data_dir = new char[1024];
  sprintf(data_dir, "free-energy-data");
  char *filename = new char[1024];
  sprintf(filename, "default_filename");
  char *filename_suffix = new char[1024];
  sprintf(filename_suffix, "default_filename_suffix");
  long simulation_runs = 1000000;
  double acceptance_goal = .4;
  double R = 1;
  const double well_width = 1;
  double ff = 0.3;
  double ff_small = -1;
  bool force_cube=false;
  bool pack_and_save_cube=false;
  double neighbor_scale = 2;
  double de_g = 0.05;
  double max_rdf_radius = 10;
  int totime = 0;
  double scaling_factor = 1.0;
  int small_cell_check_period = (1 * sw.N * sw.N)/10;

  poptContext optCon;
  // ----------------------------------------------------------------------------
  // Set values from parameters
  // ----------------------------------------------------------------------------
  poptOption optionsTable[] = {
    {"N", '\0', POPT_ARG_INT, &sw.N, 0, "Number of balls to simulate", "INT"},
    {"ff", '\0', POPT_ARG_DOUBLE, &ff, 0, "Filling fraction. If specified, the "
     "cell dimensions are adjusted accordingly without changing the shape of "
     "the cell."},
    {"ff_small", '\0', POPT_ARG_DOUBLE, &ff_small, 0, "Small filling fraction. If specified, "
     "This sets the desired filling fraction of the shrunk cell. Otherwise it defaults to ff."},
    {"force_cube", '\0', POPT_ARG_NONE, &force_cube, 0, "forces box to be a cube", "BOOLEAN"},
    {"pack_and_save_cube", '\0', POPT_ARG_NONE, &pack_and_save_cube, 0, "packs cube, save positions, then returns", "BOOLEAN"},
    {"walls", '\0', POPT_ARG_INT | POPT_ARGFLAG_SHOW_DEFAULT, &sw.walls, 0,
     "Number of walled dimensions (dimension order: x,y,z)", "INT"},
    {"runs", '\0', POPT_ARG_LONG | POPT_ARGFLAG_SHOW_DEFAULT, &simulation_runs,
     0, "Number of \"runs\" for which to run the simulation", "INT"},
    {"de_g", '\0', POPT_ARG_DOUBLE | POPT_ARGFLAG_SHOW_DEFAULT, &de_g, 0,
     "Resolution of distribution functions", "DOUBLE"},
    {"max_rdf_radius", '\0', POPT_ARG_DOUBLE | POPT_ARGFLAG_SHOW_DEFAULT,
     &max_rdf_radius, 0, "Set maximum radius for RDF data collection", "DOUBLE"},
    {"lenx", '\0', POPT_ARG_DOUBLE, &sw.len[x], 0,
     "Relative cell size in x dimension", "DOUBLE"},
    {"leny", '\0', POPT_ARG_DOUBLE, &sw.len[y], 0,
     "Relative cell size in y dimension", "DOUBLE"},
    {"lenz", '\0', POPT_ARG_DOUBLE, &sw.len[z], 0,
     "Relative cell size in z dimension", "DOUBLE"},
    {"filename", '\0', POPT_ARG_STRING | POPT_ARGFLAG_SHOW_DEFAULT, &filename, 0,
     "Base of output file names", "STRING"},
    {"filename_suffix", '\0', POPT_ARG_STRING | POPT_ARGFLAG_SHOW_DEFAULT,
     &filename_suffix, 0, "Output file name suffix", "STRING"},
    {"data_dir", '\0', POPT_ARG_STRING | POPT_ARGFLAG_SHOW_DEFAULT, &data_dir, 0,
     "Directory in which to save data", "data_dir"},
    {"neighbor_scale", '\0', POPT_ARG_DOUBLE | POPT_ARGFLAG_SHOW_DEFAULT,
     &neighbor_scale, 0, "Ratio of neighbor sphere radius to interaction scale "
     "times ball radius. Drastically reduces collision detections","DOUBLE"},
    {"translation_scale", '\0', POPT_ARG_DOUBLE | POPT_ARGFLAG_SHOW_DEFAULT,
     &sw.translation_scale, 0, "Standard deviation for translations of balls, "
     "relative to ball radius", "DOUBLE"},
    {"seed", '\0', POPT_ARG_INT | POPT_ARGFLAG_SHOW_DEFAULT, &seed, 0,
     "Seed for the random number generator", "INT"},
    {"acceptance_goal", '\0', POPT_ARG_DOUBLE | POPT_ARGFLAG_SHOW_DEFAULT,
     &acceptance_goal, 0, "Goal to set the acceptance rate", "DOUBLE"},
    {"time", '\0', POPT_ARG_INT, &totime, 0,
     "Timing of display information (seconds)", "INT"},
    {"R", '\0', POPT_ARG_DOUBLE | POPT_ARGFLAG_SHOW_DEFAULT,
     &R, 0, "Ball radius (for testing purposes; should always be 1)", "DOUBLE"},
    {"debug", '\0', POPT_ARG_NONE, &debug, 0, "Debug mode", "BOOLEAN"},
    {"sf", '\0', POPT_ARG_DOUBLE, &scaling_factor, 0,
      "Factor by which to scale the small cell", "DOUBLE"},
    {"sc_period", '\0', POPT_ARG_INT, &small_cell_check_period, 0,
     "Check the small cell every P iterations", "INT"},
    POPT_AUTOHELP
    POPT_TABLEEND
  };
  optCon = poptGetContext(NULL, argc, argv, optionsTable, 0);
  poptSetOtherOptionHelp(optCon, "[OPTION...]\nNumber of balls and filling "
                         "fraction or cell dimensions are required arguments.");

  int c = 0;
  // go through arguments, set them based on optionsTable
  while((c = poptGetNextOpt(optCon)) >= 0);
  if (c < -1) {
    fprintf(stderr, "\n%s: %s\n", poptBadOption(optCon, 0), poptStrerror(c));
    return 1;
  }
  poptFreeContext(optCon);

  // ----------------------------------------------------------------------------
  // Verify we have reasonable arguments and set secondary parameters
  // ----------------------------------------------------------------------------

  if(sw.walls >= 2){
    printf("Code cannot currently handle walls in more than one dimension.\n");
    return 254;
  }
  if(sw.walls > 3){
    printf("You cannot have walls in more than three dimensions.\n");
    return 254;
  }
  if(well_width < 1){
    printf("Interaction scale should be greater than (or equal to) 1.\n");
    return 254;
  }

  if(ff_small != -1 && scaling_factor != 1.0){
    printf("You can't specify both the small filling fraction and the scaling factor.");  
    return 1;
  }


  if (ff != 0) {
    // The user specified a filling fraction, so we must make it so!
    const double volume = 4*M_PI/3*R*R*R*sw.N/ff;
    const double min_cell_width = 2*sqrt(2)*R; // minimum cell width
    const int numcells = (sw.N+3)/4; // number of unit cells we need
    const int max_cubic_width
      = pow(volume/min_cell_width/min_cell_width/min_cell_width, 1.0/3);
    if (max_cubic_width*max_cubic_width*max_cubic_width >= numcells) {
      // We can get away with a cubic cell, so let's do so.  Cubic
      // cells are nice and comfortable!
      sw.len[x] = sw.len[y] = sw.len[z] = pow(volume, 1.0/3);
    } else {
      printf("N = %d\n", sw.N);
      printf("ff = %g\n", ff);
      printf("min_cell_width = %g\n", min_cell_width);
      printf("volume**1/3 = %g\n", pow(volume, 1.0/3));
      printf("max_cubic_width**3 = %d, numcells = %d\n",
             max_cubic_width*max_cubic_width*max_cubic_width, numcells);
      // A cubic cell won't work with our initialization routine, so
      // let's go with a lopsided cell that should give us something
      // that will work.
      int xcells = int( pow(numcells, 1.0/3) );
      int cellsleft = (numcells + xcells - 1)/xcells;
      int ycells = int( sqrt(cellsleft) );
      int zcells = (cellsleft + ycells - 1)/ycells;

      // The above should give a zcells that is largest, followed by
      // ycells and then xcells.  Thus we make the lenz just small
      // enough to fit these cells, and so on, to make the cell as
      // close to cubic as possible.
      sw.len[z] = zcells*min_cell_width;
      if (xcells == ycells) {
        sw.len[x] = sw.len[y] = sqrt(volume/sw.len[z]);
      } else {
        sw.len[y] = min_cell_width*ycells;
        sw.len[x] = volume/sw.len[y]/sw.len[z];
      }
      printf("Using lopsided %d x %d x %d cell (total goal %d)\n",
             xcells, ycells, zcells, numcells);
    }
  }

  // if the user didn't specifiy a small filling fraction, then we should get it.
  if(ff_small == -1){
      ff_small = (4*M_PI/3*R*R*R*sw.N)/
        (sw.len[x]*sw.len[y]*sw.len[z]*scaling_factor*scaling_factor*scaling_factor);
  }
  // if they did, then we need to get the scale factor
  else{
    scaling_factor = std::cbrt(ff/ff_small);
  }


  printf("\nSetting cell dimensions to (%g, %g, %g).\n",
         sw.len[x], sw.len[y], sw.len[z]);
  printf("\nFilling fraction of small cell is %g", ff_small);
  if (sw.N <= 0 || simulation_runs < 0 || R <= 0 ||
      neighbor_scale <= 0 || sw.translation_scale < 0 ||
      sw.len[x] < 0 || sw.len[y] < 0 || sw.len[z] < 0) {
    fprintf(stderr, "\nAll parameters must be positive.\n");
    return 1;
  }

  const double eta = (double)sw.N*4.0/3.0*M_PI*R*R*R/(sw.len[x]*sw.len[y]*sw.len[z]);
  if (eta > 1) {
    fprintf(stderr, "\nYou're trying to cram too many balls into the cell. "
            "They will never fit. Filling fraction: %g\n", eta);
    return 7;
  }

  // If a filename was not selected, make a default
  if (strcmp(filename, "default_filename") == 0) {
    char *wall_tag = new char[100];
    if(sw.walls == 0) sprintf(wall_tag,"periodic");
    else if(sw.walls == 1) sprintf(wall_tag,"wall");
    else if(sw.walls == 2) sprintf(wall_tag,"tube");
    else if(sw.walls == 3) sprintf(wall_tag,"box");
    sprintf(filename, "%s-ww%04.2f-ff%04.2f-N%i-sf%f",
            wall_tag, well_width, eta, sw.N, scaling_factor);
    printf("\nUsing default file name: ");
    delete[] wall_tag;
  }
  else
    printf("\nUsing given file name: ");
  // If a filename suffix was specified, add it
  if (strcmp(filename_suffix, "default_filename_suffix") != 0)
    sprintf(filename, "%s-%s", filename, filename_suffix);
  printf("%s\n",filename);

  printf("------------------------------------------------------------------\n");
  printf("Running %s with parameters:\n", argv[0]);
  for(int i = 1; i < argc; i++) {
    if(argv[i][0] == '-') printf("\n");
    printf("%s ", argv[i]);
  }
  printf("\nUsing scaling factor of %f", scaling_factor);
  printf("\n");
  if (totime > 0) printf("Timing information will be displayed.\n");
  if (debug) printf("DEBUG MODE IS ENABLED!\n");
  else printf("Debug mode disabled\n");
  printf("------------------------------------------------------------------\n\n");

  // ----------------------------------------------------------------------------
  // Define sw_simulation variables
  // ----------------------------------------------------------------------------

  sw.iteration = 0; // start at zeroeth iteration
  sw.max_entropy_state = 0;
  sw.min_energy_state = 0;
  sw.energy = 0;
  sw.min_important_energy = 0;

  // translation distance should scale with ball radius
  sw.translation_scale *= R;

  // neighbor radius should scale with radius and interaction scale
  sw.neighbor_R = neighbor_scale*R*well_width;

  // Find the upper limit to the maximum number of neighbors a ball could have
  sw.max_neighbors = max_balls_within(2+neighbor_scale*well_width);

  // Energy histogram and weights
  sw.interaction_distance = 2*R*well_width;
  sw.energy_levels = 1; // hard spheres can only have one energy!
  sw.energy_histogram = new long[sw.energy_levels]();
  sw.ln_energy_weights = new double[sw.energy_levels]();

  // Observed and sampled energies
  sw.pessimistic_observation = new bool[sw.energy_levels]();
  sw.pessimistic_samples = new long[sw.energy_levels]();
  sw.optimistic_samples = new long[sw.energy_levels]();

  // Transitions from one energy to another
  sw.biggest_energy_transition = max_balls_within(sw.interaction_distance);
  sw.transitions_table =
    new long[sw.energy_levels*(2*sw.biggest_energy_transition+1)]();

  // Walker histograms
  sw.walkers_up = new long[sw.energy_levels]();


  printf("memory use estimate = %.2g G\n\n",
         8*double(6*sw.energy_levels)/1024/1024/1024);

  sw.balls = new ball[sw.N];

  if(totime < 0) totime = 10*sw.N;

  // Initialize the random number generator with our seed
  random::seed(seed);

  // ----------------------------------------------------------------------------
  // Set up the initial grid of balls
  // ----------------------------------------------------------------------------

  for(int i = 0; i < sw.N; i++) // initialize ball radii
    sw.balls[i].R = R;

    //###########################  pack and save  ####################
  if(pack_and_save_cube==true){
	  INITBOX *box=load_cube(data_dir);
	  if(box!=NULL && box->numAtoms<sw.N) {delete box; box=NULL;}
	  if(box!=NULL){//---------loaded baseAtoms up to max of sw.N
		  printf("loading from baseAtoms.txt\n");
		  for(int count=0;count<(100*box->numAtoms);count++){
			  //mixes indices so the culled atoms are random
			  //atoms are only culled from the end...
			  int n1=floor(random::ran()*(box->numAtoms));
			  int n2=floor(random::ran()*(box->numAtoms));
			  double xTemp=box->list[n1].x;
			  double yTemp=box->list[n1].y;
			  double zTemp=box->list[n1].z;
			  box->list[n1].x=box->list[n2].x;
			  box->list[n1].y=box->list[n2].y;
			  box->list[n1].z=box->list[n2].z;
			  box->list[n2].x=xTemp;
			  box->list[n2].y=yTemp;
			  box->list[n2].z=zTemp;
		  }
		  //box2 is used to cull atoms from the end (if needed)
		  //box2 is simulated to mix the atoms up after culling
		  INITBOX *box2=new INITBOX(box->lx);
		  for(int i=0;i<sw.N;i++) box2->addAtom(box->list[i].x,box->list[i].y,box->list[i].z);
		  delete box;
		  box2->temperature=1000.0;
		  for(int i=0;i<100;i++) box2->simulate(sw.N*100);//mix box
		  sw.len[x] = sw.len[y] = sw.len[z] = box2->lx;
		  for(int i=0;i<sw.N;i++) {
			  sw.balls[i].pos=vector3d(box2->list[i].x,box2->list[i].y,box2->list[i].z);
		  }
		  delete box2;
	  }
	  else{//if no baseAtoms.txt then try to pack the box
		if(ff==0){printf("must initialize using --ff\n"); return 254;}
		printf("building baseAtoms.txt\n");
		const double volume = 4*M_PI/3*R*R*R*sw.N/ff;
		sw.len[x] = sw.len[y] = sw.len[z] = pow(volume, 1.0/3);
		if(pack_cube(sw)==false) {printf("could not fill box\n"); return 254;}
	}//done initializing positions
	  mkdir(data_dir, 0777); // create save directory
	  
	  char *posData = new char[4096];
	  sprintf(posData,"%s/baseAtoms.txt",data_dir);
	  FILE *pos_out = fopen((const char *)posData, "w");
	  sprintf(posData,"L = %g\nN = %i\n",sw.len[x],sw.N);
	  fprintf(pos_out,"%s",posData);
	  for(int i=0;i<sw.N;i++){
		sprintf(posData,"%g %g %g",
				sw.balls[i].pos.x,sw.balls[i].pos.y,sw.balls[i].pos.z);
		fprintf(pos_out,"%s",posData);
		if(i+1<sw.N) fprintf(pos_out,"\n");
	  }
      fclose(pos_out);
      delete[] posData;
      took("Placement");
      return 0;
  }
  //###########################  DONE pack and save  #################
  
  if(force_cube==true){//try to load baseAtoms.txt
	  if(ff==0){printf("must initialize using --ff\n"); return 254;}
	  printf("attempting to load baseAtoms.txt\n");
	  const double volume = 4*M_PI/3*R*R*R*sw.N/ff;
	  sw.len[x] = sw.len[y] = sw.len[z] = pow(volume, 1.0/3);
	  INITBOX *box=load_cube(data_dir);
	  if(box==NULL) {
		  printf("requires initialization on the smallest box\nuse the --pack_and_save --ff -N   flags\n");
		  return 254; }
	  if(box->numAtoms<sw.N){
		  printf("boxAtoms.txt contains less atoms than expected\n");
		  delete box;
		  return 254; }
	  if(box->lx>sw.len[x]){
		  printf("baseAtoms must be in a box smaller than current simulation\n");
		  delete box;
		  return 254; }
	  box->temperature=1000.0;
	  for(int i=0;i<100;i++) box->simulate(sw.N*100);//mix box
      double scaleFactor=sw.len[x]/box->lx;
	  for(int i=0;i<sw.N;i++){
          double x=(box->list[i].x)*scaleFactor;
          double y=(box->list[i].y)*scaleFactor;
          double z=(box->list[i].z)*scaleFactor;
		  sw.balls[i].pos=vector3d(x,y,z);
	  }
	  delete box;
  }
  else {
	  // Balls will be initially placed on a face centered cubic (fcc) grid
	  // Note that the unit cells need not be actually "cubic", but the fcc grid will
      //   be stretched to cell dimensions
	  const double min_cell_width = 2*sqrt(2)*R; // minimum cell width
	  const int spots_per_cell = 4; // spots in each fcc periodic unit cell
	  int cells[3]; // array to contain number of cells in x, y, and z dimensions
	  for(int i = 0; i < 3; i++){
	    cells[i] = int(sw.len[i]/min_cell_width); // max number of cells that will fit
	  }
	
	  // It is usefull to know our cell dimensions
	  double cell_width[3];
	  for(int i = 0; i < 3; i++) cell_width[i] = sw.len[i]/cells[i];
	
	  // If we made our cells to small, return with error
	  for(int i = 0; i < 3; i++){
	    if(cell_width[i] < min_cell_width){
	      printf("Placement cell size too small: (%g,  %g,  %g) coming from (%g, %g, %g)\n",
	             cell_width[0],cell_width[1],cell_width[2],
	             sw.len[0], sw.len[1], sw.len[2]);
	      printf("Minimum allowed placement cell width: %g\n",min_cell_width);
	      printf("Total simulation cell dimensions: (%g,  %g,  %g)\n",
	             sw.len[0],sw.len[1],sw.len[2]);
	      printf("Fixing the chosen ball number, filling fractoin, and relative\n"
	             "  simulation cell dimensions simultaneously does not appear to be possible\n");
	      return 176;
	    }
	  }
	
	  // Define ball positions relative to cell position
	  vector3d* offset = new vector3d[4]();
	  offset[x] = vector3d(0,cell_width[y],cell_width[z])/2;
	  offset[y] = vector3d(cell_width[x],0,cell_width[z])/2;
	  offset[z] = vector3d(cell_width[x],cell_width[y],0)/2;
	
	  // Reserve some spots at random to be vacant
	  const int total_spots = spots_per_cell*cells[x]*cells[y]*cells[z];
	  bool *spot_reserved = new bool[total_spots]();
	  int p; // Index of reserved spot
	  for(int i = 0; i < total_spots-sw.N; i++) {
	    p = floor(random::ran()*total_spots); // Pick a random spot index
	    if(spot_reserved[p] == false) // If it's not already reserved, reserve it
	      spot_reserved[p] = true;
	    else // Otherwise redo this index (look for a new spot)
	      i--;
	  }
	
	  // Place all balls in remaining spots
	  int b = 0;
	  for(int i = 0; i < cells[x]; i++) {
	    for(int j = 0; j < cells[y]; j++) {
	      for(int k = 0; k < cells[z]; k++) {
	        for(int l = 0; l < 4; l++) {
	          if(!spot_reserved[i*(4*cells[z]*cells[y])+j*(4*cells[z])+k*4+l]) {
	            sw.balls[b].pos = vector3d(i*cell_width[x],j*cell_width[y],
	                                       k*cell_width[z]) + offset[l];
	            b++;
	          }
	        }
	      }
	    }
	  }
	  delete[] offset;
	  delete[] spot_reserved;
  }
  took("Placement");

  // ----------------------------------------------------------------------------
  // Print info about the initial configuration for troubleshooting
  // ----------------------------------------------------------------------------

  {
    int most_neighbors =
      initialize_neighbor_tables(sw.balls, sw.N, sw.neighbor_R,
                                 sw.max_neighbors, sw.len, sw.walls);
    if (most_neighbors < 0) {
      fprintf(stderr, "The guess of %i max neighbors was too low. Exiting.\n",
              sw.max_neighbors);
      return 1;
    }
    printf("Neighbor tables initialized.\n");
    printf("The most neighbors is %i, whereas the max allowed is %i.\n",
           most_neighbors, sw.max_neighbors);
  }

  // ----------------------------------------------------------------------------
  // Make sure initial placement is valid
  // ----------------------------------------------------------------------------

  for(int i = 0; i < sw.N; i++) {
    for(int j = 0; j < i; j++) {
      if (overlap(sw.balls[i], sw.balls[j], sw.len, sw.walls)) {
        print_bad(sw.balls, sw.N, sw.len, sw.walls);
        printf("Error in initial placement: balls are overlapping.\n");
        return 253;
      }
    }
  }

  fflush(stdout);

  // ----------------------------------------------------------------------------
  // Initialization of cell
  // ----------------------------------------------------------------------------

  sw.initialize_translation_distance();

  // --------------------------------------------------------------------------
  // end initilization routine.
  // --------------------------------------------------------------------------

  // ----------------------------------------------------------------------------
  // Generate info to put in save files
  // ----------------------------------------------------------------------------

  mkdir(data_dir, 0777); // create save directory

  char *headerinfo = new char[4096];
  sprintf(headerinfo,
          "# version: %s\n"
          "# cell dimensions: (%g, %g, %g)\n"
          "# walls: %i\n"
          "# de_g: %g\n"
          "# seed: %li\n"
          "# N: %i\n"
          "# R: %f\n"
          "# well_width: %g\n"
          "# translation_scale: %g\n"
          "# neighbor_scale: %g\n"
          "# scaling factor: %g\n"
          "# ff: %g\n"
          "# ff_small: %g\n",
          version_identifier(),
          sw.len[0], sw.len[1], sw.len[2], sw.walls, de_g, seed, sw.N, R,
          well_width, sw.translation_scale, neighbor_scale, scaling_factor, ff, ff_small);

  char *g_fname = new char[1024];
  sprintf(g_fname, "%s/%s.dat", data_dir, filename);

  took("Initialization");

  // ----------------------------------------------------------------------------
  // MAIN PROGRAM LOOP
  // ----------------------------------------------------------------------------

  sw.moves.total = 0;
  sw.moves.working = 0;
  sw.iteration = 0;

  // tracking for free energy
  int current_valid_run = 0;
  int current_failed_run = 0;
  int longest_valid_run = 0;
  int longest_failed_run = 0;
  int total_checks_of_small_cell = 0;
  int total_valid_small_checks = 0;
  int total_failed_small_checks = 0;
  int valid_runs = 0;
  int failed_runs = 0;
  double average_valid_run = 0;
  double average_failed_run = 0;

  // Reset energy histogram and sample counts
  for(int i = 0; i < sw.energy_levels; i++){
    sw.energy_histogram[i] = 0;
    sw.pessimistic_samples[i] = 0;
    sw.optimistic_samples[i] = 0;
  }

  do {
    // ---------------------------------------------------------------
    // Move each ball once, add to energy histogram
    // ---------------------------------------------------------------
    for(int i = 0; i < sw.N; i++){
      sw.move_a_ball();
    }

    // just hacking stuff in to see what works
    // do the small bit every 100 n^2 iterations for now
    if (sw.iteration % small_cell_check_period == 0) {
      total_checks_of_small_cell++;

      if(overlap_in_small_cell(sw,  scaling_factor)){
        total_failed_small_checks++;
        
        if (current_failed_run == 0){
          // then valid run just ended so record it
          valid_runs++;
          if(current_valid_run > longest_valid_run)
            longest_valid_run = current_valid_run;
          average_valid_run = average_valid_run + (current_valid_run - average_valid_run)/valid_runs;
          current_valid_run = 0;
        }

        current_failed_run++;

        if(debug){printf("%i - false\n", current_failed_run);}
      }
      else{
        total_valid_small_checks++;

        if (current_valid_run == 0){
          // then failed run just ended so record it
          failed_runs++;
          if(current_failed_run > longest_failed_run)
            longest_failed_run = current_failed_run;
          average_failed_run = average_failed_run + (current_failed_run - average_failed_run)/failed_runs;
          current_failed_run = 0;
        }

        current_valid_run++;

        if(debug){printf("%i - true\n", current_valid_run);}
      }
    }

    // ---------------------------------------------------------------
    // Save to file
    // ---------------------------------------------------------------

    if (time_to_save() || valid_runs == simulation_runs) {
      const clock_t now = clock();
      const double secs_done = double(now)/CLOCKS_PER_SEC;
      const int seconds = int(secs_done) % 60;
      const int minutes = int(secs_done / 60) % 60;
      const int hours = int(secs_done / 3600) % 24;
      const int days = int(secs_done / 86400);
      const long percent_done = 100*valid_runs/simulation_runs;
      printf("Saving data after %i days, %02i:%02i:%02i, %li iterations (%ld%%) "
             "complete.\n", days, hours, minutes, seconds, sw.iteration,
             percent_done);
      fflush(stdout);

      char *countinfo = new char[4096];
      sprintf(countinfo,
              "# iterations: %li\n"
              "# working moves: %li\n"
              "# total moves: %li\n"
              "# acceptance rate: %g\n"
              "# longest failed run: %i\n"
              "# longest valid run: %i\n"
              "# total checks of small cell: %i\n"
              "# total failed small checks: %i\n"
              "# total valid small checks: %i\n"
              "# valid runs: %i\n"
              "# failed runs: %i\n"
              "# average valid run: %g\n"
              "# average failed run: %g\n\n",
              sw.iteration, sw.moves.working, sw.moves.total,
              double(sw.moves.working)/sw.moves.total, longest_failed_run,
              longest_valid_run, total_checks_of_small_cell, total_failed_small_checks,
              total_valid_small_checks, valid_runs, failed_runs, average_valid_run, average_failed_run);

      // Save data
      if(!sw.walls){
        FILE *g_out = fopen((const char *)g_fname, "w");
        fprintf(g_out, "%s", headerinfo);
        fprintf(g_out, "%s", countinfo);
        fclose(g_out);
      }

      delete[] countinfo;
    }
  } while (valid_runs < simulation_runs);
  // ----------------------------------------------------------------------------
  // END OF MAIN PROGRAM LOOP
  // ----------------------------------------------------------------------------

  for (int i=0; i<sw.N; i++) {
    delete[] sw.balls[i].neighbors;
  }
  delete[] sw.balls;
  delete[] sw.ln_energy_weights;
  delete[] sw.energy_histogram;

  delete[] sw.transitions_table;

  delete[] sw.walkers_up;

  delete[] sw.pessimistic_observation;
  delete[] sw.pessimistic_samples;
  delete[] sw.optimistic_samples;

  delete[] headerinfo;
  delete[] g_fname;

  delete[] data_dir;
  delete[] filename;
  delete[] filename_suffix;

  return 0;
}
Beispiel #14
0
int main(int argc, const char *argv[])
{
    int rv;
    poptContext pc;
    int opt;
    struct poptOption long_options[] = {
        POPT_AUTOHELP
        SSSD_DEBUG_OPTS
        POPT_TABLEEND
    };

    const struct CMUnitTest tests[] = {
        /* user */
        cmocka_unit_test_setup_teardown(test_ncache_nocache_user,
                                        test_ncache_setup,
                                        test_ncache_teardown),
        cmocka_unit_test_setup_teardown(test_ncache_local_user,
                                        test_ncache_setup,
                                        test_ncache_teardown),
        cmocka_unit_test_setup_teardown(test_ncache_domain_user,
                                        test_ncache_setup,
                                        test_ncache_teardown),
        cmocka_unit_test_setup_teardown(test_ncache_both_user,
                                        test_ncache_setup,
                                        test_ncache_teardown),
        /* uid */
        cmocka_unit_test_setup_teardown(test_ncache_nocache_uid,
                                        test_ncache_setup,
                                        test_ncache_teardown),
        cmocka_unit_test_setup_teardown(test_ncache_local_uid,
                                        test_ncache_setup,
                                        test_ncache_teardown),
        cmocka_unit_test_setup_teardown(test_ncache_domain_uid,
                                        test_ncache_setup,
                                        test_ncache_teardown),
        cmocka_unit_test_setup_teardown(test_ncache_both_uid,
                                        test_ncache_setup,
                                        test_ncache_teardown),
        /* group */
        cmocka_unit_test_setup_teardown(test_ncache_nocache_group,
                                        test_ncache_setup,
                                        test_ncache_teardown),
        cmocka_unit_test_setup_teardown(test_ncache_local_group,
                                        test_ncache_setup,
                                        test_ncache_teardown),
        cmocka_unit_test_setup_teardown(test_ncache_domain_group,
                                        test_ncache_setup,
                                        test_ncache_teardown),
        cmocka_unit_test_setup_teardown(test_ncache_both_group,
                                        test_ncache_setup,
                                        test_ncache_teardown),
        /* gid */
        cmocka_unit_test_setup_teardown(test_ncache_nocache_gid,
                                        test_ncache_setup,
                                        test_ncache_teardown),
        cmocka_unit_test_setup_teardown(test_ncache_local_gid,
                                        test_ncache_setup,
                                        test_ncache_teardown),
        cmocka_unit_test_setup_teardown(test_ncache_domain_gid,
                                        test_ncache_setup,
                                        test_ncache_teardown),
        cmocka_unit_test_setup_teardown(test_ncache_both_gid,
                                        test_ncache_setup,
                                        test_ncache_teardown),
    };

    /* Set debug level to invalid value so we can deside if -d 0 was used. */
    debug_level = SSSDBG_INVALID;

    pc = poptGetContext(argv[0], argc, argv, long_options, 0);
    while ((opt = poptGetNextOpt(pc)) != -1) {
        switch (opt) {
        default:
            fprintf(stderr, "\nInvalid option %s: %s\n\n",
                    poptBadOption(pc, 0), poptStrerror(opt));
            poptPrintUsage(pc, stderr, 0);
            return 1;
        }
    }
    poptFreeContext(pc);

    DEBUG_CLI_INIT(debug_level);

    tests_set_cwd();
    test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME);
    rv = cmocka_run_group_tests(tests, NULL, NULL);

    return rv;
}
Beispiel #15
0
int main(int argc, const char **argv)
{
	struct tevent_context *evt_ctx;
	struct messaging_context *msg_ctx;
	struct db_context *db;

	uint16_t count;

	const char *dbname;
	const char *opname;
	dbwrap_op op;
	const char *keyname = "";
	const char *keytype = "int32";
	dbwrap_type type;
	const char *valuestr = "0";
	int32_t value = 0;

	TALLOC_CTX *mem_ctx = talloc_stackframe();

	int ret = 1;

	struct poptOption popt_options[] = {
		POPT_AUTOHELP
		POPT_COMMON_SAMBA
		POPT_TABLEEND
	};
	int opt;
	const char **extra_argv;
	int extra_argc = 0;
	poptContext pc;

	load_case_tables();
	lp_set_cmdline("log level", "0");
	setup_logging(argv[0], DEBUG_STDERR);

	pc = poptGetContext(argv[0], argc, argv, popt_options, POPT_CONTEXT_KEEP_FIRST);

	while ((opt = poptGetNextOpt(pc)) != -1) {
		switch (opt) {
		default:
			fprintf(stderr, "Invalid option %s: %s\n",
				poptBadOption(pc, 0), poptStrerror(opt));
			goto done;
		}
	}

	/* setup the remaining options for the main program to use */
	extra_argv = poptGetArgs(pc);
	if (extra_argv) {
		extra_argv++;
		while (extra_argv[extra_argc]) extra_argc++;
	}

	lp_load_global(get_dyn_CONFIGFILE());

	if ((extra_argc < 2) || (extra_argc > 5)) {
		d_fprintf(stderr,
			  "USAGE: %s <database> <op> [<key> [<type> [<value>]]]\n"
			  "       ops: fetch, store, delete, erase, listkeys\n"
			  "       types: int32, uint32\n",
			 argv[0]);
		goto done;
	}

	dbname = extra_argv[0];
	opname = extra_argv[1];

	if (strcmp(opname, "store") == 0) {
		if (extra_argc != 5) {
			d_fprintf(stderr, "ERROR: operation 'store' requires "
				  "value argument\n");
			goto done;
		}
		valuestr = extra_argv[4];
		keytype = extra_argv[3];
		keyname = extra_argv[2];
		op = OP_STORE;
	} else if (strcmp(opname, "fetch") == 0) {
		if (extra_argc != 4) {
			d_fprintf(stderr, "ERROR: operation 'fetch' requires "
				  "type but not value argument\n");
			goto done;
		}
		op = OP_FETCH;
		keytype = extra_argv[3];
		keyname = extra_argv[2];
	} else if (strcmp(opname, "delete") == 0) {
		if (extra_argc != 3) {
			d_fprintf(stderr, "ERROR: operation 'delete' does "
				  "not allow type nor value argument\n");
			goto done;
		}
		keyname = extra_argv[2];
		op = OP_DELETE;
	} else if (strcmp(opname, "erase") == 0) {
		if (extra_argc != 2) {
			d_fprintf(stderr, "ERROR: operation 'erase' does "
				  "not take a key argument\n");
			goto done;
		}
		op = OP_ERASE;
	} else if (strcmp(opname, "listkeys") == 0) {
		if (extra_argc != 2) {
			d_fprintf(stderr, "ERROR: operation 'listkeys' does "
				  "not take a key argument\n");
			goto done;
		}
		op = OP_LISTKEYS;
	} else {
		d_fprintf(stderr,
			  "ERROR: invalid op '%s' specified\n"
			  "       supported ops: fetch, store, delete\n",
			  opname);
		goto done;
	}

	if (strcmp(keytype, "int32") == 0) {
		type = TYPE_INT32;
		value = (int32_t)strtol(valuestr, NULL, 10);
	} else if (strcmp(keytype, "uint32") == 0) {
		type = TYPE_UINT32;
		value = (int32_t)strtoul(valuestr, NULL, 10);
	} else {
		d_fprintf(stderr, "ERROR: invalid type '%s' specified.\n"
				  "       supported types: int32, uint32\n",
				  keytype);
		goto done;
	}

	evt_ctx = tevent_context_init(mem_ctx);
	if (evt_ctx == NULL) {
		d_fprintf(stderr, "ERROR: could not init event context\n");
		goto done;
	}

	msg_ctx = messaging_init(mem_ctx, procid_self(), evt_ctx);
	if (msg_ctx == NULL) {
		d_fprintf(stderr, "ERROR: could not init messaging context\n");
		goto done;
	}

	db = db_open(mem_ctx, dbname, 0, TDB_DEFAULT, O_RDWR | O_CREAT, 0644);
	if (db == NULL) {
		d_fprintf(stderr, "ERROR: could not open dbname\n");
		goto done;
	}

	for (count = 0; dispatch_table[count].cmd != NULL; count++) {
		if ((op == dispatch_table[count].op) &&
		    (type == dispatch_table[count].type))
		{
			ret = dispatch_table[count].cmd(db, keyname, &value);
			break;
		}
	}

done:
	TALLOC_FREE(mem_ctx);
	return ret;
}