From d66bae3f55b4ac3fe7263d3890cdb26380a74385 Mon Sep 17 00:00:00 2001 From: Perry Lorier Date: Sat, 19 Feb 2005 21:50:48 +0000 Subject: [PATCH] Author: Perry Lorier Log message: Lots of fixes to the convert-conf program. It no longer generates Server blocks (which have been removed from the latest copy of the config), it's smarter about how it generates it's I:line configs, the line parser now is much closer to ircu's parser avoiding a lot of bugs. And a multitude of other minor problems fixed up. git-svn-id: file:///home/klmitch/undernet-ircu/undernet-ircu-svn/ircu2/trunk@1318 c9e4aea6-c8fd-4c43-8297-357d70d61c8c --- ChangeLog | 6 ++ tools/convert-conf.py | 191 +++++++++++++++++++++++++++++++++--------- 2 files changed, 158 insertions(+), 39 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1d5dfde..a7e32ba 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2005-02-20 Perry Lorier + + * tools/convert-conf.py: A multitude of changes to deal with parsing + mistakes, generate a newer config file, better error handling, + being smarter about what config elements you generate etc. + 2005-02-20 Perry Lorier * ircd/engine_epoll.c: Change a size_t to socklen_t to match diff --git a/tools/convert-conf.py b/tools/convert-conf.py index 64a2dea..825b03f 100755 --- a/tools/convert-conf.py +++ b/tools/convert-conf.py @@ -22,48 +22,59 @@ # Usage: # convert-conf.py < old.conf > new.conf # -# $Id: convert-conf.py,v 1.1 2002-04-09 22:40:56 vampire Exp $ +# $Id: convert-conf.py,v 1.2 2005-02-19 21:50:48 isomer Exp $ # import sys from string import * +import re if len(sys.argv) > 1: f = open(sys.argv[1], "r") else: f = sys.stdin -servers = {} +connects = {} jupes = [] -feats = [] +feats = [ ("OPLEVELS","FALSE")] + +def qstr(s): + return replace(s,'"','\\"') + +def istr(s): + return str(int(strip(s))) + def do_uline(parts): - if not servers.has_key(parts[1]): - servers[parts[1]] = ['*', 0, 0, 0] - servers[parts[1]][1] = 1 + print "Uworld {" + print "\tname = \"%s\";" % qstr(parts[1]) + print "};" + print if len(parts[2]): - jupes.append(parts[2]) + for i in split(parts[2],","): + jupes.append(i) def do_hline(parts): - if not servers.has_key(parts[3]): - servers[parts[3]] = ['*', 0, 0, 0] - servers[parts[3]][0] = parts[1] - servers[parts[3]][2] = 1 + if not connects.has_key(lower(parts[3])): + connects[lower(parts[3])]={ + "name" : lower(parts[3]) + } + connects[lower(parts[3])]["hub"] = parts[1] def do_lline(parts): - if not servers.has_key(parts[3]): - servers[parts[3]] = ['*', 0, 0, 0] - servers[parts[3]][0] = parts[1] - servers[parts[3]][3] = 1 + if not connects.has_key(lower(parts[3])): + connects[lower(parts[3])]={ + "name" : lower(parts[3]) + } + del connects[lower(parts[3])]["hub"] def do_pline(parts): - print "#", join(parts, ":") print "Port {" - print "\tport = %s;" % parts[4] + print "\tport = %s;" % istr(parts[4]) if len(parts[1]): - print "\tmask = \"%s\";" % parts[1] + print "\tmask = \"%s\";" % qstr(parts[1]) if len(parts[2]): - print "\tvhost = \"%s\";" % parts[2] + print "\tvhost = \"%s\";" % qstr(parts[2]) if count(parts[3], 'S'): print "\tserver = yes;" if count(parts[3], 'H'): @@ -74,18 +85,79 @@ def do_pline(parts): def do_fline(parts): feats.append((parts[1], parts[2])) +def do_kline(parts): + if len(parts)!=4: + sys.stderr.write("WARNING: Wrong number of parameters on line %i\n" % lno) + return + letter,host,reason,user=parts + print "Kill {" + if host[:2]=="$R": + if host=="$R": + sys.stderr.write("WARNING: Empty realname kline on line %i\n" % lno) + print "\trealname = \"%s\";" % qstr(host[2:]) + else: + print "\thost = \"%s@%s\";" % (qstr(user),qstr(host)) + if reason[:1]=="!": + print "\tfile = \"%s\";" % qstr(reason[1:]) + else: + print "\treason = \"%s\";" % qstr(reason) + print "};" + print + +def do_iline(parts): + if len(parts)!=6: + sys.stderr.write("WARNING: I:line doesn't have enough fields on line %i\n" % lno) + return + iline,ip,password,host,dummy,clss = parts + for i in [0,1]: + mask = [ip,host][i] + # Ignore things that aren't masks + if "." not in mask and "*" not in mask and "@" not in mask: + continue + if "@" in mask: + user,host = split(mask,"@") + else: + user,host = "*",mask + if i==0 and not re.match("^[0-9\.\*]+$",host): + sys.stderr.write("WARNING: Bad IP mask in line %s (%s)\n" % (lno,repr(mask))) + continue + print "Client {" + if re.match("^[1-9][1-9]?$",password): + print "\tmaxlinks = %s;" % int(password) + elif password: + print "\tpassword = \"%s\";" % qstr(password) + print "\tclass = \"%s\";" % clss + if i == 0: + print "\tip = \"%s\";" % qstr(host) + else: + print "\thost = \"%s\";" % qstr(host) + if user!="*": + print "\tusername = \"%s\";" % qstr(user) + print "};" + print + +def do_cline(parts): + name=lower(parts[3]) + if not connects.has_key(name): + connects[name]={} + connects[name]["host"]=parts[1] + connects[name]["password"]=parts[2] + connects[name]["name"]=parts[3] + connects[name]["port"]=parts[4] + connects[name]["class"]=parts[5] + cvtmap = { 'M': ('General', ('name', 'vhost', 'description', '', '!numeric'), ''), 'A': ('Admin', ('location', 'contact', 'contact'), ''), 'Y': ('Class', ('name', '!pingfreq', '!connectfreq', '!maxlinks', '!sendq'), ''), - 'I': ('Client', ('ip', 'password', 'host', '', 'class'), ''), + 'I': do_iline, 'T': ('motd', ('host', 'file'), ''), 'U': do_uline, 'H': do_hline, 'L': do_lline, - 'K': ('Kill', ('host', 'reason'), ''), - 'k': ('Kill', ('host', 'reason'), ''), - 'C': ('Connect', ('host', 'password', 'name', '!port', 'class'), ''), + 'K': do_kline, + 'k': do_kline, + 'C': do_cline, 'D': ('CRULE', ('server', '', 'rule'), '\tall = yes;'), 'd': ('CRULE', ('server', '', 'rule'), ''), 'O': ('Operator', ('host', 'password', 'name', '', 'class'), '\tlocal = no;'), @@ -94,18 +166,55 @@ cvtmap = { 'F': do_fline } +lno=0 for line in f.readlines(): + lno=lno+1 line = strip(line) + if line=="": + continue + if line[0]=="#": + print "#"+line + continue + print "#",line parts = split(line, ":") + parts=[''] + # This statemachine is pretty much directly stolen from ircu + # to give an "authentic" parser :) + state=0 # normal + quoted=0 + for i in line: + if state==0: + if i=="\\": + state=1 # escaped + elif i=='"': + quoted=not quoted + elif i==':': + if quoted: + parts[-1]=parts[-1]+i + else: + parts.append("") + elif i=='#': + break + else: + parts[-1]=parts[-1]+i + elif state==1: + if i in "bfnrtv": + parts[-1]=parts[-1]+"\b\f\n\r\t\v"[index("bfnrtv",i)] + else: + parts[-1]=parts[-1]+i + state=0 + if quoted: + sys.stderr.write("WARNING: No closing quote on line %i\n"%lno) if not len(parts): continue if not cvtmap.has_key(parts[0]): + print "#Unknown:",line continue if callable(cvtmap[parts[0]]): cvtmap[parts[0]](parts) continue (block, items, extra) = cvtmap[parts[0]] - print "#", line + print block, "{" idx = 1 for item in items: @@ -113,36 +222,40 @@ for line in f.readlines(): break if len(parts[idx]) and len(item): if item[0] == '!': - print "\t%s = %s;" % (item[1:], parts[idx]) + print "\t%s = %s;" % (item[1:], istr(parts[idx])) else: - print "\t%s = \"%s\";" % (item, parts[idx]) + print "\t%s = \"%s\";" % (item, qstr(parts[idx])) idx = idx + 1 if len(extra): print extra print "};" print -for server in servers.keys(): - (mask, uw, hub, leaf) = servers[server] - print "Server {" - print "\tname = \"%s\";" % server - print "\tmask = \"%s\";" % mask - if uw: print "\tuworld = yes;" - if hub: print "\thub = yes;" - if leaf: print "\tleaf = yes;" - print "};" - print - if len(jupes): print "Jupe {" for nick in jupes: - print "\tnick = \"%s\";" % nick + print "\tnick = \"%s\";" % qstr(nick) print "};" print +if len(connects.keys()): + for i in connects.keys(): + print "Connect {" + print "\tname = \"%s\";" % qstr(connects[i]["name"]) + print "\thost = \"%s\";" % qstr(connects[i]["host"]) + print "\tpassword = \"%s\";" % qstr(connects[i]["password"]) + print "\tport = %s;" % connects[i]["port"] + print "\tclass = \"%s\";" % qstr(connects[i]["class"]) + if connects[i].has_key("hub"): + print "\thub = \"%s\";" % qstr(connects[i]["hub"]) + else: + print "\tleaf = \"yes\";" + print "};" + print + if len(feats): print "features {" for (name, value) in feats: - print "\t\"%s\" = \"%s\";" % (name, value) + print "\t\"%s\" = \"%s\";" % (qstr(name), qstr(value)) print "};" print -- 2.20.1