/[anubis]/anubis/src/rc.c
ViewVC logotype

Diff of /anubis/src/rc.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.4 by polak, Sun Feb 2 11:21:52 2003 UTC revision 1.5 by gray, Wed Feb 5 21:47:35 2003 UTC
# Line 24  Line 24 
24    
25  #include "headers.h"  #include "headers.h"
26  #include "extern.h"  #include "extern.h"
27    #include "rcfile.h"
28    
29  static int  optlength(char *);  #define setbool(a, b, c) \
30  static void match_options_common(int, char *);     do {\
31  static int  get_regex(int, char *, char *, int);          if (strcmp("yes", a) == 0) \
32  static char *parse_line_regex(char *);                  (b) |= (c); \
33  static void get_action_line(char *);          else if (strcmp("no", a) == 0) \
34  static void match_action(char *, const char *);                  (b) &= ~(c); \
35            else \
36  static time_t global_mtime;                  return RC_KW_ERROR; \
37       } while (0)
 #define set(a, b, c) \  
         if ((optlen = strlen((char *)a)) == 0) \  
                 return; \  
         if (strncmp("yes", (char *)a, optlen) == 0) \  
                 b |= c; \  
         else if (strncmp("no", (char *)a, optlen) == 0) \  
                 b &= ~c; \  
         return;  
   
 #define if_empty_quit(a) \  
         if (strlen((char *)a) == 0) \  
                 return;  
38    
39  #define if_empty_set(a, b, c) \  #define if_empty_set(a, b, c) \
40          if (strlen((char *)a) == 0) { \     do {\
41                  b &= ~c; \          if (strlen(a) == 0) { \
42                  return; \                  (b) &= ~(c); \
43          } \          } else { \
44          else if (strlen((char *)a) != 0) { \                  (b) |= (c); \
45                  b |= c; \          }\
46                  return; \     } while (0)          
47          }  
48    #define MAX_SECTIONS 10
49    
50    static RC_SECTION *parse_tree;
51    static int parse_tree_method;
52    static struct rc_secdef anubis_rc_sections[MAX_SECTIONS];
53    static int anubis_rc_numsections;
54    
55  void  struct rc_secdef *
56  open_rcfile(int method)  anubis_add_section(char *name)
57    {
58            int i;
59            
60            if (anubis_rc_numsections >= MAX_SECTIONS)
61                    abort(); /*FIXME*/
62            
63            for (i = 0; i < anubis_rc_numsections; i++)
64                    if (strcmp(anubis_rc_sections[i].name, name) == 0)
65                            return &anubis_rc_sections[i];
66            
67            anubis_rc_sections[anubis_rc_numsections].name = name;
68            anubis_rc_sections[anubis_rc_numsections].child = NULL;
69            return &anubis_rc_sections[anubis_rc_numsections++];
70    }
71    
72    RC_SECTION *
73    _open_rcfile(int method)
74  {  {
         int n;  
75          char homedir[MAXPATHLEN+1];          char homedir[MAXPATHLEN+1];
         char local_rcfile[] = DEFAULT_LOCAL_RCFILE;  
76          char *rcfile = 0;          char *rcfile = 0;
77          char *user = 0;          RC_SECTION *sec;
   
         if (method == SUPERVISOR)  
                 user = session.supervisor;  
         else if (method == CLIENT)  
                 user = session.client;  
   
         get_homedir(user, homedir, sizeof(homedir));  
         n = strlen(homedir) + strlen(local_rcfile) + 2;  
         n = n > MAXPATHLEN ? MAXPATHLEN + 1 : n + 1;  
78    
79          if (method == SUPERVISOR) {          switch (method) {
80            case CF_SUPERVISOR:
81            case CF_INIT:
82                  if (topt & T_ALTRC) {                  if (topt & T_ALTRC) {
83                          if (check_filename(options.altrc) == 0)                          if (check_filename(options.altrc) == 0)
84                                  return;                                  return NULL;
85                          rcfile = allocbuf(options.altrc, MAXPATHLEN);                          rcfile = strdup(options.altrc);
86                  }                  } else if (check_superuser())
87                            rcfile = strdup(DEFAULT_GLOBAL_RCFILE);
88                  else {                  else {
89                          if (check_superuser())                          get_homedir(session.supervisor,
90                                  rcfile = allocbuf(DEFAULT_GLOBAL_RCFILE, MAXPATHLEN);                                      homedir, sizeof(homedir));
91                          else {                          rcfile = xmalloc(strlen(homedir) +
92                                  rcfile = (char *)xmalloc(n);                                           strlen(DEFAULT_LOCAL_RCFILE) + 2);
93  #ifdef HAVE_SNPRINTF                          sprintf(rcfile, "%s/%s", homedir,
94                                  snprintf(rcfile, n - 1,                                  DEFAULT_LOCAL_RCFILE);
95  #else                  }
96                                  sprintf(rcfile,                  info(DEBUG,
97  #endif /* HAVE_SNPRINTF */                       _("Reading system configuration file %s..."), rcfile);
98                                          "%s/%s", homedir, local_rcfile);                  break;
99                          }  
100                  }          case CF_CLIENT:
101          }                  get_homedir(session.client,
102          else if (method == CLIENT) {                              homedir, sizeof(homedir));
103                  rcfile = (char *)xmalloc(n);                  rcfile = xmalloc(strlen(homedir) +
104  #ifdef HAVE_SNPRINTF                                   strlen(DEFAULT_LOCAL_RCFILE) + 2);
105                  snprintf(rcfile, n - 1,                  sprintf(rcfile, "%s/%s", homedir, DEFAULT_LOCAL_RCFILE);
106  #else                  info(DEBUG,
107                  sprintf(rcfile,                       _("Reading user configuration file %s..."), rcfile);
 #endif /* HAVE_SNPRINTF */  
                         "%s/%s", homedir, local_rcfile);  
108          }          }
109    
110          if (check_filemode(rcfile) == 0) { /* Wrong permissions... */          if (check_filemode(rcfile) == 0) { /* Wrong permissions... */
111                  free(rcfile);                  free(rcfile);
112                  return;                  return NULL;
113          }          }
114    
115          if (method == SUPERVISOR) {          sec = rc_parse(rcfile);
116                  struct stat st;          /* FIXME:
117                  if (stat(rcfile, &st) == 0) {             1) check 'sec' against anubis_rc_sections and remove the
118                          if (global_mtime != st.st_mtime)             erroneous statements
119                                  global_mtime = st.st_mtime;             2) rc_section_link(&rc_section, sec); */
                         else {  
                                 free(rcfile);  
                                 return;  
                         }  
                 }  
         }  
         fp_rcfile = fopen(rcfile, "r");  
         if (fp_rcfile == 0) {  
                 if (options.termlevel == DEBUG)  
                         anubis_error(SOFT, _("Anubis RC file error: %s."), strerror(errno));  
         }  
         else {  
                 if (method == SUPERVISOR)  
                         info(DEBUG, _("Reading system configuration file %s..."), rcfile);  
                 else if (method == CLIENT)  
                         info(DEBUG, _("Reading user configuration file %s..."), rcfile);  
         }  
120          free(rcfile);          free(rcfile);
121          return;          return sec;
122  }  }
123    
124  void  void
125  read_rcfile(int method)  open_rcfile(int method)
126  {  {
127          char rcline[LINEBUFFER+1];          if (!parse_tree || parse_tree_method != method) {
128          unsigned long rcfile_position = 0;                  RC_SECTION *sec;
129                    parse_tree_method = method;
130          if (fp_rcfile == 0)                  sec = _open_rcfile(method);
131                  return;                  if (sec)
132                            rc_section_link(&parse_tree, sec);
         rcfile_position = get_position(BEGIN_CONTROL);  
         if (rcfile_position == 0)  
                 return;  
         else  
                 info(DEBUG, _("The %s section has been found. Processing..."), "CONTROL");  
   
         fseek(fp_rcfile, rcfile_position, SEEK_SET);  
         while (fgets(rcline, LINEBUFFER, fp_rcfile) != 0)  
         {  
                 if (strncmp(rcline, "#", 1) == 0 || strncmp(rcline, LF, 1) == 0)  
                         continue; /* skip: an empty line, comment (#) */  
                 else if (strncmp(rcline, END_SECTION, endsection_len) == 0)  
                         break; /* THE END */  
                 else  
                         match_options_common(method, rcline);  
         }  
         if (!(topt & T_ALLOW_LOCAL_MTA))  
                 topt &= ~T_LOCAL_MTA;  
   
         if (method >= SUPERVISOR) {  
                 rcfile_position = get_position(BEGIN_TRANSLATION);  
                 if (rcfile_position == 0) {  
                         topt &= ~T_TRANSLATION_MAP;  
                         return;  
                 }  
                 else  
                         info(DEBUG, _("The %s section has been found. Processing..."), "TRANSLATION");  
   
                 destroy_list(&session.transmap);  
                 topt |= T_TRANSLATION_MAP;  
   
                 fseek(fp_rcfile, rcfile_position, SEEK_SET);  
                 while (fgets(rcline, LINEBUFFER, fp_rcfile) != 0)  
                 {  
                         if (strncmp(rcline, "#", 1) == 0 || strncmp(rcline, LF, 1) == 0)  
                                 continue; /* skip: an empty line, comment (#) */  
                         else if (strncmp(rcline, END_SECTION, endsection_len) == 0)  
                                 break; /* THE END */  
                         else {  
                                 remcrlf(rcline);  
                                 session.transmap_tail = new_element(session.transmap_tail,  
                                         &session.transmap, rcline);  
                         }  
                 }  
133          }          }
         return;  
134  }  }
135    
136  void  void
137  read_rcfile_allsection(void)  process_rcfile(int method)
138  {  {
139          char rcline[LINEBUFFER+1];          rc_run_section_list(method, parse_tree, anubis_rc_sections);
   
         if (fp_rcfile == 0)  
                 return;  
   
         if (all_position == 0) {  
                 all_position = get_position(BEGIN_ALL);  
                 if (all_position == 0)  
                         return;  
                 else  
                         info(DEBUG, _("The %s section has been found. Processing..."), "ALL");  
         }  
   
         fseek(fp_rcfile, all_position, SEEK_SET);  
         while (fgets(rcline, LINEBUFFER, fp_rcfile) != 0)  
         {  
                 if (strncmp(rcline, "#", 1) == 0 || strncmp(rcline, LF, 1) == 0)  
                         continue; /* skip: an empty line, comment (#) */  
                 else if (strncmp(rcline, END_SECTION, endsection_len) == 0)  
                         break; /* THE END */  
                 else {  
                         get_action_line(rcline);  
                         match_action(rcline, NULL);  
                 }  
         }  
         return;  
140  }  }
141    
142  #ifdef WITH_GUILE  /* ************************** The CONTROL Section ************************* */
143  static void  #define KW_BIND                0
144  match_action_guile(char *buf)  #define KW_TERMLEVEL           1
145  {  #define KW_ALLOW_LOCAL_MTA     2
146          char *ptr = 0;  #define KW_ALLOW_NOTPRIVILEGED 3
147          int optlen;  #define KW_LOGLEVEL            4
148            #define KW_LOGFILE             5
149          optlen = optlength(buf);  #define KW_REMOTE_MTA          6
150          if (optlen == 0)  #define KW_LOCAL_MTA           7
151                  return;  #define KW_ESMTP_AUTH          8
152    #define KW_SOCKS_PROXY         9
153          /*  #define KW_SOCKS_V4           10
154              Guile  #define KW_SOCKS_AUTH         11
         */  
   
         if (strncmp("guile-output", buf, optlen) == 0) {  
                 ptr = parse_line_option(buf);  
                 if_empty_quit(ptr);  
                 xfree(options.guile_logfile);  
                 options.guile_logfile = allocbuf(ptr, MAXPATHLEN);  
                 return;  
         }  
         if (strncmp("guile-debug", buf, optlen) == 0) {  
                 ptr = parse_line_option(buf);  
                 if_empty_quit(ptr);  
                 guile_debug(strncmp("yes", ptr, 3) == 0);  
                 return;  
         }        
         if (strncmp("guile-load-path-append", buf, optlen) == 0) {  
                 ptr = parse_line_option(buf);  
                 if_empty_quit(ptr);  
                 guile_load_path_append(ptr);  
                 return;  
         }  
         if (strncmp("guile-load-program", buf, optlen) == 0) {  
                 ptr = parse_line_option(buf);  
                 if_empty_quit(ptr);  
                 guile_load_program(ptr);  
                 return;  
         }  
         if (strncmp("guile-postprocess", buf, optlen) == 0) {  
                 ptr = parse_line_option(buf);  
                 if_empty_quit(ptr);  
                 xfree(options.guile_postprocess);  
                 options.guile_postprocess = allocbuf(ptr, MAXPATHLEN);  
                 return;  
         }  
 }  
155    
156  void  int
157  read_rcfile_guile(void)  control_parser(int method, int key, char *arg,
158                   void *inv_data, void *func_data, char *line)
159  {  {
160          char rcline[LINEBUFFER+1];          switch (key) {
161            case KW_BIND:                
162          if (fp_rcfile == 0)                  parse_mtahost(arg, session.tunnel, &session.tunnel_port);
163                  return;                  if (strlen(session.tunnel) != 0)
164                            topt |= T_NAMES;
165          if (guile_position == 0) {                  break;
166                  guile_position = get_position(BEGIN_GUILE);                  
167                  if (guile_position == 0)          case KW_TERMLEVEL:          
168                          return;                  if (strcmp("silent", arg) == 0)
169                            options.termlevel = SILENT;
170                    else if (strcmp("normal", arg) == 0)
171                            options.termlevel = NORMAL;
172                    else if (strcmp("verbose", arg) == 0)
173                            options.termlevel = VERBOSE;
174                    else if (strcmp("debug", arg) == 0)
175                            options.termlevel = DEBUG;
176                  else                  else
177                          info(DEBUG, _("The %s section has been found. Processing..."), "GUILE");                          return RC_KW_ERROR;
178          }                  break;
179                    
180            case KW_ALLOW_LOCAL_MTA:
181                    setbool(arg, topt, T_ALLOW_LOCAL_MTA);
182                    break;
183                    
184            case KW_ALLOW_NOTPRIVILEGED:
185                    safe_strcpy(session.notprivileged, arg);
186                    break;
187    
188          fseek(fp_rcfile, guile_position, SEEK_SET);          case KW_LOGFILE:
189          while (fgets(rcline, LINEBUFFER, fp_rcfile) != 0)                  if (method & (CF_SUPERVISOR|CF_INIT)) {
         {  
                 if (strncmp(rcline, "#", 1) == 0  
                     || strncmp(rcline, LF, 1) == 0)  
                         continue; /* skip: an empty line, comment (#) */  
                 else if (strncmp(rcline, END_SECTION, endsection_len) == 0)  
                         break; /* THE END */  
                 else {  
                         get_action_line(rcline);  
                         match_action_guile(rcline);  
                 }  
         }  
         return;  
 }  
 #endif /* WITH_GUILE */  
   
 void  
 close_rcfile(void)  
 {  
         if (fp_rcfile == 0)  
                 return;  
         if (fclose(fp_rcfile) != 0)  
                 anubis_error(SOFT, _("Fatal fclose() error. %s."), strerror(errno));  
         fp_rcfile = 0;  
         return;  
 }  
   
 char *  
 parse_line_option(char *line)  
 {  
         char *ptr = 0;  
         ptr = strchr(line, '=');  
   
         if (ptr == 0)  
                 return line;  
         do {  
                 ptr++;  
         } while (*ptr == ' ' || *ptr == '\t');  
   
         remcrlf(ptr);  
         return ptr;  
 }  
   
 static int  
 optlength(char *p)  
 {  
         register int n = 0;  
         while (*p != ' ' && *p != '\t' && *p != '=')  
         {  
                 n++;  
                 p++;  
         }  
         return n;  
 }  
   
 static void  
 match_options_common(int method, char *rcline)  
 {  
         char *ptr = 0;  
         char buf[LINEBUFFER+1];  
         int optlen;  
   
         safe_strcpy(buf, rcline);  
         change_to_lower(buf);  
         optlen = optlength(buf);  
         if (optlen == 0)  
                 return;  
   
         if (method == INIT) {  
                 if (strncmp("bind", buf, optlen) == 0) {  
                         ptr = parse_line_option(rcline);  
                         if_empty_quit(ptr);  
                         parse_mtahost(ptr, session.tunnel, &session.tunnel_port);  
                         if (strlen(session.tunnel) != 0)  
                                 topt |= T_NAMES;  
                         return;  
                 }  
         }  
         if (method >= SUPERVISOR) {  
                 if (strncmp("termlevel", buf, optlen) == 0) {  
                         ptr = parse_line_option(buf);  
                         if ((optlen = strlen(ptr)) == 0)  
                                 return;  
                         if (strncmp("silent", ptr, optlen) == 0)  
                                 options.termlevel = SILENT;  
                         else if (strncmp("normal", ptr, optlen) == 0)  
                                 options.termlevel = NORMAL;  
                         else if (strncmp("verbose", ptr, optlen) == 0)  
                                 options.termlevel = VERBOSE;  
                         else if (strncmp("debug", ptr, optlen) == 0)  
                                 options.termlevel = DEBUG;  
                         return;  
                 }  
                 if (strncmp("allow-local-mta", buf, optlen) == 0) {  
                         set(parse_line_option(buf), topt, T_ALLOW_LOCAL_MTA);  
                 }  
                 if (strncmp("user-notprivileged", buf, optlen) == 0) {  
                         safe_strcpy(session.notprivileged, parse_line_option(rcline));  
                         if_empty_set(session.notprivileged, topt, T_USER_NOTPRIVIL);  
                 }  
         }  
         if (strncmp("logfile", buf, optlen) == 0) {  
                 ptr = parse_line_option(rcline);  
                 if_empty_quit(ptr);  
   
                 if (method >= SUPERVISOR) {  
190                          xfree(options.slogfile);                          xfree(options.slogfile);
191                          options.slogfile = allocbuf(ptr, MAXPATHLEN);                          options.slogfile = allocbuf(arg, MAXPATHLEN);
192                          return;                  } else if (method == CF_CLIENT) {
                 }  
                 if (method == CLIENT) {  
193                          xfree(options.ulogfile);                          xfree(options.ulogfile);
194                          options.ulogfile = allocbuf(ptr, MAXPATHLEN);                          options.ulogfile = allocbuf(arg, MAXPATHLEN);
                         return;  
                 }  
                 return;  
         }  
         if (method == CLIENT) {  
                 if (strncmp("loglevel", buf, optlen) == 0) {  
                         ptr = parse_line_option(buf);  
                         if ((optlen = strlen(ptr)) == 0)  
                                 return;  
                         if (strncmp("none", ptr, optlen) == 0)  
                                 options.uloglevel = NONE;  
                         else if (strncmp("all", ptr, optlen) == 0)  
                                 options.uloglevel = ALL;  
                         else if (strncmp("fails", ptr, optlen) == 0)  
                                 options.uloglevel = FAILS;  
                         return;  
195                  }                  }
196          }                  break;
197          if (strncmp("remote-mta", buf, optlen) == 0) {                  
198                  ptr = parse_line_option(rcline);          case KW_LOGLEVEL:
199                  if_empty_quit(ptr);                  if (strcmp("none", arg) == 0)
200                  parse_mtaport(ptr, session.mta, &session.mta_port);                          options.uloglevel = NONE;
201                  return;                  else if (strcmp("all", arg) == 0)
202          }                          options.uloglevel = ALL;
203          if (strncmp("local-mta", buf, optlen) == 0) {                  else if (strcmp("fails", arg) == 0)
204                            options.uloglevel = FAILS;
205                    else
206                            return RC_KW_ERROR;
207                    break;
208                    
209            case KW_REMOTE_MTA:
210                    parse_mtaport(arg, session.mta, &session.mta_port);
211                    break;
212                    
213            case KW_LOCAL_MTA: {
214                  char *a = 0;                  char *a = 0;
215                  char *p = 0;                  char *p = 0;
216                  char tmp[LINEBUFFER+1];                  char tmp[LINEBUFFER+1];
                 ptr = parse_line_option(rcline);  
                 if_empty_quit(ptr);  
217    
218                  a = strchr(ptr, ' '); /* an extra arguments */                  a = strchr(arg, ' '); /* an extra arguments */
219                  if (a) {                  if (a) {
220                          *a++ = '\0';                          *a++ = '\0';
221                          p = strrchr(ptr, '/');                          p = strrchr(arg, '/');
222                          if (p)                          if (p)
223                                  p++;                                  p++;
224                          else                          else
225                                  p = ptr;                                  p = arg;
226  #ifdef HAVE_SNPRINTF                          snprintf(tmp, sizeof(tmp), "%s %s", p, a);
227                          snprintf(tmp, LINEBUFFER,                          p = arg;
 #else  
                         sprintf(tmp,  
 #endif /* HAVE_SNPRINTF */  
                                 "%s %s", p, a);  
                         p = ptr;  
228                          a = tmp;                          a = tmp;
229                  }                  } else { /* no arguments */
230                  else { /* no arguments */                          p = arg;
231                          p = ptr;                          a = strrchr(arg, '/');
                         a = strrchr(ptr, '/');  
232                          if (a)                          if (a)
233                                  a++;                                  a++;
234                          else                          else
235                                  a = ptr;                                  a = arg;
236                  }                  }
237                  xfree(session.execpath);                  xfree(session.execpath);
238                  session.execpath = allocbuf(p, MAXPATHLEN);                  session.execpath = allocbuf(p, MAXPATHLEN);
# Line 468  match_options_common(int method, char *r Line 243  match_options_common(int method, char *r
243                  }                  }
244                  session.execargs = gen_execargs(a);                  session.execargs = gen_execargs(a);
245                  topt |= T_RCEXECARGS;                  topt |= T_RCEXECARGS;
                 return;  
246          }          }
247          if (strncmp("esmtp-auth", buf, optlen) == 0) {          break;
248                  char *p = 0;                  
249                  ptr = parse_line_option(rcline);          case KW_ESMTP_AUTH: {
250                  if_empty_quit(ptr);                  char *p = strchr(arg, ':');
                 p = strchr(ptr, ':');  
251                  if (p) {                  if (p) {
252                          safe_strcpy(session.mta_password, ++p);                          safe_strcpy(session.mta_password, ++p);
253                          *--p = '\0';                          *--p = '\0';
254                          safe_strcpy(session.mta_username, ptr);                          safe_strcpy(session.mta_username, arg);
255                          topt |= T_ESMTP_AUTH;                          topt |= T_ESMTP_AUTH;
256                  }                  }
257                  return;          }              
258          }          break;
259                    
260          /*          case KW_SOCKS_PROXY:
261             Proxies.                  parse_mtaport(arg, session.socks, &session.socks_port);
         */  
   
         if (strncmp("socks-proxy", buf, optlen) == 0) {  
                 parse_mtaport(parse_line_option(rcline), session.socks,  
                 &session.socks_port);  
262                  if_empty_set(session.socks, topt, T_SOCKS);                  if_empty_set(session.socks, topt, T_SOCKS);
263          }                  break;
264          if (strncmp("socks-v4", buf, optlen) == 0) {                  
265                  set(parse_line_option(buf), topt, T_SOCKS_V4);          case KW_SOCKS_V4:
266          }                  setbool(arg, topt, T_SOCKS_V4);
267          if (strncmp("socks-auth", buf, optlen) == 0) {                  break;
268                    
269            case KW_SOCKS_AUTH: {
270                  char *p = 0;                  char *p = 0;
271                  ptr = parse_line_option(rcline);                  p = strchr(arg, ':');
                 if_empty_quit(ptr);  
                 p = strchr(ptr, ':');  
272                  if (p) {                  if (p) {
273                          safe_strcpy(session.socks_password, ++p);                          safe_strcpy(session.socks_password, ++p);
274                          *--p = '\0';                          *--p = '\0';
275                          safe_strcpy(session.socks_username, ptr);                          safe_strcpy(session.socks_username, arg);
276                          topt |= T_SOCKS_AUTH;                          topt |= T_SOCKS_AUTH;
277                  }                  }
278                  return;                  break;
279            }
280            
281            default:
282                    return RC_KW_UNKNOWN;
283          }          }
284            return RC_KW_HANDLED;
285    }
286    
287          /*  static struct rc_kwdef init_kw[] = {
288             TLS/SSL.          { "bind", KW_BIND },
289          */          { NULL },
290    };
291    
292    static struct rc_secdef_child init_sect_child = {
293            NULL,
294            CF_INIT,
295            init_kw,
296            control_parser,
297            NULL
298    };
299    
300    static struct rc_kwdef init_supervisor_kw[] = {
301            { "termlevel", KW_TERMLEVEL },
302            { "allow-local-mta", KW_ALLOW_LOCAL_MTA },
303            { "user-notprivileged", KW_ALLOW_NOTPRIVILEGED },
304            { NULL }
305    };
306    
307    static struct rc_secdef_child init_supervisor_sect_child = {
308            NULL,
309            CF_INIT|CF_SUPERVISOR,
310            init_supervisor_kw,
311            control_parser,
312            NULL
313    };
314    
315    struct rc_kwdef client_kw[] = {
316            { "loglevel", KW_LOGLEVEL },
317            { NULL },
318    };
319    
320    static struct rc_secdef_child client_sect_child = {
321            NULL,
322            CF_CLIENT,
323            client_kw,
324            control_parser,
325            NULL
326    };
327    
328    struct rc_kwdef control_kw[] = {
329            { "logfile", KW_LOGFILE },
330            { "remote-mta", KW_REMOTE_MTA },
331            { "local-mta", KW_LOCAL_MTA },
332            { "esmtp-auth", KW_ESMTP_AUTH },
333            { "socks-proxy", KW_SOCKS_PROXY },
334            { "socks-v4", KW_SOCKS_V4 },
335            { "socks-auth", KW_SOCKS_AUTH },
336            { NULL },
337    };
338    
339    static struct rc_secdef_child control_sect_child = {
340            NULL,
341            CF_ALL,
342            control_kw,
343            control_parser,
344            NULL
345    };
346    
347    /* FIXME: This belongs to another file */
348  #if defined(HAVE_TLS) || defined(HAVE_SSL)  #if defined(HAVE_TLS) || defined(HAVE_SSL)
349          if (strncmp("ssl", buf, optlen) == 0) {  #define KW_SSL                 1
350                  set(parse_line_option(buf), topt, T_SSL);  #define KW_ONEWAY_SSL          2
351          }  #define KW_CERT                3
352          if (strncmp("oneway-ssl", buf, optlen) == 0) {  #define KW_KEY                 4
353                  set(parse_line_option(buf), topt, T_SSL_ONEWAY);  #define KW_CAFILE              5
354          }  
355          if (strncmp("cert", buf, optlen) == 0) {  int
356                  ptr = parse_line_option(rcline);  tls_parser(int method, int key, char *arg,
357                  if_empty_quit(ptr);             void *inv_data, void *func_data, char *line)
358    {
359            switch (key) {
360            case KW_SSL:
361                    setbool(arg, topt, T_SSL);
362                    break;
363                    
364            case KW_ONEWAY_SSL:
365                    setbool(arg, topt, T_SSL_ONEWAY);
366                    break;
367                    
368            case KW_CERT:
369                  xfree(secure.cert);                  xfree(secure.cert);
370                  secure.cert = allocbuf(ptr, MAXPATHLEN);                  secure.cert = allocbuf(arg, MAXPATHLEN);
371                  if (method == CLIENT)                  if (method == CF_CLIENT)
372                          topt |= T_SSL_CKCLIENT;                          topt |= T_SSL_CKCLIENT;        
373                  return;                  break;
374          }                  
375          if (strncmp("key", buf, optlen) == 0) {          case KW_KEY:
                 ptr = parse_line_option(rcline);  
                 if_empty_quit(ptr);  
376                  xfree(secure.key);                  xfree(secure.key);
377                  secure.key = allocbuf(ptr, MAXPATHLEN);                  secure.key = allocbuf(arg, MAXPATHLEN);
378                  if (method == CLIENT)                  if (method == CF_CLIENT)
379                          topt |= T_SSL_CKCLIENT;                          topt |= T_SSL_CKCLIENT;
380                  return;                  break;
381          }                  
382          if (strncmp("cafile", buf, optlen) == 0) {          case KW_CAFILE:
                 ptr = parse_line_option(rcline);  
                 if_empty_quit(ptr);  
383                  xfree(secure.cafile);                  xfree(secure.cafile);
384                  secure.cafile = allocbuf(ptr, MAXPATHLEN);                  secure.cafile = allocbuf(arg, MAXPATHLEN);
385                  return;                  break;
386          }                  
387  #endif /* HAVE_TLS or HAVE_SSL */          default:
388                    return RC_KW_UNKNOWN;
389          return;          }
390  }          return RC_KW_HANDLED;
391    }
392    
393    static struct rc_kwdef tls_kw[] = {
394            { "ssl", KW_SSL },
395            { "oneway-ssl", KW_ONEWAY_SSL },
396            { "cert", KW_CERT },
397            { "key", KW_KEY },
398            { "cafile", KW_CAFILE },
399            { NULL }
400    };
401    
402    static struct rc_secdef_child tls_sect_child = {
403            NULL,
404            CF_ALL,
405            tls_kw,
406            tls_parser,
407            NULL
408    };
409    #endif
410    
411  int  void
412  read_regex_block(int method, char *regex, int size)  control_section_init()
 {  
         char rcline[LINEBUFFER+1];  
   
         if (fp_rcfile == 0)  
                 return 0;  
   
         while (fgets(rcline, LINEBUFFER, fp_rcfile) != 0)  
         {  
                 if (strncmp(rcline, "#", 1) == 0 || strncmp(rcline, LF, 1) == 0)  
                         continue; /* skip: an empty line, comment (#) */  
                 else if (strncmp(rcline, END_SECTION, endsection_len) == 0)  
                         break; /* END OF REGEX BLOCK */  
                 else {  
                         if (get_regex(method, rcline, regex, size) == 0)  
                                 continue;  
                         else  
                                 return 1;  
                 }  
         }  
         return 0;  
 }  
   
 static int  
 get_regex(int method, char *rcline, char *regex, int size)  
413  {  {
414          char *ptr = 0;          struct rc_secdef *sp = anubis_add_section("CONTROL");
415          int rs = 0;          rc_secdef_add_child(sp, &init_sect_child);
416            rc_secdef_add_child(sp, &init_supervisor_sect_child);
417          if (method == HEADER) { /* "IF HEADER =..." */          rc_secdef_add_child(sp, &client_sect_child);
418                  rs = regex_match("[ \t]*if[ \t]+header.*=", rcline);          rc_secdef_add_child(sp, &control_sect_child);
419                  if (rs == 0)  #if defined(HAVE_TLS) || defined(HAVE_SSL)
420                          rs = regex_match("[ \t]*rule.*=", rcline);          rc_secdef_add_child(sp, &tls_sect_child);
421          }  #endif
         else if (method == COMMAND) { /* "IF COMMAND =..." */  
                 rs = regex_match("[ \t]*if[ \t]+command.*=", rcline);  
         }  
         if (rs == 0)  
                 return 0;  
         ptr = parse_line_regex(rcline);  
         if (strlen(ptr) == 0)  
                 return 0;  
         strncpy(regex, ptr, size);  
         return 1;  
 }  
   
 static char *  
 parse_line_regex(char *rcline)  
 {  
         char *ptr = 0;  
         char *optptr = 0;  
         int len;  
         char optbuf[LINEBUFFER+1];  
         memset(optbuf, 0, LINEBUFFER + 1);  
   
         ptr = strchr(rcline, '=');  
         if (ptr == 0)  
                 return rcline;  
   
         len = strlen(rcline);  
         len -= strlen(ptr);  
         strncpy(optbuf, rcline, len);  
   
         optptr = strchr(optbuf, ':'); /* additional options */  
         if (optptr) {  
                 optptr++;  
                 change_to_lower(optptr);  
                 if (strstr(optptr, "basic"))  
                         ropt |= R_BASIC;  
                 if (strstr(optptr, "scase"))  
                         ropt |= R_SCASE;  
 #ifdef HAVE_PCRE  
                 if (strstr(optptr, "perlre"))  
                         ropt |= R_PERLRE;  
 #endif /* HAVE_PCRE */  
         }  
         else  
                 ropt = 0;  
         ptr++;  
         remcrlf(ptr);  
         return ptr;  
422  }  }
423    
424  /*********************  /* ********************** The ALL and RULE Sections *********************** */
425   Read an ACTION-BLOCK  #define KW_ADD                      1
426  **********************/  #define KW_REMOVE                   2                
427    #define KW_MODIFY                   3
428    #define KW_SIGNATURE_FILE_APPEND    4
429    #define KW_BODY_APPEND              5
430    #define KW_BODY_CLEAR_APPEND        6
431    #define KW_ROT13_SUBJECT            7
432    #define KW_ROT13_BODY               8
433    #define KW_RM_RRT                   9
434    #define KW_RM_POST                 10  
435    #define KW_RM_HEADER               11
436    #define KW_RM_LT                   12
437    #define KW_RM_RLT                  13
438    #define KW_EXTERNAL_BODY_PROCESSOR 14
439    
440  int  int
441  read_action_block(const char *source_line)  all_parser(int method, int key, char *arg,
442  {             void *inv_data, void *func_data, char *line)
         char rcline[LINEBUFFER+1];  
   
         if (fp_rcfile == 0)  
                 return 0;  
   
         while (fgets(rcline, LINEBUFFER, fp_rcfile) != 0)  
         {  
                 if (strncmp(rcline, "#", 1) == 0 || strncmp(rcline, LF, 1) == 0)  
                         continue; /* skip: an empty line, comment (#) */  
                 else if (regex_match("[ \t]*(done|fi)[^0-9A-Za-z][ \t]*", rcline))  
                         break; /* 'fi' - END OF REGEX BLOCK ACTION */  
                 else {  
                         get_action_line(rcline);  
                         match_action(rcline, source_line);  
                         return 1;  
                 }  
         }  
         return 0;  
 }  
   
 static void  
 get_action_line(char *rcline)  
 {  
         char *ptr = 0;  
         char buf[LINEBUFFER+1];  
   
         safe_strcpy(buf, rcline);  
         ptr = buf;  
         while (*ptr == ' ' || *ptr == '\t')  
                 ptr++;  
   
         remcrlf(ptr);  
         strncpy(rcline, ptr, LINEBUFFER);  
         return;  
 }  
   
 static void  
 match_action(char *rcline, const char *source_line)  
443  {  {
444          char *ptr = 0;          switch (key) {
445          char *outbuf = 0;          case KW_ADD:
         char buf[LINEBUFFER+1];  
         int optlen;  
   
         outbuf = substitute(rcline, submatch);  
         if (outbuf) {  
                 strncpy(rcline, outbuf, LINEBUFFER);  
                 free(outbuf);  
         }  
         safe_strcpy(buf, rcline);  
         change_to_lower(buf);  
         optlen = optlength(buf);  
         if (optlen == 0)  
                 return;  
   
         if (strncmp("add", buf, optlen) == 0) {  
                 ptr = parse_line_option(rcline);  
                 if_empty_quit(ptr);  
446                  message.addlist_tail = new_element(message.addlist_tail,                  message.addlist_tail = new_element(message.addlist_tail,
447                          &message.addlist, ptr);                                                     &message.addlist, arg);
448                  return;                  break;
449          }                  
450          if (strncmp("remove", buf, optlen) == 0) {          case KW_REMOVE:                                
                 ptr = parse_line_option(rcline);  
                 if_empty_quit(ptr);  
451                  message.remlist_tail = new_element(message.remlist_tail,                  message.remlist_tail = new_element(message.remlist_tail,
452                          &message.remlist, ptr);                                                     &message.remlist, arg);
453                  return;                  break;
454          }                  
455          if (strncmp("modify", buf, optlen) == 0) {          case KW_MODIFY: {
456                  char *p = 0;                  char *p = 0;
457                  char modify[LINEBUFFER+1];                  char modify[LINEBUFFER+1];
458                  ptr = parse_line_option(rcline);  
459                  if_empty_quit(ptr);                  p = strstr(arg, " >> "); /* "SPC>>SPC" is a separator */
                 p = strstr(ptr, " >> "); /* "SPC>>SPC" is a separator */  
460                  if (p) {                  if (p) {
461                          p += 4;                          p += 4;
462                          strncpy(modify, p, LINEBUFFER-2);                          strncpy(modify, p, LINEBUFFER-2);
463                          strcat(modify, CRLF);                          strcat(modify, CRLF);
464                          p -= 4;                          p -= 4;
465                          *p = '\0';                          *p = '\0';
466                          message.modlist_tail = new_element(message.modlist_tail,                          message.modlist_tail =
467                                  &message.modlist, ptr);                                  new_element(message.modlist_tail,
468                                                &message.modlist, arg);
469                          message.modlist_tail->modify = strdup(modify);                          message.modlist_tail->modify = strdup(modify);
470                  }                  }
                 return;  
         }  
         if (strncmp("rot13-subject", buf, optlen) == 0) {  
                 set(parse_line_option(buf), mopt, M_ROT13S);  
         }  
         if (strncmp("rot13-body", buf, optlen) == 0) {  
                 set(parse_line_option(buf), mopt, M_ROT13B);  
471          }          }
472          if (strncmp("signature-file-append", buf, optlen) == 0) {          break;
473                  set(parse_line_option(buf), mopt, M_SIGNATURE);                  
474          }          case KW_SIGNATURE_FILE_APPEND:
475          if (strncmp("body-clear-append", buf, optlen) == 0) {                  setbool(arg, mopt, M_SIGNATURE);
476                  ptr = parse_line_option(rcline);                  break;
477                  if_empty_quit(ptr);                  
478            case KW_BODY_APPEND:
479                  xfree(message.body_append);                  xfree(message.body_append);
480                  message.body_append = allocbuf(ptr, MAXPATHLEN);                  message.body_append = allocbuf(arg, MAXPATHLEN);
481                  mopt |= M_BODYAPPEND;                  mopt |= M_BODYAPPEND;
482                  mopt |= M_BODYCLEARAPPEND;                  mopt &= ~M_BODYCLEARAPPEND;
483                  return;                  break;
484          }                  
485          if (strncmp("body-append", buf, optlen) == 0) {          case KW_BODY_CLEAR_APPEND:    
                 ptr = parse_line_option(rcline);  
                 if_empty_quit(ptr);  
486                  xfree(message.body_append);                  xfree(message.body_append);
487                  message.body_append = allocbuf(ptr, MAXPATHLEN);                  message.body_append = allocbuf(arg, MAXPATHLEN);
488                  mopt |= M_BODYAPPEND;                  mopt |= M_BODYAPPEND;
489                  mopt &= ~M_BODYCLEARAPPEND;                  mopt |= M_BODYCLEARAPPEND;
490                  return;                  break;
491          }                  
492          if (strncmp("external-body-processor", buf, optlen) == 0) {          case KW_ROT13_SUBJECT:        
493                  ptr = parse_line_option(rcline);                  setbool(arg, mopt, M_ROT13S);
494                  if_empty_quit(ptr);                  break;
495                    
496            case KW_ROT13_BODY:
497                    setbool(arg, mopt, M_ROT13B);
498                    break;
499                    
500            case KW_RM_RRT:                
501                    xfree(rm.rrt);
502                    rm.rrt = allocbuf(arg, 0);
503                    mopt |= M_RM;
504                    mopt |= M_RMRRT;
505                    break;
506                    
507            case KW_RM_POST:                
508                    xfree(rm.post);
509                    rm.post = allocbuf(arg, 0);
510                    mopt |= M_RM;
511                    mopt |= M_RMPOST;
512                    break;
513                    
514            case KW_RM_HEADER:            
515                    xfree(rm.header);
516                    rm.header = allocbuf(arg, LINEBUFFER + 1);
517                    mopt |= M_RMHEADER;
518                    break;
519                    
520            case KW_RM_LT:                  
521                    xfree(rm.latent_time);
522                    rm.latent_time = allocbuf(arg, 16);
523                    mopt |= M_RMLT;
524                    break;
525                    
526            case KW_RM_RLT:                
527                    xfree(rm.latent_time);
528                    rm.latent_time = allocbuf(arg, 16);
529                    mopt |= M_RMLT;
530                    break;
531                    
532            case KW_EXTERNAL_BODY_PROCESSOR:
533                  xfree(message.exteditor);                  xfree(message.exteditor);
534                  message.exteditor = allocbuf(ptr, MAXPATHLEN);                  message.exteditor = allocbuf(arg, MAXPATHLEN);
535                  mopt |= M_EXTBODYPROC;                  mopt |= M_EXTBODYPROC;
536                  return;                  break;
537          }                  
538            default:
539                    return RC_KW_UNKNOWN;
540            }
541            return RC_KW_HANDLED;
542    }
543    
544    struct rc_kwdef all_kw[] = {
545            { "add",                     KW_ADD },                    
546            { "remove",                  KW_REMOVE },                  
547            { "modify",                  KW_MODIFY },                  
548            { "signature-file-append",   KW_SIGNATURE_FILE_APPEND },  
549            { "body-append",             KW_BODY_APPEND },            
550            { "body-clear-append",       KW_BODY_CLEAR_APPEND },      
551            { "rot13-subject",           KW_ROT13_SUBJECT },          
552            { "rot13-body",              KW_ROT13_BODY },              
553            { "rm-rrt",                  KW_RM_RRT },                  
554            { "rm-post",                 KW_RM_POST },                
555            { "rm-header",               KW_RM_HEADER },              
556            { "rm-lt",                   KW_RM_LT },                  
557            { "rm-rlt",                  KW_RM_RLT },                  
558            { "external-body-processor", KW_EXTERNAL_BODY_PROCESSOR },
559            { NULL }
560    };
561    
562    static struct rc_secdef_child all_sect_child = {
563            NULL,
564            CF_CLIENT,
565            all_kw,
566            all_parser,
567            NULL
568    };
569    
570    
         /*  
            GnuPG support.  
         */  
571    
572  #ifdef HAVE_GPG  #ifdef HAVE_GPG
573          if (strncmp("gpg-passphrase", buf, optlen) == 0) {  #define KW_GPG_PASSPHRASE         1
574                  ptr = parse_line_option(rcline);  #define KW_GPG_ENCRYPT            2
575                  if_empty_quit(ptr);  #define KW_GPG_SIGN               3
576    #define KW_RM_GPG                 4
577    
578    int
579    gpg_parser(int method, int key, char *arg,
580               void *inv_data, void *func_data, char *line)
581    {
582            switch (key) {
583            case KW_GPG_PASSPHRASE:
584                  if (gpg.passphrase) {                  if (gpg.passphrase) {
585                          memset(gpg.passphrase, 0, strlen(gpg.passphrase));                          memset(gpg.passphrase, 0, strlen(gpg.passphrase));
586                          xfree(gpg.passphrase);                          xfree(gpg.passphrase);
587                  }                  }
588                  gpg.passphrase = allocbuf(ptr, 0);                  gpg.passphrase = allocbuf(arg, 0);
589                  mopt |= M_GPG_PASSPHRASE;                  mopt |= M_GPG_PASSPHRASE;
590                  return;                  break;
591          }                  
592          if (strncmp("gpg-encrypt", buf, optlen) == 0) {          case KW_GPG_ENCRYPT:
                 ptr = parse_line_option(rcline);  
                 if_empty_quit(ptr);  
593                  xfree(gpg.keys);                  xfree(gpg.keys);
594                  gpg.keys = allocbuf(ptr, 0);                  gpg.keys = allocbuf(arg, 0);
595                  gpg.keys = (char *)xrealloc((char *)gpg.keys, strlen(gpg.keys) + 2);                  gpg.keys = xrealloc(gpg.keys, strlen(gpg.keys) + 2);
596                  strcat(gpg.keys, ",");                  strcat(gpg.keys, ",");
597                  mopt |= M_GPG_ENCRYPT;                  mopt |= M_GPG_ENCRYPT;
598                  return;                  break;
599          }                  
600          if (strncmp("gpg-sign", buf, optlen) == 0) {          case KW_GPG_SIGN:              
601                  ptr = parse_line_option(rcline);                  if (strcmp(arg, "yes") == 0
602                  if_empty_quit(ptr);                      || (mopt & M_GPG_PASSPHRASE) == 0) {
                 if (regex_match("yes", ptr) == 0  
                 || (mopt & M_GPG_PASSPHRASE) == 0) {  
603                          if (gpg.passphrase) {                          if (gpg.passphrase) {
604                                  memset(gpg.passphrase, 0, strlen(gpg.passphrase));                                  memset(gpg.passphrase, 0,
605                                           strlen(gpg.passphrase));
606                                  xfree(gpg.passphrase);                                  xfree(gpg.passphrase);
607                          }                          }
608                          gpg.passphrase = allocbuf(ptr, 0);                          gpg.passphrase = allocbuf(arg, 0);
609                  }                  }
610                  mopt |= M_GPG_SIGN;                  mopt |= M_GPG_SIGN;
611                  return;                  break;
612          }                  
613  #endif /* HAVE_GPG */          case KW_RM_GPG:
   
         /*  
            Guile support  
         */  
 #ifdef WITH_GUILE  
         if (strncmp("guile-rewrite-line", buf, optlen) == 0) {  
                 ptr = parse_line_option(rcline);  
                 if_empty_quit(ptr);  
                 guile_rewrite_line(ptr, source_line);  
                 return;  
         }  
 #endif /* WITH_GUILE */  
           
         /*  
            Remailer Type-I support.  
         */  
   
         if (strncmp("rm-rrt", buf, optlen) == 0) {  
                 ptr = parse_line_option(rcline);  
                 if_empty_quit(ptr);  
                 xfree(rm.rrt);  
                 rm.rrt = allocbuf(ptr, 0);  
                 mopt |= M_RM;  
                 mopt |= M_RMRRT;  
                 return;  
         }  
         if (strncmp("rm-post", buf, optlen) == 0) {  
                 ptr = parse_line_option(rcline);  
                 if_empty_quit(ptr);  
                 xfree(rm.post);  
                 rm.post = allocbuf(ptr, 0);  
                 mopt |= M_RM;  
                 mopt |= M_RMPOST;  
                 return;  
         }  
 #ifdef HAVE_GPG  
         if (strncmp("rm-gpg", buf, optlen) == 0) {  
                 ptr = parse_line_option(rcline);  
                 if_empty_quit(ptr);  
614                  xfree(gpg.rm_key);                  xfree(gpg.rm_key);
615                  gpg.rm_key = allocbuf(ptr, 0);                  gpg.rm_key = allocbuf(arg, 0);
616                  mopt |= M_RMGPG;                  mopt |= M_RMGPG;
617                  return;                  break;
618          }                  
619  #endif /* HAVE_GPG */          default:
620          if (strncmp("rm-header", buf, optlen) == 0) {                  return RC_KW_UNKNOWN;
621                  ptr = parse_line_option(rcline);          }
622                  if_empty_quit(ptr);          return RC_KW_HANDLED;
                 xfree(rm.header);  
                 rm.header = allocbuf(ptr, LINEBUFFER + 1);  
                 mopt |= M_RMHEADER;  
                 return;  
         }  
         if (strncmp("rm-lt", buf, optlen) == 0) {  
                 ptr = parse_line_option(rcline);  
                 if_empty_quit(ptr);  
                 xfree(rm.latent_time);  
                 rm.latent_time = allocbuf(ptr, 16);  
                 mopt |= M_RMLT;  
                 return;  
         }  
         if (strncmp("rm-rlt", buf, optlen) == 0) {  
                 set(parse_line_option(buf), mopt, M_RMRLT);  
         }  
         return;  
623  }  }
624    
 /**************************  
  Find the 'LINE' position.  
 ***************************/  
625    
626  unsigned long  struct rc_kwdef gpg_kw[] = {
627  get_position(char *line)          { "gpg-passphrase",          KW_GPG_PASSPHRASE },          
628            { "gpg-encrypt",             KW_GPG_ENCRYPT },            
629            { "gpg-sign",                KW_GPG_SIGN },                
630            { "rm-gpg",                  KW_RM_GPG },                  
631            { NULL },
632    };
633    
634    static struct rc_secdef_child gpg_sect_child = {
635            NULL
636            CF_CLIENT,
637            gpg_kw,
638            gpg_parser,
639            NULL
640    };
641    
642    #endif
643    
644    void
645    all_section_init()
646  {  {
647          char buf[LINEBUFFER+1];          struct rc_secdef *sp = anubis_add_section("ALL");
648            rc_secdef_add_child(sp, &all_sect_child);
649    #ifdef HAVE_GPG
650            rc_secdef_add_child(sp, &gpg_sect_child);
651    #endif
652    }
653    
654          if (fp_rcfile == 0 || line == 0)  void
655                  return 0;  rule_section_init()
656    {
657            struct rc_secdef *sp = anubis_add_section("RULE");
658            
659            rc_secdef_add_child(sp, &all_sect_child);
660    #ifdef HAVE_GPG
661            rc_secdef_add_child(sp, &gpg_sect_child);
662    #endif
663    }
664    
665          rewind(fp_rcfile);  void
666          while (fgets(buf, LINEBUFFER, fp_rcfile) != 0)  rc_system_init()
667          {  {
668                  if (strncmp(buf, line, strlen(line)) == 0)          control_section_init();
669                          return (unsigned long)ftell(fp_rcfile);          all_section_init();
670          }          translate_section_init();
671          return 0;          rule_section_init();
672    #ifdef WITH_GUILE
673            guile_section_init();
674    #endif
675  }  }
676    
677  /* EOF */  /* Placeholders */
678    void
679    rcfile_process_cond(char *name, int method, char *line)
680    {
681            RC_SECTION *sec = rc_section_lookup(parse_tree, name);
682            rc_run_section(CF_CLIENT, sec, anubis_rc_sections, method, line, NULL);
683    }
684    
685    void
686    rcfile_process_section(int method, char *name, void *data)
687    {
688            RC_SECTION *sec = rc_section_lookup(parse_tree, name);
689            rc_run_section(method, sec, anubis_rc_sections, 0, NULL, data);
690    }

Legend:
Removed from v.1.4  
changed lines
  Added in v.1.5

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26