diff options
| -rw-r--r-- | fs_selfservice/FS-SelfService/MANIFEST | 2 | ||||
| -rw-r--r-- | fs_selfservice/FS-SelfService/Makefile.PL | 2 | ||||
| -rw-r--r-- | fs_selfservice/FS-SelfService/SelfService/XMLRPC.pm | 87 | ||||
| -rw-r--r-- | fs_selfservice/FS-SelfService/cgi/xmlrpc.cgi | 18 | ||||
| -rw-r--r-- | fs_selfservice/FS-SelfService/freeside-selfservice-xmlrpc-server | 59 | 
5 files changed, 167 insertions, 1 deletions
diff --git a/fs_selfservice/FS-SelfService/MANIFEST b/fs_selfservice/FS-SelfService/MANIFEST index ebd0d3b1a..a619b2b6c 100644 --- a/fs_selfservice/FS-SelfService/MANIFEST +++ b/fs_selfservice/FS-SelfService/MANIFEST @@ -2,5 +2,7 @@ Changes  Makefile.PL  MANIFEST  SelfService.pm +SelfService/XMLRPC.pm  test.pl  freeside-selfservice-clientd +freeside-selfservice-xmlrpc-server diff --git a/fs_selfservice/FS-SelfService/Makefile.PL b/fs_selfservice/FS-SelfService/Makefile.PL index 85c92b4fb..c078f0865 100644 --- a/fs_selfservice/FS-SelfService/Makefile.PL +++ b/fs_selfservice/FS-SelfService/Makefile.PL @@ -5,7 +5,7 @@ WriteMakefile(      'NAME'		=> 'FS::SelfService',      'VERSION_FROM'	=> 'SelfService.pm', # finds $VERSION      'EXE_FILES'         => [ 'freeside-selfservice-clientd', -                             #'freeside-selfservice-xmlrpc-server', +                             'freeside-selfservice-xmlrpc-server',                             ],      'INSTALLSCRIPT'     => '/usr/local/sbin',      'INSTALLSITEBIN'    => '/usr/local/sbin', diff --git a/fs_selfservice/FS-SelfService/SelfService/XMLRPC.pm b/fs_selfservice/FS-SelfService/SelfService/XMLRPC.pm new file mode 100644 index 000000000..71d489bde --- /dev/null +++ b/fs_selfservice/FS-SelfService/SelfService/XMLRPC.pm @@ -0,0 +1,87 @@ +package FS::SelfService::XMLRPC; + +=head1 NAME + +FS::SelfService::XMLRPC - Freeside XMLRPC accessible self-service API + +=head1 SYNOPSIS + +=head1 DESCRIPTION + +Use this API to implement your own client "self-service" module vi XMLRPC. + +Each routine described in L<FS::SelfService> is available vi XMLRPC.  All +values are passed to the selfservice-server in a struct of strings.  The +return values are in a struct as strings, arrays, or structs as appropriate +for the values described in L<FS::SelfService>. + +=head1 BUGS + +-head1 SEE ALSO + +L<freeside-selfservice-clientd>, L<freeside-selfservice-server>,L<FS::SelfService> + +=cut + +use strict; +use vars qw($DEBUG $AUTOLOAD); +use FS::SelfService; + +$DEBUG = 0; +$FS::SelfService::DEBUG = $DEBUG; + +sub AUTOLOAD { +  my $call = $AUTOLOAD; +  $call =~ s/^FS::SelfService::XMLRPC:://; +  if (exists($FS::SelfService::autoload{$call})) { +    shift; #discard package name; +    $call = "FS::SelfService::$call"; +    no strict 'refs'; +    &{$call}(@_); +  }else{ +    die "No such procedure: $call"; +  } +} + +package SOAP::Transport::HTTP::Daemon;  # yuck + +use POSIX qw(:sys_wait_h); + +no warnings 'redefine'; + +sub handle { +  my $self = shift->new; + +  local $SIG{CHLD} = 'IGNORE'; + +ACCEPT: +  while (my $c = $self->accept) { +     +    my $kid = 0; +    do { +      $kid = waitpid(-1, WNOHANG); +      warn "found kid $kid"; +    } while $kid > 0; + +    my $pid = fork; +    next ACCEPT if $pid; + +    if ( not defined $pid ) { +      warn "fork() failed: $!"; +      $c = undef; +    } else { +      while (my $r = $c->get_request) { +        $self->request($r); +        $self->SUPER::handle; +        $c->send_response($self->response); +      } +      # replaced ->close, thanks to Sean Meisner <Sean.Meisner@VerizonWireless.com> +      # shutdown() doesn't work on AIX. close() is used in this case. Thanks to Jos Clijmans <jos.clijmans@recyfin.be> +      UNIVERSAL::isa($c, 'shutdown') ? $c->shutdown(2) : $c->close();  +      $c->close; +    } +    exit; +  } +} + +1; diff --git a/fs_selfservice/FS-SelfService/cgi/xmlrpc.cgi b/fs_selfservice/FS-SelfService/cgi/xmlrpc.cgi new file mode 100644 index 000000000..559ae04d8 --- /dev/null +++ b/fs_selfservice/FS-SelfService/cgi/xmlrpc.cgi @@ -0,0 +1,18 @@ +#!/usr/bin/perl -Tw + +use strict; +use XMLRPC::Transport::HTTP; +use XMLRPC::Lite; # for XMLRPC::Serializer +use FS::SelfService::XMLRPC; + +my %typelookup = ( +  base64 => [10, sub {$_[0] =~ /[^\x09\x0a\x0d\x20-\x7f]/}, 'as_base64'], +  dateTime => [35, sub {$_[0] =~ /^\d{8}T\d\d:\d\d:\d\d$/}, 'as_dateTime'], +  string => [40, sub {1}, 'as_string'], +); +my $serializer = new XMLRPC::Serializer(typelookup => \%typelookup); +  +XMLRPC::Transport::HTTP::CGI->dispatch_to('FS::SelfService::XMLRPC') +                            ->serializer($serializer) +                            ->handle; + diff --git a/fs_selfservice/FS-SelfService/freeside-selfservice-xmlrpc-server b/fs_selfservice/FS-SelfService/freeside-selfservice-xmlrpc-server new file mode 100644 index 000000000..bd4f83b3c --- /dev/null +++ b/fs_selfservice/FS-SelfService/freeside-selfservice-xmlrpc-server @@ -0,0 +1,59 @@ +#!/usr/bin/perl -w +# +# freeside-selfservice-xmlrpc-server +# + +use strict; +use Fcntl qw(:flock); +use POSIX; +use Getopt::Std; +use XMLRPC::Transport::HTTP; +use XMLRPC::Lite; # for XMLRPC::Serializer; +use FS::SelfService::XMLRPC; + +use vars qw( $opt_p $opt_d ); +use vars qw( $DEBUG ); + +getopts("p:d"); +$DEBUG = $opt_d; +my $tag = $opt_p ? ':'.$opt_p : ''; + +my %typelookup = ( +  base64 => [10, sub {$_[0] =~ /[^\x09\x0a\x0d\x20-\x7f]/}, 'as_base64'], +  dateTime => [35, sub {$_[0] =~ /^\d{8}T\d\d:\d\d:\d\d$/}, 'as_dateTime'], +  string => [40, sub {1}, 'as_string'], +); +my $serializer = new XMLRPC::Serializer(typelookup => \%typelookup); + +my $log_file = "/usr/local/freeside/selfservice.xmlrpc$tag.log"; + +my $pid = fork; +defined($pid) or die "Can't fork to start: $!"; +print "Started daemon with pid $pid\n" if $pid; +exit if $pid; + +POSIX::setsid(); +open STDIN, "/dev/null" or die "Can't get rid of STDIN"; +open STDOUT, ">/dev/null" or die "Can't get rid of STDOUT"; +open STDERR, ">&STDOUT" or die "Can't get rid of STDERR"; + +$SIG{__WARN__} = \&_logmsg; +$SIG{__DIE__} = sub { &_logmsg(@_); exit }; + +my $daemon = XMLRPC::Transport::HTTP::Daemon +  ->new(LocalPort => $opt_p ? $opt_p : 8080) +  ->dispatch_to('FS::SelfService::XMLRPC') +  ->serializer($serializer); + +warn "Handling request at ", $daemon->url, "\n"; +$daemon->handle; + +sub _logmsg { +  chomp( my $msg = shift ); +  my $log = new IO::File ">>$log_file"; +  flock($log, LOCK_EX); +  seek($log, 0, 2); +  print $log "[". scalar(localtime). "] [$$] $msg\n"; +  flock($log, LOCK_UN); +  close $log; +}  | 
