From: rjones Date: Thu, 28 Jun 2007 20:49:10 +0000 (+0000) Subject: Working bot. X-Git-Url: http://git.annexia.org/?p=xavierbot.git;a=commitdiff_plain;h=1e6d6c08bec29a317316f107b7d9bde285c1f798;hp=d165f93ed79c62a1fa76f391d87ffc4d215b9efe Working bot. --- diff --git a/.cvsignore b/.cvsignore new file mode 100644 index 0000000..8492223 --- /dev/null +++ b/.cvsignore @@ -0,0 +1,3 @@ +ocamlbotwrapper +*.cmi +*.cmo \ No newline at end of file diff --git a/MANIFEST b/MANIFEST new file mode 100644 index 0000000..7751be5 --- /dev/null +++ b/MANIFEST @@ -0,0 +1,11 @@ +.cvsignore +Makefile +Makefile.config +MANIFEST +init +init.in +ocamlbotwrapper.c +ocamlbotwrapper.c.in +pa_noexternal.ml +xavierbot.pl +xavierbot.pl.in diff --git a/Makefile b/Makefile index fb78aa0..2570558 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.1 2007/06/28 19:47:26 rjones Exp $ +# $Id: Makefile,v 1.2 2007/06/28 20:49:10 rjones Exp $ include Makefile.config @@ -14,6 +14,7 @@ ocamlbotwrapper.c: ocamlbotwrapper.c.in Makefile.config sed \ -e 's|@OCAML@|$(OCAML)|' \ -e 's|@INITSCRIPT@|$(INITSCRIPT)|' \ + -e 's|@CHROOTDIR@|$(CHROOTDIR)|' \ < $< > $@ init: init.in Makefile.config @@ -33,4 +34,32 @@ pa_noexternal.cmo: pa_noexternal.ml -pp "camlp4o pa_extend.cmo q_MLast.cmo" -I +camlp4 -c $< clean: - rm -f ocamlbotwrapper *.o *.cmo *.cmi *~ \ No newline at end of file + rm -f ocamlbotwrapper *.o *.cmo *.cmi *~ + +# Distribution. + +dist: + $(MAKE) check-manifest + rm -rf $(PACKAGE)-$(VERSION) + mkdir $(PACKAGE)-$(VERSION) + tar -cf - -T MANIFEST | tar -C $(PACKAGE)-$(VERSION) -xf - + tar zcf $(PACKAGE)-$(VERSION).tar.gz $(PACKAGE)-$(VERSION) + rm -rf $(PACKAGE)-$(VERSION) + ls -l $(PACKAGE)-$(VERSION).tar.gz + +check-manifest: + @for d in `find -type d -name CVS | grep -v '^\./debian/'`; \ + do \ + b=`dirname $$d`/; \ + awk -F/ '$$1 != "D" {print $$2}' $$d/Entries | \ + sed -e "s|^|$$b|" -e "s|^\./||"; \ + done | sort > .check-manifest; \ + sort MANIFEST > .orig-manifest; \ + diff -u .orig-manifest .check-manifest; rv=$$?; \ + rm -f .orig-manifest .check-manifest; \ + exit $$rv + + +.PHONY: depend dist check-manifest dpkg doc print_test + +.SUFFIXES: .cmo .cmi .cmx .ml .mli diff --git a/Makefile.config b/Makefile.config index f8022b1..ed97661 100644 --- a/Makefile.config +++ b/Makefile.config @@ -1,4 +1,4 @@ -# $Id: Makefile.config,v 1.1 2007/06/28 19:47:26 rjones Exp $ +# $Id: Makefile.config,v 1.2 2007/06/28 20:49:10 rjones Exp $ PACKAGE := xavierbot VERSION := 0.1 @@ -26,3 +26,11 @@ OCAML=/usr/bin/ocaml # OCaml command user. OCAMLUSER=nobody + + +# If you want to run it without installing, leave the +# following uncommented. You will also need to create +# directory $(CHROOTDIR), compile everything, and make +# ocamlbotwrapper be chown root.root, chmod ug+s. +INITSCRIPT=init +WRAPPER=./ocamlbotwrapper diff --git a/init b/init index 0401dba..c8b1cbc 100644 --- a/init +++ b/init @@ -1,5 +1,5 @@ (* Initialise the toplevel environment. - * $Id: init,v 1.1 2007/06/28 19:47:26 rjones Exp $ + * $Id: init,v 1.2 2007/06/28 20:49:10 rjones Exp $ * - Removes the Pervasives module and any dangerous functions. * - Loads just the modules we want to give access to, and just * the functions within those modules that we want to give. diff --git a/ocamlbotwrapper.c b/ocamlbotwrapper.c index d7ad40d..d5f7127 100644 --- a/ocamlbotwrapper.c +++ b/ocamlbotwrapper.c @@ -1,5 +1,5 @@ /* -*- C -*- - * $Id: ocamlbotwrapper.c,v 1.1 2007/06/28 19:47:26 rjones Exp $ + * $Id: ocamlbotwrapper.c,v 1.2 2007/06/28 20:49:10 rjones Exp $ * SUID wrapper around ocaml program. */ @@ -16,8 +16,32 @@ const char *new_environ[] = { int main () { + /* Don't worry about races here because we're just checking that + * the installation looks reasonable. + * + * Die if the init script does not exist. */ + if (access ("init", R_OK) == -1) { + perror ("init"); + exit (1); + } + + /* Die if the ocaml program does not exist. */ + if (access ("/usr/bin/ocaml", R_OK|X_OK) == -1) { + perror ("/usr/bin/ocaml"); + exit (1); + } + + /* Die if the chroot directory does not exist. */ + if (access ("/var/local/xavierbot/chroot", R_OK|X_OK) == -1) { + perror ("/var/local/xavierbot/chroot"); + exit (1); + } + /* Run the ocaml program with the correct args. */ - execle ("/usr/bin/ocaml", "@OCAML@", "-init", "xavierbot/share/xavierbot/init", NULL, new_environ); + execle ("/usr/bin/ocaml", "@OCAML@", + "-init", "init", + "-noprompt", + NULL, new_environ); /* If it failed, die with an error message. */ perror ("/usr/bin/ocaml"); diff --git a/ocamlbotwrapper.c.in b/ocamlbotwrapper.c.in index 76aa4cd..b10b9c7 100644 --- a/ocamlbotwrapper.c.in +++ b/ocamlbotwrapper.c.in @@ -1,5 +1,5 @@ /* -*- C -*- - * $Id: ocamlbotwrapper.c.in,v 1.1 2007/06/28 19:47:26 rjones Exp $ + * $Id: ocamlbotwrapper.c.in,v 1.2 2007/06/28 20:49:10 rjones Exp $ * SUID wrapper around ocaml program. */ @@ -16,8 +16,32 @@ const char *new_environ[] = { int main () { + /* Don't worry about races here because we're just checking that + * the installation looks reasonable. + * + * Die if the init script does not exist. */ + if (access ("@INITSCRIPT@", R_OK) == -1) { + perror ("@INITSCRIPT@"); + exit (1); + } + + /* Die if the ocaml program does not exist. */ + if (access ("@OCAML@", R_OK|X_OK) == -1) { + perror ("@OCAML@"); + exit (1); + } + + /* Die if the chroot directory does not exist. */ + if (access ("@CHROOTDIR@", R_OK|X_OK) == -1) { + perror ("@CHROOTDIR@"); + exit (1); + } + /* Run the ocaml program with the correct args. */ - execle ("@OCAML@", "@OCAML@", "-init", "@INITSCRIPT@", NULL, new_environ); + execle ("@OCAML@", "@OCAML@", + "-init", "@INITSCRIPT@", + "-noprompt", + NULL, new_environ); /* If it failed, die with an error message. */ perror ("@OCAML@"); diff --git a/xavierbot.pl b/xavierbot.pl index f79310d..7601136 100755 --- a/xavierbot.pl +++ b/xavierbot.pl @@ -2,44 +2,31 @@ # xavierbot : an OCaml interpreter IRC bot. # By Richard W.M. Jones . # This code is in the Public Domain. -# $Id: xavierbot.pl,v 1.3 2007/06/28 19:47:26 rjones Exp $ +# $Id: xavierbot.pl,v 1.4 2007/06/28 20:49:10 rjones Exp $ use strict; -use POE qw(Component::IRC); +use POE qw(Component::IRC Wheel::Run); + +$ENV{PATH} = "/usr/bin:/bin"; #---------------------------------------------------------------------- # Start of configuration. my $nick = "xavierbot"; my $ircname = "Xavierbot"; # Printable name. -#my $server = "chat.freenode.net"; -my $server = "devserv.devel.redhat.com"; +my $server = "chat.freenode.net"; +#my $server = "devserv.devel.redhat.com"; my $port = 6667; - -my @channels = ("#ocaml"); +my $channel = "#ocaml"; # End of configuration. #---------------------------------------------------------------------- -my $irc = POE::Component::IRC->spawn ( - nick => $nick, - ircname => $ircname, - server => $server, - port => $port, - ) or die "POE::Component::IRC->spawn failed: $!"; - POE::Session->create ( package_states => [ - main => [ qw(_default _start irc_001 irc_public) ], + main => [ qw(_default _start irc_001 irc_public got_stdout) ], ], - heap => { irc => $irc }, -); - -POE::Wheel::Run->new ( - Program => [ "/usr/local/sbin/ocamlbotwrapper" ], - StdoutEvent => 'stdout_event', - StderrEvent => 'stdout_event', ); POE::Kernel->run (); @@ -49,6 +36,24 @@ sub _start { my ($kernel, $heap) = @_[KERNEL,HEAP]; + my $irc = POE::Component::IRC->spawn + ( + nick => $nick, + ircname => $ircname, + server => $server, + port => $port, + ) or die "POE::Component::IRC->spawn failed: $!"; + + my $ocaml = POE::Wheel::Run->new + ( + Program => "./ocamlbotwrapper", + StdoutEvent => "got_stdout", + StderrEvent => "got_stdout", + ) or die "POE::Wheel::Run->new ./ocamlbotwrapper failed: $!"; + + $heap->{irc} = $irc; + $heap->{ocaml} = $ocaml; + my $irc_session = $heap->{irc}->session_id (); $kernel->post ($irc_session => register => "all"); $kernel->post ($irc_session => connect => { }); @@ -63,21 +68,21 @@ sub irc_001 my $poco_object = $sender->get_heap (); print "Connected to ", $poco_object->server_name (), "\n"; - $kernel->post ($sender => join => $_ ) for @channels; + $kernel->post ($sender => join => $channel); undef; } sub irc_public { - my ($kernel, $sender, $who, $where, $what) = - @_[KERNEL,SENDER,ARG0,ARG1,ARG2]; + my ($kernel, $sender, $who, $where, $what, $heap) = + @_[KERNEL,SENDER,ARG0,ARG1,ARG2,HEAP]; my $nick = (split /!/, $who)[0]; my $channel = $where->[0]; print "got: $what\n"; - if (my ($rot13) = $what =~ /^rot13 (.+)/) { - $rot13 =~ tr[a-zA-Z][n-za-mN-ZA-M]; - $kernel->post ($sender => privmsg => $channel => "$nick: $rot13"); + if (my ($stmt) = $what =~ /^\s*([^#].*;;)\s*$/) { + print "stmt = $stmt\n"; + $heap->{ocaml}->put ("$stmt\n"); } undef; } @@ -100,10 +105,11 @@ sub _default #---------------------------------------------------------------------- -# Start the bot. +# Bot wrote something. -sub stdout_event +sub got_stdout { - my ($heap, $input, $wheel_id) = @_[HEAP,ARG0,ARG1]; + my ($kernel,$heap, $input, $wheel_id) = @_[KERNEL,HEAP,ARG0,ARG1]; print "Child said: $input\n"; + $kernel->post ($heap->{irc} => privmsg => $channel => "$input"); } diff --git a/xavierbot.pl.in b/xavierbot.pl.in index 8b97671..243dcbc 100755 --- a/xavierbot.pl.in +++ b/xavierbot.pl.in @@ -2,44 +2,31 @@ # xavierbot : an OCaml interpreter IRC bot. # By Richard W.M. Jones . # This code is in the Public Domain. -# $Id: xavierbot.pl.in,v 1.1 2007/06/28 19:47:26 rjones Exp $ +# $Id: xavierbot.pl.in,v 1.2 2007/06/28 20:49:10 rjones Exp $ use strict; -use POE qw(Component::IRC); +use POE qw(Component::IRC Wheel::Run); + +$ENV{PATH} = "/usr/bin:/bin"; #---------------------------------------------------------------------- # Start of configuration. my $nick = "xavierbot"; my $ircname = "Xavierbot"; # Printable name. -#my $server = "chat.freenode.net"; -my $server = "devserv.devel.redhat.com"; +my $server = "chat.freenode.net"; +#my $server = "devserv.devel.redhat.com"; my $port = 6667; - -my @channels = ("#ocaml"); +my $channel = "#ocaml"; # End of configuration. #---------------------------------------------------------------------- -my $irc = POE::Component::IRC->spawn ( - nick => $nick, - ircname => $ircname, - server => $server, - port => $port, - ) or die "POE::Component::IRC->spawn failed: $!"; - POE::Session->create ( package_states => [ - main => [ qw(_default _start irc_001 irc_public) ], + main => [ qw(_default _start irc_001 irc_public got_stdout) ], ], - heap => { irc => $irc }, -); - -POE::Wheel::Run->new ( - Program => [ "@WRAPPER@" ], - StdoutEvent => 'stdout_event', - StderrEvent => 'stdout_event', ); POE::Kernel->run (); @@ -49,6 +36,24 @@ sub _start { my ($kernel, $heap) = @_[KERNEL,HEAP]; + my $irc = POE::Component::IRC->spawn + ( + nick => $nick, + ircname => $ircname, + server => $server, + port => $port, + ) or die "POE::Component::IRC->spawn failed: $!"; + + my $ocaml = POE::Wheel::Run->new + ( + Program => "@WRAPPER@", + StdoutEvent => "got_stdout", + StderrEvent => "got_stdout", + ) or die "POE::Wheel::Run->new @WRAPPER@ failed: $!"; + + $heap->{irc} = $irc; + $heap->{ocaml} = $ocaml; + my $irc_session = $heap->{irc}->session_id (); $kernel->post ($irc_session => register => "all"); $kernel->post ($irc_session => connect => { }); @@ -63,21 +68,21 @@ sub irc_001 my $poco_object = $sender->get_heap (); print "Connected to ", $poco_object->server_name (), "\n"; - $kernel->post ($sender => join => $_ ) for @channels; + $kernel->post ($sender => join => $channel); undef; } sub irc_public { - my ($kernel, $sender, $who, $where, $what) = - @_[KERNEL,SENDER,ARG0,ARG1,ARG2]; + my ($kernel, $sender, $who, $where, $what, $heap) = + @_[KERNEL,SENDER,ARG0,ARG1,ARG2,HEAP]; my $nick = (split /!/, $who)[0]; my $channel = $where->[0]; print "got: $what\n"; - if (my ($rot13) = $what =~ /^rot13 (.+)/) { - $rot13 =~ tr[a-zA-Z][n-za-mN-ZA-M]; - $kernel->post ($sender => privmsg => $channel => "$nick: $rot13"); + if (my ($stmt) = $what =~ /^\s*([^#].*;;)\s*$/) { + print "stmt = $stmt\n"; + $heap->{ocaml}->put ("$stmt\n"); } undef; } @@ -100,10 +105,11 @@ sub _default #---------------------------------------------------------------------- -# Start the bot. +# Bot wrote something. -sub stdout_event +sub got_stdout { - my ($heap, $input, $wheel_id) = @_[HEAP,ARG0,ARG1]; + my ($kernel,$heap, $input, $wheel_id) = @_[KERNEL,HEAP,ARG0,ARG1]; print "Child said: $input\n"; + $kernel->post ($heap->{irc} => privmsg => $channel => "$input"); }