From d17b009ffec3077bf8db6e6902a7456ec90e9c38 Mon Sep 17 00:00:00 2001 From: Matěj Cepl Date: Mon, 5 Jan 2015 09:03:05 +0100 Subject: First draft of the pure Python parser done, we should be noarch. Fixes #2 --- setup.py | 37 +------------ test/__init__.py | 13 ----- test/test_pyg.py | 13 ++--- test/test_wlp.py | 93 +++++++++++++++++++------------ whitelist.py | 34 ++++++------ wlp.py | 36 ++++++++++++ wlp/Makefile | 42 -------------- wlp/Makefile.C | 61 --------------------- wlp/README | 12 ---- wlp/commands.l | 76 -------------------------- wlp/commands.y | 111 ------------------------------------- wlp/macro.h | 44 --------------- wlp/structs.c | 164 ------------------------------------------------------- wlp/structs.h | 35 ------------ wlp/test.c | 113 -------------------------------------- wlp/wlp.c | 154 --------------------------------------------------- wlp/yytest.c | 25 --------- wlp_lex.py | 12 ---- wlp_parser.py | 68 +++++++++++++++++++++++ wlp_yacc.py | 108 ------------------------------------ 20 files changed, 187 insertions(+), 1064 deletions(-) create mode 100644 wlp.py delete mode 100644 wlp/Makefile delete mode 100644 wlp/Makefile.C delete mode 100644 wlp/README delete mode 100644 wlp/commands.l delete mode 100644 wlp/commands.y delete mode 100644 wlp/macro.h delete mode 100644 wlp/structs.c delete mode 100644 wlp/structs.h delete mode 100644 wlp/test.c delete mode 100644 wlp/wlp.c delete mode 100644 wlp/yytest.c delete mode 100644 wlp_lex.py create mode 100644 wlp_parser.py delete mode 100644 wlp_yacc.py diff --git a/setup.py b/setup.py index e74d78a..d370040 100644 --- a/setup.py +++ b/setup.py @@ -1,42 +1,15 @@ #!/usr/bin/python # -*- coding: utf-8 -*- from __future__ import print_function + +from mail2news import VERSION, DESC import os.path from setuptools import setup -from distutils.core import Extension -from distutils.command.build_ext import build_ext -from subprocess import check_call -from mail2news import VERSION, DESC - - -class Build_WLP_ext(build_ext): - def run(self): - self.make_file( - 'wlp/commands.y', 'wlp/commands.tab.c', check_call, - # Yes, the following line contains list-in-list-in-tuple, and - # that's how it should be. - # otherwise, subsequent calls down the stack unwind the list and - # check_call won't get it. - ([['yacc', '-d', '-o', 'wlp_c/commands.tab.c', - 'wlp_c/commands.y']]), - 'Generating lexer') - self.make_file( - 'wlp/commands.l', 'wlp/lex.yy.c', check_call, - ([['lex', '-o', 'wlp/lex.yy.c', 'wlp/commands.l']]), - 'Generating parser') - build_ext.run(self) def read(fname): return open(os.path.join(os.path.dirname(__file__), fname)).read() -# see https://github.com/Turbo87/py-xcsoar/blob/master/setup.py -wlp_module = Extension('wlp', - sources=['wlp/wlp.c', - 'wlp/structs.c', - 'wlp/commands.tab.c', - 'wlp/lex.yy.c']) - setup(name='pygn', version=VERSION, # the current Debian version is 0.9.8 @@ -46,14 +19,8 @@ setup(name='pygn', long_description=read('README'), url='https://gitlab.com/mcepl/pyg', py_modules=['mail2news', 'news2mail', 'setup', 'whitelist'], - ext_modules=[wlp_module], test_suite="test", scripts=['pygm2n', 'pygn2m'], - cmdclass={ - 'build_ext': Build_WLP_ext - }, - # TODO package actually requires lex and yacc port, but not sure - # how to say it here requires=['rply'], license="GPLv3", keywords=["nntp", "email", "gateway"], diff --git a/test/__init__.py b/test/__init__.py index 55f45b6..e69de29 100644 --- a/test/__init__.py +++ b/test/__init__.py @@ -1,13 +0,0 @@ -import os.path -import sys -import sysconfig - - -def distutils_dir_name(dname): - """Returns the name of a distutils build directory""" - f = "{dirname}.{platform}-{version[0]}.{version[1]}" - return f.format(dirname=dname, - platform=sysconfig.get_platform(), - version=sys.version_info) -wlp_lib_path = os.path.join('build', distutils_dir_name('lib')) -sys.path.insert(0, wlp_lib_path) diff --git a/test/test_pyg.py b/test/test_pyg.py index 240228b..4c1c1c0 100755 --- a/test/test_pyg.py +++ b/test/test_pyg.py @@ -1,15 +1,12 @@ #!/usr/bin/python # -*- coding: utf-8 -*- -import mail2news -import os -import os.path import re import subprocess -import sys -import test import unittest +import mail2news + class TestM2N(unittest.TestCase): expected_output = """Newsgroups: pyg.test @@ -38,6 +35,7 @@ one line test self.assertEqual(out, self.expected_output) +# @unittest.skip('not ready') class TestN2M(unittest.TestCase): expected_output = """Received: from GATEWAY by mitmanek.ceplovi.cz with pyg for ; Mon Dec 15 17:13:30 2014 (CEST) @@ -59,15 +57,12 @@ Resent-Sender: sender@example.com """ % (mail2news.VERSION, mail2news.DESC) def test_n2m(self): - env = os.environ - env['PYTHONPATH'] = ":".join(sys.path) - with open('examples/articletest.accepted') as in_mail: pid = subprocess.Popen(['./pygn2m', '-Tvt', 'test@example.com', '-s', 'sender@example.com', '-w', 'examples/whitelist.example'], stdin=subprocess.PIPE, - stdout=subprocess.PIPE, env=env) + stdout=subprocess.PIPE) in_message = in_mail.read().replace('pyg@pyg.server.tld', 'kame@inwind.it') out, err = pid.communicate(in_message) diff --git a/test/test_wlp.py b/test/test_wlp.py index 9825e44..430c235 100755 --- a/test/test_wlp.py +++ b/test/test_wlp.py @@ -1,13 +1,27 @@ #!/usr/bin/python # -*- coding: utf-8 -*- -import logging -logging.basicConfig(level=logging.DEBUG) import unittest -import wlp -import wlp_lex -import wlp_yacc +import wlp_parser from rply import Token +import whitelist +import wlp + + +# logging.basicConfig(level=logging.DEBUG) + +EXPECTED_WL = { + 'alfarano@students.cs.unibo.it': { + 'From:': 'Cosimo Alfarano', + 'X-Firstname:': 'Cosimo' + }, + 'kame@innocent.com': { + 'From:': 'kame@inwind.it', + 'Reply-to': 'me', + 'Reply-to:': 'KA', + 'Sender:': 'Kalfa' + } +} class TestWLP(unittest.TestCase): @@ -49,44 +63,55 @@ class TestWLP(unittest.TestCase): Token('VAR', 'Sender:'), Token('VAL', '"Kalfa"') ] - tokens = list(wlp_lex.lexer.lex(self.test_input)) + tokens = list(wlp_parser.lexer.lex(self.test_input)) self.assertEqual(tokens, expected_stream) def test_wlp_parser(self): expected_tree = [ - [[Token('OWNER', ''), - [[Token('VAR', 'From:'), - Token('VAL', "'ME'"), - [Token('VAR', 'Sender:'), Token('VAL', '"Cosimo"')], - [Token('VAR', 'Reply-to'), Token('VAL', '"me"')]]]], - [[Token('OWNER', ''), - [[Token('VAR', 'From:'), - Token('VAL', "'Cosimo Alfarano'"), - [Token('VAR', 'X-Firstname:'), Token('VAL', "'Cosimo'")]]]]]], - [[Token('OWNER', ''), - [[Token('VAR', 'From:'), - Token('VAL', "'kame@inwind.it'"), - [Token('VAR', 'Reply-to:'), Token('VAL', '"KA"')], - [Token('VAR', 'Sender:'), Token('VAL', '"Kalfa"')]]]]] + [ + Token('OWNER', ''), + [ + [Token('VAR', 'From:'), Token('VAL', "'ME'")], + [Token('VAR', 'Sender:'), Token('VAL', '"Cosimo"')], + [Token('VAR', 'Reply-to'), Token('VAL', '"me"')] + ] + ], + [ + Token('OWNER', ''), + [ + [Token('VAR', 'From:'), Token('VAL', "'Cosimo Alfarano'")], + [Token('VAR', 'X-Firstname:'), Token('VAL', "'Cosimo'")] + ] + ], + [ + Token('OWNER', ''), + [ + [Token('VAR', 'From:'), Token('VAL', "'kame@inwind.it'")], + [Token('VAR', 'Reply-to:'), Token('VAL', '"KA"')], + [Token('VAR', 'Sender:'), Token('VAL', '"Kalfa"')] + ] + ] ] - lex_stream = wlp_lex.lexer.lex(self.test_input) - tree = wlp_yacc.parser.parse(lex_stream) + lex_stream = wlp_parser.lexer.lex(self.test_input) + tree = wlp_parser.parser.parse(lex_stream) self.assertEqual(tree, expected_tree) - def test_wlp_C_parser(self): + def test_wlp(self): wlp.setfilebyname('examples/whitelist.example') wl_dict = wlp.mkdict() - expected_dict = {'alfarano@students.cs.unibo.it': { - 'From:': 'Cosimo Alfarano', - 'X-Firstname:': 'Cosimo' - }, - 'kame@innocent.com': { - 'From:': 'kame@inwind.it', - 'Reply-to': 'me', - 'Reply-to:': 'KA', - 'Sender:': 'Kalfa'} - } - self.assertEqual(wl_dict, expected_dict) + self.assertEqual(wl_dict, EXPECTED_WL) + + +class TestWhitelist(unittest.TestCase): + def setUp(self): + self.wl = whitelist.whitelist('examples/whitelist.example') + + def test_init(self): + self.assertEqual(self.wl.wl, EXPECTED_WL) + + def test_checkfrom(self): + self.assertEqual(self.wl.checkfrom('kame@inwind.it'), + 'kame@innocent.com') if __name__ == "__main__": unittest.main() diff --git a/whitelist.py b/whitelist.py index cd0906c..7eb111e 100644 --- a/whitelist.py +++ b/whitelist.py @@ -13,8 +13,10 @@ whitelist manage a list of trusted user. """ import logging +# logging.basicConfig(level=logging.DEBUG) import sys import time + import wlp @@ -29,7 +31,7 @@ class whitelist(object): DENY = 0 ACCEPT = 1 - def __init__(self, wlfile='wl.pyg', logfile='pyg.log'): + def __init__(self, wlfile, logfile='pyg.log'): self.logger = logging.getLogger(__name__) self.logger.setLevel(logging.INFO) log_fh = logging.FileHandler(logfile) @@ -49,12 +51,12 @@ class whitelist(object): def checkfrom(self, fromhead): """have you permission to be here, sir?""" - for owner in self.wl.keys(): + for owner in self.wl: # here colon after 'From' IS required, because binary module wl # expects it. # TODO: when switching to the python lexxing, remove this # limitation. - if fromhead[:-1].find(self.wl[owner]['From:']) >= 0: + if fromhead.find(self.wl[owner]['From:']) >= 0: return owner else: return None @@ -77,25 +79,25 @@ class whitelist(object): self.logger.info('at %s (%s)', ltime, tzone) if owner is not None: - self.logger.info('\tWLOwner: ' + owner + '') - self.logger.info('\tFrom: ' + heads.get('From', 'NOT PRESENT')) - self.logger.info('\tSubject: ' + heads.get('Subject', 'NOT PRESENT')) - self.logger.info('\tSender: ' + heads.get('Sender', 'NOT PRESENT')) - self.logger.info('\tDate: ' + heads.get('Date', 'NOT PRESENT')) + self.logger.debug('\tWLOwner: ' + owner + '') + self.logger.debug('\tFrom: ' + heads.get('From', 'NOT PRESENT')) + self.logger.debug('\tSubject: ' + heads.get('Subject', 'NOT PRESENT')) + self.logger.debug('\tSender: ' + heads.get('Sender', 'NOT PRESENT')) + self.logger.debug('\tDate: ' + heads.get('Date', 'NOT PRESENT')) # some client create Message-Id other Message-ID. if 'Message-ID' in heads: - self.logger.info('\tMessage-ID: ' + heads.get('Message-ID')) + self.logger.debug('\tMessage-ID: ' + heads.get('Message-ID')) else: - self.logger.info('\tMessage-Id: ' + heads.get('Message-Id', - 'NOT PRESENT')) + self.logger.debug('\tMessage-Id: ' + heads.get('Message-Id', + 'NOT PRESENT')) # X-Newsgroups: and To: are present if user is trusted, else # Newsgroup: exists since no changes on nntp headers are done. if 'X-Newsgroups' in heads: - self.logger.info('\tTo: ' + heads.get('To', 'NOT PRESENT')) - self.logger.info('\tX-Newsgroups: ' + heads.get('X-Newsgroups', - 'NOT PRESENT')) + self.logger.debug('\tTo: ' + heads.get('To', 'NOT PRESENT')) + self.logger.debug('\tX-Newsgroups: ' + heads.get('X-Newsgroups', + 'NOT PRESENT')) else: - self.logger.info('\tNewsgroups: ' + - heads.get('Newsgroups', 'NOT PRESENT')) + self.logger.debug('\tNewsgroups: ' + + heads.get('Newsgroups', 'NOT PRESENT')) diff --git a/wlp.py b/wlp.py new file mode 100644 index 0000000..64d7361 --- /dev/null +++ b/wlp.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +import wlp_parser + + +__current_file = None + + +def setfilebyname(name): + global __current_file + __current_file = open(name, 'r') + + +def setfilebyfd(fd): + global __current_file + __current_file = fd + + +def mkdict(): + dict = {} + if __current_file is None: + raise ValueError('current file has not been set.') + + tree = wlp_parser.parser.parse( + wlp_parser.lexer.lex(__current_file.read())) + + for subtree in tree: + current_key = subtree[0].getstr().strip('<>') + if current_key not in dict: + dict[current_key] = {} + + for key, value in subtree[1]: + key = key.getstr() + value = value.getstr().strip("'\"") + dict[current_key][key] = value + + return dict diff --git a/wlp/Makefile b/wlp/Makefile deleted file mode 100644 index 7480b47..0000000 --- a/wlp/Makefile +++ /dev/null @@ -1,42 +0,0 @@ -MODULEDIR=module -CSRCDIR=C -BINDIR=.. - -# modules name without $(MODULEDIR) -SOLIST=test.so - - - -all: bin - -bin: initmodule wlp makemodule - chmod 0644 $(MODULEDIR)/*.so - mv $(MODULEDIR)/*.so $(BINDIR) - -# Init Makefile & Co. file for building python module -initmodule: - $(MAKE) -C $(MODULEDIR) -f Makefile.pre.in boot - -# The White List Parser Module -wlp: - $(MAKE) -C $(CSRCDIR) archive - -# Really make python module as .so -makemodule: - $(MAKE) -C $(MODULEDIR) - - - -clean: cleanmodule cleansrc - rm -f $(BINDIR)/*.so - -cleansrc: - $(MAKE) -C $(CSRCDIR) clean - -cleanmodule: - @if test -f $(MODULEDIR)/Makefile; then $(MAKE) -C $(MODULEDIR) clean ;fi - rm -f $(MODULEDIR)/Makefile.pre $(MODULEDIR)/Makefile - rm -f $(MODULEDIR)/config.c - rm -f $(MODULEDIR)/sedscript - rm -f $(MODULEDIR)/Setup - diff --git a/wlp/Makefile.C b/wlp/Makefile.C deleted file mode 100644 index 0c962e6..0000000 --- a/wlp/Makefile.C +++ /dev/null @@ -1,61 +0,0 @@ -DESTDIR= -LIBDIR=/usr/lib64 -BINDIR=/usr/bin -PYGLIBDIR=$(DESTDIR)/$(LIBDIR)/pyg -PYGBINDIR=$(DESTDIR)/$(BINDIR) - -CC=gcc -AR=ar -FLEX=flex -YACC=bison - -CCOPTS=-Wall -ansi -CCSHARED=-fPIC -AROPTS=-rs -FLEXOPTS= -YACCOPTS=-d - -#CPPFLAGS:=$(shell dpkg-buildflags --get CPPFLAGS) -CPPFLAGS:= -# Add more -I and -D options here -## CFLAGS=$(OPT) -I$(INCLUDEPY) -I$(EXECINCLUDEPY) $(DEFS) $(shell dpkg-buildflags --get CFLAGS) -OPTFLAGS=-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -OPTFLAGS+=-grecord-gcc-switches -m64 -mtune=generic -CFLAGS=$(OPTFLAGS) -CXXFLAGS:=$(OPTFLAGS) -OPTLDFLAGS=-Wl,-z,relro -#LDFLAGS:=$(shell dpkg-buildflags --get LDFLAGS) -LDFLAGS:=$(OPTLDFLAGS) - -SRCDIR=. -BINDIR=. - -OBJFILE=structs.o commands.tab.o lex.yy.o - -all: archive bin - -# archive file for python module -archive: structs bison flex macro.h structs.h commands.tab.h - mkdir -p $(PYGLIBDIR) - $(AR) $(AROPTS) $(PYGLIBDIR)/wlp.a $(OBJFILE) - -# binary (executable) file for testing -executable: bin - -bin: structs bison flex macro.h structs.h commands.tab.h - $(CC) $(CCSHARED) $(CCOPTS) $(OBJFILE) \ - yytest.c $(PYGLIBDIR)/libfl.a -o ./yytest - -flex: - $(FLEX) $(FLEXOPTS) commands.l - $(CC) $(CCSHARED) -c lex.yy.c -o lex.yy.o - -bison: - $(YACC) $(YACCOPTS) -d commands.y -b commands - $(CC) $(CCSHARED) -c commands.tab.c -o commands.tab.o - -structs: - $(CC) $(CCSHARED) $(CCOPTS) -c structs.c -o structs.o - -clean: - rm -f $(OBJFILE) lex.yy.c commands.tab.h commands.tab.c wlp.a yytest diff --git a/wlp/README b/wlp/README deleted file mode 100644 index 9c4d9b7..0000000 --- a/wlp/README +++ /dev/null @@ -1,12 +0,0 @@ -To make wlp python module extension type 'make', it should be sufficient. -If it doesn't work, please, send a bug report with full make output to -author or package maintainer and/or (better) try manually to do this steps and -reporting output of the one which give error via email: - -make -C module -f Makefile.pre.in boot # to initialiaze python module Makefile -make -C src archive # to compile python .c extension -make -C module # to really make .so python module - -Please, remeber to report full output. - -Cosimo Alfarano diff --git a/wlp/commands.l b/wlp/commands.l deleted file mode 100644 index ab954cf..0000000 --- a/wlp/commands.l +++ /dev/null @@ -1,76 +0,0 @@ -%{ -/* Lex analyzer for bison grammar */ - -#include "commands.tab.h" -/*#define DEBUG*/ -#include "macro.h" -#include -%} - -OWNER "<"[a-zA-Z0-9_.+-]+@[a-zA-Z0-9._-]+">" -VAL ['`"][a-zA-Z0-9@_+.<>() -]+['`"] -VAR [a-zA-Z0-9_<>-]+[:]? - -%option noyywrap - -%% - - - - -{OWNER} { - DBG("OWNER %s\n",yytext); - yylval.text=yytext; - return(OWNERID); - } - - -{VAL} { - DBG("VAL %s\n",yytext); - yylval.text=yytext; - return(VALID); - } - -{VAR} { - DBG("VAR %s\n",yytext); - yylval.text=yytext; - return(VARID); - } - - -"{" | -"}" | -"=" { - yylval.text=yytext; - return(*yytext); - } - - -"#"[^\n]* | -"\n" | -[[:space:]] ; /* comments 'til EOL and strip all spaces and \n */ - - -"." { - DBG("NOTSTR %s\n",yytext); - yylval.text=yytext; - return(ERROR); - } - - -%% - -#include "structs.h" - -extern struct wlp_list_t *list; - -int parse(FILE *file) -{ - struct wlp_node_t *tmp; - int count; - yyin=file; - - DBG("go!\n"); - yyparse(); - DBG("EOF found\n"); -} diff --git a/wlp/commands.y b/wlp/commands.y deleted file mode 100644 index e6cfb18..0000000 --- a/wlp/commands.y +++ /dev/null @@ -1,111 +0,0 @@ - -%{ -/*#define YYSTYPE char**/ -/*#define DEBUG*/ -#include "macro.h" -#include "string.h" -%} - -%union { - char *text; - char c; -} - -%token VARID -%token VALID -%token OWNERID - -%token ERROR -%token EOFTOK - - -%{ -char left[80], right[80], owner[80]; -char type = 0; /*unused*/ -%} - -%% - - -block: - blockstatement - | block blockstatement - ; - -blockstatement: - owner '{' commandline '}' - ; - -commandline: - command | commandline command - ; - -command: - varpart '=' valpart { found(left,right,owner); } - ; - -owner: - OWNERID { - DBG("Owner %s\n",$1); - strncpy(owner,$1,strlen($1)+1); - } - ; - -varpart: - VARID { - DBG("Left %s\n",$1); - strncpy(left,$1,strlen($1)+1); - } - ; - -valpart: - VALID { - DBG("Right %s\n",$1); - strncpy(right,$1,strlen($1)+1); - } - ; - -%% - -#include -#include -#include "structs.h" - -extern struct wlp_list_t *list; - -int yyerror (char *s) /* Called by yyparse on error */ -{ - printf ("error: %s\n", s); - return 1; -} - -int found(const char* left, const char* right, const char *owner) -{ - static struct wlp_node_t *node; - - /* alloc node with non-empty fields (ie alloc them too)*/ - node = wlpn_alloc(FALSE); - if(!node) { - DBG("wlpn_alloc in found returned NULL\n"); - } - - strncpy(node->right,right,strlen(right)); - strncpy(node->left,left,strlen(left)); - strncpy(node->owner,owner,strlen(owner)); - - #ifndef WITHQUOTES - /* remove quotes of value part */ - node->right += 1; - node->right[strlen(node->right)-1] = '\0'; - #endif - #ifndef WITHANGBRACKETS - /* remove angle brackets of owner part */ - node->owner += 1; - node->owner[strlen(node->owner)-1] = '\0'; - #endif - - if(!list) - list = wlpl_init(node); - else - wlpn_add(list,node); -} diff --git a/wlp/macro.h b/wlp/macro.h deleted file mode 100644 index 303b3c6..0000000 --- a/wlp/macro.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * macro.h - Copyright 2000, 2001 Cosimo Alfarano - * You can use this software under the terms of the GPL. If we meet some day, - * and you think this stuff is worth it, you can buy me a beer in return. - * - * Thanks to md for this useful formula. Beer is beer. - */ - - -#ifndef _macro_h_ -#define _macro_h_ - -#define LINELEN 2048 -#define TRUE 1 -#define FALSE 0 - -/* -#define WITHQUOTES -#define WITHANGBRACKETS -*/ - -#define ERR(a,b...) fprintf(stderr, a, ## b) - -/* Define it for debug info on stderr (better if in .c module ...) */ -/* -#ifndef DEBUG - #define DEBUG -#endif -*/ - - -#ifdef DEBUG - #define DBG(a...) fprintf(stderr, ## a) - /* for a verbose debug*/ - #define VDBG(a,b...) fprintf(stderr, "%s(): " a, __FUNCTION__ , ## b) -#else - #define DBG(a...) - #define VDBG(a...) -#endif - - -#endif - -/* EOF */ diff --git a/wlp/structs.c b/wlp/structs.c deleted file mode 100644 index 8c33443..0000000 --- a/wlp/structs.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * structs.c - Copyright 2000 by Cosimo Alfarano - * You can use this software under the terms of the GPL. If we meet some day, - * and you think this stuff is worth it, you can buy me a beer in return. - * - * Thanks to md for this useful formula. Beer is beer. - */ - - -#include -#include -#include -#include - -#include "structs.h" -#include "macro.h" - -struct wlp_node_t *wlpn_add(struct wlp_list_t *list,struct wlp_node_t *node) -{ - struct wlp_node_t *ret; - - if(node) { - node->next = list->head; - node->prev = list->tail; - - list->tail->next = node; - list->head->prev = node; - - list->tail = node; - - list->count++; - - ret = node; - } else { - DBG("cannot add %s %s to list. NULL pointer?\n", - node->left,node->right); - ret = NULL; - } - - return ret; -} - -void wlpn_free(struct wlp_node_t *node) -{ - free(node->left); - free(node->right); - free(node->owner); - free(node); -} - - -struct wlp_node_t *wlpn_alloc(const char empty) -{ - static struct wlp_node_t *node; - - node = calloc(sizeof(struct wlp_node_t),1); - - if (!node) { - perror("wlpn_create malloc"); - - /* calloc set *node to zero, it I don't want alloc anything, - leave it untouched, else alloc fields */ - } else if (!empty) { - node->left = calloc(LINELEN+1,1); - if (!node->left) { - perror("wlpn_create malloc (left)"); - free(node); - node = NULL; - } - - /*if node is NULL, previous calloc returned error...*/ - if(node && !(node->right = calloc(LINELEN+1,1))) { - perror("wlpn_create malloc (right)"); - free(node); - node = NULL; - } - - if(node && !(node->owner = calloc(LINELEN+1,1))) { - perror("wlpn_create malloc (owner)"); - free(node); - node = NULL; - } - } - return node; -} - -struct wlp_list_t *wlpl_init(struct wlp_node_t *node) -{ - static struct wlp_list_t *list; - - list = malloc(sizeof(struct wlp_list_t)); - - if (list) { - list->head = node; - list->tail = list->head; - - list->head->next = list->head; - list->head->prev = list->head; - - list->count=1; - } else { - perror("wlpl_init malloc"); - return NULL; - } - - return list; -} - - -struct wlp_node_t *wlpn_searchowner(struct wlp_list_t *mbl,const char *owner) -{ - struct wlp_node_t *ret; - - DBG("searching for %s\n",owner); - - if(!mbl) - ret = NULL; - else { - int found = FALSE; - ret = mbl->head; - - do { - if(!strcmp(owner,ret->owner)) { - DBG("found!\n"); - found = TRUE; - } else { - DBG("not found: %s\n",ret->onwer); - ret = ret->next; - } - } while(ret != mbl->head && !found); - - if(!found) - ret = NULL; - } - - DBG("%s\n", (ret)?ret->owner:"not found"); - - return ret; -} - - -struct wlp_node_t *wlpn_extract(struct wlp_list_t *list,struct wlp_node_t *node) -{ - struct wlp_node_t *ret; - - if(list && node) { - node->prev->next = node->next; - node->next->prev = node->prev; - - if(list->tail == node) - list->tail = node->prev; - if(list->head == node) - list->head = node->next; - - list->count--; - - ret = node; - } else { - DBG("wlpn_extract: list addr %l and node %l (one is NULL)\n",list,addr) - ret = NULL; - } - - return ret; -} diff --git a/wlp/structs.h b/wlp/structs.h deleted file mode 100644 index 92036a7..0000000 --- a/wlp/structs.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * structs.h - Copyright 2000, 2001 by Cosimo Alfarano - * You can use this software under the terms of the GPL. If we meet some day, - * and you think this stuff is worth it, you can buy me a beer in return. - * - * Thanks to md for this useful formula. Beer is beer. - */ - -#ifndef _structs_h_ -#define _structs_h_ - -typedef struct wlp_node_t { - char *left,*right; - char *owner; - char type; /* unused */ - struct wlp_node_t *next, *prev; -} wlp_node_t; - -typedef struct wlp_list_t { - int count; - struct wlp_node_t *head, *tail; -} wlp_list_t; - - -/* white list parser data structure manipulation */ -struct wlp_list_t *wlpl_init(struct wlp_node_t *node); -struct wlp_node_t *wlpn_alloc(const char empty); -void wlpn_free(struct wlp_node_t *node); -struct wlp_node_t *wlpn_add(struct wlp_list_t *wlpl,struct wlp_node_t *wlpn); -struct wlp_node_t *wlpn_extract(struct wlp_list_t *wlpl,struct wlp_node_t *wlpn); -/*struct wlp_node_t *wlpn_search(struct wlp_list_t *wlpl,const char id);*/ - -#endif /* _structs_h_ */ - -/* EOF */ diff --git a/wlp/test.c b/wlp/test.c deleted file mode 100644 index 47717b5..0000000 --- a/wlp/test.c +++ /dev/null @@ -1,113 +0,0 @@ -#include /* should be modified to be pythonX.Y */ -#include -#include - -#include "structs.h" -#include "macro.h" - -/* first declare static functions */ - -struct wlp_list_t *list; - -static FILE *fd = NULL; - -static PyObject *node2dict(struct wlp_node_t *node); - -static PyObject *wlp_setfilebyname(PyObject *self, PyObject *args) { - char *file; - - DBG("setfilebyname\n"); - if (!PyArg_ParseTuple(args, "s", &file)) - return NULL; - - fd = fopen(file,"r"); - - return Py_None; -} - -static PyObject *wlp_setfilebyfd(PyObject *self, PyObject *args) { - PyObject *file = NULL; - - if (!PyArg_ParseTuple(args, "O", &file)) - return NULL; - - if(!file) - return NULL; - - if(!PyFile_Check(file)) - return NULL; - - fd = PyFile_AsFile(file); - - return Py_None; - -} - - - -static PyObject *wlp_mklist(PyObject *self, PyObject *args) { - struct wlp_node_t *tmp; - int count; - - PyObject *pylist = NULL; - - DBG("a\n"); - parse(fd); - - DBG("count %d\n"list->count); - pylist = PyList_New(0); - - DBG("a\n"); - if(!pylist) - return NULL; - - DBG("a\n"); - if(list) - for(tmp = list->head, count=0; - tmp != list->head || count == 0; - tmp = tmp->next, count++) { - DBG("FOUND(%d) '%s' ('%s': '%s')\n",count,tmp->owner,tmp->left,tmp->right); - if(PyList_Append(pylist,node2dict(tmp))==-1) { - DBG("List failed\n"); - return NULL; - } - DBG("a\n"); - } - - return pylist; -} - - -static PyObject *node2dict(struct wlp_node_t *node) { - PyObject *dict = PyDict_New(); - - if(!dict) - return NULL; - - PyDict_SetItem(dict, - Py_BuildValue("s","owner"), - Py_BuildValue("s",node->owner)); - - PyDict_SetItem(dict, - Py_BuildValue("s",node->left), - Py_BuildValue("s",node->right)); - - return dict; - -} - -/* second a table with methods/functions matching */ - -static PyMethodDef wlp_methods[] = { - {"mklist", wlp_mklist, METH_VARARGS}, - {"setfilebyname", wlp_setfilebyname, METH_VARARGS}, - {"setfilebyfd", wlp_setfilebyfd, METH_VARARGS}, - {NULL,NULL} -}; - - -/* last the init function, the only one non-static */ - -void initwlp() { - (void) Py_InitModule("wlp",wlp_methods); -} diff --git a/wlp/wlp.c b/wlp/wlp.c deleted file mode 100644 index 6a36617..0000000 --- a/wlp/wlp.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - * wlp.c - Copyright 2000, 2001 by Cosimo Alfarano - * You can use this software under the terms of the GPL. If we meet some day, - * and you think this stuff is worth it, you can buy me a beer in return. - * - * Thanks to md for this useful formula. Beer is beer. - */ - -#include -#include -#include - -#include "structs.h" -#include "macro.h" - - -static FILE *fd = NULL; - -struct wlp_list_t *list; - -static PyObject *node2dict(struct wlp_node_t *node); - - - -/* - * wlp_setfilebyname(): get FILE* fd from filename string. - */ - -static PyObject *wlp_setfilebyname(PyObject *self, PyObject *args) { - char *file; - - - DBG("setfilebyname\n"); - if (!PyArg_ParseTuple(args, "s", &file)) - return NULL; - - if((fd = fopen(file,"r"))) { - return Py_None; - } else { - PyErr_SetFromErrno(PyExc_Exception); -/* - PyErr_SetString(PyExc_Exception, - (errno<=sys_nerr-1)? - sys_errlist[errno]: - "Unknown Error on fopen() of confifuration file"); -*/ - return NULL; - } -} - - - -/* - * wlp_setfilebydf(): get FILE* fd from FileObject. - */ - -static PyObject *wlp_setfilebyfd(PyObject *self, PyObject *args) { - PyObject *file = NULL; - - if(!PyArg_ParseTuple(args, "O", &file)) - return NULL; - - if(!file) - return NULL; - - if(!PyFile_Check(file)) - return NULL; - - fd = PyFile_AsFile(file); - - return Py_None; -} - -/* - * wlp_mkdict(): make a dictonary of the form - * {ownername: {var1: val1, var2: val2,...}} - */ - -static PyObject *wlp_mkdict(PyObject *self, PyObject *args) { - PyObject *pydicttmp = NULL; - PyObject *pydict = PyDict_New(); - struct wlp_node_t *tmp; - int count; - - if(!pydict) - return NULL; - - /* fopen()*/ - if(fd) - parse(fd); - else - return Py_None; - - if(list) - for(tmp = list->head, count = 0; - tmp != list->head || count == 0; - tmp = tmp->next, count++) { - DBG("FOUND(%d) '%s' ('%s': '%s')\n",count,tmp->owner,tmp->left,tmp->right); - pydicttmp = PyDict_GetItem(pydict, - PyString_FromString(tmp->owner)); - - if(!pydicttmp) { - DBG("%s: owner not found, create new item\n", - tmp->owner); - PyDict_SetItemString(pydict, - tmp->owner, - node2dict(tmp)); - } else { - DBG("%s: owner found,appendig items\n", - tmp->owner); - PyDict_SetItemString(pydicttmp, - tmp->left, - Py_BuildValue("s",tmp->right)); - PyDict_SetItemString(pydict, - tmp->owner, - pydicttmp); - } - } - - return pydict; -} - -/* - * node2dict(): transoform a wlp_node_t node in a python dictionary of the form - * { var: val } - * to be used by mkdict() - */ - -static PyObject *node2dict(struct wlp_node_t *node) { - PyObject *dict = PyDict_New(); - - if(!dict) - dict = Py_None; - else { - PyDict_SetItem(dict, - Py_BuildValue("s",node->left), - Py_BuildValue("s",node->right)); - } - - return dict; - -} - -static PyMethodDef wlp_methods[] = { - {"mkdict", wlp_mkdict, METH_VARARGS}, - {"setfilebyname", wlp_setfilebyname, METH_VARARGS}, - {"setfilebyfd", wlp_setfilebyfd, METH_VARARGS}, - {NULL,NULL} -}; - - -void initwlp() { - (void) Py_InitModule("wlp",wlp_methods); -} diff --git a/wlp/yytest.c b/wlp/yytest.c deleted file mode 100644 index 74c6fe7..0000000 --- a/wlp/yytest.c +++ /dev/null @@ -1,25 +0,0 @@ -#include - -#include "structs.h" -#include "macro.h" - - - -int parse(FILE *file); - -struct wlp_list_t *list; - -int main(int argc,char **argv) { - struct wlp_node_t *tmp; - int count; - - parse(NULL); - - if(list) - for(tmp = list->head, count=0; - tmp != list->head || count == 0; - tmp = tmp->next, count++) - printf("FOUND(%d) '%s' '%s' '%s'\n",count,tmp->left,tmp->right,tmp->owner); - - return(0); -} diff --git a/wlp_lex.py b/wlp_lex.py deleted file mode 100644 index 2cd912b..0000000 --- a/wlp_lex.py +++ /dev/null @@ -1,12 +0,0 @@ -import rply - -lg = rply.LexerGenerator() -# Add takes a rule name, and a regular expression that defines the rule. -lg.add("OWNER", r'<[a-zA-Z0-9_.+-]+@[a-zA-Z0-9._-]+>') -lg.add("VAL", r'[\'`"][a-zA-Z0-9@_+.<>() -]+[\'`"]') -lg.add("VAR", r'[a-zA-Z0-9_<>-]+[:]?') - -lg.ignore(r"\s+") -lg.ignore(r'[{}=]+') - -lexer = lg.build() diff --git a/wlp_parser.py b/wlp_parser.py new file mode 100644 index 0000000..35da516 --- /dev/null +++ b/wlp_parser.py @@ -0,0 +1,68 @@ +import rply + +__lg = rply.LexerGenerator() +# Add takes a rule name, and a regular expression that defines the rule. +__lg.add("OWNER", r'<[a-zA-Z0-9_.+-]+@[a-zA-Z0-9._-]+>') +__lg.add("VAL", r'[\'`"][a-zA-Z0-9@_+.<>() -]+[\'`"]') +__lg.add("VAR", r'[a-zA-Z0-9_<>-]+[:]?') + +__lg.ignore(r"\s+") +__lg.ignore(r'[{}=]+') + +lexer = __lg.build() + +__pg = rply.ParserGenerator(['OWNER', 'VAL', 'VAR'], + cache_id='wlp_parser') + +""" + $accept ::= block $end + block ::= blockstatement + | block blockstatement + blockstatement ::= owner '{' commandline '}' + commandline ::= command + | commandline command + command ::= varpart '=' valpart + owner ::= OWNERID + varpart ::= VARID + valpart ::= VALID +""" + + +@__pg.production('main : block') +def main(p): + return p[0] + + +@__pg.production('block : blockstatement') +def block(p): + return p + + +@__pg.production('block : block blockstatement') +def block_blockstatement(p): + p[0].append(p[1]) + return p[0] + + +@__pg.production('blockstatement : OWNER commandline') +def blockstatement(p): + return [p[0], p[1]] + + +@__pg.production('commandline : command') +def commandline(p): + return p + + +@__pg.production('commandline : commandline command') +def commandline_command(p): + p[0].append(p[1]) + return p[0] + + +@__pg.production('command : VAR VAL') +def command(p): + return p + + +parser = __pg.build() diff --git a/wlp_yacc.py b/wlp_yacc.py deleted file mode 100644 index 910ed1f..0000000 --- a/wlp_yacc.py +++ /dev/null @@ -1,108 +0,0 @@ -import logging - -import rply - -logging.basicConfig(format='%(levelname)s:%(funcName)s:%(message)s', - level=logging.DEBUG) - -pg = rply.ParserGenerator(['OWNER', 'VAL', 'VAR'], - cache_id='wlp_parser') - -""" - $accept ::= block $end - - block ::= blockstatement - | block blockstatement - - blockstatement ::= owner '{' commandline '}' - - commandline ::= command - | commandline command - - command ::= varpart '=' valpart - - owner ::= OWNERID - - varpart ::= VARID - - valpart ::= VALID -""" - -## Makes from this source -## -## { -## From: = 'ME' Sender: = "Cosimo" Reply-to = "me" -## } -## -## { -## From: = 'Cosimo Alfarano' -## X-Firstname: = 'Cosimo' -## } -## -## { -## From: = 'kame@inwind.it' -## Reply-to: = "KA" -## Sender: = "Kalfa" -## } -## -## this dictionary -## -## expected_dict = {'alfarano@students.cs.unibo.it': { -## 'From:': 'Cosimo Alfarano', -## 'X-Firstname:': 'Cosimo' -## }, -## 'kame@innocent.com': { -## 'From:': 'kame@inwind.it', -## 'Reply-to': 'me', -## 'Reply-to:': 'KA', -## 'Sender:': 'Kalfa'} -## } - - -@pg.production('main : block') -def main(p): - return p[0] - - -# block: -# blockstatement -# | block blockstatement -@pg.production('block : blockstatement') -def block(p): - logging.debug('block p = %s', p) - return p[0] - - -@pg.production('block : block blockstatement') -def block_blockstatement(p): - logging.debug('block p = %s', p) - return [p[0], [p[1]]] - - -# blockstatement: -# owner '{' commandline '}' -@pg.production('blockstatement : OWNER commandline') -def blockstatement(p): - logging.debug('blockstatement p = %s', p) - return [p[0], [p[1]]] - - -# commandline: -# command | commandline command -@pg.production('commandline : command') -def commandline(p): - logging.debug('commandline p = %s', p) - return p[0] - -@pg.production('commandline : commandline command') -def commandline_command(p): - return p[0] + [p[1]] - -# command: -# varpart '=' valpart { found(left,right,owner); } -@pg.production('command : VAR VAL') -def command(p): - logging.debug('command p = %s', p) - return [p[0], p[1]] - -parser = pg.build() -- cgit