1 /***************************************************************************/
2 /*    This code is part of WWW grabber called pavuk                        */
3 /*    Copyright (c) 1997 - 2001 Stefan Ondrejicka                          */
4 /*    Distributed under GPL 2 or later                                     */
5 /***************************************************************************/
6 
7 #include "config.h"
8 
9 #include <unistd.h>
10 #include <stdio.h>
11 #include <netdb.h>
12 #include <string.h>
13 #include <sys/types.h>
14 #include <sys/stat.h>
15 #include <fcntl.h>
16 #include <limits.h>
17 #include <errno.h>
18 
19 #include "config.h"
20 #include "tools.h"
21 #include "ftp.h"
22 #include "http.h"
23 #include "gopher.h"
24 #include "authinfo.h"
25 #include "times.h"
26 #include "html.h"
27 #include "lfname.h"
28 #include "re.h"
29 #include "mopt.h"
30 #include "jstrans.h"
31 #include "tag_pattern.h"
32 
33 static void cfg_version_info(void);
34 static int cfg_load_scenario(const char *);
35 
36 #include "options.h"
37 
38 struct strategie_mapt
39 {
40   strategie id;
41   char *name;
42   char *label;
43 };
44 
45 static struct strategie_mapt strategie_map[] = {
46   {SSTRAT_DO_SIRKY, "level", gettext_nop("Level order")},
47   {SSTRAT_DO_SIRKY_I, "leveli", gettext_nop("Level order, inline first")},
48   {SSTRAT_DO_HLBKY, "pre", gettext_nop("Pre order")},
49   {SSTRAT_DO_HLBKY_I, "prei", gettext_nop("Pre order, inline first")},
50 };
51 
get_strategie_by_str(char * str)52 static strategie get_strategie_by_str(char *str)
53 {
54   int i;
55 
56   for(i = 0; i < SSTRAT_LAST; i++)
57   {
58     if(!strcasecmp(str, strategie_map[i].name))
59       return strategie_map[i].id;
60   }
61 
62   return SSTRAT_LAST;
63 }
64 
get_strategie_str(strategie id)65 static char *get_strategie_str(strategie id)
66 {
67   return strategie_map[id].name;
68 }
69 
get_strategie_label(strategie id)70 char *get_strategie_label(strategie id)
71 {
72   return gettext(strategie_map[id].label);
73 }
74 
75 static const struct
76 {
77   char *name;
78   int id;
79 } _ssl_versions[] =
80 {
81   {"ssl23", 1},
82   {"ssl2",  2},
83   {"ssl3",  3},
84   {"tls1",  4}
85 };
86 
get_ssl_version_by_str(char * str)87 static strategie get_ssl_version_by_str(char *str)
88 {
89   int i;
90 
91   for(i = 0; i < NUM_ELEM(_ssl_versions); i++)
92   {
93     if(!strcasecmp(str, _ssl_versions[i].name))
94       return _ssl_versions[i].id;
95   }
96 
97   return -1;
98 }
99 
get_ssl_version_str(strategie id)100 static char *get_ssl_version_str(strategie id)
101 {
102   return _ssl_versions[id - 1].name;
103 }
104 
105 /**********************************/
106 /* show program usage information */
107 /**********************************/
usage(void)108 void usage(void)
109 {
110   int i;
111 
112   cfg.bgmode = FALSE;
113 
114   xprintf(0,
115     gettext("Usage:  %s  [options]  [any number of URLS]\npavuk-%s %s\n"),
116     cfg.prg_path, VERSION, HOSTTYPE);
117 
118   for(i = 0; i < NUM_ELEM(params); i++)
119   {
120     if(params[i].help)
121       xprintf(0, gettext(params[i].help));
122   }
123 
124   fflush(stdout);
125   exit(PAVUK_EXIT_OK);
126 }
127 
usage_short(void)128 void usage_short(void)
129 {
130   xprintf(0, "%s %s %s %s\n", PACKAGE, VERSION, REVISION, HOSTTYPE);
131   xprintf(0, gettext("Type \"%s --help\" for long help\n"), cfg.prg_path);
132   exit(PAVUK_EXIT_CFG_ERR);
133 }
134 
cfg_version_info(void)135 static void cfg_version_info(void)
136 {
137   xprintf(0, "%s %s %s %s\n", PACKAGE, VERSION, REVISION, HOSTTYPE);
138   xprintf(0, gettext("Optional features available :\n"));
139 #ifdef DEBUG
140   xprintf(0, gettext(" - Debug mode\n"));
141 #endif
142 
143 #ifdef GETTEXT_NLS
144   xprintf(0, gettext(" - GNU gettext internationalization of messages\n"));
145 #endif
146 
147 #ifdef HAVE_FLOCK
148   xprintf(0, gettext(" - flock() document locking\n"));
149 #endif
150 
151 #ifdef HAVE_FCNTL_LOCK
152   xprintf(0, gettext(" - fcntl() document locking\n"));
153 #endif
154 
155 #ifdef I_FACE
156 #ifdef GTK_FACE
157   xprintf(0, gettext(" - Gtk GUI interface\n"));
158 #endif
159 #ifdef WITH_TREE
160   xprintf(0, gettext(" - URL tree preview\n"));
161 #endif
162 #endif
163 
164 #ifdef USE_SSL
165   xprintf(0, gettext(" - HTTP and FTP over SSL\n"));
166 
167 #if defined(USE_SSL_IMPL_OPENSSL) && defined(OPENSSL)
168 #define __SSLIMP "OpenSSL"
169 #elif defined(USE_SSL_IMPL_OPENSSL)
170 #define __SSLIMP "SSLeay"
171 #elif defined(USE_SSL_IMPL_NSS)
172 #define __SSLIMP "NSS3"
173 #else
174 #define __SSLIMP "unknown"
175 #endif
176   xprintf(0, gettext(" - SSL layer implemented with %s library\n"), __SSLIMP);
177 #endif
178 
179 #ifdef SOCKS
180   xprintf(0, gettext(" - Socks proxy support\n"));
181 #endif
182 #ifdef HAVE_FSTATFS
183   xprintf(0, gettext(" - filesystem free space checking\n"));
184 #endif
185 
186 #ifdef HAVE_REGEX
187   xprintf(0,
188     gettext
189     (" - optional regex patterns in -fnrules and -*rpattern options\n"));
190 #endif
191 
192 #ifdef HAVE_POSIX_REGEX
193   xprintf(0, gettext(" - POSIX regexp\n"));
194 #endif
195 
196 #ifdef HAVE_V8_REGEX
197   xprintf(0, gettext(" - Bell V8 regexp\n"));
198 #endif
199 
200 #ifdef HAVE_BSD_REGEX
201   xprintf(0, gettext(" - BSD regexp\n"));
202 #endif
203 
204 #ifdef HAVE_GNU_REGEX
205   xprintf(0, gettext(" - GNU regexp\n"));
206 #endif
207 
208 #ifdef HAVE_PCRE_REGEX
209   xprintf(0, gettext(" - PCRE regexp\n"));
210 #endif
211 
212 #ifdef HAVE_BDB_18x
213   xprintf(0,
214     gettext(" - support for loading files from Netscape browser cache\n"));
215 #endif
216 
217 #ifdef HAVE_TERMIOS
218   xprintf(0,
219     gettext
220     (" - support for detecting whether pavuk is running as background job\n"));
221 #endif
222 
223 #ifdef HAVE_MT
224   xprintf(0, gettext(" - multithreading support\n"));
225 #endif
226 
227 #ifdef ENABLE_NTLM
228   xprintf(0, gettext(" - NTLM authorization support\n"));
229 #endif
230 
231 #ifdef HAVE_MOZJS
232   xprintf(0, gettext(" - JavaScript bindings\n"));
233 #endif
234 
235 #ifdef HAVE_INET6
236   xprintf(0, gettext(" - IPv6 support\n"));
237 #endif
238 
239   exit(PAVUK_EXIT_OK);
240 }
241 
htmltag_set_disabled(char * tagstr,int disable)242 static int htmltag_set_disabled(char *tagstr, int disable)
243 {
244   int i, j;
245   bool_t tfound, afound;
246   char *tag;
247   char *attrib;
248   char *pom, *strtokbuf;
249 
250   if(!strcasecmp(tagstr, "all"))
251   {
252     for(i = 0; i < html_link_tags_num(); i++)
253     {
254       for(j = 0; html_link_tags[i].attribs[j].attrib; j++)
255       {
256         if(disable)
257           html_link_tags[i].attribs[j].stat |= LINK_DISABLED;
258         else
259           html_link_tags[i].attribs[j].stat &= ~LINK_DISABLED;
260       }
261     }
262 
263     return -1;
264   }
265 
266   pom = tl_strdup(tagstr);
267   tag = strtokc_r(pom, ',', &strtokbuf);
268   attrib = strtokc_r(NULL, ';', &strtokbuf);
269 
270   while(tag)
271   {
272     tfound = FALSE;
273     afound = FALSE;
274     for(i = 0; i < html_link_tags_num(); i++)
275     {
276       if(!strcasecmp(html_link_tags[i].tag, tag))
277       {
278         tfound = TRUE;
279         for(j = 0; html_link_tags[i].attribs[j].attrib; j++)
280         {
281           if(attrib && *attrib)
282           {
283             if(!strcasecmp(html_link_tags[i].attribs[j].attrib, attrib))
284             {
285               afound = TRUE;
286               if(disable)
287                 html_link_tags[i].attribs[j].stat |= LINK_DISABLED;
288               else
289                 html_link_tags[i].attribs[j].stat &= ~LINK_DISABLED;
290               break;
291             }
292           }
293           else
294           {
295             afound = TRUE;
296             if(disable)
297               html_link_tags[i].attribs[j].stat |= LINK_DISABLED;
298             else
299               html_link_tags[i].attribs[j].stat &= ~LINK_DISABLED;
300           }
301         }
302         break;
303       }
304     }
305     if(!(tfound && afound))
306     {
307       xprintf(0, gettext("HTML tag not supported : %s.%s\n"), tag,
308         attrib ? attrib : "(null)");
309     }
310 
311     tag = strtokc_r(NULL, ',', &strtokbuf);
312     attrib = strtokc_r(NULL, ';', &strtokbuf);
313   }
314 
315   _free(pom);
316   return -1;
317 }
318 
cfg_set_to_default(cfg_param_t * cpar)319 static void cfg_set_to_default(cfg_param_t * cpar)
320 {
321   char **p;
322   int x, j;
323 
324   if(cpar->type & PARAM_UNSUPPORTED)
325     return;
326 
327   if(cpar->type & PARAM_FOREIGN)
328     return;
329 
330   switch (cpar->type)
331   {
332   case PARAM_NUM:
333     *((long *) cpar->val_adr) = (long) cpar->default_val;
334     break;
335   case PARAM_PBOOL:
336     *((bool_t *) cpar->val_adr) = (bool_t) (long) cpar->default_val;
337     break;
338   case PARAM_NBOOL:
339     *((bool_t *) cpar->val_adr) = (bool_t) (long) cpar->default_val;
340     break;
341   case PARAM_PORT_RANGE:
342     *((long *) cpar->val_adr) = (long) cpar->default_val;
343     *((long *) cpar->mval_adr) = (long) cpar->mdefault_val;
344     break;
345   case PARAM_PATH:
346   case PARAM_STR:
347   case PARAM_PASS:
348     _free(*((char **) cpar->val_adr));
349     *((char **) cpar->val_adr) = (char *) cpar->default_val;
350     break;
351   case PARAM_STRLIST:
352     for(p = *((char ***) cpar->val_adr); p && *p; p++)
353       _free(*p);
354     _free(*(char ***) cpar->val_adr);
355 
356     *((char ***) cpar->val_adr) = (char **) cpar->default_val;
357     if(cpar->mval_adr)
358       *((bool_t *) cpar->mval_adr) = (bool_t) (long) cpar->mdefault_val;
359     break;
360   case PARAM_CONN:
361     _free(*((char **) cpar->val_adr));
362     *((char **) cpar->val_adr) = (char *) cpar->default_val;
363     if(cpar->mval_adr)
364       *((long *) cpar->mval_adr) = (long) cpar->mdefault_val;
365     break;
366   case PARAM_AUTHSCH:
367     *((long *) cpar->val_adr) = (long) cpar->default_val;
368     break;
369   case PARAM_MODE:
370     *((long *) cpar->val_adr) = (long) cpar->default_val;
371     break;
372   case PARAM_TIME:
373     *((time_t *) cpar->val_adr) = (time_t) 0;
374     break;
375   case PARAM_HTMLTAG:
376     for(x = 0; x < html_link_tags_num(); x++)
377       for(j = 0; html_link_tags[x].attribs[j].attrib; j++)
378         html_link_tags[x].attribs[j].stat &= ~LINK_DISABLED;
379     break;
380   case PARAM_TWO_QSTR:
381     *((char **) cpar->val_adr) = (char *) cpar->default_val;
382     *((char **) cpar->mval_adr) = (char *) cpar->mdefault_val;
383     break;
384   case PARAM_DOUBLE:
385     *((double *) cpar->val_adr) = *(double *) cpar->default_val;
386     break;
387   case PARAM_LFNAME:
388     while(cfg.lfnames)
389     {
390       lfname_free((lfname *) cfg.lfnames->data);
391       cfg.lfnames = dllist_remove_entry(cfg.lfnames, cfg.lfnames);
392     }
393     break;
394   case PARAM_RE:
395 #ifdef HAVE_REGEX
396     {
397       dllist *ptr = *((dllist **) cpar->val_adr);
398 
399       *((dllist **) cpar->val_adr) = NULL;
400 
401       while(ptr)
402       {
403         re_free((re_entry *) ptr->data);
404         ptr = dllist_remove_entry(ptr, ptr);
405       }
406     }
407 #endif
408     break;
409   case PARAM_USTRAT:
410     *((strategie *) cpar->val_adr) = (strategie) cpar->default_val;
411     break;
412   case PARAM_SSLVER:
413     *((long *) cpar->val_adr) = (long) cpar->default_val;
414     break;
415   case PARAM_HTTPHDR:
416     {
417       dllist *ptr = *(dllist **) cpar->val_adr;
418       *(dllist **) cpar->val_adr = NULL;
419 
420       while(ptr)
421       {
422         httphdr_free((httphdr *)ptr->data);
423         ptr = dllist_remove_entry(ptr, ptr);
424       }
425     }
426     break;
427   case PARAM_DEBUGL:
428     *((long *) cpar->val_adr) = (long) cpar->default_val;
429     break;
430   case PARAM_REQUEST:
431     {
432       dllist *ptr = *(dllist **) cpar->val_adr;
433       *(dllist **) cpar->val_adr = NULL;
434       while(ptr)
435       {
436         url_info_free((url_info *) ptr->data);
437         ptr = dllist_remove_entry(ptr, ptr);
438       }
439     }
440     break;
441   case PARAM_TRANSPARENT:
442     {
443       if(cpar->val_adr)
444       {
445         http_proxy *pr = *((http_proxy **) cpar->val_adr);
446         if(pr)
447           http_proxy_free(pr);
448       }
449     }
450     break;
451   case PARAM_PROXY:
452     {
453       dllist *ptr = *((dllist **) cpar->val_adr);
454       *((dllist **) cpar->val_adr) = NULL;
455 
456       while(ptr)
457       {
458         http_proxy *pr = (http_proxy *) ptr->data;
459         http_proxy_unref(pr);
460         ptr = dllist_remove_entry(ptr, ptr);
461       }
462     }
463     break;
464   case PARAM_FUNC:
465     break;
466   case PARAM_JSTRANS:
467 #ifdef HAVE_REGEX
468     while(cfg.js_transform)
469     {
470       js_transform_free((js_transform_t *) cfg.js_transform->data);
471       cfg.js_transform =
472         dllist_remove_entry(cfg.js_transform, cfg.js_transform);
473     }
474 #endif
475     break;
476   case PARAM_NUMLIST:
477     {
478       dllist *ptr = *((dllist **) cpar->val_adr);
479       *((dllist **) cpar->val_adr) = NULL;
480       while(ptr)
481         ptr = dllist_remove_entry(ptr, ptr);
482       if(cpar->mval_adr)
483         *((bool_t *) cpar->mval_adr) = (bool_t) (long) cpar->mdefault_val;
484     }
485     break;
486   case PARAM_FTPHS:
487     {
488       dllist *ptr = *((dllist **) cpar->val_adr);
489       *((dllist **) cpar->val_adr) = NULL;
490       for(; ptr; ptr = dllist_remove_entry(ptr, ptr))
491         ftp_handshake_info_free((ftp_handshake_info *)ptr->data);
492     }
493     break;
494   case PARAM_TAGPAT:
495     {
496       dllist *ptr = *((dllist **) cpar->val_adr);
497       *((dllist **) cpar->val_adr) = NULL;
498       for(; ptr; ptr = dllist_remove_entry(ptr, ptr))
499         tag_pattern_free((tag_pattern_t *)ptr->data);
500     }
501     break;
502   }
503 }
504 
cfg_set_all_to_default(void)505 void cfg_set_all_to_default(void)
506 {
507   int i;
508 
509   for(i = 0; i < NUM_ELEM(params); i++)
510     cfg_set_to_default(&(params[i]));
511 }
512 
cfg_setup_default(void)513 void cfg_setup_default(void)
514 {
515   int i, x, j;
516 
517   for(i = 0; i < NUM_ELEM(params); i++)
518   {
519     if(params[i].type & PARAM_UNSUPPORTED)
520       continue;
521 
522     if(params[i].type & PARAM_FOREIGN)
523       continue;
524 
525     switch (params[i].type)
526     {
527     case PARAM_NUM:
528       *((long *) params[i].val_adr) = (long) params[i].default_val;
529       break;
530     case PARAM_PBOOL:
531       *((bool_t *) params[i].val_adr) = (bool_t) (long) params[i].default_val;
532       break;
533     case PARAM_NBOOL:
534       *((bool_t *) params[i].val_adr) = (bool_t) (long) params[i].default_val;
535       break;
536     case PARAM_PORT_RANGE:
537       *((long *) params[i].val_adr) = (long) params[i].default_val;
538       *((long *) params[i].mval_adr) = (long) params[i].mdefault_val;
539       break;
540     case PARAM_PATH:
541     case PARAM_STR:
542     case PARAM_PASS:
543       *((char **) params[i].val_adr) = (char *) params[i].default_val;
544       break;
545     case PARAM_STRLIST:
546       *((char ***) params[i].val_adr) = (char **) params[i].default_val;
547       if(params[i].mval_adr)
548         *((bool_t *) params[i].mval_adr) =
549           (bool_t) (long) params[i].mdefault_val;
550       break;
551     case PARAM_CONN:
552       *((char **) params[i].val_adr) = (char *) params[i].default_val;
553       if(params[i].mval_adr)
554         *((long *) params[i].mval_adr) = (long) params[i].mdefault_val;
555       break;
556     case PARAM_AUTHSCH:
557       *((long *) params[i].val_adr) = (long) params[i].default_val;
558       break;
559     case PARAM_MODE:
560       *((long *) params[i].val_adr) = (long) params[i].default_val;
561       break;
562     case PARAM_TIME:
563       *((time_t *) params[i].val_adr) = (time_t) 0;
564       break;
565     case PARAM_HTMLTAG:
566       for(x = 0; x < html_link_tags_num(); x++)
567         for(j = 0; html_link_tags[x].attribs[j].attrib; j++)
568           html_link_tags[x].attribs[j].stat &= ~LINK_DISABLED;
569       break;
570     case PARAM_TWO_QSTR:
571       *((char **) params[i].val_adr) = (char *) params[i].default_val;
572       *((char **) params[i].mval_adr) = (char *) params[i].mdefault_val;
573       break;
574     case PARAM_DOUBLE:
575       *((double *) params[i].val_adr) = *(double *) params[i].default_val;
576       break;
577     case PARAM_LFNAME:
578       cfg.lfnames = NULL;
579       break;
580     case PARAM_RE:
581 #ifdef HAVE_REGEX
582       *((dllist **) params[i].val_adr) = NULL;
583 #endif
584       break;
585     case PARAM_USTRAT:
586       *((strategie *) params[i].val_adr) = (strategie) params[i].default_val;
587       break;
588     case PARAM_SSLVER:
589       *((long *) params[i].val_adr) = (long) params[i].default_val;
590       break;
591     case PARAM_HTTPHDR:
592       *((dllist **) params[i].val_adr) = NULL;
593       break;
594     case PARAM_DEBUGL:
595       *((long *) params[i].val_adr) = (long) params[i].default_val;
596       break;
597     case PARAM_REQUEST:
598       *((dllist **) params[i].val_adr) = NULL;
599       break;
600     case PARAM_TRANSPARENT:
601       *((http_proxy **) params[i].val_adr) = NULL;
602       break;
603     case PARAM_PROXY:
604       *((dllist **) params[i].val_adr) = NULL;
605       break;
606     case PARAM_FUNC:
607       break;
608     case PARAM_JSTRANS:
609 #ifdef HAVE_REGEX
610       cfg.js_transform = NULL;
611 #endif
612       break;
613     case PARAM_NUMLIST:
614       *((dllist **) params[i].val_adr) = (dllist *) params[i].default_val;
615       if(params[i].mval_adr)
616         *((bool_t *) params[i].mval_adr) =
617           (bool_t) (long) params[i].mdefault_val;
618       break;
619     case PARAM_FTPHS:
620       *((dllist **) params[i].val_adr) = (dllist *) params[i].default_val;
621       break;
622     case PARAM_TAGPAT:
623       *((dllist **) params[i].val_adr) = (dllist *) params[i].default_val;
624       break;
625     }
626   }
627 }
628 
cfg_get_num_params(cfg_param_t * cpar)629 int cfg_get_num_params(cfg_param_t * cpar)
630 {
631   long num;
632 
633   static const struct
634   {
635     par_type_t type;
636     int num_params;
637   } tab[] =
638   {
639     {PARAM_NUM, 1},
640     {PARAM_PBOOL, 0},
641     {PARAM_NBOOL, 0},
642     {PARAM_STR, 1},
643     {PARAM_PASS, 1},
644     {PARAM_STRLIST, 1},
645     {PARAM_CONN, 1},
646     {PARAM_AUTHSCH, 1},
647     {PARAM_MODE, 1},
648     {PARAM_PATH, 1},
649     {PARAM_TIME, 1},
650     {PARAM_HTMLTAG, 1},
651     {PARAM_TWO_QSTR, 2},
652     {PARAM_DOUBLE, 1},
653     {PARAM_LFNAME, 3},
654     {PARAM_RE, 1},
655     {PARAM_USTRAT, 1},
656     {PARAM_SSLVER, 1},
657     {PARAM_HTTPHDR, 1},
658     {PARAM_DEBUGL, 1},
659     {PARAM_REQUEST, 1},
660     {PARAM_PROXY, 1},
661     {PARAM_TRANSPARENT, 1},
662     {PARAM_FUNC, 0},
663     {PARAM_JSTRANS, 4},
664     {PARAM_NUMLIST, 1},
665     {PARAM_FTPHS, 2},
666     {PARAM_TAGPAT, 3},
667     {PARAM_PORT_RANGE, 1}
668   };
669 
670   num = tab[cpar->type].num_params;
671 
672   if(cpar->type == PARAM_FUNC)
673     num = (long) cpar->default_val;
674 
675   return num;
676 }
677 
cfg_get_option_string(cfg_param_t * param,int type)678 static char *cfg_get_option_string(cfg_param_t * param, int type)
679 {
680   switch (type)
681   {
682   case MOPT_OPT_SHORT:
683     return param->short_cmd;
684   case MOPT_OPT_LONG:
685     return param->long_cmd;
686   case MOPT_OPT_COMPAT:
687     return param->long_cmd;
688   default:
689     return "";
690   }
691 }
692 
cfg_setup_cmdln(int argc,char ** argv)693 void cfg_setup_cmdln(int argc, char **argv)
694 {
695   int nr = 0;
696   double dnr = 0.0;
697   char *p = NULL;
698   char **pl = NULL;
699   mopt_t mopt;
700   cfg_param_t *cpar;
701   int moptrv;
702 
703   mopt_init(&mopt, NUM_ELEM(params), params, argc, argv);
704 
705   for(;;)
706   {
707     moptrv = mopt_get_next_param(&mopt, &cpar);
708 
709     if(moptrv == MOPT_END)
710       break;
711 
712     if(moptrv == MOPT_ERR)
713     {
714       xprintf(0, gettext("Error parsing commandline\n"));
715       usage_short();
716       break;
717     }
718 
719     if(moptrv == MOPT_MISSINGP)
720     {
721       xprintf(0,
722         gettext("Not enough number of parameters for \"-%s\" option\n"),
723         cfg_get_option_string(cpar, mopt.option_type));
724       usage_short();
725       break;
726     }
727 
728     if(moptrv == MOPT_UNKNOWN)
729     {
730       xprintf(0, gettext("Unknown option %s\n"), argv[mopt.current]);
731       usage_short();
732       break;
733     }
734 
735     if(moptrv == MOPT_BAD)
736     {
737       xprintf(0, gettext("Wrong format of option %s\n"), argv[mopt.current]);
738       usage_short();
739       break;
740     }
741 
742     if(moptrv == MOPT_OK)
743     {
744       if(cpar->type & PARAM_UNSUPPORTED)
745       {
746         xprintf(0,
747           gettext
748           ("WARNING: option \"-%s\" not supported in current configuration!\n"),
749           cfg_get_option_string(cpar, mopt.option_type));
750         continue;
751       }
752 
753       if(cpar->type & PARAM_FOREIGN)
754         continue;
755 
756       switch (cpar->type)
757       {
758       case PARAM_NUM:
759         nr = _atoi(mopt.args[0]);
760         if(errno == ERANGE)
761         {
762           xprintf(0,
763             gettext("Please specify number with parameter \"-%s\"\n"),
764             cfg_get_option_string(cpar, mopt.option_type));
765           usage_short();
766         }
767         *((int *) cpar->val_adr) = nr;
768         break;
769       case PARAM_PBOOL:
770         *((bool_t *) cpar->val_adr) = TRUE;
771         break;
772       case PARAM_NBOOL:
773         *((bool_t *) cpar->val_adr) = FALSE;
774         break;
775       case PARAM_PORT_RANGE:
776         if(sscanf(mopt.args[0], "%ld:%ld",
777             (long *) cpar->val_adr,
778             (long *) cpar->mval_adr) != 2
779           || *((long *) cpar->val_adr) <= 1023 ||
780           *((long *) cpar->mval_adr) > 65535 ||
781           *((long *) cpar->val_adr) >= *((long *) cpar->mval_adr))
782         {
783           xprintf(0, gettext("Invalid port range \"%s\"\n"), mopt.args[0]);
784           usage_short();
785         }
786         break;
787       case PARAM_PASS:
788       case PARAM_STR:
789         cfg_set_to_default(cpar);
790         if(mopt.args[0][0])
791           p = tl_strdup(mopt.args[0]);
792         else
793           p = NULL;
794         *((char **) cpar->val_adr) = p;
795         if(cpar->type == PARAM_PASS)
796         {
797           if(mopt.args[0][0])
798           {
799             memset(mopt.args[0], ' ', strlen(mopt.args[0]));
800             strcpy(mopt.args[0], "*");
801           }
802         }
803         break;
804       case PARAM_PATH:
805         cfg_set_to_default(cpar);
806         if(mopt.args[0][0])
807         {
808 #ifdef __CYGWIN__
809           p = cvt_win32_to_unix_path(mopt.args[0]);
810 #else
811           p = get_abs_file_path_oss(mopt.args[0]);
812 #endif
813         }
814         *((char **) cpar->val_adr) = p;
815         break;
816       case PARAM_STRLIST:
817         cfg_set_to_default(cpar);
818         pl = tl_str_split(mopt.args[0], ",");
819         if(cpar->mval_adr)
820           *((bool_t *) cpar->mval_adr) = (bool_t) (long) cpar->mdefault_val;
821         *((char ***) cpar->val_adr) = pl;
822         break;
823       case PARAM_CONN:
824         cfg_set_to_default(cpar);
825         if(mopt.args[0][0])
826         {
827           p = strchr(mopt.args[0], ':');
828           if(p)
829           {
830             nr = _atoi(p + 1);
831             if(errno == ERANGE)
832             {
833               struct servent *se;
834 
835               if((se = getservbyname(p + 1, "tcp")))
836               {
837                 nr = ntohs(se->s_port);
838               }
839               else
840               {
841                 xprintf(0, gettext("Unknown port \"%s\"\n"), p + 1);
842               }
843             }
844             if(cpar->mval_adr)
845               *((int *) cpar->mval_adr) = (int) nr;
846           }
847         }
848         else
849           p = NULL;
850 
851         *((char **) cpar->val_adr) =
852           p ? tl_strndup(mopt.args[0],
853           p - mopt.args[0]) : tl_strdup(mopt.args[0]);
854         break;
855       case PARAM_AUTHSCH:
856         nr = authinfo_get_type(mopt.args[0]);
857         if(nr == HTTP_AUTH_NONE)
858         {
859           xprintf(0, gettext("Bad auth scheme \"%s\"\n"), mopt.args[0]);
860           usage_short();
861         }
862         else
863           *((int *) cpar->val_adr) = nr;
864         break;
865       case PARAM_MODE:
866         cfg.mode = mode_get_by_str(mopt.args[0]);
867         if(cfg.mode == MODE_UNKNOWN)
868         {
869           xprintf(0, gettext("Unknow operation mode \"%s\"\n"), mopt.args[0]);
870           usage_short();
871         }
872         break;
873       case PARAM_TIME:
874         *((time_t *) cpar->val_adr) = time_scn_cmd(mopt.args[0]);
875         break;
876       case PARAM_HTMLTAG:
877         htmltag_set_disabled(mopt.args[0], (long) cpar->default_val);
878         break;
879       case PARAM_TWO_QSTR:
880         cfg_set_to_default(cpar);
881         p = tl_strdup(mopt.args[0]);
882         *((char **) cpar->val_adr) = p;
883 
884         p = tl_strdup(mopt.args[1]);
885         *((char **) cpar->mval_adr) = p;
886         break;
887       case PARAM_DOUBLE:
888         dnr = _atof(mopt.args[0]);
889         if(errno == ERANGE)
890         {
891           xprintf(0,
892             gettext
893             ("Please specify floating number with parameter \"-%s\"\n"),
894             cfg_get_option_string(cpar, mopt.option_type));
895           usage_short();
896         }
897         *((double *) cpar->val_adr) = dnr;
898         break;
899       case PARAM_LFNAME:
900         {
901           lfname_type t;
902           lfname *lfnm;
903 
904           if(!strcasecmp(mopt.args[0], "F"))
905             t = LFNAME_FNMATCH;
906 #ifdef HAVE_REGEX
907           else if(!strcasecmp(mopt.args[0], "R"))
908             t = LFNAME_REGEX;
909 #endif
910           else
911           {
912             t = LFNAME_UNKNOWN;
913 #ifdef HAVE_REGEX
914 #define __CONDITIONS "F or R"
915 #else
916 #define __CONDITIONS "F"
917 #endif
918             xprintf(0,
919               gettext("Please specify proper condition type for -%s (%s)\n"),
920               cfg_get_option_string(cpar, mopt.option_type), __CONDITIONS);
921 #undef __CONDITIONS
922             usage_short();
923           }
924           lfnm = lfname_new(t, mopt.args[1], mopt.args[2]);
925           if(!lfnm)
926             usage_short();
927 
928           cfg.lfnames = dllist_append(cfg.lfnames, (dllist_t) lfnm);
929         }
930         break;
931       case PARAM_RE:
932 #ifdef HAVE_REGEX
933         {
934           re_entry *ree = NULL;
935 
936           if(!(ree = re_make(mopt.args[0])))
937           {
938             xprintf(0,
939               gettext("Please specify valid RE with parameter \"-%s\"\n"),
940               cfg_get_option_string(cpar, mopt.option_type));
941             usage_short();
942           }
943           *((dllist **) cpar->val_adr) =
944             dllist_append(*((dllist **) cpar->val_adr), (dllist_t) ree);
945         }
946 #endif
947         break;
948       case PARAM_USTRAT:
949         *(strategie *) cpar->val_adr = get_strategie_by_str(mopt.args[0]);
950         if(*(strategie *) cpar->val_adr == SSTRAT_LAST)
951         {
952           xprintf(0, gettext("Unknown URL scheduling strategy - \"%s\"\n"),
953             mopt.args[0]);
954           usage_short();
955         }
956         break;
957       case PARAM_SSLVER:
958         *(int *) cpar->val_adr = get_ssl_version_by_str(mopt.args[0]);
959         if(*(int *) cpar->val_adr == -1)
960         {
961           xprintf(0, gettext("Unknown SSL version - \"%s\"\n"), mopt.args[0]);
962           usage_short();
963         }
964         break;
965       case PARAM_HTTPHDR:
966         {
967           httphdr *hr = httphdr_parse(mopt.args[0]);
968           if(!hr)
969           {
970             xprintf(0, gettext("Invalid additional HTTP header - \"%s\"\n"),
971               mopt.args[0]);
972             usage_short();
973           }
974           *((dllist **) cpar->val_adr) =
975             dllist_append(*((dllist **) cpar->val_adr), (dllist_t) hr);
976         }
977         break;
978       case PARAM_DEBUGL:
979 #ifdef DEBUG
980         {
981           int dl = debug_level_parse(mopt.args[0]);
982           if(dl == -1)
983           {
984             usage_short();
985           }
986           *((int *) cpar->val_adr) = dl;
987         }
988 #endif
989         break;
990       case PARAM_REQUEST:
991         {
992           url_info *ui = url_info_parse(mopt.args[0]);
993           if(!ui)
994           {
995             xprintf(0, gettext("Invalid request specification - \"%s\"\n"),
996               mopt.args[0]);
997             usage_short();
998           }
999           *((dllist **) cpar->val_adr) =
1000             dllist_append(*((dllist **) cpar->val_adr), (dllist_t) ui);
1001         }
1002         break;
1003       case PARAM_TRANSPARENT:
1004         if(mopt.args[0][0])
1005         {
1006           http_proxy *pr = http_proxy_parse(mopt.args[0]);
1007 
1008           if(!pr)
1009             usage_short();
1010           else
1011             *((http_proxy **) cpar->val_adr) = pr;
1012         }
1013         else
1014         {
1015           cfg_set_to_default(cpar);
1016         }
1017         break;
1018       case PARAM_PROXY:
1019         if(mopt.args[0][0])
1020         {
1021           http_proxy *pr = http_proxy_parse(mopt.args[0]);
1022 
1023           if(!pr)
1024             usage_short();
1025           else
1026             *((dllist **) cpar->val_adr) =
1027               dllist_append(*((dllist **) cpar->val_adr), (dllist_t) pr);
1028         }
1029         else
1030         {
1031           cfg_set_to_default(cpar);
1032         }
1033         break;
1034       case PARAM_FUNC:
1035         {
1036           int (*_cfg_func) (char *, char *, char *, char *);
1037 
1038           _cfg_func = cpar->val_adr;
1039 
1040           if(_cfg_func)
1041           {
1042             if(_cfg_func(mopt.args[0], mopt.args[1], mopt.args[2],
1043                 mopt.args[3]))
1044             {
1045               usage_short();
1046             }
1047           }
1048         }
1049         break;
1050       case PARAM_JSTRANS:
1051 #ifdef HAVE_REGEX
1052         {
1053           js_transform_t *jt;
1054 
1055           jt = js_transform_new(mopt.args[0], mopt.args[1], mopt.args[2],
1056           mopt.args[3], (long) cpar->mdefault_val);
1057 
1058           if(!jt)
1059           {
1060             xprintf(0, gettext("Invalid parameters for \"-%s\" option\n"),
1061               cfg_get_option_string(cpar, mopt.option_type));
1062             usage_short();
1063           }
1064           else
1065           {
1066             cfg.js_transform = dllist_append(cfg.js_transform, (dllist_t) jt);
1067           }
1068         }
1069 #endif
1070         break;
1071       case PARAM_NUMLIST:
1072         {
1073           dllist *ptr = tl_numlist_split(mopt.args[0], ",");
1074 
1075           if(!ptr && mopt.args[0][0])
1076           {
1077             xprintf(0,
1078               gettext("Invalid number list \"%s\" for option \"-%s\"\n"),
1079               mopt.args[0], cfg_get_option_string(cpar, mopt.option_type));
1080             usage_short();
1081           }
1082           cfg_set_to_default(cpar);
1083           if(cpar->mval_adr)
1084             *((bool_t *) cpar->mval_adr) = (bool_t) (long) cpar->mdefault_val;
1085           *((dllist **) cpar->val_adr) = ptr;
1086         }
1087         break;
1088       case PARAM_FTPHS:
1089         {
1090           ftp_handshake_info *fhi;
1091           fhi = ftp_handshake_info_parse(mopt.args[0], mopt.args[1]);
1092 
1093           if(!fhi)
1094           {
1095             xprintf(0,
1096               gettext
1097               ("Invalid FTP login handshake string \"%s\" for option \"-%s\"\n"),
1098               mopt.args[1], cfg_get_option_string(cpar, mopt.option_type));
1099             usage_short();
1100           }
1101           *((dllist **) cpar->val_adr) =
1102             dllist_append(*((dllist **) cpar->val_adr), (dllist_t) fhi);
1103         }
1104         break;
1105       case PARAM_TAGPAT:
1106         {
1107           tag_pattern_t *tp;
1108           tp = tag_pattern_new((long) cpar->mdefault_val,
1109             mopt.args[0], mopt.args[1], mopt.args[2]);
1110           if(!tp)
1111             usage_short();
1112           *((dllist **) cpar->val_adr) =
1113             dllist_append(*((dllist **) cpar->val_adr), (dllist_t) tp);
1114         }
1115         break;
1116       }
1117     }
1118 
1119     if(moptrv == MOPT_PARAM)
1120     {
1121       url_info *ui;
1122       ui = url_info_new(mopt.args[0]);
1123       cfg.request = dllist_append(cfg.request, (dllist_t) ui);
1124       cfg.total_cnt++;
1125     }
1126   }
1127   mopt_destroy(&mopt);
1128 }
1129 
cfg_load_fd(bufio * fd)1130 static int cfg_load_fd(bufio * fd)
1131 {
1132   int i;
1133   bool_t found;
1134   int nr;
1135   double dnr;
1136   char *p;
1137   char lnbuf[4096];
1138   char *lns;
1139   pavuk_mode temp_mode;
1140   int rv = 0;
1141 
1142   while(bufio_readln(fd, lnbuf, sizeof(lnbuf)) > 0)
1143   {
1144     strip_nl(lnbuf);
1145     for(lns = lnbuf; *lns && tl_ascii_isspace(*lns); lns++);
1146     if(*lns == '#' || !*lns)
1147       continue;
1148 
1149     found = FALSE;
1150 
1151     for(i = 0; i < NUM_ELEM(params); i++)
1152     {
1153       if(!params[i].par_entry)
1154         continue;
1155       if(!strncasecmp(lns, params[i].par_entry, strlen(params[i].par_entry)))
1156       {
1157         if(params[i].type & PARAM_UNSUPPORTED)
1158         {
1159           xprintf(0,
1160             gettext
1161             ("WARNING: option \"-%s\" not supported in current configuration!\n"),
1162             params[i].par_entry);
1163           continue;
1164         }
1165 
1166         if(params[i].type & PARAM_FOREIGN)
1167           continue;
1168 
1169         lns += strlen(params[i].par_entry);
1170         for(; *lns && tl_ascii_isspace(*lns); lns++);
1171         for(p = lns + strlen(lns) - 1; p >= lns && tl_ascii_isspace(*p); p--)
1172           *p = '\0';
1173 
1174         if(!*lns)
1175         {
1176           cfg_set_to_default(&(params[i]));
1177           continue;
1178         }
1179 
1180         found = TRUE;
1181         switch (params[i].type)
1182         {
1183         case PARAM_NUM:
1184           nr = _atoi(lns);
1185           if(errno == ERANGE)
1186           {
1187             xprintf(0, gettext("Please specify number \"%s\"\n"),
1188               params[i].par_entry);
1189             rv = 1;
1190           }
1191           else
1192             *((int *) params[i].val_adr) = nr;
1193           break;
1194         case PARAM_PBOOL:
1195         case PARAM_NBOOL:
1196           if(!strcasecmp(lns, "false"))
1197           {
1198             *((bool_t *) params[i].val_adr) = FALSE;
1199           }
1200           else if(!strcasecmp(lns, "true"))
1201           {
1202             *((bool_t *) params[i].val_adr) = TRUE;
1203           }
1204           else
1205           {
1206             xprintf(0,
1207               gettext("Only \"true\" & \"false\" is allowed : \"%s\"\n"),
1208               lns);
1209             rv = 1;
1210           }
1211           break;
1212         case PARAM_PORT_RANGE:
1213           if(sscanf(lns, "%ld:%ld",
1214               (long *) params[i].val_adr,
1215               (long *) params[i].mval_adr) != 2
1216             || *((long *) params[i].val_adr) <= 1023 ||
1217             *((long *) params[i].mval_adr) > 65535 ||
1218             *((long *) params[i].val_adr) >= *((long *) params[i].mval_adr))
1219           {
1220             xprintf(0, gettext("Invalid port range \"%s\"\n"), lns);
1221             rv = 1;
1222           }
1223           break;
1224         case PARAM_STR:
1225         case PARAM_PASS:
1226           cfg_set_to_default(&params[i]);
1227           *((char **) params[i].val_adr) = *lns ? tl_strdup(lns) : NULL;
1228           break;
1229         case PARAM_PATH:
1230           cfg_set_to_default(&params[i]);
1231 #ifdef __CYGWIN__
1232           *((char **) params[i].val_adr) =
1233             *lns ? cvt_win32_to_unix_path(lns) : NULL;
1234 #else
1235           *((char **) params[i].val_adr) =
1236             *lns ? get_abs_file_path_oss(lns) : NULL;
1237 #endif
1238           break;
1239         case PARAM_STRLIST:
1240           cfg_set_to_default(&params[i]);
1241           if(params[i].mval_adr)
1242             *((bool_t *) params[i].mval_adr) =
1243               (bool_t) (long) params[i].mdefault_val;
1244           if(*lns)
1245             *((char ***) params[i].val_adr) = tl_str_split(lns, ",");
1246           break;
1247         case PARAM_CONN:
1248           cfg_set_to_default(&params[i]);
1249           p = strchr(lns, ':');
1250           if(p)
1251           {
1252             nr = _atoi(p + 1);
1253             if(errno == ERANGE)
1254             {
1255               struct servent *se;
1256 
1257               if((se = getservbyname(p + 1, "tcp")))
1258               {
1259                 nr = ntohs(se->s_port);
1260               }
1261               else
1262               {
1263                 xprintf(0, gettext("Unknown port \"%s\"\n"), p + 1);
1264                 rv = 1;
1265               }
1266             }
1267             if(params[i].mval_adr)
1268               *((int *) params[i].mval_adr) = (int) nr;
1269           }
1270           *((char **) params[i].val_adr) =
1271             p ? tl_strndup(lns, p - lns) : tl_strdup(lns);
1272           break;
1273         case PARAM_AUTHSCH:
1274           nr = authinfo_get_type(lns);
1275           if(nr == HTTP_AUTH_NONE)
1276           {
1277             xprintf(0, gettext("Bad auth scheme \"%s\"\n"), lns);
1278             rv = 1;
1279           }
1280           else
1281             *((int *) params[i].val_adr) = nr;
1282           break;
1283         case PARAM_MODE:
1284           temp_mode = mode_get_by_str(lns);
1285           if(temp_mode == MODE_UNKNOWN)
1286           {
1287             xprintf(0, gettext("Unknow operation mode \"%s\"\n"), lns);
1288             rv = 1;
1289           }
1290           else
1291             *((pavuk_mode *) params[i].val_adr) = temp_mode;
1292           break;
1293         case PARAM_TIME:
1294           {
1295             time_t ttm = time_scn_cmd(lns);
1296             if(!params[i].val_adr)
1297             {
1298               xprintf(0, gettext("Bad time parameter \"%s\"\n"), lns);
1299               rv = 1;
1300             }
1301             else
1302               *(time_t *) params[i].val_adr = ttm;
1303           }
1304           break;
1305         case PARAM_HTMLTAG:
1306           htmltag_set_disabled(lns, (long) params[i].default_val);
1307           break;
1308         case PARAM_TWO_QSTR:
1309           cfg_set_to_default(&params[i]);
1310           if(lns && *lns)
1311           {
1312             char *xp = tl_strdup(lns);
1313 
1314             *(char **) params[i].val_adr = tl_strdup(get_1qstr(xp));
1315             *(char **) params[i].mval_adr = tl_strdup(get_1qstr(NULL));
1316 
1317             _free(xp);
1318           }
1319           else
1320           {
1321             *(char **) params[i].val_adr = NULL;
1322             *(char **) params[i].mval_adr = NULL;
1323           }
1324           break;
1325         case PARAM_DOUBLE:
1326           dnr = _atof(lns);
1327           if(errno == ERANGE)
1328           {
1329             xprintf(0, gettext("Please specify floating number \"%s\"\n"),
1330               params[i].par_entry);
1331             rv = 1;
1332           }
1333           else
1334             *(double *) params[i].val_adr = dnr;
1335           break;
1336         case PARAM_LFNAME:
1337           {
1338             char *ps1 = tl_strdup(get_1qstr(lns));
1339             char *ps2 = tl_strdup(get_1qstr(NULL));
1340             char *ps3 = tl_strdup(get_1qstr(NULL));
1341             lfname_type t;
1342             lfname *lfnm;
1343 
1344             if(!ps1 || !ps2 || !ps3)
1345             {
1346               t = LFNAME_UNKNOWN;
1347               xprintf(0, gettext("Please specify proper arguments for %s\n"),
1348                 params[i].par_entry);
1349               rv = 1;
1350             }
1351             else if(!strcasecmp(ps1, "F"))
1352               t = LFNAME_FNMATCH;
1353 #ifdef HAVE_REGEX
1354             else if(!strcasecmp(ps1, "R"))
1355               t = LFNAME_REGEX;
1356 #endif
1357             else
1358             {
1359               t = LFNAME_UNKNOWN;
1360               xprintf(0,
1361                 gettext("Please specify proper condition type for %s (%s)\n"),
1362                 params[i].par_entry,
1363 #ifdef HAVE_REGEX
1364                 "F or R"
1365 #else
1366                 "F"
1367 #endif
1368                 );
1369               rv = 1;
1370             }
1371             if(t != LFNAME_UNKNOWN)
1372             {
1373               lfnm = lfname_new(t, ps2, ps3);
1374               if(lfnm)
1375                 cfg.lfnames = dllist_append(cfg.lfnames, (dllist_t) lfnm);
1376               else
1377                 rv = 1;
1378             }
1379             _free(ps1);
1380             _free(ps2);
1381             _free(ps3);
1382           }
1383           break;
1384         case PARAM_RE:
1385 #ifdef HAVE_REGEX
1386           {
1387             re_entry *ree;
1388             if(!(ree = re_make(lns)))
1389             {
1390               xprintf(0, gettext("Please specify valid RE \"%s\"\n"),
1391                 params[i].par_entry);
1392               rv = 1;
1393             }
1394             else
1395               *(dllist **) params[i].val_adr =
1396                 dllist_append(*((dllist **) params[i].val_adr), (dllist_t) ree);
1397           }
1398 #endif
1399           break;
1400         case PARAM_USTRAT:
1401           {
1402             strategie strtg = get_strategie_by_str(lns);
1403             if(strtg == SSTRAT_LAST)
1404             {
1405               xprintf(0,
1406                 gettext("Unknown URL scheduling strategy - \"%s\"\n"), lns);
1407               rv = 1;
1408             }
1409             else
1410               *(strategie *) params[i].val_adr = strtg;
1411           }
1412           break;
1413         case PARAM_SSLVER:
1414           {
1415             int sslv = get_ssl_version_by_str(lns);
1416             if(sslv == -1)
1417             {
1418               xprintf(0, gettext("Unknown SSL version - \"%s\"\n"), lns);
1419               rv = 1;
1420             }
1421             else
1422               *(int *) params[i].val_adr = sslv;
1423           }
1424           break;
1425         case PARAM_HTTPHDR:
1426           {
1427             httphdr *hr = httphdr_parse(lns);
1428             if(!hr)
1429             {
1430               xprintf(0, gettext("Invalid additional HTTP header - \"%s\"\n"),
1431                 lns);
1432               rv = 1;
1433             }
1434             else
1435               *((dllist **) params[i].val_adr) =
1436                 dllist_append(*((dllist **) params[i].val_adr), (dllist_t) hr);
1437           }
1438           break;
1439         case PARAM_DEBUGL:
1440 #ifdef DEBUG
1441           {
1442             int dl = debug_level_parse(lns);
1443             if(dl != -1)
1444               *((int *) params[i].val_adr) = dl;
1445             else
1446               rv = 1;
1447           }
1448 #endif
1449           break;
1450         case PARAM_REQUEST:
1451           {
1452             url_info *ui = url_info_parse(lns);
1453             if(!ui)
1454             {
1455               xprintf(0, gettext("Invalid request specification - \"%s\"\n"),
1456                 lns);
1457               rv = 1;
1458             }
1459             else
1460               *((dllist **) params[i].val_adr) =
1461                 dllist_append(*((dllist **) params[i].val_adr), (dllist_t) ui);
1462           }
1463           break;
1464         case PARAM_TRANSPARENT:
1465           if(lns)
1466           {
1467             http_proxy *pr = http_proxy_parse(lns);
1468             if(pr)
1469               *((http_proxy **) params[i].val_adr) = pr;
1470             else
1471               rv = 1;
1472           }
1473           break;
1474         case PARAM_PROXY:
1475           if(lns)
1476           {
1477             http_proxy *pr = http_proxy_parse(lns);
1478 
1479             if(pr)
1480               *((dllist **) params[i].val_adr) =
1481                 dllist_append(*((dllist **) params[i].val_adr), (dllist_t) pr);
1482             else
1483               rv = 1;
1484           }
1485           break;
1486         case PARAM_FUNC:
1487           break;
1488         case PARAM_JSTRANS:
1489 #ifdef HAVE_REGEX
1490           {
1491             char *ps1 = tl_strdup(get_1qstr(lns));
1492             char *ps2 = tl_strdup(get_1qstr(NULL));
1493             char *ps3 = tl_strdup(get_1qstr(NULL));
1494             char *ps4 = tl_strdup(get_1qstr(NULL));
1495 
1496             js_transform_t *jt;
1497 
1498             jt = js_transform_new(ps1, ps2, ps3, ps4,
1499             (long) params[i].mdefault_val);
1500 
1501             if(!jt)
1502             {
1503               xprintf(0,
1504                 gettext("Invalid js_transform specification - \"%s\"\n"),
1505                 lns);
1506               rv = 1;
1507             }
1508             else
1509               cfg.js_transform = dllist_append(cfg.js_transform, (dllist_t) jt);
1510             _free(ps1);
1511             _free(ps2);
1512             _free(ps3);
1513             _free(ps4);
1514           }
1515 #endif
1516           break;
1517         case PARAM_NUMLIST:
1518           cfg_set_to_default(&params[i]);
1519           if(params[i].mval_adr)
1520             *((bool_t *) params[i].mval_adr) =
1521               (bool_t) (long) params[i].mdefault_val;
1522           if(*lns)
1523             *((dllist **) params[i].val_adr) = tl_numlist_split(lns, ",");
1524           if(*lns && !*((dllist **) params[i].val_adr))
1525           {
1526             xprintf(0,
1527               gettext("Invalid number list specification - \"%s\"\n"), lns);
1528             rv = 1;
1529           }
1530           break;
1531         case PARAM_FTPHS:
1532           {
1533             char *ps1 = tl_strdup(get_1qstr(lns));
1534             char *ps2 = tl_strdup(get_1qstr(NULL));
1535             ftp_handshake_info *fhi = NULL;
1536 
1537             if(ps1 && ps2)
1538               fhi = ftp_handshake_info_parse(ps1, ps2);
1539 
1540             if(!fhi)
1541             {
1542               xprintf(0,
1543                 gettext("Invalid FTP login handshake string \"%s\".\n"), lns);
1544               rv = 1;
1545             }
1546             *((dllist **) params[i].val_adr) =
1547               dllist_append(*((dllist **) params[i].val_adr), (dllist_t) fhi);
1548             _free(ps1);
1549             _free(ps2);
1550           }
1551           break;
1552         case PARAM_TAGPAT:
1553           {
1554             char *ps1 = tl_strdup(get_1qstr(lns));
1555             char *ps2 = tl_strdup(get_1qstr(NULL));
1556             char *ps3 = tl_strdup(get_1qstr(NULL));
1557             tag_pattern_t *tp = NULL;
1558 
1559             if(ps1 && ps2 && ps3)
1560 	    {
1561               tp = tag_pattern_new((long) params[i].mdefault_val,
1562 	      ps1, ps2, ps3);
1563             }
1564             if(!tp)
1565               rv = 1;
1566             *((dllist **) params[i].val_adr) =
1567               dllist_append(*((dllist **) params[i].val_adr), (dllist_t) tp);
1568             _free(ps1);
1569             _free(ps2);
1570             _free(ps3);
1571           }
1572           break;
1573         }
1574       }
1575     }
1576     if(!found && !strncasecmp(lns, "URL:", 4))
1577     {
1578       url_info *ui;
1579 
1580       lns += 4;
1581       for(; *lns && tl_ascii_isspace(*lns); lns++);
1582       for(p = lns + strlen(lns); *p && tl_ascii_isspace(*p); p--)
1583         *p = '\0';
1584       if(!*lns)
1585         continue;
1586 
1587       ui = url_info_new(lns);
1588       cfg.request = dllist_append(cfg.request, (dllist_t) ui);
1589       cfg.total_cnt++;
1590     }
1591     else if(!found)
1592     {
1593       xprintf(0, gettext("Unable to parse \"%s\"\n"), lns);
1594       rv = 1;
1595     }
1596   }
1597 
1598   return rv;
1599 }
1600 
cfg_load(const char * filename)1601 int cfg_load(const char *filename)
1602 {
1603   int rv;
1604   bufio *fd;
1605 
1606   if(!(fd = bufio_open(filename, O_BINARY | O_RDONLY)))
1607   {
1608     xperror(filename);
1609     return -1;
1610   }
1611 
1612   rv = cfg_load_fd(fd);
1613 
1614   bufio_close(fd);
1615 
1616   return rv;
1617 }
1618 
cfg_load_scenario(const char * filename)1619 static int cfg_load_scenario(const char *filename)
1620 {
1621   char *fn;
1622   int rv;
1623 
1624   _free(cfg.scenario);
1625 
1626   if(strchr(filename, '/') || !cfg.scndir)
1627     fn = tl_strdup(filename);
1628   else
1629     fn = tl_str_concat(tl_strdup(cfg.scndir), "/", filename, NULL);
1630 
1631   if((rv = cfg_load(fn)))
1632   {
1633     xprintf(0, gettext("ERROR: Scenario loading failed (%s)\n"), fn);
1634     exit(PAVUK_EXIT_CFG_ERR);
1635   }
1636 
1637   cfg.scenario = fn;
1638 
1639   return rv;
1640 }
1641 
cfg_load_setup(void)1642 void cfg_load_setup(void)
1643 {
1644   char pom[PATH_MAX];
1645   char *p;
1646 
1647 #ifdef DEFAULTRC
1648   if(!access(DEFAULTRC, R_OK))
1649     cfg_load(DEFAULTRC);
1650 #endif
1651   p = getenv("PAVUKRC_FILE");
1652   if(!p)
1653   {
1654     snprintf(pom, sizeof(pom), "%s/%s", cfg.path_to_home, ".pavukrc");
1655     p = pom;
1656   }
1657   if(!access(p, R_OK))
1658     cfg_load(p);
1659 }
1660 
cfg_dump_fd(int fd)1661 static int cfg_dump_fd(int fd)
1662 {
1663   int i, j;
1664   char pom[8192];
1665   char pom2[20];
1666   char **pl;
1667 
1668   if(cfg.request)
1669   {
1670     dllist *dptr;
1671 
1672     for(dptr = cfg.request; dptr; dptr = dptr->next)
1673     {
1674       url_info *ui = (url_info *) dptr->data;
1675 
1676       if(ui->type == URLI_NORMAL && !ui->localname)
1677       {
1678         write(fd, "URL: ", 5);
1679         write(fd, ui->urlstr, strlen(ui->urlstr));
1680         write(fd, "\n", 1);
1681       }
1682     }
1683   }
1684 
1685   for(i = 0; i < NUM_ELEM(params); i++)
1686   {
1687     if(params[i].type & PARAM_UNSUPPORTED)
1688       continue;
1689     if(params[i].type & PARAM_FOREIGN)
1690       continue;
1691     if(!params[i].par_entry)
1692       continue;
1693 
1694     switch (params[i].type)
1695     {
1696     case PARAM_NUM:
1697       snprintf(pom, sizeof(pom), "%s %ld\n", params[i].par_entry,
1698         *((long *) params[i].val_adr));
1699       write(fd, pom, strlen(pom));
1700       break;
1701     case PARAM_NBOOL:
1702     case PARAM_PBOOL:
1703       if(*((bool_t *) params[i].val_adr))
1704         snprintf(pom, sizeof(pom), "%s true\n", params[i].par_entry);
1705       else
1706         snprintf(pom, sizeof(pom), "%s false\n", params[i].par_entry);
1707       write(fd, pom, strlen(pom));
1708       break;
1709     case PARAM_PORT_RANGE:
1710       if(*((long *) params[i].val_adr) >= 0)
1711       {
1712         snprintf(pom, sizeof(pom), "%s %ld:%ld\n", params[i].par_entry,
1713           *((long *) params[i].val_adr), *((long *) params[i].mval_adr));
1714         write(fd, pom, strlen(pom));
1715       }
1716       break;
1717     case PARAM_PATH:
1718     case PARAM_STR:
1719     case PARAM_PASS:
1720       if(*((char **) params[i].val_adr))
1721       {
1722         snprintf(pom, sizeof(pom), "%s %s\n", params[i].par_entry,
1723           *((char **) params[i].val_adr));
1724         write(fd, pom, strlen(pom));
1725       }
1726       break;
1727     case PARAM_STRLIST:
1728       if(!params[i].mval_adr || (params[i].mval_adr &&
1729           (*((bool_t *) params[i].mval_adr) ==
1730             (bool_t) (long) params[i].mdefault_val)))
1731       {
1732         pl = *((char ***) params[i].val_adr);
1733         if(pl && pl[0])
1734         {
1735           snprintf(pom, sizeof(pom), "%s %s", params[i].par_entry, pl[0]);
1736           write(fd, pom, strlen(pom));
1737 
1738           j = 1;
1739           while(pl[j])
1740           {
1741             write(fd, ",", 1);
1742             write(fd, pl[j], strlen(pl[j]));
1743             j++;
1744           }
1745           write(fd, "\n", 1);
1746         }
1747       }
1748       break;
1749     case PARAM_CONN:
1750       if(*((char **) params[i].val_adr))
1751       {
1752         snprintf(pom, sizeof(pom), "%s %s:%d\n", params[i].par_entry,
1753           *((char **) params[i].val_adr), *((int *) params[i].mval_adr));
1754         write(fd, pom, strlen(pom));
1755       }
1756       break;
1757     case PARAM_AUTHSCH:
1758       snprintf(pom, sizeof(pom), "%s %s\n", params[i].par_entry,
1759         http_auths[*((long *) params[i].val_adr)].name);
1760       write(fd, pom, strlen(pom));
1761       break;
1762     case PARAM_MODE:
1763       snprintf(pom, sizeof(pom), "%s %s\n", params[i].par_entry,
1764         mode_get_str(cfg.mode));
1765       write(fd, pom, strlen(pom));
1766       break;
1767     case PARAM_TIME:
1768       if(*((time_t *) params[i].val_adr))
1769       {
1770         LOCK_TIME;
1771         strftime(pom2, sizeof(pom2), "%Y.%m.%d.%H:%M",
1772           localtime((time_t *) params[i].val_adr));
1773         UNLOCK_TIME;
1774         snprintf(pom, sizeof(pom), "%s %s\n", params[i].par_entry, pom2);
1775         write(fd, pom, strlen(pom));
1776       }
1777       break;
1778     case PARAM_HTMLTAG:
1779       {
1780         int x, y;
1781         bool_t first = TRUE;
1782 
1783         snprintf(pom, sizeof(pom), "%s ", params[i].par_entry);
1784         for(x = 0; x < html_link_tags_num(); x++)
1785         {
1786           for(y = 0; html_link_tags[x].attribs[y].attrib; y++)
1787           {
1788             if(!(html_link_tags[x].attribs[y].stat & LINK_DISABLED) ==
1789               !(params[i].default_val))
1790             {
1791               if(!first)
1792               {
1793                 strncat(pom, ";", sizeof(pom) - strlen(pom));
1794                 pom[sizeof(pom) - 1] = '\0';
1795               }
1796               strncat(pom, html_link_tags[x].tag, sizeof(pom) - strlen(pom));
1797               pom[sizeof(pom) - 1] = '\0';
1798               strncat(pom, ",", sizeof(pom) - strlen(pom));
1799               pom[sizeof(pom) - 1] = '\0';
1800               strncat(pom, html_link_tags[x].attribs[y].attrib,
1801                 sizeof(pom) - strlen(pom));
1802               pom[sizeof(pom) - 1] = '\0';
1803               first = FALSE;
1804             }
1805           }
1806         }
1807         strncat(pom, "\n", sizeof(pom) - strlen(pom));
1808         pom[sizeof(pom) - 1] = '\0';
1809         if(!first)
1810           write(fd, pom, strlen(pom));
1811       }
1812       break;
1813     case PARAM_TWO_QSTR:
1814       if(*((char **) params[i].val_adr))
1815       {
1816         char *p1, *p2;
1817         p1 = escape_str(*((char **) params[i].val_adr), "\\\"");
1818         p2 = escape_str(*((char **) params[i].mval_adr), "\\\"");
1819         snprintf(pom, sizeof(pom), "%s \"%s\" \"%s\"\n", params[i].par_entry,
1820           p1, p2);
1821         _free(p1);
1822         _free(p2);
1823         write(fd, pom, strlen(pom));
1824       }
1825       break;
1826     case PARAM_DOUBLE:
1827       snprintf(pom, sizeof(pom), "%s %.3f\n", params[i].par_entry,
1828         *((double *) params[i].val_adr));
1829       write(fd, pom, strlen(pom));
1830       break;
1831     case PARAM_LFNAME:
1832       {
1833         dllist *pdl = cfg.lfnames;
1834         while(pdl)
1835         {
1836           lfname *lfnm = (lfname *) pdl->data;
1837           char *p1, *p2;
1838 
1839           p1 = escape_str(lfnm->matchstr, "\\\"");
1840           p2 = escape_str(lfnm->transstr, "\\\"");
1841 
1842           snprintf(pom, sizeof(pom), "%s \"%s\" \"%s\" \"%s\"\n",
1843             params[i].par_entry, (lfnm->type == LFNAME_FNMATCH) ? "F" : "R",
1844             p1, p2);
1845           _free(p1);
1846           _free(p2);
1847           write(fd, pom, strlen(pom));
1848 
1849           pdl = pdl->next;
1850         }
1851       }
1852       break;
1853     case PARAM_RE:
1854 #ifdef HAVE_REGEX
1855       {
1856         dllist *ptr = *((dllist **) params[i].val_adr);
1857         while(ptr)
1858         {
1859           re_entry *ree = (re_entry *) ptr->data;
1860 
1861           snprintf(pom, sizeof(pom), "%s %s\n", params[i].par_entry,
1862             ree->pattern);
1863           write(fd, pom, strlen(pom));
1864 
1865           ptr = ptr->next;
1866         }
1867       }
1868 #endif
1869       break;
1870     case PARAM_USTRAT:
1871       snprintf(pom, sizeof(pom), "%s %s\n", params[i].par_entry,
1872         get_strategie_str(*(strategie *) params[i].val_adr));
1873       write(fd, pom, strlen(pom));
1874       break;
1875     case PARAM_SSLVER:
1876       snprintf(pom, sizeof(pom), "%s %s\n", params[i].par_entry,
1877         get_ssl_version_str(*(int *) params[i].val_adr));
1878       write(fd, pom, strlen(pom));
1879       break;
1880     case PARAM_HTTPHDR:
1881       {
1882         dllist *ptr = *((dllist **) params[i].val_adr);
1883         while(ptr)
1884         {
1885           httphdr *hr = (httphdr *) ptr->data;
1886 
1887           snprintf(pom, sizeof(pom), "%s %s%s %s\n", params[i].par_entry,
1888             hr->all ? "+" : "", hr->name, hr->val);
1889           write(fd, pom, strlen(pom));
1890 
1891           ptr = ptr->next;
1892         }
1893       }
1894       break;
1895     case PARAM_DEBUGL:
1896 #ifdef DEBUG
1897       {
1898         char strbuf[1024];
1899         debug_level_construct(*((int *) params[i].val_adr), strbuf);
1900         snprintf(pom, sizeof(pom), "%s %s\n", params[i].par_entry, strbuf);
1901         write(fd, pom, strlen(pom));
1902       }
1903 #endif
1904       break;
1905     case PARAM_REQUEST:
1906       {
1907         dllist *ptr = *((dllist **) params[i].val_adr);
1908         while(ptr)
1909         {
1910           url_info *ui = (url_info *) ptr->data;
1911 
1912           if(ui->type != URLI_NORMAL || ui->localname)
1913           {
1914             char *p = url_info_dump(ui);
1915             snprintf(pom, sizeof(pom), "%s %s\n", params[i].par_entry, p);
1916             _free(p);
1917             write(fd, pom, strlen(pom));
1918           }
1919 
1920           ptr = ptr->next;
1921         }
1922       }
1923       break;
1924     case PARAM_TRANSPARENT:
1925       {
1926         http_proxy *pr = *((http_proxy **) params[i].val_adr);
1927         if(pr)
1928         {
1929           snprintf(pom, sizeof(pom), "%s %s:%d\n", params[i].par_entry,
1930             pr->addr, pr->port);
1931           write(fd, pom, strlen(pom));
1932         }
1933       }
1934       break;
1935     case PARAM_PROXY:
1936       {
1937         dllist *ptr = *((dllist **) params[i].val_adr);
1938         while(ptr)
1939         {
1940           http_proxy *pr = (http_proxy *) ptr->data;
1941           snprintf(pom, sizeof(pom), "%s %s:%hu\n", params[i].par_entry,
1942             pr->addr, pr->port);
1943           write(fd, pom, strlen(pom));
1944 
1945           ptr = ptr->next;
1946         }
1947       }
1948       break;
1949     case PARAM_FUNC:
1950       break;
1951     case PARAM_JSTRANS:
1952 #ifdef HAVE_REGEX
1953       {
1954         dllist *ptr;
1955         for(ptr = cfg.js_transform; ptr; ptr = ptr->next)
1956         {
1957           js_transform_t *jt = (js_transform_t *) ptr->data;
1958           char *p[4];
1959 
1960           if(jt->type != (long) params[i].mdefault_val)
1961             continue;
1962 
1963           p[0] = escape_str(jt->re->pattern, "\\\"");
1964           p[1] = escape_str(jt->transform, "\\\"");
1965           p[2] = escape_str(jt->tag, "\\\"");
1966           p[3] = escape_str(jt->attrib, "\\\"");
1967 
1968           snprintf(pom, sizeof(pom), "%s \"%s\" \"%s\" \"%s\" \"%s\"\n",
1969             params[i].par_entry, p[0], p[1], p[2], p[3]);
1970           _free(p[0]);
1971           _free(p[1]);
1972           _free(p[2]);
1973           _free(p[3]);
1974           write(fd, pom, strlen(pom));
1975         }
1976       }
1977 #endif
1978       break;
1979     case PARAM_NUMLIST:
1980       if(!params[i].mval_adr || (params[i].mval_adr &&
1981           (*((bool_t *) params[i].mval_adr) ==
1982             (bool_t) (long) params[i].mdefault_val)))
1983       {
1984         dllist *ptr = *((dllist **) params[i].val_adr);
1985         if(ptr)
1986         {
1987           snprintf(pom, sizeof(pom), "%s %ld", params[i].par_entry,
1988             (long) ptr->data);
1989           write(fd, pom, strlen(pom));
1990 
1991           j = 1;
1992           for(; ptr; ptr = ptr->next)
1993           {
1994             snprintf(pom, sizeof(pom), ",%ld", (long) ptr->data);
1995             write(fd, pom, strlen(pom));
1996           }
1997           write(fd, "\n", 1);
1998         }
1999       }
2000       break;
2001     case PARAM_FTPHS:
2002       {
2003         dllist *ptr;
2004         for(ptr = *((dllist **) params[i].val_adr); ptr; ptr = ptr->next)
2005         {
2006           char *p, *p2;
2007           ftp_handshake_info *fhi = (ftp_handshake_info *)ptr->data;
2008 
2009           p = ftp_handshake_info_data_dump(fhi);
2010           p2 = escape_str(p, "\\\"");
2011           _free(p);
2012           p = p2;
2013           if(*fhi->host)
2014             snprintf(pom, sizeof(pom),
2015               "%s \"%s:%hu\" \"%s\"\n",
2016               params[i].par_entry, fhi->host, fhi->port, p);
2017           else
2018             snprintf(pom, sizeof(pom),
2019               "%s \"\" \"%s\"\n", params[i].par_entry, p);
2020 
2021           _free(p);
2022           write(fd, pom, strlen(pom));
2023         }
2024       }
2025       break;
2026     case PARAM_TAGPAT:
2027       {
2028         dllist *ptr;
2029         for(ptr = *((dllist **) params[i].val_adr); ptr; ptr = ptr->next)
2030         {
2031           char *t, *a, *u;
2032           tag_pattern_t *tp = (tag_pattern_t *) ptr->data;
2033 
2034           t = escape_str(tp->tag, "\\\"");
2035           a = escape_str(tp->attrib, "\\\"");
2036           u = escape_str(tp->urlp, "\\\"");
2037 
2038           snprintf(pom, sizeof(pom),
2039             "%s \"%s\" \"%s\" \"%s\"\n", params[i].par_entry, t, a, u);
2040 
2041           _free(t);
2042           _free(a);
2043           _free(u);
2044 
2045           write(fd, pom, strlen(pom));
2046         }
2047       }
2048       break;
2049     }
2050   }
2051   return 0;
2052 }
2053 
cfg_dump(const char * filename)2054 int cfg_dump(const char *filename)
2055 {
2056   int fd;
2057 
2058   if((fd = open(filename, O_BINARY | O_CREAT | O_WRONLY, 0666)) < 0)
2059   {
2060     xperror(filename);
2061     return -1;
2062   }
2063 
2064   ftruncate(fd, 0);
2065 
2066   cfg_dump_fd(fd);
2067 
2068   close(fd);
2069   return 0;
2070 }
2071 
cfg_load_pref(void)2072 int cfg_load_pref(void)
2073 {
2074   bufio *fd;
2075   char filename[PATH_MAX];
2076 
2077   snprintf(filename, sizeof(filename), "%s/.pavuk_prefs", cfg.path_to_home);
2078 
2079   if(!(fd = bufio_open(filename, O_BINARY | O_RDONLY)))
2080   {
2081     return -1;
2082   }
2083 
2084   cfg_set_all_to_default();
2085 
2086   cfg_load_fd(fd);
2087 
2088   bufio_close(fd);
2089 
2090   return 0;
2091 }
2092 
cfg_dump_pref(void)2093 int cfg_dump_pref(void)
2094 {
2095   int fd;
2096   char filename[PATH_MAX];
2097 
2098   snprintf(filename, sizeof(filename), "%s/.pavuk_prefs", cfg.path_to_home);
2099 
2100   if((fd = open(filename, O_BINARY | O_CREAT | O_WRONLY, 0666)) < 0)
2101   {
2102     xperror(filename);
2103     return -1;
2104   }
2105 
2106   ftruncate(fd, 0);
2107 
2108   cfg_dump_fd(fd);
2109 
2110   close(fd);
2111   return 0;
2112 }
2113 
cfg_dump_cmd(const char * filename)2114 int cfg_dump_cmd(const char *filename)
2115 {
2116   int fd;
2117   int rv;
2118 
2119   if((fd = open(filename, O_BINARY | O_CREAT | O_WRONLY, 0666)) < 0)
2120   {
2121     xperror(filename);
2122     return -1;
2123   }
2124 
2125   rv = cfg_dump_cmd_fd(fd);
2126 
2127   close(fd);
2128 
2129   return rv;
2130 }
2131 
cfg_dump_cmd_fd(int fd)2132 int cfg_dump_cmd_fd(int fd)
2133 {
2134   int i, j;
2135   char pom[8192];
2136   char pom2[20];
2137   char **pl;
2138 
2139   ftruncate(fd, 0);
2140 
2141   write(fd, cfg.prg_path, strlen(cfg.prg_path));
2142 
2143   write(fd, " ", 1);
2144 
2145   if(cfg.request)
2146   {
2147     dllist *dptr;
2148 
2149     for(dptr = cfg.request; dptr; dptr = dptr->next)
2150     {
2151       url_info *ui = (url_info *) dptr->data;
2152 
2153       if(ui->type == URLI_NORMAL && !ui->localname)
2154       {
2155         write(fd, " '", 2);
2156         write(fd, ui->urlstr, strlen(ui->urlstr));
2157         write(fd, "' ", 2);
2158       }
2159     }
2160   }
2161 
2162   for(i = 0; i < NUM_ELEM(params); i++)
2163   {
2164     if(params[i].type & PARAM_UNSUPPORTED)
2165       continue;
2166     if(params[i].type & PARAM_FOREIGN)
2167       continue;
2168     if(!params[i].long_cmd)
2169       continue;
2170 
2171     if(!params[i].par_entry &&
2172       (params[i].type != PARAM_PBOOL) && (params[i].type != PARAM_NBOOL))
2173       continue;
2174 
2175     switch (params[i].type)
2176     {
2177     case PARAM_NUM:
2178       snprintf(pom, sizeof(pom), " -%s=%ld ", params[i].long_cmd,
2179         *((long *) params[i].val_adr));
2180       write(fd, pom, strlen(pom));
2181       break;
2182     case PARAM_NBOOL:
2183       if(!*((bool_t *) params[i].val_adr))
2184       {
2185         write(fd, " -", 2);
2186         write(fd, params[i].long_cmd, strlen(params[i].long_cmd));
2187         write(fd, " ", 1);
2188       }
2189       break;
2190     case PARAM_PBOOL:
2191       if(*((bool_t *) params[i].val_adr))
2192       {
2193         write(fd, " -", 2);
2194         write(fd, params[i].long_cmd, strlen(params[i].long_cmd));
2195         write(fd, " ", 1);
2196       }
2197       break;
2198     case PARAM_PORT_RANGE:
2199       if(*((long *) params[i].val_adr) >= 0)
2200       {
2201         snprintf(pom, sizeof(pom), " -%s=%ld:%ld ", params[i].long_cmd,
2202           *((long *) params[i].val_adr), *((long *) params[i].mval_adr));
2203         write(fd, pom, strlen(pom));
2204       }
2205       break;
2206     case PARAM_PATH:
2207     case PARAM_STR:
2208     case PARAM_PASS:
2209       if(*((char **) params[i].val_adr))
2210       {
2211         snprintf(pom, sizeof(pom), " -%s '%s' ", params[i].long_cmd,
2212           *((char **) params[i].val_adr));
2213         write(fd, pom, strlen(pom));
2214       }
2215       break;
2216     case PARAM_STRLIST:
2217       if(!params[i].mval_adr || (params[i].mval_adr &&
2218           (*((bool_t *) params[i].mval_adr) ==
2219             (bool_t) (long) params[i].mdefault_val)))
2220       {
2221         pl = *((char ***) params[i].val_adr);
2222         if(pl && pl[0])
2223         {
2224           snprintf(pom, sizeof(pom), " -%s '%s", params[i].long_cmd, pl[0]);
2225           write(fd, pom, strlen(pom));
2226 
2227           j = 1;
2228           while(pl[j])
2229           {
2230             write(fd, ",", 1);
2231             write(fd, pl[j], strlen(pl[j]));
2232             j++;
2233           }
2234           write(fd, "' ", 2);
2235         }
2236       }
2237       break;
2238     case PARAM_CONN:
2239       if(*((char **) params[i].val_adr))
2240       {
2241         snprintf(pom, sizeof(pom), "-%s %s:%hu ", params[i].long_cmd,
2242           *((char **) params[i].val_adr), *((int *) params[i].mval_adr));
2243         write(fd, pom, strlen(pom));
2244       }
2245       break;
2246     case PARAM_AUTHSCH:
2247       snprintf(pom, sizeof(pom), " -%s %s ", params[i].long_cmd,
2248         http_auths[*((long *) params[i].val_adr)].name);
2249       write(fd, pom, strlen(pom));
2250       break;
2251     case PARAM_MODE:
2252       snprintf(pom, sizeof(pom), " -%s %s ", params[i].long_cmd,
2253         mode_get_str(cfg.mode));
2254       write(fd, pom, strlen(pom));
2255       break;
2256     case PARAM_TIME:
2257       if(*((time_t *) params[i].val_adr))
2258       {
2259         LOCK_TIME;
2260         strftime(pom2, sizeof(pom2), "%Y.%m.%d.%H:%M",
2261           localtime((time_t *) params[i].val_adr));
2262         UNLOCK_TIME;
2263         snprintf(pom, sizeof(pom), " -%s %s ", params[i].long_cmd, pom2);
2264         write(fd, pom, strlen(pom));
2265       }
2266       break;
2267     case PARAM_HTMLTAG:
2268       {
2269         int x, y;
2270         bool_t first = TRUE;
2271 
2272         snprintf(pom, sizeof(pom), " -%s '", params[i].long_cmd);
2273         for(x = 0; x < html_link_tags_num(); x++)
2274         {
2275           for(y = 0; html_link_tags[x].attribs[y].attrib; y++)
2276           {
2277             if(!(html_link_tags[x].attribs[y].stat & LINK_DISABLED) ==
2278               !(params[i].default_val))
2279             {
2280               if(!first)
2281               {
2282                 strncat(pom, ";", sizeof(pom) - strlen(pom));
2283                 pom[sizeof(pom) - 1] = '\0';
2284               }
2285               strncat(pom, html_link_tags[x].tag, sizeof(pom) - strlen(pom));
2286               pom[sizeof(pom) - 1] = '\0';
2287               strncat(pom, ",", sizeof(pom) - strlen(pom));
2288               pom[sizeof(pom) - 1] = '\0';
2289               strncat(pom, html_link_tags[x].attribs[y].attrib,
2290                 sizeof(pom) - strlen(pom));
2291               pom[sizeof(pom) - 1] = '\0';
2292               first = FALSE;
2293             }
2294           }
2295         }
2296         strncat(pom, "' ", sizeof(pom) - strlen(pom));
2297         pom[sizeof(pom) - 1] = '\0';
2298         if(!first)
2299           write(fd, pom, strlen(pom));
2300       }
2301       break;
2302     case PARAM_TWO_QSTR:
2303       if(*((char **) params[i].val_adr))
2304       {
2305         snprintf(pom, sizeof(pom), " -%s '%s' '%s' ", params[i].long_cmd,
2306           *((char **) params[i].val_adr), *((char **) params[i].mval_adr));
2307         write(fd, pom, strlen(pom));
2308       }
2309       break;
2310     case PARAM_DOUBLE:
2311       snprintf(pom, sizeof(pom), " -%s=%.3f ", params[i].long_cmd,
2312         *((double *) params[i].val_adr));
2313       write(fd, pom, strlen(pom));
2314       break;
2315     case PARAM_LFNAME:
2316       {
2317         dllist *pdl = cfg.lfnames;
2318         while(pdl)
2319         {
2320           lfname *lfnm = (lfname *)pdl->data;
2321 
2322           snprintf(pom, sizeof(pom), " -%s \'%s\' \'%s\' \'%s\' ",
2323             params[i].long_cmd, (lfnm->type == LFNAME_FNMATCH) ? "F" : "R",
2324             lfnm->matchstr, lfnm->transstr);
2325           write(fd, pom, strlen(pom));
2326 
2327           pdl = pdl->next;
2328         }
2329       }
2330       break;
2331     case PARAM_RE:
2332 #ifdef HAVE_REGEX
2333       {
2334         dllist *ptr = *((dllist **) params[i].val_adr);
2335         while(ptr)
2336         {
2337           re_entry *ree = (re_entry *)ptr->data;
2338 
2339           snprintf(pom, sizeof(pom), " -%s \'%s\' ", params[i].long_cmd,
2340             ree->pattern);
2341           write(fd, pom, strlen(pom));
2342 
2343           ptr = ptr->next;
2344         }
2345       }
2346 #endif
2347       break;
2348     case PARAM_USTRAT:
2349       snprintf(pom, sizeof(pom), " -%s=%s ", params[i].long_cmd,
2350         get_strategie_str(*(strategie *) params[i].val_adr));
2351       write(fd, pom, strlen(pom));
2352       break;
2353     case PARAM_SSLVER:
2354       snprintf(pom, sizeof(pom), " -%s=%s ", params[i].long_cmd,
2355         get_ssl_version_str(*(int *) params[i].val_adr));
2356       write(fd, pom, strlen(pom));
2357       break;
2358     case PARAM_HTTPHDR:
2359       {
2360         dllist *ptr = *((dllist **) params[i].val_adr);
2361         while(ptr)
2362         {
2363           httphdr *hr = (httphdr *) ptr->data;
2364 
2365           snprintf(pom, sizeof(pom), " -%s \"%s%s %s\" ", params[i].long_cmd,
2366             hr->all ? "+" : "", hr->name, hr->val);
2367           write(fd, pom, strlen(pom));
2368 
2369           ptr = ptr->next;
2370         }
2371       }
2372       break;
2373     case PARAM_DEBUGL:
2374 #ifdef DEBUG
2375       {
2376         char strbuf[1024];
2377         debug_level_construct(*((int *) params[i].val_adr), strbuf);
2378         snprintf(pom, sizeof(pom), " -%s \'%s\' ", params[i].long_cmd,
2379           strbuf);
2380         write(fd, pom, strlen(pom));
2381       }
2382 #endif
2383       break;
2384     case PARAM_REQUEST:
2385       {
2386         dllist *ptr = *((dllist **) params[i].val_adr);
2387         while(ptr)
2388         {
2389           url_info *ui = (url_info *) ptr->data;
2390 
2391           if(ui->type != URLI_NORMAL || ui->localname)
2392           {
2393             char *p = url_info_dump(ui);
2394             snprintf(pom, sizeof(pom), " -%s \'%s\' ", params[i].long_cmd, p);
2395             _free(p);
2396             write(fd, pom, strlen(pom));
2397           }
2398 
2399           ptr = ptr->next;
2400         }
2401       }
2402       break;
2403     case PARAM_TRANSPARENT:
2404       {
2405         http_proxy *pr = *((http_proxy **) params[i].val_adr);
2406         snprintf(pom, sizeof(pom), " -%s=%s:%d ", params[i].long_cmd,
2407           pr->addr, pr->port);
2408         write(fd, pom, strlen(pom));
2409       }
2410       break;
2411     case PARAM_PROXY:
2412       {
2413         dllist *ptr = *((dllist **) params[i].val_adr);
2414         while(ptr)
2415         {
2416           http_proxy *pr = (http_proxy *) ptr->data;
2417           snprintf(pom, sizeof(pom), " -%s=%s:%hu ", params[i].long_cmd,
2418             pr->addr, pr->port);
2419           write(fd, pom, strlen(pom));
2420 
2421           ptr = ptr->next;
2422         }
2423       }
2424       break;
2425     case PARAM_FUNC:
2426       break;
2427     case PARAM_JSTRANS:
2428 #ifdef HAVE_REGEX
2429       {
2430         dllist *ptr;
2431         for(ptr = cfg.js_transform; ptr; ptr = ptr->next)
2432         {
2433           js_transform_t *jt = (js_transform_t *) ptr->data;
2434           if(jt->type != (long) params[i].mdefault_val)
2435             continue;
2436 
2437           snprintf(pom, sizeof(pom), " -%s \'%s\' \'%s\' \'%s\' \'%s\' ",
2438             params[i].long_cmd, jt->re->pattern, jt->transform, jt->tag,
2439             jt->attrib);
2440           write(fd, pom, strlen(pom));
2441         }
2442       }
2443 #endif
2444       break;
2445     case PARAM_NUMLIST:
2446       if(!params[i].mval_adr || (params[i].mval_adr &&
2447           (*((bool_t *) params[i].mval_adr) ==
2448             (bool_t) (long) params[i].mdefault_val)))
2449       {
2450         dllist *ptr = *((dllist **) params[i].val_adr);
2451         if(ptr)
2452         {
2453           snprintf(pom, sizeof(pom), "-%s %ld", params[i].long_cmd,
2454             (long) ptr->data);
2455           write(fd, pom, strlen(pom));
2456 
2457           j = 1;
2458           for(; ptr; ptr = ptr->next)
2459           {
2460             snprintf(pom, sizeof(pom), ",%ld", (long) ptr->data);
2461             write(fd, pom, strlen(pom));
2462           }
2463           write(fd, " ", 1);
2464         }
2465       }
2466       break;
2467     case PARAM_FTPHS:
2468       {
2469         dllist *ptr;
2470         for(ptr = *((dllist **) params[i].val_adr); ptr; ptr = ptr->next)
2471         {
2472           char *p;
2473           ftp_handshake_info *fhi = (ftp_handshake_info *) ptr->data;
2474 
2475           p = ftp_handshake_info_data_dump(fhi);
2476 
2477           if(*fhi->host)
2478             snprintf(pom, sizeof(pom),
2479               "-%s \"%s:%hu\" \"%s\" ",
2480               params[i].long_cmd, fhi->host, fhi->port, p);
2481           else
2482             snprintf(pom, sizeof(pom),
2483               "-%s \"\" \"%s\" ", params[i].long_cmd, p);
2484           _free(p);
2485           write(fd, pom, strlen(pom));
2486         }
2487       }
2488       break;
2489     case PARAM_TAGPAT:
2490       {
2491         dllist *ptr;
2492         for(ptr = *((dllist **) params[i].val_adr); ptr; ptr = ptr->next)
2493         {
2494           tag_pattern_t *tp = (tag_pattern_t *) ptr->data;
2495 
2496           snprintf(pom, sizeof(pom),
2497             "-%s \"%s\" \"%s\" \"%s\" ",
2498             params[i].long_cmd, tp->tag, tp->attrib, tp->urlp);
2499 
2500           write(fd, pom, strlen(pom));
2501         }
2502       }
2503       break;
2504     }
2505   }
2506 
2507   return 0;
2508 }
2509 
cfg_free_params(void)2510 void cfg_free_params(void)
2511 {
2512   int i;
2513 
2514   for(i = 0; i < NUM_ELEM(params); i++)
2515     cfg_set_to_default(&(params[i]));
2516 }
2517 
2518 #if defined(HAVE_MT) && defined(I_FACE)
2519 
_copy_strnar(char ** orig)2520 static char **_copy_strnar(char **orig)
2521 {
2522   int n, i;
2523   char **rv;
2524 
2525   if(!orig)
2526     return NULL;
2527 
2528   for(n = 0; orig[n]; n++);
2529   n++;
2530   rv = (char **) _malloc(n * sizeof(char **));
2531 
2532   for(i = 0; i < n; i++)
2533     rv[i] = tl_strdup(orig[i]);
2534 
2535   return rv;
2536 }
2537 
2538 #ifdef HAVE_REGEX
_copy_relist(dllist * orig)2539 static dllist *_copy_relist(dllist * orig)
2540 {
2541   dllist *rv, *ptr;
2542 
2543   if(!orig)
2544     return NULL;
2545 
2546   rv = NULL;
2547   ptr = orig;
2548 
2549   while(ptr)
2550   {
2551     rv = dllist_append(rv, re_make(((re_entry *) ptr->data)->pattern));
2552     ptr = ptr->next;
2553   }
2554 
2555   return rv;
2556 }
2557 
_copy_jstrans(dllist * orig)2558 static dllist *_copy_jstrans(dllist * orig)
2559 {
2560   dllist *rv, *ptr;
2561 
2562   if(!orig)
2563     return NULL;
2564 
2565   rv = NULL;
2566   ptr = orig;
2567 
2568   while(ptr)
2569   {
2570     js_transform_t *jt = ptr->data;
2571 
2572     rv = dllist_append(rv, js_transform_new(jt->re->pattern,
2573         jt->transform, jt->tag, jt->attrib, jt->type));
2574     ptr = ptr->next;
2575   }
2576 
2577   return rv;
2578 }
2579 #endif
2580 
_copy_lfnames(dllist * orig)2581 static dllist *_copy_lfnames(dllist * orig)
2582 {
2583   dllist *rv, *ptr;
2584 
2585   if(!orig)
2586     return NULL;
2587 
2588   rv = NULL;
2589   ptr = orig;
2590 
2591   while(ptr)
2592   {
2593     lfname *ln = (lfname *) ptr->data;
2594     rv = dllist_append(rv, lfname_new(ln->type, ln->matchstr, ln->transstr));
2595     ptr = ptr->next;
2596   }
2597 
2598   return rv;
2599 }
2600 
_copy_httphdr(dllist * orig)2601 static dllist *_copy_httphdr(dllist * orig)
2602 {
2603   dllist *rv, *ptr;
2604 
2605   if(!orig)
2606     return NULL;
2607 
2608   rv = NULL;
2609   ptr = orig;
2610 
2611   while(ptr)
2612   {
2613     httphdr *ov, *nv;
2614 
2615     ov = (httphdr *) ptr->data;
2616     nv = _malloc(sizeof(httphdr));
2617 
2618     nv->all = ov->all;
2619     nv->name = tl_strdup(ov->name);
2620     nv->val = tl_strdup(ov->val);
2621 
2622     rv = dllist_append(rv, nv);
2623     ptr = ptr->next;
2624   }
2625 
2626   return rv;
2627 }
2628 
_copy_urlinfo(dllist * orig)2629 static dllist *_copy_urlinfo(dllist * orig)
2630 {
2631   dllist *rv, *ptr;
2632 
2633   if(!orig)
2634     return NULL;
2635 
2636   rv = NULL;
2637   ptr = orig;
2638 
2639   while(ptr)
2640   {
2641     url_info *ui;
2642 
2643     ui = url_info_duplicate((url_info *) ptr->data);
2644 
2645     rv = dllist_append(rv, ui);
2646     ptr = ptr->next;
2647   }
2648 
2649   return rv;
2650 }
2651 
_copy_numlist(dllist * orig)2652 static dllist *_copy_numlist(dllist * orig)
2653 {
2654   dllist *rv = NULL, *ptr;
2655 
2656   for(ptr = orig; ptr; ptr = ptr->next)
2657     rv = dllist_append(rv, ptr->data);
2658 
2659   return rv;
2660 }
2661 
_copy_ftphs(dllist * orig)2662 static dllist *_copy_ftphs(dllist * orig)
2663 {
2664   dllist *rv = NULL;
2665 
2666   for(; orig; orig = orig->next)
2667     rv = dllist_append(rv, ftp_handshake_info_dup(orig->data));
2668 
2669   return rv;
2670 }
2671 
_copy_tagpat(dllist * orig)2672 static dllist *_copy_tagpat(dllist * orig)
2673 {
2674   dllist *rv = NULL;
2675 
2676   for(; orig; orig = orig->next)
2677   {
2678     tag_pattern_t *tp = orig->data;
2679 
2680     rv = dllist_append(rv, tag_pattern_new(tp->type, tp->tag,
2681         tp->attrib, tp->urlp));
2682   }
2683 
2684   return rv;
2685 }
2686 
privcfg_make_copy(_config_struct_priv_t * pcfg)2687 void privcfg_make_copy(_config_struct_priv_t * pcfg)
2688 {
2689   LOCK_GCFG;
2690 
2691   memset(pcfg, '\0', sizeof(_config_struct_priv_t));
2692 
2693   pcfg->timestamp = time(NULL);
2694 
2695   pcfg->default_prefix = tl_strdup(cfg.default_prefix);
2696   pcfg->info_dir = tl_strdup(cfg.info_dir);
2697   pcfg->subdir = tl_strdup(cfg.subdir);
2698   pcfg->cache_dir = tl_strdup(cfg.cache_dir);
2699   pcfg->post_cmd = tl_strdup(cfg.post_cmd);
2700   pcfg->http_proxy_pass = tl_strdup(cfg.http_proxy_pass);
2701   pcfg->http_proxy_user = tl_strdup(cfg.http_proxy_user);
2702   pcfg->ftp_proxy_pass = tl_strdup(cfg.ftp_proxy_pass);
2703   pcfg->ftp_proxy_user = tl_strdup(cfg.ftp_proxy_user);
2704   pcfg->ftp_proxy = tl_strdup(cfg.ftp_proxy);
2705   pcfg->ftp_proxy_port = cfg.ftp_proxy_port;
2706   pcfg->gopher_proxy = tl_strdup(cfg.gopher_proxy);
2707   pcfg->gopher_proxy_port = cfg.gopher_proxy_port;
2708   pcfg->name_auth = tl_strdup(cfg.name_auth);
2709   pcfg->passwd_auth = tl_strdup(cfg.passwd_auth);
2710   pcfg->index_name = tl_strdup(cfg.index_name);
2711   pcfg->store_name = tl_strdup(cfg.store_name);
2712   pcfg->from = tl_strdup(cfg.from);
2713   pcfg->identity = tl_strdup(cfg.identity);
2714   pcfg->auth_ntlm_domain = tl_strdup(cfg.auth_ntlm_domain);
2715   pcfg->ftp_list_options = tl_strdup(cfg.ftp_list_options);
2716 
2717   pcfg->accept_lang = _copy_strnar(cfg.accept_lang);
2718   pcfg->accept_chars = _copy_strnar(cfg.accept_chars);
2719   pcfg->cookies_disabled_domains = _copy_strnar(cfg.cookies_disabled_domains);
2720   pcfg->dont_touch_url_pattern = _copy_strnar(cfg.dont_touch_url_pattern);
2721 
2722   pcfg->lfnames = _copy_lfnames(cfg.lfnames);
2723   pcfg->http_headers = _copy_httphdr(cfg.http_headers);
2724   pcfg->formdata = _copy_urlinfo(cfg.formdata);
2725   pcfg->ftp_login_hs = _copy_ftphs(cfg.ftp_login_hs);
2726   pcfg->condition.tag_patterns = _copy_tagpat(cfg.condition.tag_patterns);
2727 
2728   pcfg->condition.ports = _copy_numlist(cfg.condition.ports);
2729 
2730   pcfg->condition.sites = _copy_strnar(cfg.condition.sites);
2731   pcfg->condition.allow_site = cfg.condition.allow_site;
2732   pcfg->condition.sufix = _copy_strnar(cfg.condition.sufix);
2733   pcfg->condition.allow_sufix = cfg.condition.allow_sufix;
2734   pcfg->condition.dir_prefix = _copy_strnar(cfg.condition.dir_prefix);
2735   pcfg->condition.allow_prefix = cfg.condition.allow_prefix;
2736   pcfg->condition.domains = _copy_strnar(cfg.condition.domains);
2737   pcfg->condition.allow_domain = cfg.condition.allow_domain;
2738   pcfg->condition.mime = _copy_strnar(cfg.condition.mime);
2739   pcfg->condition.allow_mime = cfg.condition.allow_mime;
2740 
2741   pcfg->condition.pattern = _copy_strnar(cfg.condition.pattern);
2742   pcfg->condition.url_pattern = _copy_strnar(cfg.condition.url_pattern);
2743   pcfg->condition.skip_pattern = _copy_strnar(cfg.condition.skip_pattern);
2744   pcfg->condition.skip_url_pattern =
2745     _copy_strnar(cfg.condition.skip_url_pattern);
2746 
2747   pcfg->condition.uexit = tl_strdup(cfg.condition.uexit);
2748   pcfg->condition.follow_cmd = tl_strdup(cfg.condition.follow_cmd);
2749 
2750   pcfg->tr_del_chr = tl_strdup(cfg.tr_del_chr);
2751   pcfg->tr_str_s1 = tl_strdup(cfg.tr_str_s1);
2752   pcfg->tr_str_s2 = tl_strdup(cfg.tr_str_s2);
2753   pcfg->tr_chr_s1 = tl_strdup(cfg.tr_chr_s1);
2754   pcfg->tr_chr_s2 = tl_strdup(cfg.tr_chr_s2);
2755 
2756 #ifdef HAVE_BDB_18x
2757   pcfg->ns_cache_dir = tl_strdup(cfg.ns_cache_dir);
2758   pcfg->moz_cache_dir = tl_strdup(cfg.moz_cache_dir);
2759 #endif
2760 
2761 
2762 #ifdef HAVE_REGEX
2763   pcfg->advert_res = _copy_relist(cfg.advert_res);
2764   pcfg->js_patterns = _copy_relist(cfg.js_patterns);
2765   pcfg->dont_touch_url_rpattern = _copy_relist(cfg.dont_touch_url_rpattern);
2766   pcfg->dont_touch_tag_rpattern = _copy_relist(cfg.dont_touch_tag_rpattern);
2767 
2768   pcfg->js_transform = _copy_jstrans(cfg.js_transform);
2769 
2770   pcfg->condition.rpattern = _copy_relist(cfg.condition.rpattern);
2771   pcfg->condition.rskip_pattern = _copy_relist(cfg.condition.rskip_pattern);
2772   pcfg->condition.rurl_pattern = _copy_relist(cfg.condition.rurl_pattern);
2773   pcfg->condition.rskip_url_pattern =
2774     _copy_relist(cfg.condition.rskip_url_pattern);
2775 
2776   pcfg->condition.aip = _copy_relist(cfg.condition.aip);
2777   pcfg->condition.skipip = _copy_relist(cfg.condition.skipip);
2778 #endif
2779 
2780 #ifdef USE_SSL
2781   pcfg->ssl_proxy = tl_strdup(cfg.ssl_proxy);
2782   pcfg->ssl_proxy_port = cfg.ssl_proxy_port;
2783   pcfg->ssl_cipher_list = tl_strdup(cfg.ssl_cipher_list);
2784   pcfg->ssl_cert_passwd = tl_strdup(cfg.ssl_cert_passwd);
2785 
2786 #ifdef USE_SSL_IMPL_OPENSSL
2787   pcfg->ssl_cert_file = tl_strdup(cfg.ssl_cert_file);
2788   pcfg->ssl_key_file = tl_strdup(cfg.ssl_key_file);
2789   pcfg->egd_socket = tl_strdup(cfg.egd_socket);
2790 #endif
2791 #ifdef USE_SSL_IMPL_NSS
2792   pcfg->nss_cert_dir = tl_strdup(cfg.nss_cert_dir);
2793 #endif
2794 #endif
2795   UNLOCK_GCFG;
2796 
2797 }
2798 
2799 #define __free_strnar(orig) _free_strnar(orig);orig = NULL;
2800 
_free_strnar(char ** orig)2801 static void _free_strnar(char **orig)
2802 {
2803   int n;
2804 
2805   if(!orig)
2806     return;
2807 
2808   for(n = 0; orig[n]; n++)
2809     _free(orig[n]);
2810   _free(orig);
2811 }
2812 
2813 #ifdef HAVE_REGEX
2814 #define __free_relist(orig) _free_relist(orig);orig = NULL;
2815 
_free_relist(dllist * orig)2816 static void _free_relist(dllist * orig)
2817 {
2818   dllist *rv, *ptr;
2819 
2820   if(!orig)
2821     return;
2822 
2823   rv = NULL;
2824   ptr = orig;
2825 
2826   while(ptr)
2827   {
2828     re_free((re_entry *) ptr->data);
2829     ptr = dllist_remove_entry(ptr, ptr);
2830   }
2831 }
2832 
2833 #define __free_jstrans(orig) _free_jstrans(orig);orig = NULL;
2834 
_free_jstrans(dllist * orig)2835 static void _free_jstrans(dllist * orig)
2836 {
2837   dllist *rv, *ptr;
2838 
2839   if(!orig)
2840     return;
2841 
2842   rv = NULL;
2843   ptr = orig;
2844 
2845   while(ptr)
2846   {
2847     js_transform_free((js_transform_t *) ptr->data);
2848     ptr = dllist_remove_entry(ptr, ptr);
2849   }
2850 }
2851 
2852 #endif
2853 
2854 #define __free_lfnames(orig) _free_lfnames(orig);orig = NULL;
2855 
_free_lfnames(dllist * orig)2856 static void _free_lfnames(dllist * orig)
2857 {
2858   dllist *ptr;
2859 
2860   if(!orig)
2861     return;
2862 
2863   ptr = orig;
2864 
2865   while(ptr)
2866   {
2867     lfname_free((lfname *) ptr->data);
2868     ptr = dllist_remove_entry(ptr, ptr);
2869   }
2870 }
2871 
2872 #define __free_httphdr(orig) _free_httphdr(orig);orig = NULL;
2873 
_free_httphdr(dllist * orig)2874 static void _free_httphdr(dllist * orig)
2875 {
2876   dllist *ptr;
2877 
2878   if(!orig)
2879     return;
2880 
2881   ptr = orig;
2882 
2883   while(ptr)
2884   {
2885     httphdr *ov = (httphdr *) ptr->data;
2886 
2887     _free(ov->name);
2888     _free(ov->val);
2889 
2890     ptr = dllist_remove_entry(ptr, ptr);
2891   }
2892 }
2893 
2894 #define __free_urlinfo(orig) _free_urlinfo(orig);orig = NULL;
2895 
_free_urlinfo(dllist * orig)2896 static void _free_urlinfo(dllist * orig)
2897 {
2898   dllist *ptr;
2899 
2900   if(!orig)
2901     return;
2902 
2903   ptr = orig;
2904 
2905   while(ptr)
2906   {
2907     url_info_free((url_info *) ptr->data);
2908     ptr = dllist_remove_entry(ptr, ptr);
2909   }
2910 }
2911 
2912 #define __free_numlist(orig) _free_numlist(orig);orig = NULL;
2913 
_free_numlist(dllist * orig)2914 static void _free_numlist(dllist * orig)
2915 {
2916   while(orig)
2917     orig = dllist_remove_entry(orig, orig);
2918 }
2919 
2920 #define __free_ftphs(orig) _free_ftphs(orig);orig = NULL;
2921 
_free_ftphs(dllist * orig)2922 static void _free_ftphs(dllist * orig)
2923 {
2924   for(; orig; orig = dllist_remove_entry(orig, orig))
2925     ftp_handshake_info_free(orig->data);
2926 }
2927 
2928 #define __free_tagpat(orig) _free_tagpat(orig);orig = NULL;
2929 
_free_tagpat(dllist * orig)2930 static void _free_tagpat(dllist * orig)
2931 {
2932   for(; orig; orig = dllist_remove_entry(orig, orig))
2933     tag_pattern_free(orig->data);
2934 }
2935 
privcfg_free(_config_struct_priv_t * pcfg)2936 void privcfg_free(_config_struct_priv_t * pcfg)
2937 {
2938   _free(pcfg->default_prefix);
2939   _free(pcfg->info_dir);
2940   _free(pcfg->subdir);
2941   _free(pcfg->cache_dir);
2942   _free(pcfg->post_cmd);
2943   _free(pcfg->http_proxy_pass);
2944   _free(pcfg->http_proxy_user);
2945   _free(pcfg->ftp_proxy_pass);
2946   _free(pcfg->ftp_proxy_user);
2947   _free(pcfg->ftp_proxy);
2948   _free(pcfg->gopher_proxy);
2949   _free(pcfg->name_auth);
2950   _free(pcfg->passwd_auth);
2951   _free(pcfg->index_name);
2952   _free(pcfg->store_name);
2953   _free(pcfg->from);
2954   _free(pcfg->identity);
2955   _free(pcfg->auth_ntlm_domain);
2956   _free(pcfg->auth_proxy_ntlm_domain);
2957   _free(pcfg->ftp_list_options);
2958 
2959   __free_strnar(pcfg->accept_lang);
2960   __free_strnar(pcfg->accept_chars);
2961   __free_strnar(pcfg->cookies_disabled_domains);
2962   __free_strnar(pcfg->dont_touch_url_pattern);
2963 
2964   __free_lfnames(pcfg->lfnames);
2965   __free_httphdr(pcfg->http_headers);
2966   __free_urlinfo(pcfg->formdata);
2967   __free_ftphs(pcfg->ftp_login_hs);
2968   __free_tagpat(pcfg->condition.tag_patterns);
2969 
2970   __free_numlist(pcfg->condition.ports);
2971 
2972   __free_strnar(pcfg->condition.sites);
2973   __free_strnar(pcfg->condition.sufix);
2974   __free_strnar(pcfg->condition.dir_prefix);
2975   __free_strnar(pcfg->condition.domains);
2976   __free_strnar(pcfg->condition.mime);
2977 
2978   __free_strnar(pcfg->condition.pattern);
2979   __free_strnar(pcfg->condition.url_pattern);
2980   __free_strnar(pcfg->condition.skip_pattern);
2981   __free_strnar(pcfg->condition.skip_url_pattern);
2982 
2983   _free(pcfg->condition.uexit);
2984   _free(pcfg->condition.follow_cmd);
2985 
2986   _free(pcfg->tr_del_chr);
2987   _free(pcfg->tr_str_s1);
2988   _free(pcfg->tr_str_s2);
2989   _free(pcfg->tr_chr_s1);
2990   _free(pcfg->tr_chr_s2);
2991 
2992 #ifdef HAVE_BDB_18x
2993   _free(pcfg->ns_cache_dir);
2994   _free(pcfg->moz_cache_dir);
2995 #endif
2996 
2997 #ifdef HAVE_REGEX
2998   __free_relist(pcfg->advert_res);
2999   __free_relist(pcfg->dont_touch_url_rpattern);
3000   __free_relist(pcfg->dont_touch_tag_rpattern);
3001   __free_relist(pcfg->js_patterns);
3002   __free_jstrans(pcfg->js_transform);
3003 
3004   __free_relist(pcfg->condition.rpattern);
3005   __free_relist(pcfg->condition.rskip_pattern);
3006   __free_relist(pcfg->condition.rurl_pattern);
3007   __free_relist(pcfg->condition.rskip_url_pattern);
3008 
3009   __free_relist(pcfg->condition.aip);
3010   __free_relist(pcfg->condition.skipip);
3011 #endif
3012 
3013 #ifdef USE_SSL
3014   _free(pcfg->ssl_proxy);
3015   _free(pcfg->ssl_cipher_list);
3016   _free(pcfg->ssl_cert_passwd);
3017 
3018 #ifdef USE_SSL_IMPL_OPENSSL
3019   _free(pcfg->egd_socket);
3020   _free(pcfg->ssl_cert_file);
3021   _free(pcfg->ssl_key_file);
3022 #endif
3023 #ifdef USE_SSL_IMPL_NSS
3024   _free(pcf->nss_cert_dir);
3025 #endif
3026 #endif
3027   memset(pcfg, '\0', sizeof(_config_struct_priv_t));
3028 }
3029 
3030 #endif /* HAVE_MT && I_FACE */
3031