1/* ============================================================================ 2 * Copyright (C) 1999 Angus Mackay. All rights reserved; 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2, or (at your option) 7 * any later version. 8 * 9 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, 10 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 11 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 12 * AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 13 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 14 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 15 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 16 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 17 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 18 * POSSIBILITY OF SUCH DAMAGE. 19 * ============================================================================ 20 */ 21 22/* 23 * conf_file.c 24 * 25 * simple config file code 26 * 27 */ 28 29 30#ifdef HAVE_CONFIG_H 31# include <config.h> 32#endif 33 34#include <stdio.h> 35#include <stdlib.h> 36#include <string.h> 37#if HAVE_ERRNO_H 38# include <errno.h> 39#endif 40 41#include <conf_file.h> 42#include <dprintf.h> 43 44#if HAVE_STRERROR 45//extern int errno; 46# define error_string strerror(errno) 47#elif HAVE_SYS_ERRLIST 48extern const char *const sys_errlist[]; 49extern int errno; 50# define error_string (sys_errlist[errno]) 51#else 52# define error_string "error message not found" 53#endif 54 55int parse_conf_file(char *fname, struct conf_cmd *commands) 56{ 57 char buf[BUFSIZ+1]; 58 FILE *in; 59 int using_a_file = 1; 60 char *p; 61 char *cmd_start; 62 char *arg; 63 struct conf_cmd *cmd; 64 int lnum = 0; 65 66 // safety first 67 buf[BUFSIZ] = '\0'; 68 69 if(strcmp("-", fname) == 0) 70 { 71 in = stdin; 72 using_a_file = 0; 73 } 74 else 75 { 76 if((in=fopen(fname, "r")) == NULL) 77 { 78 show_message("could not open config file \"%s\": %s\n", fname, error_string); 79 return(-1); 80 } 81 } 82 83 while(lnum++, fgets(buf, BUFSIZ, in) != NULL) 84 { 85 p = buf; 86 87 /* eat space */ 88 while(*p == ' ' || *p == '\t') { p++; } 89 90 /* ignore comments and blanks */ 91 if(*p == '#' || *p == '\r' || *p == '\n' || *p == '\0') 92 { 93 continue; 94 } 95 96 cmd_start = p; 97 98 /* chomp new line */ 99 while(*p != '\0' && *p != '\r' && *p != '\n') { p++; } 100 *p = '\0'; 101 p = cmd_start; 102 103 /* find the end of the command */ 104 while(*p != '\0' && *p != '=') { p++; } 105 106 /* insure that it is terminated and find arg */ 107 if(*p == '\0') 108 { 109 arg = NULL; 110 } 111 else 112 { 113 *p = '\0'; 114 p++; 115 arg = p; 116 } 117 118 /* look up the command */ 119 cmd = commands; 120 while(cmd->name != NULL) 121 { 122 if(strcmp(cmd->name, cmd_start) == 0) 123 { 124 dprintf((stderr, "using cmd %s\n", cmd->name)); 125 break; 126 } 127 cmd++; 128 } 129 if(cmd->name == NULL) 130 { 131 show_message("%s,%d: unknown command: %s\n", fname, lnum, cmd_start); 132 133 fprintf(stderr, "commands are:\n"); 134 cmd = commands; 135 while(cmd->name != NULL) 136 { 137 fprintf(stderr, " %-14s usage: ", cmd->name); 138 fprintf(stderr, cmd->help, cmd->name); 139 fprintf(stderr, "\n"); 140 cmd++; 141 } 142 goto ERR; 143 } 144 145 /* check the arg */ 146 switch(cmd->arg_type) 147 { 148 case CONF_NEED_ARG: 149 if(arg == NULL) 150 { 151 show_message("option \"%s\" requires an argument\n", cmd->name); 152 goto ERR; 153 } 154 break; 155 case CONF_OPT_ARG: 156 if(arg == NULL) 157 { 158 arg = ""; 159 } 160 break; 161 case CONF_NO_ARG: 162 arg = ""; 163 break; 164 default: 165 dprintf((stderr, "case not handled: %d\n", cmd->arg_type)); 166 break; 167 } 168 169 /* is the command implemented? */ 170 if(!cmd->available) 171 { 172 show_message("the command \"%s\" is not available\n", cmd->name); 173 continue; 174 } 175 176 /* handle the command */ 177 cmd->proc(cmd, arg); 178 } 179 180 if(using_a_file) 181 { 182 if(in) 183 { 184 fclose(in); 185 } 186 } 187 return 0; 188 189ERR: 190 if(using_a_file) 191 { 192 if(in) 193 { 194 fclose(in); 195 } 196 } 197 return(-1); 198} 199