Import from http://svn.freenode.net/ircd-seven/private/beu/seven (r196).
[seven-1.x.git] / tools / convertilines.c
blob0ca33f34fdb5ce64949f6d10002ce028d6e335ac
1 /* tools/convertilines.c
2 * Copyright (c) 2002 Hybrid Development Team
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
8 * 1.Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2.Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3.The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
24 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
25 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
28 * $Id: convertilines.c 62 2006-09-22 23:51:46Z spb $
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <ctype.h>
34 #include <string.h>
36 #define BUFSIZE 512
38 #define FLAGS_RESTRICTED 0x001
39 #define FLAGS_EXCEEDLIMIT 0x002
40 #define FLAGS_KLINEEXEMPT 0x004
41 #define FLAGS_NEEDIDENT 0x010
42 #define FLAGS_NOTILDE 0x020
44 struct flag_table_struct
46 const char *name;
47 int flag;
49 static struct flag_table_struct flag_table[] =
51 { "restricted", FLAGS_RESTRICTED },
52 { "exceed_limit", FLAGS_EXCEEDLIMIT },
53 { "kline_exempt", FLAGS_KLINEEXEMPT },
54 { "need_ident", FLAGS_NEEDIDENT },
55 { "no_tilde", FLAGS_NOTILDE },
56 { NULL, 0 }
59 struct AuthBlock
61 struct AuthBlock *next;
63 char **hostname;
64 int hostnum;
66 char *spoof;
67 char *passwd;
68 int class;
69 int flags;
71 /* indicates one of above */
72 int special;
73 int specialk;
76 static struct AuthBlock *auth_spoof = NULL;
77 static struct AuthBlock *auth_special = NULL;
78 static struct AuthBlock *auth_passwd = NULL;
79 static struct AuthBlock *auth_general = NULL;
80 static struct AuthBlock *auth_restricted = NULL;
82 static void ConvertConf(FILE* file,FILE *out);
83 static void set_flags(struct AuthBlock *, const char *, const char *);
84 static void usage(void);
85 static char *getfield(char *);
86 static struct AuthBlock *find_matching_conf(struct AuthBlock *);
87 static void ReplaceQuotes(char *out, char *in);
88 static void oldParseOneLine(FILE *out, char *in);
89 static void write_auth_entries(FILE *out);
90 static void write_specific(FILE *out, struct AuthBlock *);
91 static int match(struct AuthBlock *, struct AuthBlock *);
93 int main(int argc,char *argv[])
95 FILE *in;
96 FILE *out;
98 if(argc < 3)
99 usage();
101 if((in = fopen(argv[1],"r")) == NULL)
103 fprintf(stderr, "Can't open %s for reading\n", argv[1]);
104 usage();
107 if((out = fopen(argv[2],"w")) == NULL)
109 fprintf(stderr, "Can't open %s for writing\n", argv[2]);
110 usage();
113 ConvertConf(in, out);
115 return 0;
118 void usage()
120 fprintf(stderr, "convertilines conf.old conf.new\n");
121 exit(-1);
125 * ConvertConf()
126 * Read configuration file.
129 * Inputs - FILE* to config file to convert
130 * - FILE* to output for new style conf
134 #define MAXCONFLINKS 150
136 static void ConvertConf(FILE* file, FILE *out)
138 char line[BUFSIZE];
139 char quotedLine[BUFSIZE];
140 char* p;
142 while (fgets(line, sizeof(line), file))
144 if ((p = strchr(line, '\n')))
145 *p = '\0';
147 ReplaceQuotes(quotedLine,line);
149 if(!*quotedLine || quotedLine[0] == '#' || quotedLine[0] == '\n' ||
150 quotedLine[0] == ' ' || quotedLine[0] == '\t')
151 continue;
153 if(quotedLine[0] == '.')
155 char *filename;
156 char *back;
158 if(!strncmp(quotedLine+1,"include ",8))
160 if( (filename = strchr(quotedLine+8,'"')) )
161 filename++;
162 else
164 fprintf(stderr, "Bad config line: %s", quotedLine);
165 continue;
168 if((back = strchr(filename,'"')))
169 *back = '\0';
170 else
172 fprintf(stderr, "Bad config line: %s", quotedLine);
173 continue;
179 /* Could we test if it's conf line at all? -Vesa */
180 if (quotedLine[1] == ':')
181 oldParseOneLine(out,quotedLine);
185 fclose(file);
187 write_auth_entries(out);
188 fclose(out);
192 * ReplaceQuotes
193 * Inputs - input line to quote
194 * Output - quoted line
195 * Side Effects - All quoted chars in input are replaced
196 * with quoted values in output, # chars replaced with '\0'
197 * otherwise input is copied to output.
199 static void ReplaceQuotes(char* quotedLine,char *inputLine)
201 char *in;
202 char *out;
203 static char quotes[] = {
204 0, /* */
205 0, /* a */
206 '\b', /* b */
207 0, /* c */
208 0, /* d */
209 0, /* e */
210 '\f', /* f */
211 0, /* g */
212 0, /* h */
213 0, /* i */
214 0, /* j */
215 0, /* k */
216 0, /* l */
217 0, /* m */
218 '\n', /* n */
219 0, /* o */
220 0, /* p */
221 0, /* q */
222 '\r', /* r */
223 0, /* s */
224 '\t', /* t */
225 0, /* u */
226 '\v', /* v */
227 0, /* w */
228 0, /* x */
229 0, /* y */
230 0, /* z */
231 0,0,0,0,0,0
235 * Do quoting of characters and # detection.
237 for (out = quotedLine,in = inputLine; *in; out++, in++)
239 if (*in == '\\')
241 in++;
242 if(*in == '\\')
243 *out = '\\';
244 else if(*in == '#')
245 *out = '#';
246 else
247 *out = quotes[ (unsigned int) (*in & 0x1F) ];
249 else if (*in == '#')
251 *out = '\0';
252 return;
254 else
255 *out = *in;
257 *out = '\0';
261 * oldParseOneLine
262 * Inputs - pointer to line to parse
263 * - pointer to output to write
264 * Output -
265 * Side Effects - Parse one old style conf line.
268 static void oldParseOneLine(FILE *out,char* line)
270 char conf_letter;
271 char* tmp;
272 const char* host_field=NULL;
273 const char* passwd_field=NULL;
274 const char* user_field=NULL;
275 const char* port_field = NULL;
276 const char* classconf_field = NULL;
277 int class_field = 0;
279 tmp = getfield(line);
281 conf_letter = *tmp;
283 for (;;) /* Fake loop, that I can use break here --msa */
285 /* host field */
286 if ((host_field = getfield(NULL)) == NULL)
287 return;
289 /* pass field */
290 if ((passwd_field = getfield(NULL)) == NULL)
291 break;
293 /* user field */
294 if ((user_field = getfield(NULL)) == NULL)
295 break;
297 /* port field */
298 if ((port_field = getfield(NULL)) == NULL)
299 break;
301 /* class field */
302 if ((classconf_field = getfield(NULL)) == NULL)
303 break;
305 break;
308 if (!passwd_field)
309 passwd_field = "";
310 if (!user_field)
311 user_field = "";
312 if (!port_field)
313 port_field = "";
314 if (classconf_field)
315 class_field = atoi(classconf_field);
317 switch( conf_letter )
319 case 'i':
320 case 'I':
322 struct AuthBlock *ptr;
323 struct AuthBlock *tempptr;
325 tempptr = malloc(sizeof(struct AuthBlock));
326 memset(tempptr, 0, sizeof(*tempptr));
328 if(conf_letter == 'i')
330 tempptr->flags |= FLAGS_RESTRICTED;
331 tempptr->specialk = 1;
334 if(passwd_field && *passwd_field)
335 tempptr->passwd = strdup(passwd_field);
337 tempptr->class = class_field;
339 set_flags(tempptr, user_field, host_field);
341 /* dont add specials/passworded ones to existing auth blocks */
342 if((ptr = find_matching_conf(tempptr)))
344 int authindex;
346 authindex = ptr->hostnum;
347 ptr->hostnum++;
349 ptr->hostname = realloc((void *)ptr->hostname, ptr->hostnum * sizeof(void *));
351 ptr->hostname[authindex] = strdup(tempptr->hostname[0]);
353 free(tempptr->hostname[0]);
354 free(tempptr->hostname);
355 free(tempptr);
357 else
359 ptr = tempptr;
361 if(ptr->spoof)
363 ptr->next = auth_spoof;
364 auth_spoof = ptr;
366 else if(ptr->special)
368 ptr->next = auth_special;
369 auth_special = ptr;
371 else if(ptr->passwd)
373 ptr->next = auth_passwd;
374 auth_passwd = ptr;
376 else if(ptr->specialk)
378 ptr->next = auth_restricted;
379 auth_restricted = ptr;
381 else
383 ptr->next = auth_general;
384 auth_general = ptr;
388 break;
390 default:
391 break;
395 static void write_auth_entries(FILE *out)
397 struct AuthBlock *ptr;
399 for(ptr = auth_spoof; ptr; ptr = ptr->next)
400 write_specific(out, ptr);
402 for(ptr = auth_special; ptr; ptr = ptr->next)
403 write_specific(out, ptr);
405 for(ptr = auth_passwd; ptr; ptr = ptr->next)
406 write_specific(out, ptr);
408 for(ptr = auth_general; ptr; ptr = ptr->next)
409 write_specific(out, ptr);
411 for(ptr = auth_restricted; ptr; ptr = ptr->next)
412 write_specific(out, ptr);
416 static void write_specific(FILE *out, struct AuthBlock *ptr)
418 int i;
419 int prev = 0;
421 fprintf(out, "auth {\n");
423 for(i = 0; i < ptr->hostnum; i++)
424 fprintf(out, "\tuser = \"%s\";\n", ptr->hostname[i]);
426 if(ptr->spoof)
427 fprintf(out, "\tspoof = \"%s\";\n", ptr->spoof);
429 if(ptr->passwd)
430 fprintf(out, "\tpassword = \"%s\";\n", ptr->passwd);
432 if(ptr->flags)
434 fprintf(out, "\tflags = ");
436 for(i = 0; flag_table[i].flag; i++)
438 if(ptr->flags & flag_table[i].flag)
440 fprintf(out, "%s%s",
441 prev ? ", " : "",
442 flag_table[i].name);
443 prev = 1;
447 fprintf(out, ";\n");
450 fprintf(out, "\tclass = \"%d\";\n", ptr->class);
451 fprintf(out, "};\n");
455 * field breakup for ircd.conf file.
457 static char *getfield(char *newline)
459 static char *line = NULL;
460 char *end, *field;
462 if (newline)
463 line = newline;
465 if (line == NULL)
466 return(NULL);
468 field = line;
469 if ((end = strchr(line,':')) == NULL)
471 line = NULL;
472 if ((end = strchr(field,'\n')) == NULL)
473 end = field + strlen(field);
475 else
476 line = end + 1;
477 *end = '\0';
478 return(field);
481 struct AuthBlock *find_matching_conf(struct AuthBlock *acptr)
483 struct AuthBlock *ptr;
485 for(ptr = auth_spoof; ptr; ptr = ptr->next)
487 if(match(ptr, acptr))
488 return ptr;
491 for(ptr = auth_special; ptr; ptr = ptr->next)
493 if(match(ptr, acptr))
494 return ptr;
497 for(ptr = auth_passwd; ptr; ptr = ptr->next)
499 if(match(ptr, acptr))
500 return ptr;
503 for(ptr = auth_restricted; ptr; ptr = ptr->next)
505 if(match(ptr, acptr))
506 return ptr;
509 for(ptr = auth_general; ptr; ptr = ptr->next)
511 if(match(ptr, acptr))
512 return ptr;
516 return NULL;
519 static int match(struct AuthBlock *ptr, struct AuthBlock *acptr)
521 if((ptr->class == acptr->class) &&
522 (ptr->flags == acptr->flags))
524 const char *p1, *p2;
526 /* check the spoofs match.. */
527 if(ptr->spoof)
528 p1 = ptr->spoof;
529 else
530 p1 = "";
532 if(acptr->spoof)
533 p2 = acptr->spoof;
534 else
535 p2 = "";
537 if(strcmp(p1, p2))
538 return 0;
540 /* now check the passwords match.. */
541 if(ptr->passwd)
542 p1 = ptr->passwd;
543 else
544 p1 = "";
546 if(acptr->passwd)
547 p2 = acptr->passwd;
548 else
549 p2 = "";
551 if(strcmp(p1, p2))
552 return 0;
554 return 1;
557 return 0;
560 void set_flags(struct AuthBlock *ptr, const char *user_field, const char *host_field)
562 for(; *user_field; user_field++)
564 switch(*user_field)
566 case '=':
567 if(host_field)
568 ptr->spoof = strdup(host_field);
570 ptr->special = 1;
571 break;
573 case '-':
574 ptr->flags |= FLAGS_NOTILDE;
575 ptr->special = 1;
576 break;
578 case '+':
579 ptr->flags |= FLAGS_NEEDIDENT;
580 ptr->specialk = 1;
581 break;
583 case '^': /* is exempt from k/g lines */
584 ptr->flags |= FLAGS_KLINEEXEMPT;
585 ptr->special = 1;
586 break;
588 case '>':
589 ptr->flags |= FLAGS_EXCEEDLIMIT;
590 ptr->special = 1;
591 break;
593 case '_':
594 case '!':
595 case '$':
596 case '%':
597 case '&':
598 case '<':
599 break;
601 default:
603 int authindex;
604 authindex = ptr->hostnum;
605 ptr->hostnum++;
607 ptr->hostname = realloc((void *)ptr->hostname, ptr->hostnum * sizeof(void *));
609 /* if the IP field contains something useful, use that */
610 if(strcmp(host_field, "NOMATCH") && (*host_field != 'x') &&
611 strcmp(host_field, "*") && !ptr->spoof)
612 ptr->hostname[authindex] = strdup(host_field);
613 else
614 ptr->hostname[authindex] = strdup(user_field);
616 return;