* Copyright 1993, Garrett A. Wollman.
* Copyright 1993, University of Vermont and State Agricultural College.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND AUTHOR ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR AUTHOR BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
const char chkconfig_c_rcsid
[] =
"$Id: chkconfig.c,v 1.4 1993/11/12 03:54:24 wollman Exp $";
static int testvalue(const char *);
static int printflags(const char *);
static int setvalue(const char *, int);
static int printvalues(void);
static void die(const char *);
static int is_on(const char *, size_t);
static const char *configdir
= _PATH_CONFIG
;
static int sortbystate
= 0;
int main(int argc
, char **argv
) {
while((opt
= getopt(argc
, argv
, "osfd:v")) != EOF
) {
if(sortbystate
&& optind
!= argc
) {
fprintf(stderr
, "%s: -s: too many arguments\n", whoami
);
if(force
&& optind
== argc
) {
fprintf(stderr
, "%s: -f: too few arguments\n", whoami
);
return doflags
? printflags(argv
[optind
]) : testvalue(argv
[optind
]);
return setvalue(argv
[optind
], is_on(argv
[optind
+ 1],
strlen(argv
[optind
+ 1])));
static int is_on(const char *str
, size_t len
) {
if(!str
|| len
< 2) return 0;
return ( ((str
[0] == 'o') || (str
[0] == 'O'))
&& ((str
[1] == 'n') || (str
[1] == 'N'))
&& ((len
== 2) || (str
[2] == '\n')));
static void chat(const char *str
, int state
) {
printf("`%s' is %s.\n", str
, state
? "ON" : "OFF");
static const char *confname(const char *str
, const char *str2
) {
int len
= strlen(configdir
) + strlen(str
) + strlen(str2
) + 2;
static int testvalue(const char *str
) {
int rv
= 1; /* NB: shell's convention is opposite C's */
fname
= confname(str
, "");
} while(line
&& line
[0] == '#');
rv
= !is_on(line
, len
); /* shell's convention is opposite C's */
free((void *)fname
); /* cast away `const' to avoid warning */
chat(str
, !rv
); /* tell the user about it if verbose */
static char *getflags(const char *str
) {
fname
= confname(str
, ".flags");
} while(line
&& line
[0] == '#');
if(line
[len
- 1] == '\n') --len
;
if((rv
= (char *) malloc(len
+ 1)) == NULL
) {
static int printflags(const char *str
) {
if(flags
[0]) printf("%s\n", flags
);
static int setvalue(const char *str
, int state
) {
fname
= confname(str
, "");
* Yes, I know this is bogus, but SGI must have had some sort of
"%s: configuration file does not exist;"
" use `-f' flag to create it.\n", whoami
);
fprintf(fp
, "%s\n", state
? "on" : "off");
* From here down is the code for listing the value of every option.
static struct q
*offhead
; /* only used for sortbystate == 1 */
static void insert(const char *fname
) {
q
->state
= state
= !testvalue(fname
);
q
->flags
= getflags(fname
);
if(state
|| !sortbystate
)
while(*headp
&& strcmp(q
->name
, (**headp
).name
) > 0) {
static int printvalues(void) {
verbose
= 0; /* we're already verbose enough */
dir
= opendir(configdir
);
while((entry
= readdir(dir
))) {
if(stat(entry
->d_name
, &stab
) < 0) {
if(S_ISREG(stab
.st_mode
) && !strchr(entry
->d_name
, '.')) {
* Now we're done reading the file names, so we can print them out.
* Thanks to insert(), everything is already in ASCII order.
#define FORMAT "%15s %-5s %s\n"
"Option", "State", "Flags");
"===============", "=====", "====================");
while((temp
= offhead
)) {
printf(FORMAT
, temp
->name
, "off", temp
->flags
);
printf("%15s %s %s\n", "Option", "State", "Flags");
"===============", "=====", "====================");
printf(FORMAT
, temp
->name
, temp
->state
? "on" : "off", temp
->flags
);
static void die(const char *why
) {
fprintf(stderr
, "%s: %s: %s\n", whoami
, why
, strerror(errno
));
static void usage(void) {
fprintf(stderr
, "%s: usage:\n"
"%s [ -d configdir ] [ -s ]\n"
"%s [ -d configdir ] option\n"
"%s [ -d configdir ] [ -f ] option [ on | off ]\n",
whoami
, whoami
, whoami
, whoami
);