[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Little config files that switch things on and off



System V (or is it IRIX) has a chkconfig utility that lets you throw and
check switches that are used in init scripts. You create /etc/config and
then run "chkconfig verbose on", and then "chkconfig verbose" to check the
"verbose" switch in your scripts. Here is a chkconfig.c that I wrote a while
back for Debian. Create /etc/config, compile this, and run it.

	Bruce
/*
 * chkconfig - get/set configuration flags.
 *  A work-alike of the System-V "chkconfig".
 *  Bruce Perens, December 1995
 *	Copyright (C) 1995 Bruce Perens
 *	This program is free software under the GNU General Public License.
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <fcntl.h>

static const char	dir_name[] = "/etc/config";
static const int	dir_length = sizeof(dir_name) - 1;
static const char	on[] = "on\n";
static const char	off[] = "off\n";

static int
getConfiguration(const char * name)
{
	char				pathname[PATH_MAX + 1];
	char				value[3];
	int					fd;
	int					status;
	
	memcpy(pathname, dir_name, dir_length);
	pathname[dir_length] = '/';
	strncpy(&pathname[dir_length+1], name, PATH_MAX - dir_length);

	fd = open(pathname, O_RDONLY);
	if ( fd < 0 ) {
		if ( errno != ENOENT )
			perror(pathname);
		return -1;
	}

	status = read(fd, value, sizeof(value));

	close(fd);

	if ( status < 2 )
		return 0;

	if ( value[0] != 'o' || value[1] != 'n' )
		return 0;
	if ( status > 2 ) {
		if ( value[2] != '\n' && value[2] != '\r' && value[2] != '\t'
		 &&  value[2] != ' ' )
			return 0;
	}
	return 1;
}

static void
setConfiguration(const char * name, int value, int force)
{
	char				pathname[PATH_MAX + 1];
	int					fd;
	int					failed;
	
	memcpy(pathname, dir_name, dir_length);
	pathname[dir_length] = '/';
	strncpy(&pathname[dir_length+1], name, PATH_MAX - dir_length);

	umask(0);

	fd = open(
	 pathname
	,force ? O_WRONLY|O_CREAT|O_TRUNC : O_WRONLY|O_TRUNC
	,0644);

	if ( fd < 0 ) {
		perror(pathname);
		exit(0);
	}


	if ( value )
		failed = ( write(fd, on, sizeof(on) - 1) != (sizeof(on) - 1) );
	else
		failed = ( write(fd, off, sizeof(off) - 1) != (sizeof(off) - 1) );

	close(fd);

	if ( failed ) {
		perror(pathname);
		exit(-1);
	}
	exit(0);
}

static int
noDirectories(const struct dirent * d)
{
	return ( d->d_name[0] != '.'
	 || (d->d_name[1] != '\0'
	  && (d->d_name[1] != '.' || d->d_name[2] != '\0')) );
}

static void
showConfigurations()
{
	struct dirent * *	array = 0;
	int	count = scandir(dir_name, &array, noDirectories, alphasort);
	int					i;

	if ( count < 0 ) {
		perror(dir_name);
		exit(-1);
	}

	for ( i = 0; i < count; i++ ) {
		struct dirent *	d = array[i];
		int value = getConfiguration(d->d_name);

		printf("%s\t%s", d->d_name, value ? on : off);
		free((void *)d);
	}
	free((void *)array);
}

static volatile void
usage()
{
	static const char	message[] =
	 "\n"
	 "Usage:\tchkconfig [ -s ]\t\t\tPrint all configurations.\n"
	 "\tchkconfig [ -f ] name [ on | off ]\tSet value.\n"
	 "\n"
	 "\t-f:\t\tForce creation if value doesn't exist.\n"
	 "\n"
	 "\ton | off:\tValue. Default is \"off\".\n";

	fprintf(stderr, "%s", message);
	exit(-1);
}

int
main(int argc, char * * argv)
{
	if ( argc < 2 ) {
		showConfigurations();
		return 0;
	}
	if ( argc == 2 ) {
		if ( argv[1][0] == '-' ) {
			if ( argv[1][1] == 's' && argv[2] == 0 ) {
				showConfigurations();
				return 0;
			}
			else
				usage();
		}
		return getConfiguration(argv[1]) == 0;
	}
	else if ( argc >= 3 && argc <= 4 ) {
		int	force = 0;
		int	value = 0;

		if ( argv[1][0] == '-' && argv[1][1] == 'f' && argv[1][2] == '\0' ) {
			force = 1;
			argv++;
			argc--;
		}
		if ( argc == 3 ) {
			value = ( (argv[2][0] == 'o' || argv[2][0] == 'O')
			 &&  (argv[2][1] == 'n' || argv[2][1] == 'N') );
		}
		setConfiguration(argv[1], value, force);
		return 0;
	}
	else
		usage();
}


Reply to: