1/* MiniUPnP project 2 * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/ 3 * author: Ryan Wagoner 4 * 5 * Copyright (c) 2006, Thomas Bernard 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions are met: 10 * * Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * * Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * * The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 */ 30#include <stdio.h> 31#include <string.h> 32#include <stdlib.h> 33#include <ctype.h> 34#include "options.h" 35#include "utils.h" 36#include "upnpglobalvars.h" 37 38struct option * ary_options = NULL; 39int num_options = 0; 40 41static const struct { 42 enum upnpconfigoptions id; 43 const char * name; 44} optionids[] = { 45 { UPNPIFNAME, "network_interface" }, 46 { UPNPPORT, "port" }, 47 { UPNPPRESENTATIONURL, "presentation_url" }, 48 { UPNPNOTIFY_INTERVAL, "notify_interval" }, 49 { UPNPUUID, "uuid"}, 50 { UPNPSERIAL, "serial"}, 51 { UPNPMODEL_NAME, "model_name"}, 52 { UPNPMODEL_NUMBER, "model_number"}, 53 { UPNPFRIENDLYNAME, "friendly_name"}, 54 { UPNPMEDIADIR, "media_dir"}, 55 { UPNPALBUMART_NAMES, "album_art_names"}, 56 { UPNPINOTIFY, "inotify" }, 57 { UPNPDBDIR, "db_dir" }, 58 { UPNPLOGDIR, "log_dir" }, 59 { UPNPLOGLEVEL, "log_level" }, 60 { UPNPMINISSDPDSOCKET, "minissdpdsocket"}, 61 { ENABLE_TIVO, "enable_tivo" }, 62 { ENABLE_DLNA_STRICT, "strict_dlna" }, 63 { ROOT_CONTAINER, "root_container" }, 64 { USER_ACCOUNT, "user" }, 65 { FORCE_SORT_CRITERIA, "force_sort_criteria" }, 66 { MAX_CONNECTIONS, "max_connections" }, 67 { MERGE_MEDIA_DIRS, "merge_media_dirs" } 68}; 69 70int 71readoptionsfile(const char * fname) 72{ 73 FILE *hfile = NULL; 74 char buffer[1024]; 75 char *equals; 76 char *name; 77 char *value; 78 char *t; 79 int linenum = 0; 80 int i; 81 enum upnpconfigoptions id; 82 83 if(!fname || *fname == '\0') 84 return -1; 85 86 memset(buffer, 0, sizeof(buffer)); 87 88#ifdef DEBUG 89 printf("Reading configuration from file %s\n", fname); 90#endif 91 92 if(!(hfile = fopen(fname, "r"))) 93 return -1; 94 95 while(fgets(buffer, sizeof(buffer), hfile)) 96 { 97 linenum++; 98 t = strchr(buffer, '\n'); 99 if(t) 100 { 101 *t = '\0'; 102 t--; 103 while((t >= buffer) && isspace(*t)) 104 { 105 *t = '\0'; 106 t--; 107 } 108 } 109 110 /* skip leading whitespaces */ 111 name = buffer; 112 while(isspace(*name)) 113 name++; 114 115 /* check for comments or empty lines */ 116 if(name[0] == '#' || name[0] == '\0') continue; 117 118 if(!(equals = strchr(name, '='))) 119 { 120 fprintf(stderr, "parsing error file %s line %d : %s\n", 121 fname, linenum, name); 122 continue; 123 } 124 125 /* remove ending whitespaces */ 126 for(t=equals-1; t>name && isspace(*t); t--) 127 *t = '\0'; 128 129 *equals = '\0'; 130 value = equals+1; 131 132 /* skip leading whitespaces */ 133 while(isspace(*value)) 134 value++; 135 136 id = UPNP_INVALID; 137 for(i=0; i<sizeof(optionids)/sizeof(optionids[0]); i++) 138 { 139 /*printf("%2d %2d %s %s\n", i, optionids[i].id, name, 140 optionids[i].name); */ 141 142 if(0 == strcmp(name, optionids[i].name)) 143 { 144 id = optionids[i].id; 145 break; 146 } 147 } 148 149 if(id == UPNP_INVALID) 150 { 151 if (strcmp(name, "include") == 0) 152 readoptionsfile(value); 153 else 154 fprintf(stderr, "parsing error file %s line %d : %s=%s\n", 155 fname, linenum, name, value); 156 } 157 else 158 { 159 num_options++; 160 t = realloc(ary_options, num_options * sizeof(struct option)); 161 if(!t) 162 { 163 fprintf(stderr, "memory allocation error: %s=%s\n", 164 name, value); 165 num_options--; 166 continue; 167 } 168 else 169 ary_options = (struct option *)t; 170 171 ary_options[num_options-1].id = id; 172 strncpyt(ary_options[num_options-1].value, value, MAX_OPTION_VALUE_LEN); 173 } 174 175 } 176 177 fclose(hfile); 178 179 return 0; 180} 181 182void 183freeoptions(void) 184{ 185 struct media_dir_s *media_path, *last_path; 186 struct album_art_name_s *art_names, *last_name; 187 188 media_path = media_dirs; 189 while (media_path) 190 { 191 free(media_path->path); 192 last_path = media_path; 193 media_path = media_path->next; 194 free(last_path); 195 } 196 197 art_names = album_art_names; 198 while (art_names) 199 { 200 free(art_names->name); 201 last_name = art_names; 202 art_names = art_names->next; 203 free(last_name); 204 } 205 206 if(ary_options) 207 { 208 free(ary_options); 209 ary_options = NULL; 210 num_options = 0; 211 } 212} 213 214