Author: Isomer <isomer@undernet.org>
[ircu2.10.12-pk.git] / tools / convert-conf.py
1 #!/usr/bin/env python
2 #
3 # IRC - Internet Relay Chat, tools/convert-conf.py
4 # Copyright (C) 2002 Alex Badea <vampire@p16.pub.ro>
5 #
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 1, or (at your option)
9 # any later version.
10 #
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 #
20 #
21 # Configuration file converter from 2.10.11 to 2.10.12 format
22 # Usage:
23 #   convert-conf.py < old.conf > new.conf
24 #
25 # $Id: convert-conf.py,v 1.4 2005-04-09 03:54:24 isomer Exp $
26 #
27
28 import sys
29 from string import *
30 import re
31
32 if len(sys.argv) > 1:
33         f = open(sys.argv[1], "r")
34 else:
35         f = sys.stdin
36
37 connects = {}
38 jupes = []
39 feats = [ ("OPLEVELS","FALSE")]
40
41 def qstr(s):
42         return replace(s,'"','\\"')
43
44 def istr(s):
45         return str(int(strip(s)))
46         
47
48 def do_uline(parts):
49         print "Uworld {"
50         print "\tname = \"%s\";" % qstr(parts[1])
51         print "};"
52         print
53         if len(parts[2]):
54                 for i in split(parts[2],","):
55                         jupes.append(i)
56
57 def do_hline(parts):
58         if not connects.has_key(lower(parts[3])):
59                 connects[lower(parts[3])]={
60                         "name" : lower(parts[3])
61                 }
62         connects[lower(parts[3])]["hub"] = parts[1]
63
64 def do_lline(parts):
65         if not connects.has_key(lower(parts[3])):
66                 connects[lower(parts[3])]={
67                         "name" : lower(parts[3])
68                 }
69         del connects[lower(parts[3])]["hub"]
70
71 def do_pline(parts):
72         print "Port {"
73         print "\tport = %s;" % istr(parts[4])
74         if len(parts[1]):
75                 print "\tmask = \"%s\";" % qstr(parts[1])
76         if len(parts[2]):
77                 print "\tvhost = \"%s\";" % qstr(parts[2])
78         if count(parts[3], 'S'):
79                 print "\tserver = yes;"
80         if count(parts[3], 'H'):
81                 print "\thidden = yes;"
82         print "};"
83         print
84
85 def do_fline(parts):
86         feats.append((parts[1], parts[2]))
87
88 def do_kline(parts):
89         if len(parts)!=4:
90                 sys.stderr.write("WARNING: Wrong number of parameters on line %i\n" % lno)
91                 return
92         letter,host,reason,user=parts
93         print "Kill {"
94         if host[:2]=="$R":
95                 if host=="$R":
96                         sys.stderr.write("WARNING: Empty realname kline on line %i\n" % lno)
97                 print "\trealname = \"%s\";" % qstr(host[2:])
98         else:
99                 print "\thost = \"%s@%s\";" % (qstr(user),qstr(host))
100         if reason[:1]=="!":
101                 print "\tfile = \"%s\";" % qstr(reason[1:])
102         else:
103                 print "\treason = \"%s\";" % qstr(reason)
104         print "};"
105         print
106
107 def do_iline(parts):
108         if len(parts)!=6:
109                 sys.stderr.write("WARNING: I:line doesn't have enough fields on line %i\n" % lno)
110                 return
111         iline,ip,password,hostname,dummy,clss = parts
112         for i in [0,1]:
113                 mask = [ip,hostname][i]
114                 # Ignore things that aren't masks
115                 if "." not in mask and "*" not in mask and "@" not in mask:
116                         continue
117                 if "@" in mask:
118                         user,host = split(mask,"@")
119                 else:
120                         user,host = "*",mask
121                 if i==0 and not re.match("^[0-9\.\*]+$",host):
122                         sys.stderr.write("WARNING: Bad IP mask in line %s (%s)\n" % (lno,repr(mask)))
123                         continue
124                 print "Client {"
125                 if re.match("^[1-9][1-9]?$",password):
126                         print "\tmaxlinks = %s;" % int(password)
127                 elif password:
128                         print "\tpassword = \"%s\";" % qstr(password)
129                 print "\tclass = \"%s\";" % clss
130                 if i == 0:
131                         print "\tip = \"%s\";" % qstr(host)
132                 else:
133                         print "\thost = \"%s\";" % qstr(host)
134                 if user!="*":
135                         print "\tusername = \"%s\";" % qstr(user)
136                 print "};"
137                 print
138
139 def do_cline(parts):
140         name=lower(parts[3])
141         if not connects.has_key(name):
142                 connects[name]={}
143         connects[name]["host"]=parts[1]
144         connects[name]["password"]=parts[2]
145         connects[name]["name"]=parts[3]
146         connects[name]["port"]=parts[4]
147         connects[name]["class"]=parts[5]
148
149 cvtmap = {
150         'M': ('General', ('name', 'vhost', 'description', '', '!numeric'), ''),
151         'A': ('Admin', ('location', 'contact', 'contact'), ''),
152         'Y': ('Class', ('name', '!pingfreq', '!connectfreq', '!maxlinks', '!sendq'), ''),
153         'I': do_iline,
154         'T': ('motd', ('host', 'file'), ''),
155         'U': do_uline,
156         'H': do_hline,
157         'L': do_lline,
158         'K': do_kline,
159         'k': do_kline,
160         'C': do_cline,
161         'D': ('CRULE', ('server', '', 'rule'), '\tall = yes;'),
162         'd': ('CRULE', ('server', '', 'rule'), ''),
163         'O': ('Operator', ('host', 'password', 'name', '', 'class'), '\tlocal = no;'),
164         'o': ('Operator', ('host', 'password', 'name', '', 'class'), '\tlocal = yes;'),
165         'P': do_pline,
166         'F': do_fline
167 }
168
169 lno=0
170 for line in f.readlines():
171         lno=lno+1
172         line = strip(line)
173         if line=="":
174                 continue
175         if line[0]=="#":
176                 print "#"+line
177                 continue
178         print "#",line
179         parts = split(line, ":")
180         parts=['']
181         # This statemachine is pretty much directly stolen from ircu
182         # to give an "authentic" parser :)
183         state=0 # normal
184         quoted=0
185         for i in line:
186                 if state==0:
187                         if i=="\\":
188                                 state=1 # escaped
189                         elif i=='"':
190                                 quoted=not quoted
191                         elif i==':':
192                                 if quoted:
193                                         parts[-1]=parts[-1]+i
194                                 else:
195                                         parts.append("")
196                         elif i=='#':
197                                 break
198                         else:
199                                 parts[-1]=parts[-1]+i
200                 elif state==1:
201                         if i in "bfnrtv":
202                                 parts[-1]=parts[-1]+"\b\f\n\r\t\v"[index("bfnrtv",i)]
203                         else:
204                                 parts[-1]=parts[-1]+i
205                         state=0
206         if quoted:
207                 sys.stderr.write("WARNING: No closing quote on line %i\n"%lno)
208         if not len(parts):
209                 continue
210         if not cvtmap.has_key(parts[0]):
211                 print "#Unknown:",line
212                 continue
213         if callable(cvtmap[parts[0]]):
214                 cvtmap[parts[0]](parts)
215                 continue
216         (block, items, extra) = cvtmap[parts[0]]
217
218         print block, "{"
219         idx = 1
220         for item in items:
221                 if idx >= len(parts):
222                         break
223                 if len(parts[idx]) and len(item):
224                         if item[0] == '!':
225                                 print "\t%s = %s;" % (item[1:], istr(parts[idx]))
226                         else:
227                                 print "\t%s = \"%s\";" % (item, qstr(parts[idx]))
228                 idx = idx + 1
229         if len(extra):
230                 print extra
231         print "};"
232         print
233
234 if len(jupes):
235         print "Jupe {"
236         for nick in jupes:
237                 print "\tnick = \"%s\";" % qstr(nick)
238         print "};"
239         print
240
241 if len(connects.keys()):
242         for i in connects.keys():
243                 print "Connect {"
244                 print "\tname = \"%s\";" % qstr(connects[i]["name"])
245                 print "\thost = \"%s\";" % qstr(connects[i]["host"])
246                 print "\tpassword = \"%s\";" % qstr(connects[i]["password"])
247                 print "\tport = %s;" % connects[i]["port"]
248                 print "\tclass = \"%s\";" % qstr(connects[i]["class"])
249                 if connects[i].has_key("hub"):
250                         print "\thub = \"%s\";" % qstr(connects[i]["hub"])
251                 else:
252                         print "\tleaf;"
253                 print "};"
254                 print
255
256 if len(feats):
257         print "features {"
258         for (name, value) in feats:
259                 print "\t\"%s\" = \"%s\";" % (qstr(name), qstr(value))
260         print "};"
261         print