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 38#include <conf_file.h> 39#include <dprintf.h> 40 41#if HAVE_STRERROR 42extern int errno; 43# define error_string strerror(errno) 44#elif HAVE_SYS_ERRLIST 45extern const char *const sys_errlist[]; 46extern int errno; 47# define error_string (sys_errlist[errno]) 48#else 49# define error_string "error message not found" 50#endif 51 52int parse_conf_file(char *fname, struct conf_cmd *commands) 53{ 54 char buf[BUFSIZ+1]; 55 FILE *in; 56 int using_a_file = 1; 57 char *p; 58 char *cmd_start; 59 char *arg; 60 struct conf_cmd *cmd; 61 int lnum = 0; 62 63 // safety first 64 buf[BUFSIZ] = '\0'; 65 66 if(strcmp("-", fname) == 0) 67 { 68 in = stdin; 69 using_a_file = 0; 70 } 71 else 72 { 73 if((in=fopen(fname, "r")) == NULL) 74 { 75 show_message("could not open config file \"%s\": %s\n", fname, error_string); 76 return(-1); 77 } 78 } 79 80 while(lnum++, fgets(buf, BUFSIZ, in) != NULL) 81 { 82 p = buf; 83 84 /* eat space */ 85 while(*p == ' ' || *p == '\t') { p++; } 86 87 /* ignore comments and blanks */ 88 if(*p == '#' || *p == '\r' || *p == '\n' || *p == '\0') 89 { 90 continue; 91 } 92 93 cmd_start = p; 94 95 /* chomp new line */ 96 while(*p != '\0' && *p != '\r' && *p != '\n') { p++; } 97 *p = '\0'; 98 p = cmd_start; 99 100 /* find the end of the command */ 101 while(*p != '\0' && *p != '=') { p++; } 102 103 /* insure that it is terminated and find arg */ 104 if(*p == '\0') 105 { 106 arg = NULL; 107 } 108 else 109 { 110 *p = '\0'; 111 p++; 112 arg = p; 113 } 114 115 /* look up the command */ 116 cmd = commands; 117 while(cmd->name != NULL) 118 { 119 if(strcmp(cmd->name, cmd_start) == 0) 120 { 121 dprintf((stderr, "using cmd %s\n", cmd->name)); 122 break; 123 } 124 cmd++; 125 } 126 if(cmd->name == NULL) 127 { 128 show_message("%s,%d: unknown command: %s\n", fname, lnum, cmd_start); 129 130 fprintf(stderr, "commands are:\n"); 131 cmd = commands; 132 while(cmd->name != NULL) 133 { 134 fprintf(stderr, " %-14s usage: ", cmd->name); 135 fprintf(stderr, cmd->help, cmd->name); 136 fprintf(stderr, "\n"); 137 cmd++; 138 } 139 goto ERR; 140 } 141 142 /* check the arg */ 143 switch(cmd->arg_type) 144 { 145 case CONF_NEED_ARG: 146 if(arg == NULL) 147 { 148 show_message("option \"%s\" requires an argument\n", cmd->name); 149 goto ERR; 150 } 151 break; 152 case CONF_OPT_ARG: 153 if(arg == NULL) 154 { 155 arg = ""; 156 } 157 break; 158 case CONF_NO_ARG: 159 arg = ""; 160 break; 161 default: 162 dprintf((stderr, "case not handled: %d\n", cmd->arg_type)); 163 break; 164 } 165 166 /* is the command implemented? */ 167 if(!cmd->available) 168 { 169 show_message("the command \"%s\" is not available\n", cmd->name); 170 continue; 171 } 172 173 /* handle the command */ 174 cmd->proc(cmd, arg); 175 } 176 177 if(using_a_file) 178 { 179 if(in) 180 { 181 fclose(in); 182 } 183 } 184 return 0; 185 186ERR: 187 if(using_a_file) 188 { 189 if(in) 190 { 191 fclose(in); 192 } 193 } 194 return(-1); 195} 196