1 /*
2 * Copyright (C) 2009-2015 Christian Heckendorf <heckendorfc@gmail.com>
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 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include "harpconfig.h"
19 #include "defs.h"
20 #include "insert.h"
21 #include "util.h"
22
23 struct lconf listconf;
24 struct iconf insertconf;
25 struct dconf debugconf;
26
27 static const char insertflags[]={'r','a','t','y','k',0};
28
29 extern struct option longopts[];
30
argConfig(char * buffer)31 static void argConfig(char *buffer){
32 char *setting=buffer;
33 int y=0,argfound=0;
34 while(*setting!='=' && *setting)setting++;
35 if(*setting && *(setting+1))argfound=1;
36 *(setting++)=0;
37
38 for(y=0;longopts[y].name;y++){
39 if(strcmp(buffer,longopts[y].name)==0){
40 if(y!=AVERBOSE || !argfound)
41 arglist[y].active=1;
42 else
43 arglist[y].active=(int)strtol(setting,NULL,10);
44
45 if(longopts[y].has_arg>0){
46 if(argfound){
47 if(!(arglist[y].subarg=malloc(sizeof(char)*2)))return;
48 arglist[y].subarg[0]=*setting;
49 arglist[y].subarg[1]=0;
50 }
51 else
52 arglist[y].active=0;
53 }
54
55 return;
56 }
57 }
58 }
59
listConfig(char * buffer)60 static void listConfig(char *buffer){
61 char *setting=buffer;
62 int argfound=0;
63 while(*setting!='=' && *setting)setting++;
64 if(*setting && *(setting+1))argfound=1;
65 *(setting++)=0;
66
67 if(strcmp("width",buffer)==0){
68 if(argfound)
69 listconf.maxwidth=(int)strtol(setting,NULL,10);
70 else // bad config. hard coded defaults
71 listconf.maxwidth=30;
72 }
73 else if(strcmp("exception",buffer)==0){
74 if(argfound)
75 listconf.exception=(int)strtol(setting,NULL,10);
76 else // bad config. hard coded defaults
77 listconf.exception=0;
78 }
79 }
80
insertConfig(char * buffer)81 static void insertConfig(char *buffer){
82 char *setting=buffer;
83 static int formatsize=0;
84 while(*setting!='=' && *setting)setting++;
85 *(setting++)=0;
86
87 if(strcmp("usemetadata",buffer)==0){
88 if(*setting!='y'){
89 if(insertconf.second_cb==&metadataInsert)
90 insertconf.second_cb=NULL;
91 if(insertconf.first_cb==&metadataInsert)
92 insertconf.first_cb=NULL;
93 if(insertconf.second_cb && !insertconf.first_cb){
94 insertconf.first_cb=insertconf.second_cb;
95 insertconf.second_cb=NULL;
96 }
97 }
98 else{
99 if(insertconf.first_cb && insertconf.second_cb){
100 insertconf.first_cb=insertconf.second_cb;
101 insertconf.second_cb=NULL;
102 }
103 if(!insertconf.first_cb)
104 insertconf.first_cb=&metadataInsert;
105 else
106 insertconf.second_cb=&metadataInsert;
107 }
108 }
109 else if(strcmp("usefilepath",buffer)==0){
110 if(*setting!='y'){
111 if(insertconf.second_cb==&filepathInsert)
112 insertconf.second_cb=NULL;
113 if(insertconf.first_cb==&filepathInsert)
114 insertconf.first_cb=NULL;
115 if(insertconf.second_cb && !insertconf.first_cb){
116 insertconf.first_cb=insertconf.second_cb;
117 insertconf.second_cb=NULL;
118 }
119 }
120 else{
121 if(insertconf.first_cb && insertconf.second_cb){
122 insertconf.first_cb=insertconf.second_cb;
123 insertconf.second_cb=NULL;
124 }
125 if(!insertconf.first_cb)
126 insertconf.first_cb=&filepathInsert;
127 else
128 insertconf.second_cb=&filepathInsert;
129 }
130 }
131 else if(strcmp("format",buffer)==0){
132 char *ptr=setting;
133 int koi=0;
134 const char *pflag="(.*)";
135 char *pattern;
136 int pi=0;
137 int ret;
138 int siz;
139 if(++formatsize==ICONF_MAX_FORMAT_SIZE){
140 fprintf(stderr,"Insert format buffer is full. Please check your config file.");
141 return;
142 }
143 insertconf.keyorder[formatsize]=NULL;
144 insertconf.keyorder[formatsize-1]=malloc(MI_NULL*sizeof(int));
145
146 siz=strlen(setting)+(strlen(pflag)-2)*MI_NULL;
147 pattern=malloc(siz);
148
149 while(*ptr){
150 do{
151 pattern[pi++]=*ptr;
152 }while(*ptr && *(++ptr)!='%');
153
154 if(*ptr && ptr[1] && koi<MI_NULL){
155 int i,j,custom=0;
156 if(ptr[1]=='['){
157 custom=1;
158 ptr+=2;
159 pattern[pi++]='(';
160 for(j=1;j>0 && *ptr;ptr++){
161 if(*ptr=='[' && *(ptr-1)!='\\')
162 j++;
163 if(*ptr==']' && *(ptr-1)!='\\')
164 j--;
165 if(j)
166 pattern[pi++]=*ptr;
167 }
168 pattern[pi++]=')';
169 if(*ptr==0)
170 break;
171 ptr--;
172 }
173 for(i=0;insertflags[i];i++){
174 if(insertflags[i]==ptr[1]){
175 insertconf.keyorder[formatsize-1][koi++]=i;
176 break;
177 }
178 }
179
180 if(!custom){
181 for(i=0;pflag[i];i++)
182 pattern[pi++]=pflag[i];
183 }
184
185 ptr++;
186 }
187 else
188 break;
189
190 ptr++;
191 }
192 insertconf.keyorder[formatsize-1][koi]=MI_NULL;
193 pattern[pi++]=0;
194
195 if((ret=regcomp(insertconf.pattern+formatsize-1,pattern,REG_EXTENDED))){
196 regerror(ret,NULL,pattern,siz);
197 fprintf(stderr,"Compile regex failed! (%d) %s\n",ret,pattern);
198 }
199
200 free(pattern);
201 }
202 else if(strcmp("accuratelength",buffer)==0 && *setting=='y'){
203 insertconf.length=0;
204 }
205 }
206
create_logfile(char * template,char * dir,char ** dst_filename,FILE ** dst_fd)207 static void create_logfile(char *template, char *dir, char **dst_filename, FILE **dst_fd){
208 char tmp[256];
209 int fid;
210
211 sprintf(tmp,template,dir);
212 expand(tmp);
213
214 if((fid=mkstemp(tmp))==-1)
215 return;
216
217 if(*dst_filename){
218 /* Debugs won't print at this point unless specified in the config file. */
219 //char msg[350];
220 //sprintf(msg,"Removing log: %s.\n\tPlease check config file for duplicate entries.",*dst_filename);
221 //debug(1,msg);
222 unlink(*dst_filename);
223 free(*dst_filename);
224 }
225 *dst_filename=strdup(tmp);
226
227 if(*dst_fd)
228 fclose(*dst_fd);
229 *dst_fd=fdopen(fid,"w");
230 //sprintf(tmp,"Logging to: %s",*dst_filename);
231 //debug(1,tmp);
232 }
233
debugConfig(char * buffer)234 static void debugConfig(char *buffer){
235 char *setting=buffer;
236 while(*setting!='=' && *setting)setting++;
237 *(setting++)=0;
238
239 if(strcmp("logging",buffer)==0 && *setting=='y'){
240 debugconf.log=1;
241 }
242 else if(strcmp("directory",buffer)==0){
243 if(debugconf.dir==NULL || strcmp(debugconf.dir,setting)!=0){
244 if(debugconf.dir)
245 free(debugconf.dir);
246 debugconf.dir=strdup(setting);
247 }
248 }
249 else if(strcmp("playlog",buffer)==0 && *setting=='y' && debugconf.dir){
250 create_logfile("%s/player.log.XXXXXX",debugconf.dir,&debugconf.playfilename,&debugconf.playfd);
251 }
252 else if(strcmp("loglevel",buffer)==0){
253 debugconf.level=(int)strtol(setting,NULL,10);
254 if(debugconf.level>0 && debugconf.dir){
255 create_logfile("%s/debug.log.XXXXXX",debugconf.dir,&debugconf.msgfilename,&debugconf.msgfd);
256 }
257 }
258 }
259
configInit()260 static void configInit(){
261 if((insertconf.keyorder=malloc(sizeof(char*)*ICONF_MAX_FORMAT_SIZE)))
262 *insertconf.keyorder=NULL;
263 insertconf.pattern=malloc(sizeof(char*)*ICONF_MAX_FORMAT_SIZE);
264 insertconf.length=-1;
265 insertconf.second_cb=insertconf.first_cb=NULL;
266
267 debugconf.playfilename=debugconf.msgfilename=debugconf.dir=NULL;
268 debugconf.msgfd=debugconf.playfd=NULL;
269 }
270
parseConfig(FILE * ffd)271 static void parseConfig(FILE *ffd){
272 char *buffer=malloc(255*sizeof(char));
273 char *ptr=buffer;
274 void (*dest)(char *buffer) = NULL;
275
276 if(!buffer)return;
277
278
279 while(fgets(buffer,255,ffd)){
280 if(*buffer=='['){ // New header
281 switch(buffer[1]){
282 case 'a':dest=&argConfig;break;
283 case 'l':dest=&listConfig;break;
284 case 'i':dest=&insertConfig;break;
285 case 'd':dest=&debugConfig;break;
286 default:dest=NULL;
287 }
288 continue;
289 }
290 if(dest && *buffer>64 && *buffer<123){
291 while(*(++ptr)!='\n');
292 while(*ptr<33 || *ptr>122)ptr--;
293 *(ptr+1)=0;
294 ptr=buffer;
295
296 dest(buffer);
297 }
298 }
299 free(buffer);
300 }
301
setDefaultConfig()302 void setDefaultConfig(){
303 FILE *ffd;
304 char temp[250];
305
306 configInit();
307
308 sprintf(temp,"%s/harp/defaults.conf",SHARE_PATH);
309 if((ffd=fopen(temp,"r"))==NULL){
310 exit(1);
311 }
312 parseConfig(ffd);
313 fclose(ffd);
314
315 strcpy(temp,"~/.harp/defaults.conf");
316 expand(temp);
317 if((ffd=fopen(temp,"r"))!=NULL){
318 parseConfig(ffd);
319 fclose(ffd);
320 }
321 }
322