コード例 #1
0
ファイル: alsa-utils.c プロジェクト: mattiaswal/finit
static void restore(void *UNUSED(arg))
{
	if (fexist(ALSACTL)) {
		_d("Restoring sound settings ...");
		run_interactive(ALSACTL " -g restore", "Restoring sound settings");
	}
}
コード例 #2
0
ファイル: alsa-utils.c プロジェクト: mattiaswal/finit
static void save(void *UNUSED(arg))
{
	if (fexist(ALSACTL)) {
		_d("Saving sound settings ...");
		run_interactive(ALSACTL " -g store", "Saving sound settings");
	}
}
コード例 #3
0
ファイル: sig.c プロジェクト: carriercomm/finit
void do_shutdown(int sig)
{
	touch(SYNC_SHUTDOWN);

	if (sdown)
		run_interactive(sdown, "Calling shutdown hook: %s", sdown);

	/* Call all shutdown hooks before rebooting... */
	plugin_run_hooks(HOOK_SHUTDOWN);

	/* Here is where we signal watchdogd to do a forced reset for us */
	_d("Sending SIGTERM to all processes.");
	kill(-1, SIGTERM);

	/* Wait for WDT to timeout, should be no more than ~1 sec. */
	do_sleep(2);

	_d("Sending SIGKILL to remaining processes.");
	kill(-1, SIGKILL);

	sync();
	sync();
	_d("Unmounting file systems, remounting / read-only.");
	run("/bin/umount -fa 2>/dev/null");
	run("/bin/mount -n -o remount,ro / 2>/dev/null");
	run("/sbin/swapoff -ea");

	_d("%s.", sig == SIGINT || sig == SIGUSR1 ? "Rebooting" : "Halting");
	if (sig == SIGINT || sig == SIGUSR1)
		reboot(RB_AUTOBOOT);

	reboot(RB_POWER_OFF);
}
コード例 #4
0
ファイル: sig.c プロジェクト: benatto/finit
void do_shutdown (int sig)
{
	touch(SYNC_SHUTDOWN);

	if (sdown)
		run_interactive(sdown, "Calling shutdown hook: %s", sdown);

	_d("Sending SIGTERM to all processes.");
	kill(-1, SIGTERM);

	sleep(1);
	/* Call all shutdown hooks, this is the last call before rebooting... */
	plugin_run_hooks(HOOK_SHUTDOWN);

	_d("Sending SIGKILL to remaining processes.");
	kill(-1, SIGKILL);

	sync();
	sync();
	_d("Unmounting file systems, remounting / read-only.");
	run("/bin/umount -fa 2>/dev/null");
	run("/bin/mount -n -o remount,ro / 2>/dev/null");
	run("/sbin/swapoff -ea");

	_d("%s.", sig == SIGINT || sig == SIGUSR1 ? "Rebooting" : "Halting");
	if (sig == SIGINT || sig == SIGUSR1)
		reboot(RB_AUTOBOOT);

	reboot(RB_POWER_OFF);
}
コード例 #5
0
ファイル: dbus.c プロジェクト: DaveW26z/finit
static void setup(void *UNUSED(arg))
{
#ifdef HAVE_DBUS
	_d("Starting D-Bus ...");
	makedir("/var/run/dbus", 0755);
	makedir("/var/lock/subsys/messagebus", 0755);
	run("dbus-uuidgen --ensure");
	erase("/var/run/dbus/pid");
	run_interactive("dbus-daemon --system", "Starting D-Bus");
#endif
}
コード例 #6
0
void CCharacterPhysicsSupport::update_interactive_anims	()
{
	if ( Type() != etStalker )
		return;
	VERIFY( m_EntityAlife.cast_stalker( ) );
	CAI_Stalker	*stalker = m_EntityAlife.cast_stalker( );
	CBlend *b = stalker->animation().global().blend();
	if( b && !m_interactive_animation && stalker->animation().global().callback_on_collision() )
		run_interactive	( b );
	if( m_interactive_animation && !m_interactive_animation->update( m_EntityAlife.XFORM( ) ) )
		xr_delete( m_interactive_animation );
		
}
コード例 #7
0
static void setup(void *UNUSED(arg))
{
	umask(0);

	_d("Starting D-Bus ...");
	makedir("/var/run/dbus", 0755);
	makedir("/var/lock/subsys", 0755);
	makedir("/var/lock/subsys/messagebus", 0755);
	run("dbus-uuidgen --ensure");
	erase("/var/run/dbus/pid");
	run_interactive("dbus-daemon --system", "Starting D-Bus");

	umask(022);
}
コード例 #8
0
ファイル: main.c プロジェクト: HisModusness/flatdb
int main(int argc, const char * argv[])
{
    // Too few arguments specified.
    if (argc < 2) {
        print_usage();
        return 0;
    }
    
    // One argument specified, should only be the interactive mode.
    if (argc == 2) {
        if (!strcmp("-i", argv[1])) {
            run_interactive();
            return 0;
        }
        
        print_usage();
        return 0;
    }
    
    // Two arguments. The first should either be the demonstration or worker flag.
    // The second is assumed to be a file path; errors with that are handled further down.
    if (argc == 3) {
        if (!strcmp("-d", argv[1])) {
            run_multiprocess(argv);
            return 0;
        }
        
        if (!strcmp("-w", argv[1])) {
            run_worker(argv);
            return 0;
        }
        
        if (!strcmp("-t", argv[1])) {
            run_threaded(argv[2]);
            return 0;
        }
        
        print_usage();
        return 0;
    }
    
    // Anything more and it was used wrong.
    print_usage();
    return 0;
}
コード例 #9
0
ファイル: finit.c プロジェクト: jonasj76/finit
/*
 * Check all filesystems in /etc/fstab with a fs_passno > 0
 */
static int fsck(int pass)
{
//	int save;
	struct fstab *fs;

	if (!setfsent()) {
		_pe("Failed opening fstab");
		return 1;
	}

//	if ((save = log_is_debug()))
//		log_debug();

	while ((fs = getfsent())) {
		char cmd[80];
		struct stat st;

		if (fs->fs_passno != pass)
			continue;

		errno = 0;
		if (stat(fs->fs_spec, &st) || !S_ISBLK(st.st_mode)) {
			if (!string_match(fs->fs_spec, "UUID=") && !string_match(fs->fs_spec, "LABEL=")) {
				_d("Cannot fsck %s, not a block device: %s", fs->fs_spec, strerror(errno));
				continue;
			}
		}

		if (fismnt(fs->fs_file)) {
			_d("Skipping fsck of %s, already mounted on %s.", fs->fs_spec, fs->fs_file);
			continue;
		}

		snprintf(cmd, sizeof(cmd), "fsck -a %s", fs->fs_spec);
		run_interactive(cmd, "Checking filesystem %.13s", fs->fs_spec);
	}

//	if (save)
//		log_debug();
	endfsent();

	return 0;
}
コード例 #10
0
ファイル: finit.c プロジェクト: jonasj76/finit
/*
 * Handle bootstrap transition to configured runlevel, start TTYs
 *
 * This is the final stage of bootstrap.  It changes to the default
 * (configured) runlevel, calls all external start scripts and final
 * bootstrap hooks before bringing up TTYs.
 *
 * We must ensure that all declared `task [S]` and `run [S]` jobs in
 * finit.conf, or *.conf in finit.d/, run to completion before we
 * finalize the bootstrap process by calling this function.
 */
static void finalize(void)
{
	/*
	 * Run startup scripts in the runparts directory, if any.
	 */
	if (runparts && fisdir(runparts) && !rescue)
		run_parts(runparts, NULL);

	/*
	 * Start all tasks/services in the configured runlevel
	 */
	_d("Change to default runlevel, start all services ...");
	service_runlevel(cfglevel);

	/* Clean up bootstrap-only tasks/services that never started */
	_d("Clean up all bootstrap-only tasks/services ...");
	svc_prune_bootstrap();

	/* All services/tasks/inetd/etc. in configure runlevel have started */
	_d("Running svc up hooks ...");
	plugin_run_hooks(HOOK_SVC_UP);
	service_step_all(SVC_TYPE_ANY);

	/* Convenient SysV compat for when you just don't care ... */
	if (!access(FINIT_RC_LOCAL, X_OK) && !rescue)
		run_interactive(FINIT_RC_LOCAL, "Calling %s", FINIT_RC_LOCAL);

	/* Hooks that should run at the very end */
	_d("Calling all system up hooks ...");
	plugin_run_hooks(HOOK_SYSTEM_UP);
	service_step_all(SVC_TYPE_ANY);

	/* Enable silent mode before starting TTYs */
	_d("Going silent ...");
	log_silent();

	/* Delayed start of TTYs at bootstrap */
	_d("Launching all getty services ...");
	tty_runlevel();
}
コード例 #11
0
ファイル: alsa-utils.c プロジェクト: RFCreations/finit
static void save(void *UNUSED(arg))
{
	_d("Saving sound settings ...");
	run_interactive("/usr/sbin/alsactl -g store", "Saving sound settings");
}
コード例 #12
0
int HostRender::run(RaytracingContext& context, 
			   PixelFunc const& render_pixel, 
			   int kill_timeout_seconds,
			   std::function<void()> const& render_overlay)
{
	auto render_pixel_wrapper = [&](int x, int y, RaytracingContext const &ctx, ThreadLocalData *tld)
		-> glm::vec3
	{
		RenderData data(context, tld);

		switch(context.params.render_mode) {

		case RaytracingParameters::RECURSIVE:
			if (context.params.stereo)
			{
				data.camera_mode = Camera::StereoLeft;
				auto const left = render_pixel(x, y, ctx, data);
				data.camera_mode = Camera::StereoRight;
				auto const right = render_pixel(x, y, ctx, data);
				return combine_stereo(left, right);
			}
			else
			{
				return render_pixel(x, y, ctx, data);
			}

		case RaytracingParameters::DESATURATE:
			if (context.params.stereo)
			{
				data.camera_mode = Camera::StereoLeft;
				auto const left = render_pixel(x, y, ctx, data);
				data.camera_mode = Camera::StereoRight;
				auto const right = render_pixel(x, y, ctx, data);
				return combine_stereo(desaturate(left), desaturate(right));
			}
			else
			{
				return desaturate(render_pixel(x, y, ctx, data));
			}

		case RaytracingParameters::NUM_RAYS:
			render_pixel(x, y, ctx, data);
			return heatmap(float(data.num_cast_rays - 1) / 64.0f);
		case RaytracingParameters::NORMAL:
			render_pixel(x, y, ctx, data);
			if (context.params.normal_mapping)
				return glm::normalize(data.isect.shading_normal) * 0.5f + glm::vec3(0.5f);
			else
				return glm::normalize(data.isect.normal) * 0.5f + glm::vec3(0.5f);
		case RaytracingParameters::BVH_TIME:
		case RaytracingParameters::TIME: {
			Timer timer;
			timer.start();
			if(context.params.render_mode == RaytracingParameters::TIME) {
				auto const color = render_pixel(x, y, ctx, data);
				(void) color;
			}
			else {
				Ray ray = createPrimaryRay(data, float(x) + 0.5f, float(y) + 0.5f);
				for(auto& o: context.scene->objects) {
					BVH *bvh = dynamic_cast<BVH *>(o.get());
					if(bvh) {
						bvh->intersect(ray, nullptr);
					}
				}
			}
			timer.stop();
			return heatmap(static_cast<float>(timer.getElapsedTimeInMilliSec()) * context.params.scale_render_time);
		}
		case RaytracingParameters::DUDV: {
			auto const color = render_pixel(x, y, ctx, data);
			(void) color;
			if(!data.isect.isValid())
				return glm::vec3(0.0);
			return heatmap(std::log(1.0f + 5.0f * glm::length(data.isect.dudv)));
		}
		case RaytracingParameters::AABB_INTERSECT_COUNT: {
        	Ray ray = createPrimaryRay(data, float(x) + 0.5f, float(y) + 0.5f);
			glm::vec3 accum(0.0f);
			for(auto& o: context.scene->objects) {
				auto *bvh = dynamic_cast<BVH *>(o.get());
				if(bvh) {
					accum += bvh->intersect_count(ray, 0, 0) * 0.02f;
				}
			}
			return accum;
		}
		default: /* should never happen */
			return glm::vec3(1, 0, 1);
		}
	};

	if (context.params.interactive)
	{
		return run_interactive(context, render_pixel_wrapper, render_overlay);
	}
	else
	{
		return run_noninteractive(context, render_pixel_wrapper, 
			kill_timeout_seconds);
	}
}
コード例 #13
0
ファイル: finit.c プロジェクト: jonasj76/finit
int main(int argc, char* argv[])
{
	char *path;
	char cmd[256];
	int udev = 0;
	uev_t timer;	       /* Bootstrap timer, on timeout call finalize() */
	uev_ctx_t loop;

	/*
	 * finit/init/telinit client tool uses /dev/initctl pipe
	 * for compatibility but initctl client tool uses socket
	 */
	if (getpid() != 1)
		return client(argc, argv);

	/*
	 * Initalize event context.
	 */
	uev_init(&loop);
	ctx = &loop;

	/*
	 * Set PATH and SHELL early to something sane
	 */
	setenv("PATH", _PATH_STDPATH, 1);
	setenv("SHELL", _PATH_BSHELL, 1);

	/*
	 * Mount base file system, kernel is assumed to run devtmpfs for /dev
	 */
	chdir("/");
	umask(0);
	mount("none", "/proc", "proc", 0, NULL);
	mount("none", "/sys", "sysfs", 0, NULL);
	if (fisdir("/proc/bus/usb"))
		mount("none", "/proc/bus/usb", "usbfs", 0, NULL);

	/*
	 * Parse kernel command line (debug, rescue, splash, etc.)
	 * Also calls log_init() to set correct log level
	 */
	conf_parse_cmdline();

	/* Set up canvas */
	if (!rescue && !log_is_debug())
		screen_init();

	/*
	 * In case of emergency.
	 */
	emergency_shell();

	/*
	 * Initial setup of signals, ignore all until we're up.
	 */
	sig_init();

	/*
	 * Load plugins early, finit.conf may contain references to
	 * features implemented by plugins.
	 */
	plugin_init(&loop);

	/*
	 * Hello world.
	 */
	banner();

	/*
	 * Check file filesystems in /etc/fstab
	 */
	for (int pass = 1; pass < 10 && !rescue; pass++) {
		if (fsck(pass))
			break;
	}

	/*
	 * Initialize .conf system and load static /etc/finit.conf
	 * Also initializes global_rlimit[] for udevd, below.
	 */
	conf_init();

	/*
	 * Some non-embedded systems without an initramfs may not have /dev mounted yet
	 * If they do, check if system has udevadm and perform cleanup from initramfs
	 */
	if (!fismnt("/dev"))
		mount("udev", "/dev", "devtmpfs", MS_RELATIME, "size=10%,nr_inodes=61156,mode=755");
	else if (whichp("udevadm"))
		run_interactive("udevadm info --cleanup-db", "Cleaning up udev db");

	/* Some systems use /dev/pts */
	makedir("/dev/pts", 0755);
	mount("devpts", "/dev/pts", "devpts", 0, "gid=5,mode=620");

	/*
	 * Some systems rely on us to both create /dev/shm and, to mount
	 * a tmpfs there.  Any system with dbus needs shared memory, so
	 * mount it, unless its already mounted, but not if listed in
	 * the /etc/fstab file already.
	 */
	makedir("/dev/shm", 0755);
	if (!fismnt("/dev/shm") && !ismnt("/etc/fstab", "/dev/shm"))
		mount("shm", "/dev/shm", "tmpfs", 0, NULL);

	/*
	 * New tmpfs based /run for volatile runtime data
	 * For details, see http://lwn.net/Articles/436012/
	 */
	if (fisdir("/run") && !fismnt("/run"))
		mount("tmpfs", "/run", "tmpfs", MS_NODEV, "mode=0755,size=10%");
	umask(022);

	/* Bootstrap conditions, needed for hooks */
	cond_init();

	/*
	 * Populate /dev and prepare for runtime events from kernel.
	 * Prefer udev if mdev is also available on the system.
	 */
	path = which("udevd");
	if (!path)
		path = which("/lib/systemd/systemd-udevd");
	if (path) {
		/* Desktop and server distros usually have a variant of udev */
		udev = 1;

		/* Register udevd as a monitored service */
		snprintf(cmd, sizeof(cmd), "[S12345789] pid:udevd %s -- Device event managing daemon", path);
		if (service_register(SVC_TYPE_SERVICE, cmd, global_rlimit, NULL)) {
			_pe("Failed registering %s", path);
			udev = 0;
		} else {
			snprintf(cmd, sizeof(cmd), ":1 [S] <svc%s> "
				 "udevadm trigger -c add -t devices "
				 "-- Requesting device events", path);
			service_register(SVC_TYPE_RUN, cmd, global_rlimit, NULL);

			snprintf(cmd, sizeof(cmd), ":2 [S] <svc%s> "
				 "udevadm trigger -c add -t subsystems "
				 "-- Requesting subsystem events", path);
			service_register(SVC_TYPE_RUN, cmd, global_rlimit, NULL);
		}
		free(path);
	} else {
		path = which("mdev");
		if (path) {
			/* Embedded Linux systems usually have BusyBox mdev */
			if (log_is_debug())
				touch("/dev/mdev.log");

			snprintf(cmd, sizeof(cmd), "%s -s", path);
			free(path);

			run_interactive(cmd, "Populating device tree");
		}
	}

	/*
	 * Start built-in watchdog as soon as possible, if enabled
	 */
	wdogpid = watchdog(argv[0]);

	/*
	 * Mount filesystems
	 */
	if (!rescue) {
#ifdef REMOUNT_ROOTFS
		run("mount -n -o remount,rw /");
#endif
#ifdef SYSROOT
		mount(SYSROOT, "/", NULL, MS_MOVE, NULL);
#endif
	}

	if (!rescue) {
		_d("Root FS up, calling hooks ...");
		plugin_run_hooks(HOOK_ROOTFS_UP);

		umask(0);
		if (run_interactive("mount -na", "Mounting filesystems"))
			plugin_run_hooks(HOOK_MOUNT_ERROR);

		_d("Calling extra mount hook, after mount -a ...");
		plugin_run_hooks(HOOK_MOUNT_POST);

		run("swapon -ea");
		umask(0022);
	}

	/* Base FS up, enable standard SysV init signals */
	sig_setup(&loop);

	if (!rescue) {
		_d("Base FS up, calling hooks ...");
		plugin_run_hooks(HOOK_BASEFS_UP);
	}

	/*
	 * Set up inotify watcher for /etc/finit.d and read all .conf
	 * files to figure out how to bootstrap the system.
	 */
	conf_monitor(&loop);

	/*
	 * Initalize state machine and start all bootstrap tasks
	 * NOTE: no network available!
	 */
	sm_init(&sm);
	sm_step(&sm);

	/* Debian has this little script to copy generated rules while the system was read-only */
	if (udev && fexist("/lib/udev/udev-finish"))
		run_interactive("/lib/udev/udev-finish", "Finalizing udev");

	/* Start new initctl API responder */
	api_init(&loop);
	umask(022);

	/*
	 * Wait for all SVC_TYPE_RUNTASK to have completed their work in
	 * [S], or timeout, before calling finalize()
	 */
	_d("Starting bootstrap finalize timer ...");
	uev_timer_init(&loop, &timer, service_bootstrap_cb, finalize, 1000, 1000);

	/*
	 * Enter main loop to monior /dev/initctl and services
	 */
	_d("Entering main loop ...");
	return uev_run(&loop, 0);
}
コード例 #14
0
ファイル: sig.c プロジェクト: mattiaswal/finit
void do_shutdown(shutop_t op)
{
	touch(SYNC_SHUTDOWN);

	if (sdown)
		run_interactive(sdown, "Calling shutdown hook: %s", sdown);

	/* Update UTMP db */
	utmp_set_halt();

	/*
	 * Tell all remaining non-monitored processes to exit, give them
	 * some time to exit gracefully, 2 sec is customary.
	 */
	do_kill(SIGTERM);
	do_sleep(2);
	do_kill(SIGKILL);

	/* Exit plugins and API gracefully */
	plugin_exit();
	api_exit();

	/* Reap 'em */
	while (waitpid(-1, NULL, WNOHANG) > 0)
		;

	/* Close all local non-console descriptors */
	for (int fd = 3; fd < 128; fd++)
		close(fd);

	if (vfork()) {
		/*
		 * Put PID 1 aside and let child perform reboot/halt
		 * kernel may exit child and we don't want to exit PID 1
		 * ... causing "aiii killing init" during reboot ...
		 */
		return;
	}

	/* Unmount any tmpfs before unmounting swap ... */
	unmount_tmpfs();
	run("/sbin/swapoff -e -a");

	/* ... unmount remaining regular file systems. */
	unmount_regular();

	/* We sit on / so we must remount it ro, try all the things! */
	sync();
	run("/bin/mount -n -o remount,ro -t dummytype dummydev /");
	run("/bin/mount -n -o remount,ro dummydev /");
	run("/bin/mount -n -o remount,ro /");

	/* Call mdadm to mark any RAID array(s) as clean before halting. */
	mdadm_wait();

	/* Reboot via watchdog or kernel, or shutdown? */
	if (op == SHUT_REBOOT) {
		if (wdogpid) {
			int timeout = 10;

			/* Wait here until the WDT reboots, or timeout with fallback */
			print(kill(wdogpid, SIGPWR) == 1, "Pending watchdog reboot");
			while (timeout--)
				do_sleep(1);
		}

		_d("Rebooting ...");
		reboot(RB_AUTOBOOT);
	} else if (op == SHUT_OFF) {
		_d("Powering down ...");
		reboot(RB_POWER_OFF);
	}

	/* Also fallback if any of the other two fails */
	_d("Halting ...");
	reboot(RB_HALT_SYSTEM);
}
コード例 #15
0
ファイル: finit.c プロジェクト: KroMignon/finit
int main(int argc, char* argv[])
{
	if (getpid() != 1)
		return client(argc, argv);

	/*
	 * Hello world.
	 */
	banner();

	/*
	 * Initial setup of signals, ignore all until we're up.
	 */
	sig_init();

	/*
	 * Mount base file system, kernel is assumed to run devtmpfs for /dev
	 */
	chdir("/");
	umask(0);
	mount("none", "/proc", "proc", 0, NULL);
	mount("none", "/proc/bus/usb", "usbfs", 0, NULL);
	mount("none", "/sys", "sysfs", 0, NULL);
	mkdir("/dev/pts", 0755);
	mkdir("/dev/shm", 0755);
	mount("none", "/dev/pts", "devpts", 0, "gid=5,mode=620");
	mount("none", "/dev/shm", "tmpfs", 0, NULL);
	umask(022);

	/*
	 * Parse kernel parameters
	 */
	parse_kernel_cmdline();

	/*
	 * Populate /dev and prepare for runtime events from kernel.
	 */
	run_interactive(SETUP_DEVFS, "Populating device tree");

	/*
	 * Parse configuration file
	 */
	parse_finit_conf(FINIT_CONF);

	/*
	 * Load plugins.  Must run after finit.conf has registered
	 * all services, or service plugins won't have anything to
	 * hook on to.
	 */
	print_desc("Loading plugins", NULL);
	print_result(plugin_load_all(PLUGIN_PATH));

	/*
	 * Mount filesystems
	 */
#ifdef REMOUNT_ROOTFS_RW
	run("/bin/mount -n -o remount,rw /");
#endif
#ifdef SYSROOT
	run(SYSROOT, "/", NULL, MS_MOVE, NULL);
#endif

	_d("Root FS up, calling hooks ...");
	plugin_run_hooks(HOOK_ROOTFS_UP);

	umask(0);
	run("/bin/mount -na");
	run("/sbin/swapon -ea");
	umask(0022);

	/* Cleanup stale files, if any still linger on. */
	run_interactive("rm -rf /tmp/* /var/run/* /var/lock/*", "Cleanup temporary directories");

	/* Base FS up, enable standard SysV init signals */
	sig_setup();

	_d("Base FS up, calling hooks ...");
	plugin_run_hooks(HOOK_BASEFS_UP);

	/*
	 * Start all bootstrap tasks, no network available!
	 */
	svc_bootstrap();

	/*
	 * Network stuff
	 */

	/* Setup kernel specific settings, e.g. allow broadcast ping, etc. */
	run("/sbin/sysctl -e -p /etc/sysctl.conf >/dev/null");

	/* Set initial hostname. */
	set_hostname(hostname);

	ifconfig("lo", "127.0.0.1", "255.0.0.0", 1);
	if (network)
		run_interactive(network, "Starting networking: %s", network);
	umask(022);

	/* Hooks that rely on loopback, or basic networking being up. */
	plugin_run_hooks(HOOK_NETWORK_UP);

	/*
	 * Start all tasks/services in the configured runlevel
	 */
	svc_runlevel(cfglevel);

	_d("Running svc up hooks ...");
	plugin_run_hooks(HOOK_SVC_UP);

	/*
	 * Run startup scripts in /etc/finit.d/, if any.
	 */
	if (rcsd && fisdir(rcsd)) {
		_d("Running startup scripts in %s ...", rcsd);
		run_parts(rcsd, NULL);
	}

	/* Hooks that should run at the very end */
	plugin_run_hooks(HOOK_SYSTEM_UP);

	/*
	 * Enter main loop to monior /dev/initctl and services
	 */
	return run_loop();
}
コード例 #16
0
void parse_finit_conf(char *file)
{
	FILE *fp;
	char line[LINE_SIZE];
	char cmd[CMD_SIZE];

	username = strdup(DEFUSER);
	hostname = strdup(DEFHOST);
	rcsd     = strdup(FINIT_RCSD);

	if ((fp = fopen(file, "r")) != NULL) {
		char *x;
		const char *err = NULL;

		_d("Parse %s ...", file);
		while (!feof(fp)) {
			if (!fgets(line, sizeof(line), fp))
				continue;
			chomp(line);
			_d("conf: %s", line);

			/* Skip comments. */
			if (MATCH_CMD(line, "#", x))
				continue;

			/* Do this before mounting / read-write
			 * XXX: Move to plugin which checks /etc/fstab instead */
			if (MATCH_CMD(line, "check ", x)) {
				char *dev = strip_line(x);

				strcpy(cmd, "/sbin/fsck -C -a ");
				strlcat(cmd, dev, sizeof(cmd));
				run_interactive(cmd, "Checking file system %s", dev);

				continue;
			}

			if (MATCH_CMD(line, "user ", x)) {
				if (username) free(username);
				username = strdup(strip_line(x));
				continue;
			}
			if (MATCH_CMD(line, "host ", x)) {
				if (hostname) free(hostname);
				hostname = strdup(strip_line(x));
				continue;
			}

			if (MATCH_CMD(line, "module ", x)) {
				char *mod = strip_line(x);

				strcpy(cmd, "/sbin/modprobe ");
				strlcat(cmd, mod, sizeof(cmd));
				run_interactive(cmd, "Loading kernel module %s", mod);

				continue;
			}
			if (MATCH_CMD(line, "mknod ", x)) {
				char *dev = strip_line(x);

				strcpy(cmd, "/bin/mknod ");
				strlcat(cmd, dev, sizeof(cmd));
				run_interactive(cmd, "Creating device node %s", dev);

				continue;
			}

			if (MATCH_CMD(line, "network ", x)) {
				if (network) free(network);
				network = strdup(strip_line(x));
				continue;
			}
			if (MATCH_CMD(line, "runparts ", x)) {
				if (rcsd) free(rcsd);
				rcsd = strdup(strip_line(x));
				continue;
			}
			if (MATCH_CMD(line, "startx ", x)) {
				svc_register(SVC_CMD_SERVICE, strip_line(x), username);
				continue;
			}
			if (MATCH_CMD(line, "shutdown ", x)) {
				if (sdown) free(sdown);
				sdown = strdup(strip_line(x));
				continue;
			}

			/* The desired runlevel to start when leaving
			 * bootstrap (S).  Finit supports 1-9, but most
			 * systems only use 1-6, where 6 is reserved for
			 * reboot */
			if (MATCH_CMD(line, "runlevel ", x)) {
				char *token = strip_line(x);

				cfglevel = strtonum(token, 1, 9, &err);
				if (err)
					cfglevel = RUNLEVEL;
				if (cfglevel < 1 || cfglevel > 9 || cfglevel == 6)
					cfglevel = 2; /* Fallback */
				continue;
			}

			/* Monitored daemon, will be respawned on exit, as
			 * long as the (optional) service callback returns
			 * non-zero */
			if (MATCH_CMD(line, "service ", x)) {
				svc_register(SVC_CMD_SERVICE, x, NULL);
				continue;
			}

			/* One-shot task, will not be respawned. Only runs if
			 * the (optional) service callback returns true */
			if (MATCH_CMD(line, "task ", x)) {
				svc_register(SVC_CMD_TASK, x, NULL);
				continue;
			}

			/* Like task but waits for completion, useful w/ [S] */
			if (MATCH_CMD(line, "run ", x)) {
				svc_register(SVC_CMD_RUN, x, NULL);
				continue;
			}

			if (MATCH_CMD(line, "console ", x)) {
				if (console) free(console);
				console = strdup(strip_line(x));
				continue;
			}
			if (MATCH_CMD(line, "tty ", x)) {
				tty_register(strip_line(x));
				continue;
			}
		}
		fclose(fp);
	}
}
コード例 #17
0
ファイル: hwclock.c プロジェクト: jonasj76/finit
static void save(void *arg)
{
	_d("Saving system clock to RTC ...");
	/* -w,--systohc, -u,--utc */
	run_interactive("hwclock -w -u", "Saving system time (UTC) to RTC");
}
コード例 #18
0
ファイル: finit.c プロジェクト: benatto/finit
int main(int UNUSED(args), char *argv[])
{
	/*
	 * Initial setup of signals, ignore all until we're up.
	 */
	sig_init();

	/*
	 * Mount base file system, kernel is assumed to run devtmpfs for /dev
	 */
	chdir("/");
	umask(0);
	mount("none", "/proc", "proc", 0, NULL);
	mount("none", "/proc/bus/usb", "usbfs", 0, NULL);
	mount("none", "/sys", "sysfs", 0, NULL);
	mkdir("/dev/pts", 0755);
	mkdir("/dev/shm", 0755);
	mount("none", "/dev/pts", "devpts", 0, "gid=5,mode=620");
	mount("none", "/dev/shm", "tmpfs", 0, NULL);
	umask(022);

	/*
	 * Parse kernel parameters
	 */
	parse_kernel_cmdline();

	cls();
	echo("finit " VERSION " (built " __DATE__ " " __TIME__ " by " WHOAMI ")");

	/*
	 * Populate /dev and prepare for runtime events from kernel.
	 */
#if defined(USE_UDEV)
	run_interactive("udevd --daemon", "Populating device tree");
#elif defined (MDEV)
	run_interactive(MDEV " -s", "Populating device tree");
#endif

	/*
	 * Parse configuration file
	 */
	parse_finit_conf(FINIT_CONF);

	/*
	 * Load plugins.  Must run after finit.conf has registered
	 * all services, or service plugins won't have anything to
	 * hook on to.
	 */
	print_desc("", "Loading plugins");
	print_result(plugin_load_all(PLUGIN_PATH));

	/*
	 * Mount filesystems
	 */
	_d("Mount filesystems in /etc/fstab ...");

#ifdef REMOUNT_ROOTFS_RW
	run("/bin/mount -n -o remount,rw /");
#endif
#ifdef SYSROOT
	run(SYSROOT, "/", NULL, MS_MOVE, NULL);
#endif
	_d("Root FS up, calling hooks ...");
	plugin_run_hooks(HOOK_ROOTFS_UP);

	umask(0);
	run("/bin/mount -na");
	run("/sbin/swapon -ea");
	umask(0022);

	/* Cleanup stale files, if any still linger on. */
	run_interactive("rm -rf /tmp/* /var/run/* /var/lock/*", "Cleanup temporary directories");

	/*
	 * Base FS up, enable standard SysV init signals
	 */
	sig_setup();

	_d("Base FS up, calling hooks ...");
	plugin_run_hooks(HOOK_BASEFS_UP);

	/*
	 * Network stuff
	 */

	/* Setup kernel specific settings, e.g. allow broadcast ping, etc. */
	run("/sbin/sysctl -e -p /etc/sysctl.conf >/dev/null");

	/* Set initial hostname. */
	set_hostname(hostname);

	ifconfig("lo", "127.0.0.1", "255.0.0.0", 1);
	if (network)
		run_interactive(network, "Starting networking: %s", network);
	umask(022);

	/*
	 * Hooks that rely on loopback, or basic networking being up.
	 */
	plugin_run_hooks(HOOK_NETWORK_UP);

	/*
	 * Start service monitor framework
	 */
	_d("Starting all static services from %s", FINIT_CONF);
	svc_start_all();

	/*
	 * Run startup scripts in /etc/finit.d/, if any.
	 */
	if (rcsd && fisdir(rcsd)) {
		_d("Running startup scripts in %s ...", rcsd);
		run_parts(rcsd, NULL);
	}

	/*
	 * Hooks that should run at the very end
	 */
	plugin_run_hooks(HOOK_SYSTEM_UP);

	/* Start GETTY on console */
	_d("Starting getty on console ...");
	run_getty(GETTY, argv);

	/*
	 * Enter main loop to monior /dev/initctl and services
	 */
	_d("Entering main loop ...");
	return run_loop();
}
コード例 #19
0
ファイル: usbsoftrock.c プロジェクト: recri/usbsoftrock
/**
 * Main routine. Parse commandline args and trigger actions.
 */
int main(int argc, char **argv) {
  usb_dev_handle      *handle = NULL;
  char * usbSerialID = NULL;
  int c;

// moved this malloc() here instead of within the while(1) loop
// to prevent memory leakage problem
// as *args is not free'ed.

  char **args = malloc(MAX_COMMAND_ARGS * sizeof(char *));
  int port = 19004;
  int daemon = 0;

  // Read options
  while ( (c = getopt(argc, argv, "adhi:m:p:s:u:vx:")) != -1) {
    switch (c) {
    case 'i':
      i2cAddress = atoi(optarg);
      break;
    case 'a':
      setByValue = 1;
      break;
    case 'd':
      daemon = 1;
      break;
    case 'h':
      firmware_PTT = 1;
      break;
    case 'm':
      multiplier = atof(optarg);
      break;
    case 'p': 
      port = atoi(optarg);
      break;
    case 's':
      startupFreq = atof(optarg);
      break;
    case 'x':
      fXtall = atof(optarg);
      break;
    case 'u':
      usbSerialID = optarg;
      break;
    case 'v':
      verbose++;
      break;
    default: /* '?' */
      usage(argv[0]);
      exit(EXIT_FAILURE);
    }
  }
  if (verbose) {
    printf("I2C Address = %X\n", i2cAddress);
    printf("fXtall = %f\n", fXtall);
    printf("multiplier = %f\n", multiplier);
    printf("startupFreq = %f\n", startupFreq);
  }

  if((argc <= optind) && (daemon == 0)){
	usage(argv[0]);
	exit(1);
  }

  usb_init();
  char attempt=0, error=0;
  do {
	attempt++;
	error=usbOpenDevice(&handle, USBDEV_SHARED_VENDOR, VENDOR_NAME, USBDEV_SHARED_PRODUCT, PRODUCT_NAME, usbSerialID);
	if(error != 0){
	  fprintf(stderr, "Could not open USB device \"%s\" with vid=0x%x pid=0x%x, retrying\n", PRODUCT_NAME, USBDEV_SHARED_VENDOR, USBDEV_SHARED_PRODUCT);
	  sleep(2*attempt);
	}
  } while (error && attempt < USB_MAX_RETRIES);
  if (error) {
	fprintf(stderr, "Permanent problem opening usb device. Giving up.\n");
	exit(1);
  }

  unsigned short version = readVersion(handle);
  major = (version & 0xFF00) >> 8;
  minor = (version & 0xFF);

  /* Relocate lower later */
  if (daemon) {
    printf("Starting daemon...\n");

    int socket_desc;

    socket_desc=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
    if (socket_desc==-1)
      perror("Create socket");

    struct sockaddr_in address;
    /* type of socket created in socket() */
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(port);

    /* bind the socket to the port specified above */
    int retval;
    if (bind(socket_desc,(struct sockaddr *)&address,sizeof(address)) != 0) {
      fprintf(stderr, "Error binding to port %d\n", port);
      exit(0); 
    }

    while (1) {
      ssize_t bytes;
      char buffer[1024];
      struct sockaddr_in clnt;
      socklen_t clnt_len;
      clnt_len = sizeof(clnt);

      bytes = recvfrom (socket_desc, buffer, sizeof(buffer) - 1, 0, (struct sockaddr *)&clnt, &clnt_len);
      if (bytes > 0) {
        buffer[bytes] = 0;
        if (verbose >= 2)
          printf("Returned %d bytes from %s: %s\n", bytes, inet_ntoa(clnt.sin_addr), buffer);

        if (strncmp(buffer, "quit", 4) == 0) {
          if (verbose)
            printf("Quit command received\n");
          exit(0);
        }

        char *saveptr;
        char *token;
        int argn = 0;

        for (int i=0; i < MAX_COMMAND_ARGS;i++)
          args[i] = NULL;

        token = strtok_r(buffer, " ", &saveptr);
        while (token != NULL) {
          args[argn] = strcpy(malloc(strlen(token) + 1), token);
          argn++;          
          token = strtok_r(NULL, " ", &saveptr);
        }

        // Execute command here
        char result[100];
        do_command(handle, args, argn, result);

        // Cleanup
        for (int i=0; i < MAX_COMMAND_ARGS;i++) {
          if (args[i] != NULL)
            free(args[i]);
        }

        int retlen = strlen(result);
        if (sendto(socket_desc, result, retlen,0, (struct sockaddr *) &clnt, clnt_len) != retlen) {
          perror("Failed to send ack");
          exit(1);
        }

      } else {
      	fprintf(stderr, "recvfrom returned %d\n", bytes);
      }
    }

    close(socket_desc);
    exit(0);
  }
 
  /* Device has been opened - perform the requested operation */
  if (strcmp(argv[optind], "getregisters") == 0) {

	getRegisters(handle);

  } else if(strcmp(argv[optind], "getfreq") == 0){
	double freq; 
	if (setByValue)
		freq = readFrequencyByValue(handle);
	else
		freq = getFrequency(handle);

	if (freq != 0.00)
		printf("Frequency   : %f (x %.2f)\n", freq / multiplier, multiplier);

#ifdef HAVE_LIBNCURSES
  } else if (strcmp(argv[optind], "interactive") == 0) {
      run_interactive(handle);
#endif

  } else if (strcmp(argv[optind], "getptt") == 0){
	if (firmware_PTT) PTT = getPTT(handle);
        printf("PTT   : %d\n", PTT);

 } else if (strcmp(argv[optind], "getkeys") == 0){
	keys = getkeys(handle);
        printf("Paddles: %d\n", keys);

 } else if (strcmp(argv[optind], "gettone") == 0){
        printf("CW Tone: %d\n", CW_tone);

  } else if ((strcmp(argv[optind], "ptt") == 0) && (argc >= optind + 1)) {

	PTT = (strcmp(argv[optind+1],"on") == 0) ? 1: 0;
	setPTT(handle, PTT);
	printf("PTT set to %d\n", PTT);

  } else if (strcmp(argv[optind], "calibrate") == 0) {
	
	calibrate(handle);

  } else if ((strcmp(argv[optind], "set") == 0) && (argc >= optind + 2)) {

    if ((strcmp(argv[optind+1], "bpf_addr") == 0) && (argc >= optind + 3)) {
      // set bpf_addr index value
      setBPFAddress(handle, atoi(argv[optind+2]), atoi(argv[optind+3]));
      
    } else if ((strcmp(argv[optind+1], "bpf_point") == 0) && (argc >= optind + 3)) {
      // set bpf_point index (int) value (float)
      setBPFCrossOver(handle, atoi(argv[optind+2]), atof(argv[optind+3]));
      
    } else if ((strcmp(argv[optind+1], "bpf") == 0) && (argc >= optind + 2)) {

        setBPF(handle, (strcmp(argv[optind+2],"on") == 0) ? 1 : 0);

    } else if ((strcmp(argv[optind+1], "lpf") == 0) && (argc >= optind + 2)) {

        setLPF(handle, (strcmp(argv[optind+2],"on") == 0) ? 1 : 0);

    } else if ((strcmp(argv[optind+1], "lpf_addr") == 0) && (argc >= optind + 3)) {
      // set bpf_addr index value
      setBPFAddress(handle, atoi(argv[optind+2]), atoi(argv[optind+3]));
      displayLPFs(handle);
      
    } else if ((strcmp(argv[optind+1], "lpf_point") == 0) && (argc >= optind + 3)) {
      // set lpf_point index (int) value (float)
      setLPFCrossOver(handle, atoi(argv[optind+2]), atof(argv[optind+3]));
            
    } else if (strcmp(argv[optind+1], "freq") == 0) {

      if (setByValue)
        setFreqByValue(handle, atof(argv[optind+2]));
      else
        setFrequency(handle, atof(argv[optind+2]));
      
    } else if ((strcmp(argv[optind+1], "registers") == 0 || strcmp(argv[optind+1], "regs") == 0) && argc == optind+8) {
      unsigned char regs[6];
      int i;
      for (i = 0; i < 6; i += 1)
	regs[i] = strtol(argv[optind+2+i], NULL, 0);
      setRegisters(handle, regs);
    } else if ((strcmp(argv[optind+1], "si570_addr") == 0) && (argc >= optind + 2)) {
      
      setSi570Address(handle, atoi(argv[optind+2]));
      
    } else if (strcmp(argv[optind+1], "si570_multiplier") == 0) {
        
	int index = 0;
	int valueIndex = optind+2;
	// If there are 2 args after the variable name, one is index
	if (argc >= optind + 3) {
	  index = atoi(argv[optind+2]);
	  valueIndex++;
	}
	
        double sub, mul;
        readMultiplyLO(handle, index, &mul, &sub);
        mul = atof(argv[valueIndex]);
        setMultiplyLo(handle, index, mul, sub);
        if (verbose)
            printf("Set multiply [%d] to : %f\n", index, mul);
        
    } else if (strcmp(argv[optind+1], "xtall") == 0) {

        setXtallFrequency(handle, atof(argv[optind+2]));

    } else if (strcmp(argv[optind+1], "startup") == 0) {

	setStartupFrequency(handle, atof(argv[optind+2]));

    } else {
	usage(argv[0]);
	exit(1);
    }

  } else if (strcmp(argv[optind], "solutions") == 0) {
    solveRegisters(handle);
  } else if (strcmp(argv[optind], "status") == 0) {

	printf("USB SerialID: %s\n", serialNumberString);

	if (major >= 15) {
		readFrequencyByValue(handle);
		readStartupFreq(handle);
		readXtallFreq(handle);
		readSmoothTunePPM(handle);
		if (major >= 16 || minor >= 12) {
			readSi570Address(handle);
		}

		displayBands(handle);
		displayLPFs(handle);
		
		/*
		if (major >= 16 || ((major >= 15) && (minor >= 12))) {
		  displayBands(handle);
		} else if (minor >= 10) {
		  double sub, mul;
		  readMultiplyLO(handle, 0, &mul, &sub);
		  printf("LO Subtract : %f\n", sub);
		  printf("Multiply    : %f\n", mul);
		}
		//displayBPFFilters(handle);
		//displayLPFFilters(handle);*/
	}
  } else if (strcmp(argv[optind], "tweak") == 0) {
    tweakRegisters(handle);
  } else {
	usage(argv[0]);
	exit(1);
  }
  usb_close(handle);
  return 0;
}
コード例 #20
0
int HostRender::run(RaytracingContext& context,
                    PixelFunc const& render_pixel,
                    int kill_timeout_seconds,
                    std::function<void()> const& render_overlay)
{
    auto render_pixel_wrapper = [&](int x, int y, RaytracingContext const &ctx, ThreadLocalData *tld)
                                -> glm::vec3
    {
        RenderData data(context, tld);

        switch(context.params.render_mode) {

        case RaytracingParameters::RECURSIVE:
            if (context.params.stereo)
            {
                data.camera_mode = Camera::StereoLeft;
                auto const left = render_pixel(x, y, ctx, data);
                data.camera_mode = Camera::StereoRight;
                auto const right = render_pixel(x, y, ctx, data);
                return combine_stereo(left, right);
            }
            else
            {
                return render_pixel(x, y, ctx, data);
            }

        case RaytracingParameters::DESATURATE:
            if (context.params.stereo)
            {
                data.camera_mode = Camera::StereoLeft;
                auto const left = render_pixel(x, y, ctx, data);
                data.camera_mode = Camera::StereoRight;
                auto const right = render_pixel(x, y, ctx, data);
                return combine_stereo(desaturate(left), desaturate(right));
            }
            else
            {
                return desaturate(render_pixel(x, y, ctx, data));
            }

        case RaytracingParameters::NUM_RAYS:
            render_pixel(x, y, ctx, data);
            return heatmap(float(data.num_cast_rays - 1) / 64.0f);
        case RaytracingParameters::NORMAL:
            render_pixel(x, y, ctx, data);
            return glm::normalize(data.isect.normal) * 0.5f + glm::vec3(0.5f);
        case RaytracingParameters::TIME: {
            Timer timer;
            timer.start();
            if(context.params.render_mode == RaytracingParameters::TIME) {
                auto const color = render_pixel(x, y, ctx, data);
                (void) color;
            }
            timer.stop();
            return heatmap(static_cast<float>(timer.getElapsedTimeInMilliSec()) * context.params.scale_render_time);
        }
        default: /* should never happen */
            return glm::vec3(1, 0, 1);
        }
    };

    if (context.params.interactive)
    {
        return run_interactive(context, render_pixel_wrapper, render_overlay);
    }
    else
    {
        return run_noninteractive(context, render_pixel_wrapper,
                                  kill_timeout_seconds);
    }
}
コード例 #21
0
ファイル: alsa-utils.c プロジェクト: RFCreations/finit
static void restore(void *UNUSED(arg))
{
	_d("Restoring sound settings ...");
	run_interactive("/usr/sbin/alsactl -g restore", "Restoring sound settings");
}
コード例 #22
0
ファイル: hwclock.c プロジェクト: jonasj76/finit
static void restore(void *arg)
{
	_d("Restoring system clock from RTC ...");
	/* -s,--hctosys, -u,--utc */
	run_interactive("hwclock -s -u", "Restoring system clock (UTC) from RTC");
}
コード例 #23
0
ファイル: conf.c プロジェクト: RFCreations/finit
static void parse_static(char *line)
{
	char *x;
	char cmd[CMD_SIZE];

	/* Do this before mounting / read-write
	 * XXX: Move to plugin which checks /etc/fstab instead */
	if (MATCH_CMD(line, "check ", x)) {
		char *dev = strip_line(x);

		strcpy(cmd, "/sbin/fsck -C -a ");
		strlcat(cmd, dev, sizeof(cmd));
		run_interactive(cmd, "Checking file system %s", dev);

		return;
	}

	if (MATCH_CMD(line, "user ", x)) {
		if (username) free(username);
		username = strdup(strip_line(x));
		return;
	}

	if (MATCH_CMD(line, "host ", x)) {
		if (hostname) free(hostname);
		hostname = strdup(strip_line(x));
		return;
	}

	if (MATCH_CMD(line, "module ", x)) {
		char *mod = strip_line(x);

		strcpy(cmd, "/sbin/modprobe ");
		strlcat(cmd, mod, sizeof(cmd));
		run_interactive(cmd, "Loading kernel module %s", mod);

		return;
	}

	if (MATCH_CMD(line, "mknod ", x)) {
		char *dev = strip_line(x);

		strcpy(cmd, "/bin/mknod ");
		strlcat(cmd, dev, sizeof(cmd));
		run_interactive(cmd, "Creating device node %s", dev);

		return;
	}

	if (MATCH_CMD(line, "network ", x)) {
		if (network) free(network);
		network = strdup(strip_line(x));
		return;
	}

	if (MATCH_CMD(line, "runparts ", x)) {
		if (runparts) free(runparts);
		runparts = strdup(strip_line(x));
		return;
	}

	if (MATCH_CMD(line, "include ", x)) {
		char *file = strip_line(x);

		strlcpy(cmd, file, sizeof(cmd));
		if (!fexist(cmd)) {
			_e("Cannot find include file %s, absolute path required!", x);
			return;
		}

		parse_conf(cmd);
		return;
	}

	if (MATCH_CMD(line, "startx ", x)) {
		service_register(SVC_TYPE_SERVICE, strip_line(x), 0, username);
		return;
	}

	if (MATCH_CMD(line, "shutdown ", x)) {
		if (sdown) free(sdown);
		sdown = strdup(strip_line(x));
		return;
	}

	/* The desired runlevel to start when leaving bootstrap (S).
	 * Finit supports 1-9, but most systems only use 1-6, where
	 * 6 is reserved for reboot */
	if (MATCH_CMD(line, "runlevel ", x)) {
		char *token = strip_line(x);
		const char *err = NULL;

		cfglevel = strtonum(token, 1, 9, &err);
		if (err)
			cfglevel = RUNLEVEL;
		if (cfglevel < 1 || cfglevel > 9 || cfglevel == 6)
			cfglevel = 2; /* Fallback */
		return;
	}

	/* TODO: Make console & tty dynamically loadable from /etc/finit.d */
	if (MATCH_CMD(line, "console ", x)) {
		if (console) free(console);
		console = strdup(strip_line(x));
		return;
	}

	/* TODO: Make console & tty dynamically loadable from /etc/finit.d */
	if (MATCH_CMD(line, "tty ", x)) {
		tty_register(strip_line(x));
		return;
	}
}