void env_relocate (void)
{
	DEBUGF ("%s[%d] offset = 0x%lx\n", __FUNCTION__,__LINE__,
		gd->reloc_off);

#ifdef CONFIG_AMIGAONEG3SE
	enable_nvram();
#endif

#ifdef ENV_IS_EMBEDDED
	/*
	 * The environment buffer is embedded with the text segment,
	 * just relocate the environment pointer
	 */
	env_ptr = (env_t *)((ulong)env_ptr + gd->reloc_off);
	DEBUGF ("%s[%d] embedded ENV at %p\n", __FUNCTION__,__LINE__,env_ptr);
#else
	/*
	 * We must allocate a buffer for the environment
	 */
	env_ptr = (env_t *)malloc (CFG_ENV_SIZE);
	DEBUGF ("%s[%d] malloced ENV at %p\n", __FUNCTION__,__LINE__,env_ptr);
#endif

	/*
	 * After relocation to RAM, we can always use the "memory" functions
	 */
	env_get_char = env_get_char_memory;

	if (gd->env_valid == 0) {
#if defined(CONFIG_GTH)	|| defined(CFG_ENV_IS_NOWHERE)	/* Environment not changable */
		puts ("Using default environment\n\n");
#else
		puts ("*** Warning - bad CRC, using default environment\n\n");
		show_boot_progress (-60);
#endif
	}

#ifdef CFG_PREBOOT_OVERRIDE
	if (preboot_override)
		gd->env_valid = 0;
#endif

	if (gd->env_valid == 0)
		default_env();
	else {
		env_relocate_spec ();
	}
	gd->env_addr = (ulong)&(env_ptr->data);

#ifdef CONFIG_AMIGAONEG3SE
	disable_nvram();
#endif
}
Exemple #2
0
void				create_env(char **env)
{
	int				fd;
	char			*len;
	int				i;

	if (!env[0])
		env = default_env();
	fd = open(ENV_FILE, O_RDWR | O_CREAT | O_TRUNC, 0644);
	len = ft_itoa(ft_ctablen(env));
	write(fd, len, ft_strlen(len));
	write(fd, "\n", 1);
	i = 0;
	while (env[i])
	{
		write(fd, env[i], ft_strlen(env[i]));
		write(fd, "\n", 1);
		i++;
	}
	close(fd);
}
static void use_default()
{
	puts ("*** Warning - bad CRC or NAND, using default environment\n\n");
	default_env();
}
Exemple #4
0
int main(int argc, char *argv[]){
	/* extract program name from path. e.g. /path/to/MArCd -> MArCd */
	const char* separator = strrchr(argv[0], '/');
	if ( separator ){
		program_name = separator + 1;
	} else {
		program_name = argv[0];
	}

	default_env();

	int ret;
	int option_index = 0;
	int op;

#ifdef HAVE_INIPARSER_H
	if ( config::load(argc, argv) != 0 ){ /* passing argv so it can read -f/--config */
		return 1; /* error already shown */
	}
#endif

	while ( (op = getopt_long(argc, argv, shortopts, longopts, &option_index)) != -1 ){
		switch (op){
		case '?': /* error */
			exit(1);

		case 0: /* long opt */
			break;

		case 'b': /* --daemon */
			daemon_mode = 1;
			break;

		case 's': /* --syslog */
			syslog_flag = true;
			break;

		case FLAG_USER: /* --user */
			config::set_drop_username(optarg);
			break;

		case FLAG_GROUP: /* --group */
			config::set_drop_group(optarg);
			break;

		case FLAG_DROP_PRIV: /** --drop */
			drop_priv_flag = true;
			break;

		case FLAG_NODROP_PRIV: /** --no-drop */
			drop_priv_flag = false;
			break;

		case 'f':
#ifndef HAVE_INIPARSER_H
			fprintf(stderr, "%s: configuration files not supported (build with --with-iniparser)\n", program_name);
#endif
			break;

		case 'H':
			strncpy(db_hostname, optarg, sizeof(db_hostname));
			db_hostname[sizeof(db_hostname)-1] = '\0';
			break;

		case 'N':
			strncpy(db_name, optarg, sizeof(db_name));
			db_name[sizeof(db_name)-1] = '\0';
			break;

		case 'u':
			strncpy(db_username, optarg, sizeof(db_username));
			db_username[sizeof(db_username)-1] = '\0';
			break;

		case 'p':
			if ( strcmp(optarg, "-") == 0 ){ /* read password from stdin */
				strncpy(db_password, getpass("mysql password: "******"Invalid port given to --relay: %s. Ignored\n", optarg);
				}
			}

			break;

		case FLAG_DATADIR:
			free(rrdpath);
			rrdpath = strdup(optarg);
			break;

		case FLAG_PIDFILE:
			pidfile = optarg;
			break;

		case 'v': /* --verbose */
			verbose_flag = 1;
			break;

		case 'q': /* --quiet */
			verbose_flag = 0;
			break;

		case 'd': /* --debug */
			debug_flag = 1;
			break;

		case 'h': /* --help */
			show_usage();
			exit(0);

		default:
			if ( option_index >= 0 ){
				fprintf(stderr, "flag --%s declared but not handled\n", longopts[option_index].name);
			} else {
				fprintf(stderr, "flag -%c declared but not handled\n", op);
			}
			abort();
		}
	}

	/* database */
	if ( argc > optind ){
		strncpy(db_name, argv[optind], sizeof(db_name));
		db_name[sizeof(db_name)-1] = '\0';
	}

	setup_output();

	/* test if possible to drop privileges */
	if ( drop_priv_flag && getuid() != 0 ){
		Log::message(MAIN, "Not executing as uid=0, cannot drop privileges.\n");
		drop_priv_flag = 0;
	}

	/* Drop privileges.
	 * Done before forking since unlinking requires write permission to folder so
	 * if it fails to write it will fail unlinking. It is also done before
	 * check_env so it actually check environment for the dropped user instead of
	 * root.
	 */
	if ( drop_priv_flag ){
		privilege_drop();
	}

	/* sanity checks */
	show_env();
	if ( !check_env() ){
		return 1;
	}

	if ( daemon_mode ){
		/* opening file before fork since it will be a fatal error if it fails to write the pid */
		FILE* fp = fopen(pidfile, "w");
		if ( !fp ){
			Log::fatal(MAIN, "failed to open '%s` for writing: %s\n", pidfile, strerror(errno));
			return 1;
		}

		Log::message(MAIN, "Forking to background\n");
		pid_t pid = fork();

		if ( pid ){ /* parent */
			fprintf(fp, "%d\n", pid);
			fclose(fp);

			/* change owner of pidfile */
			if ( drop_priv_flag ){
				if ( chown(pidfile, drop_uid, drop_gid) != 0 ){
					Log::error("failed to change owner of '%s`, will probably fail to unlink it later: %s\n", pidfile, strerror(errno));
				}
			}

			return 0;
		}

		fclose(fp);
	}

	/* initialize daemons */
	pthread_barrier_t barrier;
	int threads = 1;
	threads += (int)have_control_daemon;
	threads += (int)have_relay_daemon;
	pthread_barrier_init(&barrier, NULL, threads);
	control.addr = relay.addr;

	if ( have_control_daemon && (ret=Daemon::instantiate<Control>(2000, &barrier)) != 0 ){
		Log::fatal(MAIN, "Failed to initialize control daemon, terminating.\n");
		if ( daemon_mode && unlink(pidfile) == -1 ){
			Log::fatal(MAIN, "Failed to remove pidfile: %s\n", strerror(errno));
		}
		return ret;
	}

	if ( have_relay_daemon && (ret=Daemon::instantiate<Relay>(2000, &barrier)) != 0 ){
		Log::fatal(MAIN, "Failed to initialize relay daemon, terminating.\n");
		if ( daemon_mode && unlink(pidfile) == -1 ){
			Log::fatal(MAIN, "Failed to remove pidfile: %s\n", strerror(errno));
		}
		return ret;
	}

	/* install signal handler */
	signal(SIGINT, handle_signal);
	signal(SIGTERM, handle_signal);

	/* release all threads and wait for them to finish*/
	pthread_barrier_wait(&barrier);
	if ( daemon_mode ){
		Log::message(MAIN, "Threads started. Going to sleep.\n");
	} else {
		Log::message(MAIN, "Threads started. Going to sleep. Abort with SIGINT\n");
	}
	Daemon::join_all();

	/* cleanup */
	free(rrdpath);
	if ( daemon_mode && unlink(pidfile) == -1 ){
		Log::fatal(MAIN, "Failed to remove pidfile: %s\n", strerror(errno));
	}

	Log::message(MAIN, "%s terminated.\n", program_name);
	return 0;
}