From c28a1f2d8b6c0c355a96f3b8f34c2ec40971c2a1 Mon Sep 17 00:00:00 2001 From: ivan Date: Fri, 30 Apr 2004 19:08:21 +0000 Subject: 15 day open invoice reports for qis --- httemplate/index.html | 1 + 1 file changed, 1 insertion(+) diff --git a/httemplate/index.html b/httemplate/index.html index 6ad12f197..2e7fc1c84 100644 --- a/httemplate/index.html +++ b/httemplate/index.html @@ -62,6 +62,7 @@ END @@ -228,6 +229,8 @@ sub _export_command { ); } + @radius_groups = $svc_acct->radius_groups; + $self->shellcommands_queue( $svc_acct->svcnum, user => $self->option('user')||'root', host => $self->machine, @@ -266,6 +269,9 @@ sub _export_replace { ); } + @old_radius_groups = $old->radius_groups; + @new_radius_groups = $new->radius_groups; + if ( $self->option('usermod_pwonly') ) { my $error = ''; if ( $old_username ne $new_username ) { @@ -280,6 +286,10 @@ sub _export_replace { if ( $old_dir ne $new_dir ) { $error ||= "can't change dir"; } + if ( join("\n", sort @old_radius_groups) ne + join("\n", sort @new_radius_groups) ) { + $error ||= "can't change RADIUS groups"; + } return $error. ' ('. $self->exporttype. ' to '. $self->machine. ')' if $error; } diff --git a/FS/FS/part_export/shellcommands_withdomain.pm b/FS/FS/part_export/shellcommands_withdomain.pm index 8a56bab1c..4f1b25bc4 100644 --- a/FS/FS/part_export/shellcommands_withdomain.pm +++ b/FS/FS/part_export/shellcommands_withdomain.pm @@ -95,6 +95,7 @@ The following variables are available for interpolation (prefixed with
  • $dir - home directory
  • $shell
  • $quota +
  • @radius_groups
  • All other fields in svc_acct are also available. END diff --git a/FS/FS/svc_acct.pm b/FS/FS/svc_acct.pm index 100af6cb6..e97afe36a 100644 --- a/FS/FS/svc_acct.pm +++ b/FS/FS/svc_acct.pm @@ -187,8 +187,7 @@ The additional fields pkgnum and svcpart (see L) should be defined. An FS::cust_svc record will be created and inserted. The additional field I can optionally be defined; if so it should -contain an arrayref of group names. See L. (used in -sqlradius export only) +contain an arrayref of group names. See L. The additional field I can optionally be defined; if so it should contain an arrayref of FS::tablename objects. They will have their @@ -535,8 +534,8 @@ Replaces OLD_RECORD with this one in the database. If there is an error, returns the error, otherwise returns false. The additional field I can optionally be defined; if so it should -contain an arrayref of group names. See L. (used in -sqlradius export only) +contain an arrayref of group names. See L. + =cut -- cgit v1.2.1 From bc10c7592866836b56d12b4e8b18f5fa67785a24 Mon Sep 17 00:00:00 2001 From: ivan Date: Mon, 3 May 2004 15:40:10 +0000 Subject: 1. order_pkg accepts svcpart + (svc_external: id, title / svc_acct: domain) --- FS/FS/ClientAPI/MyAccount.pm | 75 ++++++++++++++++++++++++++++++-------------- 1 file changed, 52 insertions(+), 23 deletions(-) diff --git a/FS/FS/ClientAPI/MyAccount.pm b/FS/FS/ClientAPI/MyAccount.pm index d2b6e0450..3c0b0ac5a 100644 --- a/FS/FS/ClientAPI/MyAccount.pm +++ b/FS/FS/ClientAPI/MyAccount.pm @@ -12,6 +12,8 @@ use FS::Record qw(qsearch qsearchs); use FS::Msgcat qw(gettext); use FS::svc_acct; use FS::svc_domain; +use FS::svc_external; +use FS::part_svc; use FS::cust_main; use FS::cust_bill; use FS::cust_main_county; @@ -406,35 +408,61 @@ sub order_pkg { my $error = $cust_pkg->check; return { 'error' => $error } if $error; - my $svc_acct = new FS::svc_acct ( { - 'svcpart' => $p->{'svcpart'} || $cust_pkg->part_pkg->svcpart('svc_acct'), - map { $_ => $p->{$_} } - qw( username _password sec_phrase popnum ), - } ); + my @svc = (); + unless ( $p->{'svcpart'} eq 'none' ) { + + my $svcdb; + my $svcpart = ''; + if ( $p->{'svcpart'} =~ /^(\d+)$/ ) { + $svcpart = $1; + my $part_svc = qsearchs('part_svc', { 'svcpart' => $svcpart } ); + return { 'error' => "Unknown svcpart $svcpart" } unless $part_svc; + $svcdb = $part_svc->svcdb; + } else { + $svcdb = 'svc_acct'; + } + $svcpart ||= $cust_pkg->part_pkg->svcpart($svcdb); - my @acct_snarf; - my $snarfnum = 1; - while ( length($p->{"snarf_machine$snarfnum"}) ) { - my $acct_snarf = new FS::acct_snarf ( { - 'machine' => $p->{"snarf_machine$snarfnum"}, - 'protocol' => $p->{"snarf_protocol$snarfnum"}, - 'username' => $p->{"snarf_username$snarfnum"}, - '_password' => $p->{"snarf_password$snarfnum"}, + my %fields = ( + 'svc_acct' => [ qw( username _password sec_phrase popnum ) ], + 'svc_domain' => [ qw( domain ) ], + 'svc_external' => [ qw( id title ) ], + ); + + my $svc_x = "FS::$svcdb"->new( { + 'svcpart' => $svcpart, + map { $_ => $p->{$_} } @{$fields{$svcdb}} } ); - $snarfnum++; - push @acct_snarf, $acct_snarf; - } - $svc_acct->child_objects( \@acct_snarf ); + + if ( $svcdb eq 'svc_acct' ) { + my @acct_snarf; + my $snarfnum = 1; + while ( length($p->{"snarf_machine$snarfnum"}) ) { + my $acct_snarf = new FS::acct_snarf ( { + 'machine' => $p->{"snarf_machine$snarfnum"}, + 'protocol' => $p->{"snarf_protocol$snarfnum"}, + 'username' => $p->{"snarf_username$snarfnum"}, + '_password' => $p->{"snarf_password$snarfnum"}, + } ); + $snarfnum++; + push @acct_snarf, $acct_snarf; + } + $svc_x->child_objects( \@acct_snarf ); + } + + my $y = $svc_x->setdefault; # arguably should be in new method + return { 'error' => $y } if $y && !ref($y); + + $error = $svc_x->check; + return { 'error' => $error } if $error; - my $y = $svc_acct->setdefault; # arguably should be in new method - return { 'error' => $y } if $y && !ref($y); + push @svc, $svc_x; - $error = $svc_acct->check; - return { 'error' => $error } if $error; + } use Tie::RefHash; tie my %hash, 'Tie::RefHash'; - %hash = ( $cust_pkg => [ $svc_acct ] ); + %hash = ( $cust_pkg => \@svc ); #msgcat $error = $cust_main->order_pkgs( \%hash, '', 'noexport' => 1 ); return { 'error' => $error } if $error; @@ -449,7 +477,8 @@ sub order_pkg { $cust_main->apply_credits; $bill_error = $cust_main->collect; - if ( $cust_main->balance > $old_balance ) { + if ( $cust_main->balance > $old_balance + && $cust_main->payby !~ /^(BILL|DCRD|DCHK)$/ ) { $cust_pkg->cancel('quiet'=>1); return { 'error' => '_decline' }; } else { -- cgit v1.2.1 From 27bf0365cef058944b8d71379af45d514e0b0c36 Mon Sep 17 00:00:00 2001 From: ivan Date: Tue, 4 May 2004 18:44:48 +0000 Subject: don't truncate job args for display --- FS/FS/queue.pm | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/FS/FS/queue.pm b/FS/FS/queue.pm index 9dcb2e3be..8396fc904 100644 --- a/FS/FS/queue.pm +++ b/FS/FS/queue.pm @@ -352,9 +352,7 @@ END my $args; if ( $dangerous || $queue->job !~ /^FS::part_export::/ || !$noactions ) { - $args = encode_entities( join(' ', - map { length($_)<54 ? $_ : substr($_,0,32)."..." } $queue->args #1&g - ) ); + $args = encode_entities( join(' ', $queue->args) ); } else { $args = ''; } @@ -424,7 +422,7 @@ END =head1 VERSION -$Id: queue.pm,v 1.17 2004-03-03 13:42:08 ivan Exp $ +$Id: queue.pm,v 1.18 2004-05-04 18:44:48 ivan Exp $ =head1 BUGS -- cgit v1.2.1 From 2a3703dad2a512c709152c1a8d99acbe6c27b668 Mon Sep 17 00:00:00 2001 From: ivan Date: Thu, 6 May 2004 22:18:24 +0000 Subject: show service name and fully-qualified address on service add --- httemplate/edit/svc_www.cgi | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/httemplate/edit/svc_www.cgi b/httemplate/edit/svc_www.cgi index ec5169e05..e13bb44c0 100644 --- a/httemplate/edit/svc_www.cgi +++ b/httemplate/edit/svc_www.cgi @@ -53,7 +53,7 @@ if ( $cgi->param('error') ) { } my $action = $svc_www->svcnum ? 'Edit' : 'Add'; -my( %username, %arec ); +my( %svc_acct, %arec ); if ($pkgnum) { my($u_part_svc,@u_acct_svcparts); @@ -73,7 +73,8 @@ if ($pkgnum) { my($i_cust_svc); foreach $i_cust_svc ( qsearch('cust_svc',{'pkgnum'=>$cust_pkgnum,'svcpart'=>$acct_svcpart}) ) { my($svc_acct)=qsearchs('svc_acct',{'svcnum'=>$i_cust_svc->getfield('svcnum')}); - $username{$svc_acct->getfield('svcnum')}=$svc_acct->getfield('username'); + $svc_acct{$svc_acct->getfield('svcnum')}= + $svc_acct->part-svc->svc. ': '. $svc_acct->email; } } } @@ -161,9 +162,9 @@ foreach $_ (keys %arec) { print ""; print 'Username"; -- cgit v1.2.1 From 47ac05fedd2437ff079223b39934fd4bf0870df5 Mon Sep 17 00:00:00 2001 From: ivan Date: Thu, 6 May 2004 22:29:05 +0000 Subject: protect properly against deleting users linked to virtual web sites --- FS/FS/svc_acct.pm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/FS/FS/svc_acct.pm b/FS/FS/svc_acct.pm index e97afe36a..a566b81f6 100644 --- a/FS/FS/svc_acct.pm +++ b/FS/FS/svc_acct.pm @@ -30,6 +30,8 @@ use FS::radius_usergroup; use FS::export_svc; use FS::part_export; use FS::Msgcat qw(gettext); +use FS::svc_forward; +use FS::svc_www; @ISA = qw( FS::svc_Common ); -- cgit v1.2.1 From 226b17bfa055fb960b722c6a17d1c81bb8970f2c Mon Sep 17 00:00:00 2001 From: ivan Date: Thu, 6 May 2004 22:29:24 +0000 Subject: add option to change the restart command in apache exports --- FS/FS/part_export/apache.pm | 3 +++ bin/apache.export | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/FS/FS/part_export/apache.pm b/FS/FS/part_export/apache.pm index b16b3040d..17fbabff8 100644 --- a/FS/FS/part_export/apache.pm +++ b/FS/FS/part_export/apache.pm @@ -10,6 +10,9 @@ tie my %options, 'Tie::IxHash', 'user' => { label=>'Remote username', default=>'root' }, 'httpd_conf' => { label=>'httpd.conf snippet location', default=>'/etc/apache/httpd-freeside.conf', }, + 'restart' => { label=>'Apache restart command', + default=>'apachectl graceful', + }, 'template' => { label => 'Template', type => 'textarea', diff --git a/bin/apache.export b/bin/apache.export index f0a6beefc..47863a9d5 100755 --- a/bin/apache.export +++ b/bin/apache.export @@ -51,7 +51,9 @@ foreach my $export ( @exports ) { } ) or die "rsync to $machine failed: ". join(" / ", $rsync->err); # warn $rsync->out; - ssh("root\@$machine", 'apachectl graceful'); + my $restart = $export->option('restart') || 'apachectl graceful'; + + ssh("root\@$machine", $restart); } -- cgit v1.2.1 From e520b9f7d88539634225560d462d03c7d2057d9d Mon Sep 17 00:00:00 2001 From: ivan Date: Thu, 6 May 2004 22:34:14 +0000 Subject: tyop --- httemplate/edit/svc_www.cgi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httemplate/edit/svc_www.cgi b/httemplate/edit/svc_www.cgi index e13bb44c0..313ebee0b 100644 --- a/httemplate/edit/svc_www.cgi +++ b/httemplate/edit/svc_www.cgi @@ -74,7 +74,7 @@ if ($pkgnum) { foreach $i_cust_svc ( qsearch('cust_svc',{'pkgnum'=>$cust_pkgnum,'svcpart'=>$acct_svcpart}) ) { my($svc_acct)=qsearchs('svc_acct',{'svcnum'=>$i_cust_svc->getfield('svcnum')}); $svc_acct{$svc_acct->getfield('svcnum')}= - $svc_acct->part-svc->svc. ': '. $svc_acct->email; + $svc_acct->part_svc->svc. ': '. $svc_acct->email; } } } -- cgit v1.2.1 From 28f7684d096f8f5c97a68d04193bc9ba1d503ef5 Mon Sep 17 00:00:00 2001 From: ivan Date: Thu, 6 May 2004 22:37:13 +0000 Subject: brainfart --- httemplate/edit/svc_www.cgi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httemplate/edit/svc_www.cgi b/httemplate/edit/svc_www.cgi index 313ebee0b..ebc4b1148 100644 --- a/httemplate/edit/svc_www.cgi +++ b/httemplate/edit/svc_www.cgi @@ -74,7 +74,7 @@ if ($pkgnum) { foreach $i_cust_svc ( qsearch('cust_svc',{'pkgnum'=>$cust_pkgnum,'svcpart'=>$acct_svcpart}) ) { my($svc_acct)=qsearchs('svc_acct',{'svcnum'=>$i_cust_svc->getfield('svcnum')}); $svc_acct{$svc_acct->getfield('svcnum')}= - $svc_acct->part_svc->svc. ': '. $svc_acct->email; + $svc_acct->cust_svc->part_svc->svc. ': '. $svc_acct->email; } } } -- cgit v1.2.1 From a176034d4fa386de180b893e00bda36b04251778 Mon Sep 17 00:00:00 2001 From: ivan Date: Sat, 8 May 2004 07:46:31 +0000 Subject: default finger to first+last --- FS/FS/svc_acct.pm | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/FS/FS/svc_acct.pm b/FS/FS/svc_acct.pm index a566b81f6..355573b00 100644 --- a/FS/FS/svc_acct.pm +++ b/FS/FS/svc_acct.pm @@ -831,6 +831,15 @@ sub check { # $error = $self->ut_textn('finger'); # return $error if $error; + if ( $self->getfield('finger') eq '' ) { + my $cust_pkg = $self->svcnum + ? $self->cust_svc->cust_pkg + : qsearchs('cust_pkg', { 'pkgnum' => $self->getfield('pkgnum') } ); + if ( $cust_pkg ) { + my $cust_main = $cust_pkg->cust_main; + $self->setfield('finger', $cust_main->first.' '.$cust_main->get('last') ); + } + } $self->getfield('finger') =~ /^([\w \t\!\@\#\$\%\&\(\)\-\+\;\'\"\,\.\?\/\*\<\>]*)$/ or return "Illegal finger: ". $self->getfield('finger'); -- cgit v1.2.1 From d18d092121b0a488fb78f9168824db854eae480c Mon Sep 17 00:00:00 2001 From: ivan Date: Mon, 10 May 2004 08:38:26 +0000 Subject: rt and sql-ledger --- CREDITS | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CREDITS b/CREDITS index 592be445a..39b53a7b8 100644 --- a/CREDITS +++ b/CREDITS @@ -120,5 +120,11 @@ Latex invoice template based on a template from eBills by Mark Asplen-Taylor , licensed under the terms fo the GNU GPL. +Contains "Request Tracker" by Jesse +Vincent licensed under the terms of the GNU GPL. + +Contains "SQL Ledger" by DWS Systems Inc. and +contributors licensed under the terms of the GNU GPL. + Everything else is my (Ivan Kohler ) fault. -- cgit v1.2.1 From 24653b038976803a9d328eb7b5a73b78a3bd5c3a Mon Sep 17 00:00:00 2001 From: ivan Date: Mon, 10 May 2004 09:38:52 +0000 Subject: ach 5.005 --- bin/sendmail.import | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/sendmail.import b/bin/sendmail.import index 8a9de9fd3..c6ed434cd 100644 --- a/bin/sendmail.import +++ b/bin/sendmail.import @@ -28,7 +28,7 @@ $forward_svcpart = 4; use vars qw($spooldir); $spooldir = "/usr/local/etc/freeside/export.". datasrc. "/sendmail"; -mkdir $spooldir unless -d $spooldir; +mkdir($spooldir, 0755) unless -d $spooldir; print "\n\n", < Date: Mon, 10 May 2004 09:40:38 +0000 Subject: 5.005! --- bin/sendmail.import | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bin/sendmail.import b/bin/sendmail.import index c6ed434cd..a55616dc3 100644 --- a/bin/sendmail.import +++ b/bin/sendmail.import @@ -39,7 +39,7 @@ my($aliases)=&getvalue(":"); use vars qw($aliases_machine $aliases_prefix); $aliases_machine = (split(/:/, $aliases))[0]; $aliases_prefix = "$spooldir/$aliases_machine"; -mkdir $aliases_prefix unless -d $aliases_prefix; +mkdir($aliases_prefix, 0755) unless -d $aliases_prefix; #iscp("root\@$aliases","$aliases_prefix/aliases.import"); iscp("ivan\@$aliases","$aliases_prefix/aliases.import"); @@ -53,8 +53,8 @@ my($virtusertable)=&getvalue(":"); use vars qw($virtusertable_machine $virtusertable_prefix); $virtusertable_machine = (split(/:/, $virtusertable))[0]; $virtusertable_prefix = "$spooldir/$virtusertable_machine"; -mkdir $virtusertable_prefix unless -d $virtusertable_prefix; -mkdir "$virtusertable_prefix/virtusertable.import" +mkdir($virtusertable_prefix, 0755) unless -d $virtusertable_prefix; +mkdir("$virtusertable_prefix/virtusertable.import", 0755) unless -d "$virtusertable_prefix/virtusertable.import"; #iscp("root\@$virtusertable/*","$aliases_prefix/virtusertable.import/"); -- cgit v1.2.1 From cd7e487f34c2de4768670aef01f096d8530fb057 Mon Sep 17 00:00:00 2001 From: ivan Date: Mon, 10 May 2004 09:59:06 +0000 Subject: allow for multiple svc_acct svcparts --- bin/sendmail.import | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/bin/sendmail.import b/bin/sendmail.import index a55616dc3..b137433d9 100644 --- a/bin/sendmail.import +++ b/bin/sendmail.import @@ -20,11 +20,11 @@ adminsuidsetup $user; #$FS::domain_record::noserial_hack = 1; use vars qw($defaultdomain); -$defaultdomain = 'surferz.net'; +$defaultdomain = '295.ca'; -use vars qw($svcpart $forward_svcpart); -$svcpart = 2; -$forward_svcpart = 4; +use vars qw(@svcpart $forward_svcpart); +@svcpart = qw( 2 4 ); +$forward_svcpart = 7; use vars qw($spooldir); $spooldir = "/usr/local/etc/freeside/export.". datasrc. "/sendmail"; @@ -144,7 +144,7 @@ sub svcnum_or_literal { my $svc_domain = qsearchs('svc_domain', { 'domain' => $domain } ); my $domsvc = $svc_domain ? $svc_domain->svcnum : ''; - my @svc_acct = grep { $_->cust_svc->svcpart == $svcpart } + my @svc_acct = grep { grep { $_->cust_svc->svcpart == $_ } @svcpart } qsearch('svc_acct', { 'username' => $username, 'domsvc' => $domsvc, -- cgit v1.2.1 From 38606efd583311cff2703090d7c9e3de550522b1 Mon Sep 17 00:00:00 2001 From: ivan Date: Mon, 10 May 2004 10:01:38 +0000 Subject: properly nested greps --- bin/sendmail.import | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bin/sendmail.import b/bin/sendmail.import index b137433d9..ef745fc46 100644 --- a/bin/sendmail.import +++ b/bin/sendmail.import @@ -144,7 +144,9 @@ sub svcnum_or_literal { my $svc_domain = qsearchs('svc_domain', { 'domain' => $domain } ); my $domsvc = $svc_domain ? $svc_domain->svcnum : ''; - my @svc_acct = grep { grep { $_->cust_svc->svcpart == $_ } @svcpart } + my @svc_acct = grep { my $svc_acct = $_; + grep { $svc_acct->cust_svc->svcpart == $_ } @svcpart + } qsearch('svc_acct', { 'username' => $username, 'domsvc' => $domsvc, -- cgit v1.2.1 From 4121477dde8c9400bf81023bea3e0d980b34bf91 Mon Sep 17 00:00:00 2001 From: ivan Date: Mon, 10 May 2004 11:10:58 +0000 Subject: make postfix export commands configrable --- FS/FS/part_export/postfix.pm | 5 +++++ bin/postfix.export | 7 ++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/FS/FS/part_export/postfix.pm b/FS/FS/part_export/postfix.pm index c24cf19a3..4fd19ee61 100644 --- a/FS/FS/part_export/postfix.pm +++ b/FS/FS/part_export/postfix.pm @@ -11,6 +11,11 @@ tie my %options, 'Tie::IxHash', 'aliases' => { label=>'aliases file location', default=>'/etc/aliases' }, 'virtual' => { label=>'virtual file location', default=>'/etc/postfix/virtual' }, 'mydomain' => { label=>'local domain', default=>'' }, + 'newaliases' => { label=>'newaliases command', default=>'newaliases' }, + 'postmap' => { label=>'postmap command', + default=>'postmap hash:/etc/postfix/virtual', }, + 'reload' => { label=>'reload command', + default=>'postfix reload' }, ; %info = ( diff --git a/bin/postfix.export b/bin/postfix.export index 64d973837..dbb08ceb9 100755 --- a/bin/postfix.export +++ b/bin/postfix.export @@ -99,7 +99,7 @@ foreach my $export ( @exports ) { } ) or die "rsync to $machine failed: ". join(" / ", $rsync->err); # warn $rsync->out; - ssh("$user\@$machine", "newaliases"); + ssh("$user\@$machine", $export->option('newaliases') || 'newaliases'); # ssh("$user\@$machine", "postfix reload"); $rsync->exec( { @@ -107,8 +107,9 @@ foreach my $export ( @exports ) { dest => "$user\@$machine:". $export->option('virtual'), } ) or die "rsync to $machine failed: ". join(" / ", $rsync->err); # warn $rsync->out; - ssh("$user\@$machine", "postmap hash:/etc/postfix/virtual"); - ssh("$user\@$machine", "postfix reload"); + ssh("$user\@$machine", $export->option('postmap') + || 'postmap hash:/etc/postfix/virtual'); + ssh("$user\@$machine", $export->option('reload') || 'postfix reload'); } -- cgit v1.2.1 From 07242e191cb2ad247fed8dacd392ef8bf47b5392 Mon Sep 17 00:00:00 2001 From: ivan Date: Mon, 10 May 2004 13:17:23 +0000 Subject: fall back to password changing in the case of blank suspension/unsuspension commands, like some exports --- FS/FS/part_export/shellcommands.pm | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/FS/FS/part_export/shellcommands.pm b/FS/FS/part_export/shellcommands.pm index 4431cc0c4..4f201cf9c 100644 --- a/FS/FS/part_export/shellcommands.pm +++ b/FS/FS/part_export/shellcommands.pm @@ -176,14 +176,25 @@ sub _export_delete { sub _export_suspend { my($self) = shift; - $self->_export_command('suspend', @_); + $self->_export_command_or_super('suspend', @_); } sub _export_unsuspend { my($self) = shift; - $self->_export_command('unsuspend', @_); + $self->_export_command_or_super('unsuspend', @_); } +sub _export_command_or_super { + my($self, $action) = (shift, shift); + if ( $self->option($action) =~ /^\s*$/ ) { + my $method = "SUPER::_export_$action"; + $self->$method(@_); + } else { + $self->_export_command($action, @_); + } +}; + + sub _export_command { my ( $self, $action, $svc_acct) = (shift, shift, shift); my $command = $self->option($action); -- cgit v1.2.1 From 86b42d7779820cd90ab132329b98d9710add733d Mon Sep 17 00:00:00 2001 From: ivan Date: Mon, 10 May 2004 13:46:52 +0000 Subject: fix ISPMan password changing command --- FS/FS/part_export/shellcommands_withdomain.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FS/FS/part_export/shellcommands_withdomain.pm b/FS/FS/part_export/shellcommands_withdomain.pm index 4f1b25bc4..89ee95fa3 100644 --- a/FS/FS/part_export/shellcommands_withdomain.pm +++ b/FS/FS/part_export/shellcommands_withdomain.pm @@ -73,7 +73,7 @@ the same username with different domains. You will need to this.form.useradd_stdin.value = ""; this.form.userdel.value = "/usr/local/ispman/bin/ispman.delUser -d $domain $username"; this.form.userdel_stdin.value=""; - this.form.usermod.value = "/usr/local/ispman/bin/ispman.passwd.user $username\\\@$domain $new_quoted_password"; + this.form.usermod.value = "/usr/local/ispman/bin/ispman.passwd.user $new_username\\\@$new_domain $new_quoted_password"; this.form.usermod_stdin.value = ""; this.form.usermod_pwonly.checked = true; '> -- cgit v1.2.1 From 2c68c62e2f9187c534e2f2291f83b789ba9075fb Mon Sep 17 00:00:00 2001 From: ivan Date: Mon, 10 May 2004 23:16:00 +0000 Subject: fix sequences in upgrade docs? --- httemplate/docs/upgrade10.html | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/httemplate/docs/upgrade10.html b/httemplate/docs/upgrade10.html index 788eb0a97..08fc28ea5 100644 --- a/httemplate/docs/upgrade10.html +++ b/httemplate/docs/upgrade10.html @@ -110,10 +110,11 @@ ALTER TABLE part_pkg DROP CONSTRAINT part_pkg_temp_pkey; ALTER TABLE part_pkg ADD PRIMARY KEY (pkgpart); select setval('public.part_pkg_temp_pkgpart_seq', ( select max(pkgpart) from part_pkg) ); -Or on Pg versions that don't support DROP CONSTRAINT and ADD PRIMARY KEY (tested on 7.1 so far): +Or on Pg versions that don't support DROP CONSTRAINT and ADD PRIMARY KEY (tested on 7.1 and 7.2 so far): DROP INDEX part_pkg_temp_pkey; CREATE UNIQUE INDEX part_pkg_pkey ON part_pkg (pkgpart); -select setval('part_pkg_temp_pkgpart_seq', ( select max(pkgpart) from part_pkg) ); +7.1?: select setval('part_pkg_temp_pkgpart_seq', ( select max(pkgpart) from part_pkg) ); +7.2: select setval('part_pkg_pkgpart_seq', ( select max(pkgpart) from part_pkg) ); CREATE TABLE h_part_pkg_temp ( historynum serial NOT NULL, @@ -144,10 +145,11 @@ ALTER TABLE h_part_pkg DROP CONSTRAINT h_part_pkg_temp_pkey; ALTER TABLE h_part_pkg ADD PRIMARY KEY (historynum); select setval('public.h_part_pkg_temp_historynum_seq', ( select max(historynum) from h_part_pkg) ); -Or on Pg versions that don't support DROP CONSTRAINT and ADD PRIMARY KEY (tested on 7.1 so far): +Or on Pg versions that don't support DROP CONSTRAINT and ADD PRIMARY KEY (tested on 7.1 and 7.2 so far): DROP INDEX h_part_pkg_temp_pkey; CREATE UNIQUE INDEX h_part_pkg_pkey ON h_part_pkg (historynum); -select setval('h_part_pkg_temp_historynum_seq', ( select max(historynum) from h_part_pkg) ); +7.1?: select setval('h_part_pkg_temp_historynum_seq', ( select max(historynum) from h_part_pkg) ); +7.2: select setval('h_part_pkg_historynum_seq', ( select max(historynum) from h_part_pkg) ); DROP INDEX cust_bill_pkg1; -- cgit v1.2.1 From 699ce04c670c2da6b1b3821c960467b1c427d249 Mon Sep 17 00:00:00 2001 From: ivan Date: Tue, 11 May 2004 00:46:59 +0000 Subject: vary basic virtual host browse --- httemplate/index.html | 2 +- httemplate/search/svc_www.cgi | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) create mode 100755 httemplate/search/svc_www.cgi diff --git a/httemplate/index.html b/httemplate/index.html index 2e7fc1c84..b43399db1 100644 --- a/httemplate/index.html +++ b/httemplate/index.html @@ -35,7 +35,7 @@
    Username or all accounts by username or uid

    Domain or all domains

    all mail forwards by svcnum
    - +
    all virtual hosts by svcnum

    diff --git a/httemplate/search/svc_www.cgi b/httemplate/search/svc_www.cgi new file mode 100755 index 000000000..1f05c2377 --- /dev/null +++ b/httemplate/search/svc_www.cgi @@ -0,0 +1,42 @@ +<% + +#my $conf = new FS::Conf; + +my($query)=$cgi->keywords; +$query ||= ''; #to avoid use of unitialized value errors +my(@svc_www, $orderby); +if ( $query eq 'svcnum' ) { + $orderby = 'ORDER BY svcnum'; +} else { + eidiot('unimplemented'); +} + +my $count_query = 'SELECT COUNT(*) FROM svc_www'; +my $sql_query = { + 'table' => 'svc_www', + 'hashref' => {}, + 'extra_sql' => $orderby, +}; + +my $link = [ "${p}view/svc_www.cgi?", 'svcnum', ]; +#my $dlink = [ "${p}view/svc_www.cgi?", 'svcnum', ]; +my $ulink = [ "${p}view/svc_acct.cgi?", 'usersvc', ]; + + +%> +<%= include( 'elements/search.html', + 'title' => 'Virtual Host Search Results', + 'name' => 'virtual hosts', + 'query' => $sql_query, + 'count_query' => $count_query, + 'header' => [ '#', 'Zone', 'User', ], + 'fields' => [ 'svcnum', + sub { $_[0]->domain_record->zone }, + sub { $_[0]->svc_acct->email }, + ], + 'links' => [ $link, + '', + $ulink, + ], + ) +%> -- cgit v1.2.1 From 0d78ea5d2d300b4aea2a6b00af752cb45321b073 Mon Sep 17 00:00:00 2001 From: ivan Date: Tue, 11 May 2004 09:50:50 +0000 Subject: fix commands --- FS/FS/part_export/www_shellcommands.pm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/FS/FS/part_export/www_shellcommands.pm b/FS/FS/part_export/www_shellcommands.pm index 6847f6470..9f14707b0 100644 --- a/FS/FS/part_export/www_shellcommands.pm +++ b/FS/FS/part_export/www_shellcommands.pm @@ -13,10 +13,10 @@ tie my %options, 'Tie::IxHash', default=>'mkdir /var/www/$zone; chown $username /var/www/$zone; ln -s /var/www/$zone $homedir/$zone', }, 'userdel' => { label=>'Delete command', - default=>'[ -n "$zone" ] && rm -rf /var/www/$zone; rm $homedir/$zone', + default=>'[ -n "$zone" ] && rm -rf /var/www/$zone; rm $homedir/$zone', }, 'usermod' => { label=>'Modify command', - default=>'[ -n "$old_zone" ] && rm $old_homedir/$old_zone; [ "$old_zone" != "$new_zone" -a -n "$new_zone" ] && mv /var/www/$old_zone /var/www/$new_zone; [ "$old_username" != "$new_username" ] && chown -R $new_username /var/www/$new_zone; ln -s /var/www/$new_zone $new_homedir/$new_zone', + default=>'[ -n "$old_zone" ] && rm $old_homedir/$old_zone; [ "$old_zone" != "$new_zone" -a -n "$new_zone" ] && mv /var/www/$old_zone /var/www/$new_zone; [ "$old_username" != "$new_username" ] && chown -R $new_username /var/www/$new_zone; ln -s /var/www/$new_zone $new_homedir/$new_zone', }, ; @@ -33,8 +33,8 @@ Run remote commands via SSH, for virtual web sites. You will need to
  • 'checkbox', }, + { + 'key' => 'svc_www-enable_subdomains', + 'section' => '', + 'description' => 'Enable selection of specific subdomains for virtual host creation.', + 'type' => 'checkbox', + }, + + { + 'key' => 'svc_www-usersvc_svcpart', + 'section' => '', + 'description' => 'Allowable service definition svcparts for virtual hosts, one per line.', + 'type' => 'textarea', + }, + ); 1; diff --git a/httemplate/edit/svc_www.cgi b/httemplate/edit/svc_www.cgi index ebc4b1148..fe7052292 100644 --- a/httemplate/edit/svc_www.cgi +++ b/httemplate/edit/svc_www.cgi @@ -56,9 +56,13 @@ my $action = $svc_www->svcnum ? 'Edit' : 'Add'; my( %svc_acct, %arec ); if ($pkgnum) { - my($u_part_svc,@u_acct_svcparts); - foreach $u_part_svc ( qsearch('part_svc',{'svcdb'=>'svc_acct'}) ) { - push @u_acct_svcparts,$u_part_svc->getfield('svcpart'); + my @u_acct_svcparts; + foreach my $svcpart ( + map { $_->svcpart } qsearch( 'part_svc', { 'svcdb' => 'svc_acct' } ) + ) { + next if $conf->exists('svc_www-usersvc_svcpart') + && grep { $svcpart == $_ } $conf->config('svc_www-usersvc_svcpart'); + push @u_acct_svcparts, $svcpart; } my($cust_pkg)=qsearchs('cust_pkg',{'pkgnum'=>$pkgnum}); @@ -92,25 +96,23 @@ if ($pkgnum) { my($i_cust_svc); foreach $i_cust_svc ( qsearch('cust_svc',{'pkgnum'=>$cust_pkgnum,'svcpart'=>$acct_svcpart}) ) { my($svc_domain)=qsearchs('svc_domain',{'svcnum'=>$i_cust_svc->getfield('svcnum')}); - my $domain_rec; - foreach $domain_rec ( qsearch('domain_record',{ - 'svcnum' => $svc_domain->svcnum, - 'rectype' => 'A' } ), - qsearch('domain_record',{ - 'svcnum' => $svc_domain->svcnum, - 'rectype' => 'CNAME' - } ) ) { - $arec{$domain_rec->recnum} = - $domain_rec->reczone eq '@' - ? $svc_domain->domain - : $domain_rec->reczone. '.'. $svc_domain->domain; + if ( $conf->exists('svc_www-enable_subdomains') ) { + foreach my $domain_rec ( qsearch('domain_record',{ + 'svcnum' => $svc_domain->svcnum, + 'rectype' => 'A' } ), + qsearch('domain_record',{ + 'svcnum' => $svc_domain->svcnum, + 'rectype' => 'CNAME' + } ) ) { + $arec{$domain_rec->recnum} = $domain_rec->zone; + } + $arec{'www.'. $svc_domain->domain} = 'www.'. $svc_domain->domain + unless qsearchs('domain_record', { svcnum => $svc_domain->svcnum, + reczone => 'www', } ); } $arec{'@.'. $svc_domain->domain} = $svc_domain->domain unless qsearchs('domain_record', { svcnum => $svc_domain->svcnum, reczone => '@', } ); - $arec{'www.'. $svc_domain->domain} = 'www.'. $svc_domain->domain - unless qsearchs('domain_record', { svcnum => $svc_domain->svcnum, - reczone => 'www', } ); } } } -- cgit v1.2.1 From a5c64e8089d4e6c76ee070102e3a67baf1485181 Mon Sep 17 00:00:00 2001 From: ivan Date: Tue, 11 May 2004 11:22:09 +0000 Subject: need to pull in $conf --- httemplate/edit/svc_www.cgi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/httemplate/edit/svc_www.cgi b/httemplate/edit/svc_www.cgi index fe7052292..b89672a52 100644 --- a/httemplate/edit/svc_www.cgi +++ b/httemplate/edit/svc_www.cgi @@ -1,6 +1,8 @@ <% +my $conf = new FS::Conf; + my( $svcnum, $pkgnum, $svcpart, $part_svc, $svc_www ); if ( $cgi->param('error') ) { $svc_www = new FS::svc_www ( { -- cgit v1.2.1 From af37880d5ac36f2b141b2eeeb1c7aa49a50d0c5b Mon Sep 17 00:00:00 2001 From: ivan Date: Tue, 11 May 2004 11:52:02 +0000 Subject: clean this up a bit, fix svc_www-usersvc_svcpart and hopefully simplified zone select too --- httemplate/edit/svc_www.cgi | 73 ++++++++++++++++++++++++++++++++------------- 1 file changed, 52 insertions(+), 21 deletions(-) diff --git a/httemplate/edit/svc_www.cgi b/httemplate/edit/svc_www.cgi index b89672a52..ed8d42501 100644 --- a/httemplate/edit/svc_www.cgi +++ b/httemplate/edit/svc_www.cgi @@ -63,7 +63,8 @@ if ($pkgnum) { map { $_->svcpart } qsearch( 'part_svc', { 'svcdb' => 'svc_acct' } ) ) { next if $conf->exists('svc_www-usersvc_svcpart') - && grep { $svcpart == $_ } $conf->config('svc_www-usersvc_svcpart'); + && ! grep { $svcpart == $_ } + $conf->config('svc_www-usersvc_svcpart'); push @u_acct_svcparts, $svcpart; } @@ -91,31 +92,61 @@ if ($pkgnum) { push @d_acct_svcparts,$d_part_svc->getfield('svcpart'); } - foreach $i_cust_pkg ( qsearch('cust_pkg',{'custnum'=>$custnum}) ) { - my($cust_pkgnum)=$i_cust_pkg->getfield('pkgnum'); - my($acct_svcpart); - foreach $acct_svcpart (@d_acct_svcparts) { - my($i_cust_svc); - foreach $i_cust_svc ( qsearch('cust_svc',{'pkgnum'=>$cust_pkgnum,'svcpart'=>$acct_svcpart}) ) { - my($svc_domain)=qsearchs('svc_domain',{'svcnum'=>$i_cust_svc->getfield('svcnum')}); + foreach $i_cust_pkg ( qsearch( 'cust_pkg', { 'custnum' => $custnum } ) ) { + my $cust_pkgnum = $i_cust_pkg->pkgnum; + + foreach my $acct_svcpart (@d_acct_svcparts) { + + foreach my $i_cust_svc ( + qsearch( 'cust_svc', { 'pkgnum' => $cust_pkgnum, + 'svcpart' => $acct_svcpart } ) + ) { + my $svc_domain = + qsearchs( 'svc_domain', { 'svcnum' => $i_cust_svc->svcnum } ); + + my $extra_sql = "AND ( rectype = 'A' OR rectype = 'CNAME' )"; + if ( $conf->exists('svc_www-enable_subdomains') ) { + my $domain = $ + $extra_sql .= " AND ( reczone = '@' OR reczone = '". + $svc_domain->domain. ".' )"; + } + + foreach my $domain_rec ( + qsearch( 'domain_record', + { + 'svcnum' => $svc_domain->svcnum, + }, + '', + $extra_sql, + ) + ) { + $arec{$domain_rec->recnum} = $domain_rec->zone; + } + if ( $conf->exists('svc_www-enable_subdomains') ) { - foreach my $domain_rec ( qsearch('domain_record',{ - 'svcnum' => $svc_domain->svcnum, - 'rectype' => 'A' } ), - qsearch('domain_record',{ - 'svcnum' => $svc_domain->svcnum, - 'rectype' => 'CNAME' - } ) ) { - $arec{$domain_rec->recnum} = $domain_rec->zone; - } $arec{'www.'. $svc_domain->domain} = 'www.'. $svc_domain->domain - unless qsearchs('domain_record', { svcnum => $svc_domain->svcnum, - reczone => 'www', } ); + unless qsearchs( 'domain_record', { + svcnum => $svc_domain->svcnum, + reczone => 'www', + } ) + || qsearchs( 'domain_record', { + svcnum => $svc_domain->svcnum, + reczone => 'www.'.$svc-domain->domain.'.', + } ); } + $arec{'@.'. $svc_domain->domain} = $svc_domain->domain - unless qsearchs('domain_record', { svcnum => $svc_domain->svcnum, - reczone => '@', } ); + unless qsearchs('domain_record', { + svcnum => $svc_domain->svcnum, + reczone => '@', + } ) + || qsearchs('domain_record', { + svcnum => $svc_domain->svcnum, + reczone => $svc_domain->domain.'.', + } ); + } + } } -- cgit v1.2.1 From 20431ca2cc197c3d3a109d43318a0f96ea7e24d1 Mon Sep 17 00:00:00 2001 From: ivan Date: Tue, 11 May 2004 11:54:02 +0000 Subject: so close --- httemplate/edit/svc_www.cgi | 1 - 1 file changed, 1 deletion(-) diff --git a/httemplate/edit/svc_www.cgi b/httemplate/edit/svc_www.cgi index ed8d42501..cb58ce979 100644 --- a/httemplate/edit/svc_www.cgi +++ b/httemplate/edit/svc_www.cgi @@ -106,7 +106,6 @@ if ($pkgnum) { my $extra_sql = "AND ( rectype = 'A' OR rectype = 'CNAME' )"; if ( $conf->exists('svc_www-enable_subdomains') ) { - my $domain = $ $extra_sql .= " AND ( reczone = '@' OR reczone = '". $svc_domain->domain. ".' )"; } -- cgit v1.2.1 From 29da3c125643b73cb6f6219b99eadb67673e4d6d Mon Sep 17 00:00:00 2001 From: ivan Date: Tue, 11 May 2004 11:58:42 +0000 Subject: this has been an evening of logical negation --- httemplate/edit/svc_www.cgi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httemplate/edit/svc_www.cgi b/httemplate/edit/svc_www.cgi index cb58ce979..a9b1ed348 100644 --- a/httemplate/edit/svc_www.cgi +++ b/httemplate/edit/svc_www.cgi @@ -105,7 +105,7 @@ if ($pkgnum) { qsearchs( 'svc_domain', { 'svcnum' => $i_cust_svc->svcnum } ); my $extra_sql = "AND ( rectype = 'A' OR rectype = 'CNAME' )"; - if ( $conf->exists('svc_www-enable_subdomains') ) { + unless ( $conf->exists('svc_www-enable_subdomains') ) { $extra_sql .= " AND ( reczone = '@' OR reczone = '". $svc_domain->domain. ".' )"; } -- cgit v1.2.1 From a800fde5d31fb9b9cfe46b1ce2f68ea8e56bff53 Mon Sep 17 00:00:00 2001 From: ivan Date: Tue, 11 May 2004 12:01:29 +0000 Subject: i'm not usually like this. --- httemplate/edit/svc_www.cgi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httemplate/edit/svc_www.cgi b/httemplate/edit/svc_www.cgi index a9b1ed348..4989bb610 100644 --- a/httemplate/edit/svc_www.cgi +++ b/httemplate/edit/svc_www.cgi @@ -106,7 +106,7 @@ if ($pkgnum) { my $extra_sql = "AND ( rectype = 'A' OR rectype = 'CNAME' )"; unless ( $conf->exists('svc_www-enable_subdomains') ) { - $extra_sql .= " AND ( reczone = '@' OR reczone = '". + $extra_sql .= " AND ( reczone = '\@' OR reczone = '". $svc_domain->domain. ".' )"; } -- cgit v1.2.1 From 609da4bf03be911bc3ade700f40c243710f3002b Mon Sep 17 00:00:00 2001 From: ivan Date: Wed, 12 May 2004 10:03:47 +0000 Subject: for native apache installs --- Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Makefile b/Makefile index 6d3d80397..ffbd67afc 100644 --- a/Makefile +++ b/Makefile @@ -23,6 +23,8 @@ FREESIDE_DOCUMENT_ROOT = /var/www/freeside #FREESIDE_DOCUMENT_ROOT = /var/www/htdocs/freeside #suse #FREESIDE_DOCUMENT_ROOT = /srv/www/htdocs/freeside +#apache +#FREESIDE_DOCUMENT_ROOT = /usr/local/apache/htdocs/freeside #deb, redhat, fedora, mandrake, suse, others? INIT_FILE = /etc/init.d/freeside @@ -37,6 +39,8 @@ HTTPD_RESTART = /etc/init.d/apache restart #HTTPD_RESTART = /usr/local/etc/rc.d/apache.sh stop; sleep 1; /usr/local/etc/rc.d/apache.sh start #openbsd #HTTPD_RESTART = kill -TERM `cat /var/www/logs/httpd.pid`; sleep 1; /usr/sbin/httpd -u -DSSL +#apache +#HTTPD_RESTART = /usr/local/apache/bin/apachectl restart FREESIDE_RESTART = ${INIT_FILE} restart -- cgit v1.2.1 From b53f5fb951a5fdf89ba3fb597c18682e699b95e7 Mon Sep 17 00:00:00 2001 From: ivan Date: Wed, 12 May 2004 12:38:49 +0000 Subject: that wasn't pleasant --- install/redhat/9/INSTALL | 39 ++++++++++----------------------------- install/redhat/9/sources.list | 4 ++-- 2 files changed, 12 insertions(+), 31 deletions(-) diff --git a/install/redhat/9/INSTALL b/install/redhat/9/INSTALL index ce6ca5962..c32a2357b 100644 --- a/install/redhat/9/INSTALL +++ b/install/redhat/9/INSTALL @@ -1,36 +1,17 @@ #!/bin/sh - -wget --passive-ftp --continue ftp://apt-rpm.tuxfamily.org/apt/redhat/9/en/i386/RPMS.extra/apt-*i386.rpm +wget --passive-ftp --continue http://redhat.usu.edu/mirrors/apt4rpm/apt-0.5.5cnc4.1-fr1.20030325a.2.i386.rpm rpm -i apt*i386.rpm cp sources.list /etc/apt/ -apt-get update; apt-get update -#apt-get install apache mod_ssl mod_perl perl-CGI perl-CPAN perl-DBD-MySQL perl-DBD-Pg perl-DBI perl-DateManip perl-Digest-MD5 perl-HTML-Parser perl-HTML-Tagset perl-MIME-Base64 perl-Storable perl-TimeDate perl-URI perl-libnet perl-libwww-perl perl-suidperl rsync postgresql postgresql-docs postgresql-libs postgresql-server screen zsh lftp cvs #openssh - -apt-get install perl-Devel-Symdump perl-BSD-Resource rpm-build gdbm-devel expat-devel openssl-devel krb5-devel db4-devel - -wget --passive-ftp --continue http://reb00t.com/linux/RPMS/redhat-9/apache/apache-1.3.28-0.n0i.src.rpm http://reb00t.com/linux/RPMS/redhat-9/mm/mm-1.2.1-0.n0i.i686.rpm http://reb00t.com/linux/RPMS/redhat-9/mm/mm-devel-1.2.1-0.n0i.i686.rpm -rpm -i mm-1.2.1-0.n0i.i686.rpm mm-devel-1.2.1-0.n0i.i686.rpm apache-1.3.28-0.n0i.src.rpm - -install -d /usr/src/redhat -for a in BUILD RPMS SOURCES SPECS SRPMS; do install -d /usr/src/redhat/$a; done -for a in athlon i386 i486 i586 i686 noarch; do install -d /usr/src/redhat/RPMS/$a; done - -cd /usr/src/redhat/SPECS -rpmbuild -ba apache.spec - -cd /usr/src/redhat/RPMS/i386 -rpm -i apache-1.3.28-0.n0i.i386.rpm +apt-get update -apt-get install perl-CGI perl-CPAN perl-DBD-MySQL perl-DBD-Pg perl-DBI perl-DateManip perl-HTML-Parser perl-HTML-Tagset perl-TimeDate perl-URI perl-libwww-perl perl-suidperl rsync postgresql postgresql-docs postgresql-libs postgresql-server screen zsh lftp cvs gcc gd #openssh +apt-get install httpd mod_perl mod_ssl perl-CGI perl-CPAN perl-DBD-MySQL perl-DateManip perl-HTML-Parser perl-HTML-Tagset perl-TimeDate perl-URI perl-libwww-perl perl-suidperl rsync postgresql postgresql-docs postgresql-libs postgresql-server screen zsh lftp cvs gcc # gd openssh -#wget --passive-ftp --continue http://atrpms.physik.fu-berlin.de/dist/rh9/perl-GD/perl-GD-2.11-7.rh9.at.i386.rpm http://atrpms.physik.fu-berlin.de/dist/rh9/atrpms/atrpms-45-1.rh9.at.noarch.rpm http://atrpms.physik.fu-berlin.de/dist/rh9/yum/yum-2.0.4-28.rh9.at.noarch.rpm http://atrpms.physik.fu-berlin.de/dist/rh9/gd/gd-2.0.15-1_6.rh9.at.i386.rpm http://atrpms.physik.fu-berlin.de/dist/rh9/atrpms/atrpms-package-config-45-1.rh9.at.noarch.rpm -wget --passive-ftp --continue http://atrpms.physik.fu-berlin.de/dist/rh9/perl-GD/perl-GD-2.11-7.rh9.at.i386.rpm http://atrpms.physik.fu-berlin.de/dist/rh9/atrpms/atrpms-54-1.rh9.at.noarch.rpm http://atrpms.physik.fu-berlin.de/dist/rh9/yum/yum-2.0.6-0_31.rh9.at.noarch.rpm http://atrpms.physik.fu-berlin.de/dist/rh9/gd/gd-2.0.15-1_6.rh9.at.i386.rpm http://atrpms.physik.fu-berlin.de/dist/rh9/atrpms/atrpms-package-config-57-1.rh9.at.noarch.rpm +wget --passive-ftp --continue http://atrpms.physik.fu-berlin.de/dist/rh9/perl-GD/perl-GD-2.11-7.rh9.at.i386.rpm http://atrpms.physik.fu-berlin.de/dist/rh9/atrpms/atrpms-54-1.rh9.at.noarch.rpm http://atrpms.physik.fu-berlin.de/dist/rh9/gd/gd-2.0.15-1_6.rh9.at.i386.rpm cp /etc/apt/apt.conf /etc/apt/apt.conf.real -#rpm -i --replacefiles atrpms-package-config-45-1.rh9.at.noarch.rpm yum-2.0.4-28.rh9.at.noarch.rpm atrpms-45-1.rh9.at.noarch.rpm gd-2.0.15-1_6.rh9.at.i386.rpm perl-GD-2.11-7.rh9.at.i386.rpm -rpm -i --replacefiles atrpms-package-config-57-1.rh9.at.noarch.rpm yum-2.0.6-0_31.rh9.at.noarch.rpm atrpms-54-1.rh9.at.noarch.rpm gd-2.0.15-1_6.rh9.at.i386.rpm perl-GD-2.11-7.rh9.at.i386.rpm +rpm -i gd-2.0.15-1_6.rh9.at.i386.rpm atrpms-54-1.rh9.at.noarch.rpm perl-GD-2.11-7.rh9.at.i386.rpm mv /etc/apt/apt.conf.real /etc/apt/apt.conf @@ -39,13 +20,13 @@ perl -MCPAN -e"install Locale::Country, Net::Whois, Business::CreditCard, \ String::Approx, Text::Template, DBIx::DataSource, \ DBIx::DBSchema, Net::SSH, String::ShellQuote, \ Net::SCP, Apache::ASP, Tie::IxHash, Time::Duration, \ - HTML::Widgets::SelectLayers, Apache::DBI, Cache::Cache \ - Test::Pod NetAddr::IP IPC::ShareLite Chart::LinesPoints" + HTML::Widgets::SelectLayers, Apache::DBI, \ + Cache::Cache, Test::Pod, NetAddr::IP, IPC::ShareLite, \ + Chart::LinesPoints, Net::Whois::Raw, \ + Locale::SubCountry, Crypt::PasswdMD5, DBI, DBD::Pg" -echo 'OPTIONS="-DHAVE_PERL -DHAVE_SSL"' >>/etc/sysconfig/apache -#remove perl & ssl LoadModule lines from /etc/httpd/conf/httpd.conf -#as they're statically linked +#apachetoolbox i guess /usr/sbin/useradd freeside diff --git a/install/redhat/9/sources.list b/install/redhat/9/sources.list index f6f21f4c9..6dcb3b436 100644 --- a/install/redhat/9/sources.list +++ b/install/redhat/9/sources.list @@ -1,2 +1,2 @@ -rpm ftp://apt-rpm.tuxfamily.org/apt redhat/9/en/i386 os updates extra -rpm-src ftp://apt-rpm.tuxfamily.org/apt redhat/9/en/i386 os updates extra +#rpm http://download.fedoralegacy.org/apt redhat/9/i386 os updates legacy-util +rpm http://download.fedoralegacy.org/apt redhat/9/i386 os updates -- cgit v1.2.1 From e43ee0863e66d8d3e3a4453690561638ed4a92dd Mon Sep 17 00:00:00 2001 From: ivan Date: Wed, 12 May 2004 18:03:47 +0000 Subject: adding --- bin/freeside.import | 146 ++++++++++++++++++++++++++++++++++++++++++++++++++++ bin/sequences.reset | 28 ++++++++++ 2 files changed, 174 insertions(+) create mode 100644 bin/freeside.import create mode 100644 bin/sequences.reset diff --git a/bin/freeside.import b/bin/freeside.import new file mode 100644 index 000000000..fdfcc083e --- /dev/null +++ b/bin/freeside.import @@ -0,0 +1,146 @@ +#!/usr/bin/perl -w + +use strict; +use DBI; + +my $s_datasrc = 'DBI:mysql:host=ns1.enetonline.net;port=3307;user=ivan;dbname=freeside'; +my $s_dbuser = 'ivan'; +my $s_dbpass = ''; + +my $d_datasrc = 'DBI:Pg:dbname=freeside'; +my $d_dbuser = 'freeside'; +my $d_dbpass = ''; + +#my @tables = qw( +#addr_block +#agent +#agent_type +#cust_bill +#cust_bill_event +#cust_bill_pay +#cust_bill_pkg +#cust_bill_pkg_detail +#cust_credit +#cust_credit_bill +#cust_credit_refund +#cust_main +#cust_main_county +#cust_main_invoice +#cust_pay +#cust_pay_batch +#cust_pkg +#cust_refund +#cust_svc +#cust_tax_exempt +#domain_record +#export_svc +#h_addr_block +#h_agent +#h_agent_type +#h_cust_bill +#h_cust_bill_event +#h_cust_bill_pay +#h_cust_bill_pkg +#h_cust_bill_pkg_detail +#h_cust_credit +#h_cust_credit_bill +#h_cust_credit_refund +#h_cust_main +#h_cust_main_county +#h_cust_main_invoice +#h_cust_pay +#h_cust_pay_batch +#h_cust_pkg +#h_cust_refund +#h_cust_svc +#h_cust_tax_exempt +#h_domain_record +#h_export_svc +#h_msgcat +#h_nas +#h_part_bill_event +#h_part_export +#h_part_export_option +#h_part_pkg +#h_part_pop_local +#h_part_referral +#h_part_svc +#h_part_svc_column +#h_part_svc_router +#h_pkg_svc +#h_port +#h_prepay_credit +#h_queue +#h_queue_arg +#h_queue_depend +#h_radius_usergroup +#h_router +#h_router_field +#h_sb_field +#h_session +#h_svc_acct +#h_svc_acct_pop +#h_svc_broadband +#h_svc_domain +#h_svc_forward +#h_svc_www +#h_type_pkgs +#msgcat +#nas +#part_bill_event +#part_export +#part_export_option +#part_pkg + +my @tables = qw( +part_pop_local +part_referral +part_router_field +part_sb_field +part_svc +part_svc_column +part_svc_router +pkg_svc +port +prepay_credit +queue +queue_arg +queue_depend +radius_usergroup +router +router_field +sb_field +session +svc_acct +svc_acct_pop +svc_broadband +svc_domain +svc_forward +svc_www +type_pkgs +); + +my $s_dbh = DBI->connect($s_datasrc, $s_dbuser, $s_dbpass) or die $DBI::errstr; +my $d_dbh = DBI->connect($d_datasrc, $d_dbuser, $d_dbpass) or die $DBI::errstr; + +foreach my $table ( @tables ) { + $d_dbh->do("delete from $table"); + + my $s_sth = $s_dbh->prepare("select * from $table"); + $s_sth->execute or die $s_sth->errstr; + + my $row; + while ( $row = $s_sth->fetchrow_arrayref ) { + my $d_sth = $d_dbh->prepare( + "insert into $table ( ". + join(', ', @{$s_sth->{NAME}} ). + ' ) VALUES ( '. + join(', ', map { '?' } @{$s_sth->{NAME}} ). + ' )' + ) or die $d_dbh->errstr; + + $d_sth->execute(@$row) or die $d_sth->errstr; + + } +} + diff --git a/bin/sequences.reset b/bin/sequences.reset new file mode 100644 index 000000000..f0fc4b7f2 --- /dev/null +++ b/bin/sequences.reset @@ -0,0 +1,28 @@ +#!/usr/bin/perl + +use FS::UID qw(adminsuidsetup); +use FS::Record qw(dbdef dbh); + +my $user = shift; +adminsuidsetup $user or die; + +foreach my $table ( dbdef->tables ) { + my $primary_key = dbdef->table($table)->primary_key; + next unless $primary_key; + #my $local = dbdef->table($table)->column($primary_key)->local; + ##next unless $default =~ /nextval/; + #print "$local\n"; + + my $statement = "select setval('${table}_${primary_key}_seq', ( select max($primary_key) from $table ) )\n"; + my $sth = dbh->prepare($statement) or do { + warn dbh->errstr. " preparing $statement\n"; + next; + }; + $sth->execute or do { + warn dbh->errstr. " executing $statement\n"; + dbh->commit; + next; + } + +} + -- cgit v1.2.1 From aa2daf29c5bb13a3728b434159afc4065367af91 Mon Sep 17 00:00:00 2001 From: ivan Date: Wed, 12 May 2004 18:07:41 +0000 Subject: easier this way --- bin/sequences.reset | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bin/sequences.reset b/bin/sequences.reset index f0fc4b7f2..2dc1d3bb2 100644 --- a/bin/sequences.reset +++ b/bin/sequences.reset @@ -13,7 +13,11 @@ foreach my $table ( dbdef->tables ) { ##next unless $default =~ /nextval/; #print "$local\n"; - my $statement = "select setval('${table}_${primary_key}_seq', ( select max($primary_key) from $table ) )\n"; + my $statement = "select setval('${table}_${primary_key}_seq', ( select max($primary_key) from $table ) )"; + + print "$statement;\n"; + next; + my $sth = dbh->prepare($statement) or do { warn dbh->errstr. " preparing $statement\n"; next; -- cgit v1.2.1 From e975ed0585280f4cbb90b02f57114dedc43f58be Mon Sep 17 00:00:00 2001 From: ivan Date: Fri, 14 May 2004 12:25:45 +0000 Subject: add per-agent invoice templates, add per-package suspend invoice events, fix automatic creation of invoice_latex alternate templates --- FS/FS/Conf.pm | 28 ++++++++++++++ FS/FS/cust_bill.pm | 51 +++++++++++++++++++----- FS/FS/cust_main.pm | 32 +++++++++++++++ FS/FS/part_bill_event.pm | 24 ++++++------ httemplate/edit/part_bill_event.cgi | 60 +++++++++++++++++++++++++++++ httemplate/edit/process/part_bill_event.cgi | 5 ++- 6 files changed, 176 insertions(+), 24 deletions(-) diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index 3cddc20fe..e69a15622 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -108,6 +108,22 @@ sub exists { -e "$dir/$file"; } +=item config_orbase KEY SUFFIX + +Returns the configuration value or values (depending on context) for +KEY_SUFFIX, if it exists, otherwise for KEY + +=cut + +sub config_orbase { + my( $self, $file, $suffix ) = @_; + if ( $self->exists("${file}_$suffix") ) { + $self->config("${file}_$suffix"); + } else { + $self->config($file); + } +} + =item touch KEY Creates the specified configuration key if it does not exist. @@ -197,6 +213,18 @@ sub config_items { 'type' => 'textarea', } } glob($self->dir. '/invoice_latex_*') + ), + ( map { + my $basename = basename($_); + $basename =~ /^(.*)$/; + $basename = $1; + new FS::ConfItem { + 'key' => $basename, + 'section' => 'billing', + 'description' => 'Alternate Notes section for LaTeX typeset PostScript invoices. See the billing documentation for details.', + 'type' => 'textarea', + } + } glob($self->dir. '/invoice_latexnotes_*') ); } diff --git a/FS/FS/cust_bill.pm b/FS/FS/cust_bill.pm index 7e2c8fb55..367e1bc5e 100644 --- a/FS/FS/cust_bill.pm +++ b/FS/FS/cust_bill.pm @@ -316,15 +316,23 @@ sub owed { $balance; } -=item send +=item send [ TEMPLATENAME [ , AGENTNUM ] ] Sends this invoice to the destinations configured for this customer: send emails or print. See L. +TEMPLATENAME, if specified, is the name of a suffix for alternate invoices. + +AGENTNUM, if specified, means that this invoice will only be sent for customers +of the specified agent. + =cut sub send { - my($self,$template) = @_; + my $self = shift; + my $template = scalar(@_) ? shift : ''; + return '' if scalar(@_) && $_[0] && $self->cust_main->agentnum ne shift; + my @print_text = $self->print_text('', $template); my @invoicing_list = $self->cust_main->invoicing_list; @@ -654,6 +662,31 @@ sub batch_card { ''; } +sub _agent_template { + my $self = shift; + + my $cust_bill_event = qsearchs( 'part_bill_event', + { + 'payby' => $self->cust_main->payby, + 'plan' => 'send_agent', + 'eventcode' => { 'op' => 'LIKE', + 'value' => '_%, '. $self->cust_main->agentnum. ');' }, + }, + '', + 'ORDER BY seconds LIMIT 1' + ); + + return '' unless $cust_bill_event; + + if ( $cust_bill_event->eventcode =~ /\(\s*'(.*)'\s*,\s*(\d+)\s*\)\;$/ ) { + return $1; + } else { + warn "can't parse eventcode for agent-specific invoice template"; + return ''; + } + +} + =item print_text [ TIME [ , TEMPLATE ] ] Returns an text invoice, as a list of lines. @@ -798,10 +831,11 @@ sub print_text { sprintf("%10.2f", $balance_due ) ]; #create the template + $template ||= $self->_agent_template; my $templatefile = 'invoice_template'; - $templatefile .= "_$template" if $template; + $templatefile .= "_$template" if length($template); my @invoice_template = $conf->config($templatefile) - or die "cannot load config file $templatefile"; + or die "cannot load config file $templatefile"; $invoice_lines = 0; my $wasfunc = 0; foreach ( grep /invoice_lines\(\d*\)/, @invoice_template ) { #kludgy @@ -923,8 +957,10 @@ sub print_latex { @buf = (); #create the template + $template ||= $self->_agent_template; my $templatefile = 'invoice_latex'; - $templatefile .= "_$template" if $template; + my $suffix = length($template) ? "_$template" : ''; + $templatefile .= $suffix; my @invoice_template = $conf->config($templatefile) or die "cannot load config file $templatefile"; @@ -954,7 +990,7 @@ sub print_latex { $invoice_data{'notes'} = join("\n", map { my $b=$_; $b =~ s/\$(\w+)/$invoice_data{$1}/eg; $b } - $conf->config('invoice_latexnotes') + $conf->config_orbase('invoice_latexnotes', $suffix) ); $invoice_data{'footer'} =~ s/\n+$//; @@ -1396,9 +1432,6 @@ The delete method. print_text formatting (and some logic :/) is in source, but needs to be slurped in from a file. Also number of lines ($=). -missing print_ps for a nice postscript copy (maybe HylaFAX-cover-page-style -or something similar so the look can be completely customized?) - =head1 SEE ALSO L, L, L, L, diff --git a/FS/FS/cust_main.pm b/FS/FS/cust_main.pm index f275d10fe..fbd461841 100644 --- a/FS/FS/cust_main.pm +++ b/FS/FS/cust_main.pm @@ -1028,6 +1028,38 @@ sub suspend { grep { $_->suspend } $self->unsuspended_pkgs; } +=item suspend_if_pkgpart PKGPART [ , PKGPART ... ] + +Suspends all unsuspended packages (see L) matching the listed +PKGPARTs (see L). Always returns a list: an empty list on +success or a list of errors. + +=cut + +sub suspend_if_pkgpart { + my $self = shift; + my @pkgparts = @_; + grep { $_->suspend } + grep { my $pkgpart = $_->pkgpart; grep { $pkgpart eq $_ } @pkgparts } + $self->unsuspended_pkgs; +} + +=item suspend_unless_pkgpart PKGPART [ , PKGPART ... ] + +Suspends all unsuspended packages (see L) unless they match the +listed PKGPARTs (see L). Always returns a list: an empty list +on success or a list of errors. + +=cut + +sub suspend_unless_pkgpart { + my $self = shift; + my @pkgparts = @_; + grep { $_->suspend } + grep { my $pkgpart = $_->pkgpart; ! grep { $pkgpart eq $_ } @pkgparts } + $self->unsuspended_pkgs; +} + =item cancel [ OPTION => VALUE ... ] Cancels all uncancelled packages (see L) for this customer. diff --git a/FS/FS/part_bill_event.pm b/FS/FS/part_bill_event.pm index 86f929424..4774b8df9 100644 --- a/FS/FS/part_bill_event.pm +++ b/FS/FS/part_bill_event.pm @@ -149,22 +149,20 @@ sub check { || $self->ut_textn('plan') || $self->ut_anything('plandata') ; + #|| $self->ut_snumber('seconds') return $error if $error; #quelle kludge - if ( $self->plandata =~ /^templatename\s+(.*)$/ ) { - my $name= $1; - unless ( $conf->exists("invoice_template_$name") ) { - $conf->set( - "invoice_template_$name" => - join("\n", $conf->config('invoice_template') ) - ); - } - unless ( $conf->exists("invoice_latex_$name") ) { - $conf->set( - "invoice_latex_$name" => - join("\n", $conf->config('invoice_latex') ) - ); + if ( $self->plandata =~ /^(agent_)?templatename\s+(.*)$/m ) { + my $name= $2; + + foreach my $file (qw( template latex latexnotes )) { + unless ( $conf->exists("invoice_${file}_$name") ) { + $conf->set( + "invoice_${file}_$name" => + join("\n", $conf->config("invoice_$file") ) + ); + } } } diff --git a/httemplate/edit/part_bill_event.cgi b/httemplate/edit/part_bill_event.cgi index 48ed7916b..d0fa973bf 100755 --- a/httemplate/edit/part_bill_event.cgi +++ b/httemplate/edit/part_bill_event.cgi @@ -68,6 +68,31 @@ print 'Action'; #print ntable(); +sub select_pkgpart { + my $label = shift; + my $plandata = shift; + my %selected = map { $_=>1 } split(/,\s*/, $plandata->{$label}); + qq('; +} + +sub select_agentnum { + my $plandata = shift; + my $agentnum = $plandata->{'agentnum'}; + ''; +} + #this is pretty kludgy right here. tie my %events, 'Tie::IxHash', @@ -84,6 +109,18 @@ tie my %events, 'Tie::IxHash', 'code' => '$cust_main->suspend();', 'weight' => 10, }, + 'suspend-if-pkgpart' => { + 'name' => 'Suspend packages', + 'code' => '$cust_main->suspend_if_pkgpart(%%%if_pkgpart%%%);', + 'html' => sub { &select_pkgpart('if_pkgpart', @_) }, + 'weight' => 10, + }, + 'suspend-unless-pkgpart' => { + 'name' => 'Suspend packages except', + 'code' => '$cust_main->suspend_unless_pkgpart(%%%unless_pkgpart%%%);', + 'html' => sub { &select_pkgpart('unless_pkgpart', @_) }, + 'weight' => 10, + }, 'cancel' => { 'name' => 'Cancel', 'code' => '$cust_main->cancel();', @@ -140,6 +177,26 @@ tie my %events, 'Tie::IxHash', 'weight' => 50, }, + 'send_agent' => { + 'name' => 'Send invoice (email/print) ', + 'code' => '$cust_bill->send(\'%%%agent_templatename%%%\', %%%agentnum%%%);', + 'html' => sub { + ' + + + + + + + + +
    only for agent '. &select_agentnum(@_). '
    with template + +
    '; + }, + 'weight' => 50, + }, + 'send_csv_ftp' => { 'name' => 'Upload CSV invoice data to an FTP server', 'code' => '$cust_bill->send_csv( protocol => \'ftp\', @@ -188,6 +245,9 @@ foreach my $event ( keys %events ) { my %plandata = map { /^(\w+) (.*)$/; ($1, $2); } split(/\n/, $part_bill_event->plandata); my $html = $events{$event}{html}; + if ( ref($html) eq 'CODE' ) { + $html = &{$html}(\%plandata); + } while ( $html =~ /%%%(\w+)%%%/ ) { my $field = $1; $html =~ s/%%%$field%%%/$plandata{$field}/; diff --git a/httemplate/edit/process/part_bill_event.cgi b/httemplate/edit/process/part_bill_event.cgi index e224bf634..77dcd242a 100755 --- a/httemplate/edit/process/part_bill_event.cgi +++ b/httemplate/edit/process/part_bill_event.cgi @@ -5,7 +5,7 @@ my $eventpart = $cgi->param('eventpart'); my $old = qsearchs('part_bill_event',{'eventpart'=>$eventpart}) if $eventpart; #s/days/seconds/ -$cgi->param('seconds', $cgi->param('days') * 86400 ); +$cgi->param('seconds', int( $cgi->param('days') * 86400 ) ); my $error; if ( ! $cgi->param('plan_weight_eventcode') ) { @@ -21,7 +21,8 @@ if ( ! $cgi->param('plan_weight_eventcode') ) { my $plandata = ''; while ( $eventcode =~ /%%%(\w+)%%%/ ) { my $field = $1; - my $value = $cgi->param($field); + my $value = join(', ', $cgi->param($field) ); + $cgi->param($field, $value); #in case it errors out $eventcode =~ s/%%%$field%%%/$value/; $plandata .= "$field $value\n"; } -- cgit v1.2.1 From a2746023c2b286d67ab5e4d5777e8cb271525a13 Mon Sep 17 00:00:00 2001 From: ivan Date: Tue, 18 May 2004 00:20:53 +0000 Subject: patch from randell lucas for order_pkg to return pkgnum also --- FS/FS/ClientAPI/MyAccount.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FS/FS/ClientAPI/MyAccount.pm b/FS/FS/ClientAPI/MyAccount.pm index 3c0b0ac5a..77c1fc889 100644 --- a/FS/FS/ClientAPI/MyAccount.pm +++ b/FS/FS/ClientAPI/MyAccount.pm @@ -489,7 +489,7 @@ sub order_pkg { $cust_pkg->reexport; } - return { error => '' }; + return { error => '', pkgnum => $cust_pkg->pkgnum }; } -- cgit v1.2.1 From b377b1408398c471689e35dabb1bf14ef263a644 Mon Sep 17 00:00:00 2001 From: ivan Date: Wed, 19 May 2004 12:28:53 +0000 Subject: make hours/input/output/total display on invoices conditional on there being any charge for overages --- httemplate/edit/part_pkg.cgi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httemplate/edit/part_pkg.cgi b/httemplate/edit/part_pkg.cgi index 8416b3546..6c7d5dd23 100755 --- a/httemplate/edit/part_pkg.cgi +++ b/httemplate/edit/part_pkg.cgi @@ -445,7 +445,7 @@ tie my %plans, 'Tie::IxHash', }, 'fieldorder' => [qw( setup_fee recur_flat recur_included_hours recur_hourly_charge recur_included_input recur_input_charge recur_included_output recur_output_charge recur_included_total recur_total_charge )], 'setup' => 'what.setup_fee.value', - 'recur' => '\'my $last_bill = $cust_pkg->last_bill; my $hours = $cust_pkg->seconds_since_sqlradacct($last_bill, $sdate ) / 3600 - \' + what.recur_included_hours.value + \'; $hours = 0 if $hours < 0; my $input = $cust_pkg->attribute_since_sqlradacct($last_bill, $sdate, \"AcctInputOctets\" ) / 1048576; my $output = $cust_pkg->attribute_since_sqlradacct($last_bill, $sdate, \"AcctOutputOctets\" ) / 1048576; my $total = $input + $output - \' + what.recur_included_total.value + \'; $total = 0 if $total < 0; my $input = $input - \' + what.recur_included_input.value + \'; $input = 0 if $input < 0; my $output = $output - \' + what.recur_included_output.value + \'; $output = 0 if $output < 0; my $totalcharge = sprintf(\"%.2f\", \' + what.recur_total_charge.value + \' * $total); my $hourscharge = sprintf(\"%.2f\", \' + what.recur_hourly_charge.value + \' * $hours); push @details, \"Last month\\\'s excess data \". sprintf(\"%.1f\", $total). \" megs: \\\$$totalcharge\", \"Last month\\\'s excess time \". sprintf(\"%.1f\", $hours). \" hours: \\\$$hourscharge\"; \' + what.recur_flat.value + \' + $hourscharge + \' + what.recur_input_charge.value + \' * $input + \' + what.recur_output_charge.value + \' * $output + $totalcharge ;\'', + 'recur' => '\'my $last_bill = $cust_pkg->last_bill; my $hours = $cust_pkg->seconds_since_sqlradacct($last_bill, $sdate ) / 3600 - \' + what.recur_included_hours.value + \'; $hours = 0 if $hours < 0; my $input = $cust_pkg->attribute_since_sqlradacct($last_bill, $sdate, \"AcctInputOctets\" ) / 1048576; my $output = $cust_pkg->attribute_since_sqlradacct($last_bill, $sdate, \"AcctOutputOctets\" ) / 1048576; my $total = $input + $output - \' + what.recur_included_total.value + \'; $total = 0 if $total < 0; my $input = $input - \' + what.recur_included_input.value + \'; $input = 0 if $input < 0; my $output = $output - \' + what.recur_included_output.value + \'; $output = 0 if $output < 0; my $totalcharge = sprintf(\"%.2f\", \' + what.recur_total_charge.value + \' * $total); my $inputcharge = sprintf(\"%.2f\", \' + what.recur_input_charge.value + \' * $input); my $outputcharge = sprintf(\"%.2f\", \' + what.recur_output_charge.value + \' * $output); my $hourscharge = sprintf(\"%.2f\", \' + what.recur_hourly_charge.value + \' * $hours); if ( \' + what.recur_total_charge.value + \' > 0 ) { push @details, \"Last month\\\'s data \". sprintf(\"%.1f\", $total). \" megs: \\\$$totalcharge\" } if ( \' + what.recur_input_charge.value + \' > 0 ) { push @details, \"Last month\\\'s download \". sprintf(\"%.1f\", $input). \" megs: \\\$$inputcharge\" } if ( \' + what.recur_total_charge.value + \' > 0 ) { push @details, \"Last month\\\'s data \". sprintf(\"%.1f\", $total). \" megs: \\\$$totalcharge\" } if ( \' + whathorlly_charge.value + \' > 0 ) { push @details, \"Last month\\\'s time \". sprintf(\"%.1f\", $hours). \" hours: \\\$$hourscharge\"; } \' + what.recur_flat.value + \' + $hourscharge + $inputcharge + $outputcharge + $totalcharge ;\'', }, 'sql_generic' => { -- cgit v1.2.1 From 59d12a3144dfee010c84fb9df36b39d6330b89d3 Mon Sep 17 00:00:00 2001 From: ivan Date: Wed, 19 May 2004 12:30:15 +0000 Subject: finish making hours/input/output/total display on invoices conditional on there being any charge for overages --- httemplate/edit/part_pkg.cgi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httemplate/edit/part_pkg.cgi b/httemplate/edit/part_pkg.cgi index 6c7d5dd23..86a49209c 100755 --- a/httemplate/edit/part_pkg.cgi +++ b/httemplate/edit/part_pkg.cgi @@ -445,7 +445,7 @@ tie my %plans, 'Tie::IxHash', }, 'fieldorder' => [qw( setup_fee recur_flat recur_included_hours recur_hourly_charge recur_included_input recur_input_charge recur_included_output recur_output_charge recur_included_total recur_total_charge )], 'setup' => 'what.setup_fee.value', - 'recur' => '\'my $last_bill = $cust_pkg->last_bill; my $hours = $cust_pkg->seconds_since_sqlradacct($last_bill, $sdate ) / 3600 - \' + what.recur_included_hours.value + \'; $hours = 0 if $hours < 0; my $input = $cust_pkg->attribute_since_sqlradacct($last_bill, $sdate, \"AcctInputOctets\" ) / 1048576; my $output = $cust_pkg->attribute_since_sqlradacct($last_bill, $sdate, \"AcctOutputOctets\" ) / 1048576; my $total = $input + $output - \' + what.recur_included_total.value + \'; $total = 0 if $total < 0; my $input = $input - \' + what.recur_included_input.value + \'; $input = 0 if $input < 0; my $output = $output - \' + what.recur_included_output.value + \'; $output = 0 if $output < 0; my $totalcharge = sprintf(\"%.2f\", \' + what.recur_total_charge.value + \' * $total); my $inputcharge = sprintf(\"%.2f\", \' + what.recur_input_charge.value + \' * $input); my $outputcharge = sprintf(\"%.2f\", \' + what.recur_output_charge.value + \' * $output); my $hourscharge = sprintf(\"%.2f\", \' + what.recur_hourly_charge.value + \' * $hours); if ( \' + what.recur_total_charge.value + \' > 0 ) { push @details, \"Last month\\\'s data \". sprintf(\"%.1f\", $total). \" megs: \\\$$totalcharge\" } if ( \' + what.recur_input_charge.value + \' > 0 ) { push @details, \"Last month\\\'s download \". sprintf(\"%.1f\", $input). \" megs: \\\$$inputcharge\" } if ( \' + what.recur_total_charge.value + \' > 0 ) { push @details, \"Last month\\\'s data \". sprintf(\"%.1f\", $total). \" megs: \\\$$totalcharge\" } if ( \' + whathorlly_charge.value + \' > 0 ) { push @details, \"Last month\\\'s time \". sprintf(\"%.1f\", $hours). \" hours: \\\$$hourscharge\"; } \' + what.recur_flat.value + \' + $hourscharge + $inputcharge + $outputcharge + $totalcharge ;\'', + 'recur' => '\'my $last_bill = $cust_pkg->last_bill; my $hours = $cust_pkg->seconds_since_sqlradacct($last_bill, $sdate ) / 3600 - \' + what.recur_included_hours.value + \'; $hours = 0 if $hours < 0; my $input = $cust_pkg->attribute_since_sqlradacct($last_bill, $sdate, \"AcctInputOctets\" ) / 1048576; my $output = $cust_pkg->attribute_since_sqlradacct($last_bill, $sdate, \"AcctOutputOctets\" ) / 1048576; my $total = $input + $output - \' + what.recur_included_total.value + \'; $total = 0 if $total < 0; my $input = $input - \' + what.recur_included_input.value + \'; $input = 0 if $input < 0; my $output = $output - \' + what.recur_included_output.value + \'; $output = 0 if $output < 0; my $totalcharge = sprintf(\"%.2f\", \' + what.recur_total_charge.value + \' * $total); my $inputcharge = sprintf(\"%.2f\", \' + what.recur_input_charge.value + \' * $input); my $outputcharge = sprintf(\"%.2f\", \' + what.recur_output_charge.value + \' * $output); my $hourscharge = sprintf(\"%.2f\", \' + what.recur_hourly_charge.value + \' * $hours); if ( \' + what.recur_total_charge.value + \' > 0 ) { push @details, \"Last month\\\'s data \". sprintf(\"%.1f\", $total). \" megs: \\\$$totalcharge\" } if ( \' + what.recur_input_charge.value + \' > 0 ) { push @details, \"Last month\\\'s download \". sprintf(\"%.1f\", $input). \" megs: \\\$$inputcharge\" } if ( \' + what.recur_output_charge.value + \' > 0 ) { push @details, \"Last month\\\'s upload \". sprintf(\"%.1f\", $output). \" megs: \\\$$outputcharge\" } if ( \' + whathorlly_charge.value + \' > 0 ) { push @details, \"Last month\\\'s time \". sprintf(\"%.1f\", $hours). \" hours: \\\$$hourscharge\"; } \' + what.recur_flat.value + \' + $hourscharge + $inputcharge + $outputcharge + $totalcharge ;\'', }, 'sql_generic' => { -- cgit v1.2.1 From 6b9a0a746535a142c95a5841f5cb5d9dc44d2f21 Mon Sep 17 00:00:00 2001 From: ivan Date: Wed, 19 May 2004 12:31:02 +0000 Subject: continue making hours/input/output/total display on invoices conditional on there being any charge for overages --- httemplate/edit/part_pkg.cgi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httemplate/edit/part_pkg.cgi b/httemplate/edit/part_pkg.cgi index 86a49209c..460f68b2c 100755 --- a/httemplate/edit/part_pkg.cgi +++ b/httemplate/edit/part_pkg.cgi @@ -445,7 +445,7 @@ tie my %plans, 'Tie::IxHash', }, 'fieldorder' => [qw( setup_fee recur_flat recur_included_hours recur_hourly_charge recur_included_input recur_input_charge recur_included_output recur_output_charge recur_included_total recur_total_charge )], 'setup' => 'what.setup_fee.value', - 'recur' => '\'my $last_bill = $cust_pkg->last_bill; my $hours = $cust_pkg->seconds_since_sqlradacct($last_bill, $sdate ) / 3600 - \' + what.recur_included_hours.value + \'; $hours = 0 if $hours < 0; my $input = $cust_pkg->attribute_since_sqlradacct($last_bill, $sdate, \"AcctInputOctets\" ) / 1048576; my $output = $cust_pkg->attribute_since_sqlradacct($last_bill, $sdate, \"AcctOutputOctets\" ) / 1048576; my $total = $input + $output - \' + what.recur_included_total.value + \'; $total = 0 if $total < 0; my $input = $input - \' + what.recur_included_input.value + \'; $input = 0 if $input < 0; my $output = $output - \' + what.recur_included_output.value + \'; $output = 0 if $output < 0; my $totalcharge = sprintf(\"%.2f\", \' + what.recur_total_charge.value + \' * $total); my $inputcharge = sprintf(\"%.2f\", \' + what.recur_input_charge.value + \' * $input); my $outputcharge = sprintf(\"%.2f\", \' + what.recur_output_charge.value + \' * $output); my $hourscharge = sprintf(\"%.2f\", \' + what.recur_hourly_charge.value + \' * $hours); if ( \' + what.recur_total_charge.value + \' > 0 ) { push @details, \"Last month\\\'s data \". sprintf(\"%.1f\", $total). \" megs: \\\$$totalcharge\" } if ( \' + what.recur_input_charge.value + \' > 0 ) { push @details, \"Last month\\\'s download \". sprintf(\"%.1f\", $input). \" megs: \\\$$inputcharge\" } if ( \' + what.recur_output_charge.value + \' > 0 ) { push @details, \"Last month\\\'s upload \". sprintf(\"%.1f\", $output). \" megs: \\\$$outputcharge\" } if ( \' + whathorlly_charge.value + \' > 0 ) { push @details, \"Last month\\\'s time \". sprintf(\"%.1f\", $hours). \" hours: \\\$$hourscharge\"; } \' + what.recur_flat.value + \' + $hourscharge + $inputcharge + $outputcharge + $totalcharge ;\'', + 'recur' => '\'my $last_bill = $cust_pkg->last_bill; my $hours = $cust_pkg->seconds_since_sqlradacct($last_bill, $sdate ) / 3600 - \' + what.recur_included_hours.value + \'; $hours = 0 if $hours < 0; my $input = $cust_pkg->attribute_since_sqlradacct($last_bill, $sdate, \"AcctInputOctets\" ) / 1048576; my $output = $cust_pkg->attribute_since_sqlradacct($last_bill, $sdate, \"AcctOutputOctets\" ) / 1048576; my $total = $input + $output - \' + what.recur_included_total.value + \'; $total = 0 if $total < 0; my $input = $input - \' + what.recur_included_input.value + \'; $input = 0 if $input < 0; my $output = $output - \' + what.recur_included_output.value + \'; $output = 0 if $output < 0; my $totalcharge = sprintf(\"%.2f\", \' + what.recur_total_charge.value + \' * $total); my $inputcharge = sprintf(\"%.2f\", \' + what.recur_input_charge.value + \' * $input); my $outputcharge = sprintf(\"%.2f\", \' + what.recur_output_charge.value + \' * $output); my $hourscharge = sprintf(\"%.2f\", \' + what.recur_hourly_charge.value + \' * $hours); if ( \' + what.recur_total_charge.value + \' > 0 ) { push @details, \"Last month\\\'s data \". sprintf(\"%.1f\", $total). \" megs: \\\$$totalcharge\" } if ( \' + what.recur_input_charge.value + \' > 0 ) { push @details, \"Last month\\\'s download \". sprintf(\"%.1f\", $input). \" megs: \\\$$inputcharge\" } if ( \' + what.recur_output_charge.value + \' > 0 ) { push @details, \"Last month\\\'s upload \". sprintf(\"%.1f\", $output). \" megs: \\\$$outputcharge\" } if ( \' + what.recur_hourly_charge.value + \' > 0 ) { push @details, \"Last month\\\'s time \". sprintf(\"%.1f\", $hours). \" hours: \\\$$hourscharge\"; } \' + what.recur_flat.value + \' + $hourscharge + $inputcharge + $outputcharge + $totalcharge ;\'', }, 'sql_generic' => { -- cgit v1.2.1 From b970f3999c9a49146ec2f5224a60057723304d1b Mon Sep 17 00:00:00 2001 From: ivan Date: Wed, 19 May 2004 13:41:27 +0000 Subject: adding acct_sql export --- FS/FS/part_export/acct_sql.pm | 140 ++++++++++++++++++++++++++++++++++++++++++ FS/MANIFEST | 3 + FS/t/part_export-acct_sql.t | 5 ++ 3 files changed, 148 insertions(+) create mode 100644 FS/FS/part_export/acct_sql.pm create mode 100644 FS/t/part_export-acct_sql.t diff --git a/FS/FS/part_export/acct_sql.pm b/FS/FS/part_export/acct_sql.pm new file mode 100644 index 000000000..0c3b49197 --- /dev/null +++ b/FS/FS/part_export/acct_sql.pm @@ -0,0 +1,140 @@ +package FS::part_export::acct_sql; + +use vars qw(@ISA %info @saltset); +use Tie::IxHash; +#use Digest::MD5 qw(md5_hex); +use FS::Record; #qw(qsearchs); +use FS::part_export; + +@ISA = qw(FS::part_export); + +tie my %options, 'Tie::IxHash', + 'datasrc' => { label => 'DBI data source' }, + 'username' => { label => 'Database username' }, + 'password' => { label => 'Database password' }, +; + +%info = ( + 'svc' => 'svc_acct', + 'desc' => 'Real-time export of accounts to SQL databases '. + '(Postfix+Courier IMAP, others?)', + 'options' => \%options, + 'nodomain' => '', + 'notes' => < freeside col/method or callback +my %map = ( + 'username' => 'email', + 'password' => '_password', + 'crypt' => sub { + my $svc_acct = shift; + #false laziness w/shellcommands.pm + #eventually should check a "password-encoding" field + if ( length($svc_acct->_password) == 13 + || $svc_acct->_password =~ /^\$(1|2a?)\$/ ) { + $svc_acct->_password; + } else { + crypt( + $svc_acct->_password, + $saltset[int(rand(64))].$saltset[int(rand(64))] + ); + } + + }, + 'name' => 'finger', + 'maildir' => sub { shift->domain. '/maildirs/'. shift->username. '/' }, + 'domain' => sub { shift->domain }, + 'svcnum' => 'svcnum', +); + +my $table = 'mailbox'; #also needs to be configurable... + +my $primary_key = 'username'; + +sub rebless { shift; } + +sub _export_insert { + my($self, $svc_acct) = (shift, shift); + + + my %record = map { my $value = $map{$_}; + $_ => ( ref($value) + ? &{$value}($svc_acct) + : $svc_acct->$value() + ); + } keys %map; + + my $err_or_queue = + $self->acct_sql_queue( $svc_acct->svcnum, 'insert', $table, %record ); + return $err_or_queue unless ref($err_or_queue); + + ''; + +} + +sub _export_replace { +} + +sub _export_delete { + my ( $self, $svc_acct ) = (shift, shift); + my $keymap = $map{$primary_key}; + my $err_or_queue = $self->acct_sql_queue( + $svc_acct->svcnum, + 'delete', + $table, + $primary_key => ref($keymap) ? &{$keymap}($svc_acct) : $svc_acct->$keymap() + ); +} + +sub acct_sql_queue { + my( $self, $svcnum, $method ) = (shift, shift, shift); + my $queue = new FS::queue { + 'svcnum' => $svcnum, + 'job' => "FS::part_export::acct_sql::acct_sql_$method", + }; + $queue->insert( + $self->option('datasrc'), + $self->option('username'), + $self->option('password'), + @_, + ) or $queue; +} + +sub acct_sql_insert { #subroutine, not method + my $dbh = acct_sql_connect(shift, shift, shift); + my( $table, %record ) = @_; + + my $sth = $dbh->prepare( + "INSERT INTO $table ( ". join(", ", keys %record). + " ) VALUES ( ". join(", ", map '?', keys %record ). " )" + ) or die $dbh->errstr; + + $sth->execute( map $record{$_}, keys %record ) + or die "can't insert into $table table: ". $sth->errstr; + + $dbh->disconnect; +} + +sub acct_sql_connect { + #my($datasrc, $username, $password) = @_; + #DBI->connect($datasrc, $username, $password) or die $DBI::errstr; + DBI->connect(@_) or die $DBI::errstr; +} + +1; + + diff --git a/FS/MANIFEST b/FS/MANIFEST index 675429e04..e9c673dc2 100644 --- a/FS/MANIFEST +++ b/FS/MANIFEST @@ -68,6 +68,7 @@ FS/part_bill_event.pm FS/export_svc.pm FS/part_export.pm FS/part_export_option.pm +FS/part_export/acct_sql.pm FS/part_export/apache.pm FS/part_export/bind.pm FS/part_export/bind_slave.pm @@ -158,6 +159,8 @@ t/part_bill_event.t t/export_svc.t t/part_export.t t/part_export_option.t +t/part_export-acct_sql.t +t/part_export-apache.t t/part_export-bind.t t/part_export-bind_slave.t t/part_export-bsdshell.t diff --git a/FS/t/part_export-acct_sql.t b/FS/t/part_export-acct_sql.t new file mode 100644 index 000000000..9eed47259 --- /dev/null +++ b/FS/t/part_export-acct_sql.t @@ -0,0 +1,5 @@ +BEGIN { $| = 1; print "1..1\n" } +END {print "not ok 1\n" unless $loaded;} +use FS::part_export::acct_sql; +$loaded=1; +print "ok 1\n"; -- cgit v1.2.1 From c3986b04e040c54afdf14cb39b3daf5210afa739 Mon Sep 17 00:00:00 2001 From: ivan Date: Wed, 19 May 2004 14:22:52 +0000 Subject: fixing acct_sql export --- FS/FS/part_export/acct_sql.pm | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/FS/FS/part_export/acct_sql.pm b/FS/FS/part_export/acct_sql.pm index 0c3b49197..631a44c8a 100644 --- a/FS/FS/part_export/acct_sql.pm +++ b/FS/FS/part_export/acct_sql.pm @@ -56,7 +56,7 @@ my %map = ( }, 'name' => 'finger', - 'maildir' => sub { shift->domain. '/maildirs/'. shift->username. '/' }, + 'maildir' => sub { $_[0]->domain. '/maildirs/'. $_[0]->username. '/' }, 'domain' => sub { shift->domain }, 'svcnum' => 'svcnum', ); @@ -129,6 +129,20 @@ sub acct_sql_insert { #subroutine, not method $dbh->disconnect; } +sub acct_sql_delete { #subroutine, not method + my $dbh = acct_sql_connect(shift, shift, shift); + my( $table, %record ) = @_; + + my $sth = $dbh->prepare( + "DELETE FROM $table WHERE ". join(' AND ', map "$_ = ? ", keys %record ) + ) or die $dbh->errstr; + + $sth->execute( map $record{$_}, keys %record ) + or die "can't delete from $table table: ". $sth->errstr; + + $dbh->disconnect; +} + sub acct_sql_connect { #my($datasrc, $username, $password) = @_; #DBI->connect($datasrc, $username, $password) or die $DBI::errstr; -- cgit v1.2.1 From 33fbb5789fdc25696b4c3319e8118fe337892f04 Mon Sep 17 00:00:00 2001 From: ivan Date: Wed, 19 May 2004 14:29:54 +0000 Subject: fixing deletions in acct_sql export --- FS/FS/part_export/acct_sql.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/FS/FS/part_export/acct_sql.pm b/FS/FS/part_export/acct_sql.pm index 631a44c8a..05c4310cb 100644 --- a/FS/FS/part_export/acct_sql.pm +++ b/FS/FS/part_export/acct_sql.pm @@ -98,6 +98,7 @@ sub _export_delete { $table, $primary_key => ref($keymap) ? &{$keymap}($svc_acct) : $svc_acct->$keymap() ); + return $err_or_queue unless ref($err_or_queue); } sub acct_sql_queue { -- cgit v1.2.1 From af666b341de952ce205333d2e361e96661f13e93 Mon Sep 17 00:00:00 2001 From: ivan Date: Wed, 19 May 2004 14:34:13 +0000 Subject: really fixing deletions in acct_sql export --- FS/FS/part_export/acct_sql.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/FS/FS/part_export/acct_sql.pm b/FS/FS/part_export/acct_sql.pm index 05c4310cb..9b17e3998 100644 --- a/FS/FS/part_export/acct_sql.pm +++ b/FS/FS/part_export/acct_sql.pm @@ -99,6 +99,7 @@ sub _export_delete { $primary_key => ref($keymap) ? &{$keymap}($svc_acct) : $svc_acct->$keymap() ); return $err_or_queue unless ref($err_or_queue); + ''; } sub acct_sql_queue { -- cgit v1.2.1 From c37aa003cc514cde5058ba3d94b0b1a133807579 Mon Sep 17 00:00:00 2001 From: ivan Date: Wed, 26 May 2004 09:14:00 +0000 Subject: default commands now keep web content in user homedirs and link to /var/www --- FS/FS/part_export/www_shellcommands.pm | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/FS/FS/part_export/www_shellcommands.pm b/FS/FS/part_export/www_shellcommands.pm index 9f14707b0..dd909376b 100644 --- a/FS/FS/part_export/www_shellcommands.pm +++ b/FS/FS/part_export/www_shellcommands.pm @@ -10,13 +10,13 @@ use FS::part_export; tie my %options, 'Tie::IxHash', 'user' => { label=>'Remote username', default=>'root' }, 'useradd' => { label=>'Insert command', - default=>'mkdir /var/www/$zone; chown $username /var/www/$zone; ln -s /var/www/$zone $homedir/$zone', + default=>'mkdir $homedir/$zone; chown $username $homedir/$zone; ln -s $homedir/$zone /var/www/$zone', }, 'userdel' => { label=>'Delete command', - default=>'[ -n "$zone" ] && rm -rf /var/www/$zone; rm $homedir/$zone', + default=>'[ -n "$zone" ] && rm -rf /var/www/$zone; rm -rf $homedir/$zone', }, 'usermod' => { label=>'Modify command', - default=>'[ -n "$old_zone" ] && rm $old_homedir/$old_zone; [ "$old_zone" != "$new_zone" -a -n "$new_zone" ] && mv /var/www/$old_zone /var/www/$new_zone; [ "$old_username" != "$new_username" ] && chown -R $new_username /var/www/$new_zone; ln -s /var/www/$new_zone $new_homedir/$new_zone', + default=>'[ -n "$old_zone" ] && rm /var/www/$old_zone; [ "$old_zone" != "$new_zone" -a -n "$new_zone" ] && ( mv $old_homedir/$old_zone $new_homedir/$new_zone; ln -sf $new_homedir/$new_zone /var/www/$new_zone ); [ "$old_username" != "$new_username" ] && chown -R $new_username $new_homedir/$new_zone; ln -sf $new_homedir/$new_zone /var/www/$new_zone', }, ; @@ -32,9 +32,9 @@ Run remote commands via SSH, for virtual web sites. You will need to
  • /dev/null 2>&1") == 0 + or die "pslatex failed: $!"; + system("pslatex $file.tex >/dev/null 2>&1") == 0 + or die "pslatex failed: $!"; + + system('dvips', '-q', '-t', 'letter', "$file.dvi", '-o', "$file.ps" ) == 0 + or die "dbips failed: $!"; open(POSTSCRIPT, "<$file.ps") - or die "can't open $file.ps (probable error in LaTeX template): $!\n"; + or die "can't open $file.ps: $! (error in LaTeX template?)\n"; unlink("$file.dvi", "$file.log", "$file.aux", "$file.ps", "$file.tex"); @@ -1179,15 +1182,21 @@ sub print_pdf { #system('pdflatex', "$file.tex"); #! LaTeX Error: Unknown graphics extension: .eps. - #error checking!! - system('pslatex', "$file.tex"); - system('pslatex', "$file.tex"); + system("pslatex $file.tex >/dev/null 2>&1") == 0 + or die "pslatex failed: $!"; + system("pslatex $file.tex >/dev/null 2>&1") == 0 + or die "pslatex failed: $!"; #system('dvipdf', "$file.dvi", "$file.pdf" ); - system("dvips -q -t letter -f $file.dvi | gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=$file.pdf -c save pop -"); + system( + "dvips -q -t letter -f $file.dvi ". + "| gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=$file.pdf ". + " -c save pop -" + ) == 0 + or die "dvips failed: $!"; open(PDF, "<$file.pdf") - or die "can't open $file.pdf (probably error in LaTeX tempalte: $!\n"; + or die "can't open $file.pdf: $! (error in LaTeX template?)\n"; unlink("$file.dvi", "$file.log", "$file.aux", "$file.pdf", "$file.tex"); -- cgit v1.2.1 From b7f1494f55c75badc352300c6a8e55ef676d225d Mon Sep 17 00:00:00 2001 From: ivan Date: Wed, 26 May 2004 11:11:10 +0000 Subject: use File::Temp for filenames and store the temp files in cache.datasrc instead of /tmp --- FS/FS/cust_bill.pm | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/FS/FS/cust_bill.pm b/FS/FS/cust_bill.pm index 4cfc59d10..13c48d965 100644 --- a/FS/FS/cust_bill.pm +++ b/FS/FS/cust_bill.pm @@ -5,6 +5,7 @@ use vars qw( @ISA $conf $money_char ); use vars qw( $invoice_lines @buf ); #yuck use Date::Format; use Text::Template; +use File::Temp; use FS::UID qw( datasrc ); use FS::Record qw( qsearch qsearchs ); use FS::Misc qw( send_email ); @@ -1108,17 +1109,17 @@ sub print_latex { $var; } - my $dir = '/tmp'; #! /usr/local/etc/freeside/invoices.datasrc/ - my $unique = int(rand(2**31)); #UGH... use File::Temp or something + my $dir = $FS::UID::conf_dir. "cache.". $FS::UID::datasrc; + my $fh = new File::Temp( TEMPLATE => 'invoice.'. $self->invnum. '.XXXXXXXX', + DIR => $dir + SUFFIX => '.tex', + UNLINK => 0, + ) or die "can't open temp file: $!\n"; + print $fh join("\n", @filled_in ), "\n"; + close $fh; - chdir($dir); - my $file = $self->invnum. ".$unique"; - - open(TEX,">$file.tex") or die "can't open $file.tex: $!\n"; - print TEX join("\n", @filled_in ), "\n"; - close TEX; - - return $file; + $fh->filename =~ /^(.*).tex$/ or die "unparsable filename: ". $fh->filename; + return $1; } @@ -1138,6 +1139,9 @@ sub print_ps { my $file = $self->print_latex(@_); + my $dir = $FS::UID::conf_dir. "cache.". $FS::UID::datasrc; + chdir($dir); + system("pslatex $file.tex >/dev/null 2>&1") == 0 or die "pslatex failed: $!"; system("pslatex $file.tex >/dev/null 2>&1") == 0 @@ -1178,6 +1182,9 @@ sub print_pdf { my $file = $self->print_latex(@_); + my $dir = $FS::UID::conf_dir. "cache.". $FS::UID::datasrc; + chdir($dir); + #system('pdflatex', "$file.tex"); #system('pdflatex', "$file.tex"); #! LaTeX Error: Unknown graphics extension: .eps. -- cgit v1.2.1 From 4891d7608679ee4a742a8cd5ca03fbb4847b305e Mon Sep 17 00:00:00 2001 From: ivan Date: Wed, 26 May 2004 11:11:52 +0000 Subject: comma --- FS/FS/cust_bill.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FS/FS/cust_bill.pm b/FS/FS/cust_bill.pm index 13c48d965..576e4c846 100644 --- a/FS/FS/cust_bill.pm +++ b/FS/FS/cust_bill.pm @@ -1111,7 +1111,7 @@ sub print_latex { my $dir = $FS::UID::conf_dir. "cache.". $FS::UID::datasrc; my $fh = new File::Temp( TEMPLATE => 'invoice.'. $self->invnum. '.XXXXXXXX', - DIR => $dir + DIR => $dir, SUFFIX => '.tex', UNLINK => 0, ) or die "can't open temp file: $!\n"; -- cgit v1.2.1 From 9e9e7407e7e8c5a94c27609145ee65205f984ac5 Mon Sep 17 00:00:00 2001 From: ivan Date: Wed, 26 May 2004 13:02:31 +0000 Subject: update acct_sql export some more to export to alias table also and in general be more configurable --- FS/FS/part_export/acct_sql.pm | 113 +++++++++++++++++++++++++----------------- FS/FS/svc_acct.pm | 33 ++++++++++++ 2 files changed, 100 insertions(+), 46 deletions(-) diff --git a/FS/FS/part_export/acct_sql.pm b/FS/FS/part_export/acct_sql.pm index 9b17e3998..8e102fcc1 100644 --- a/FS/FS/part_export/acct_sql.pm +++ b/FS/FS/part_export/acct_sql.pm @@ -12,8 +12,37 @@ tie my %options, 'Tie::IxHash', 'datasrc' => { label => 'DBI data source' }, 'username' => { label => 'Database username' }, 'password' => { label => 'Database password' }, + 'table' => { label => 'Database table' }, + 'schema' => { label => + 'Database schema mapping to Freeside methods.', + type => 'textarea', + }, + 'primary_key' => { label => 'Database primary key' }, ; +tie my %postfix_courierimap_mailbox_map, 'Tie::IxHash', + 'username' => 'email', + 'password' => '_password', + 'crypt' => 'crypt_password', + 'name' => 'finger', + 'maildir' => 'virtual_maildir', + 'domain' => 'domain', + 'svcnum' => 'svcnum', +; +my $postfix_courierimap_mailbox_map = + join('\n', map "$_ $postfix_courierimap_mailbox_map{$_}", + keys %postfix_courierimap_mailbox_map ); + +tie my %postfix_courierimap_alias_map, 'Tie::IxHash', + 'address' => 'email', + 'goto' => 'email', + 'domain' => 'domain', + 'svcnum' => 'svcnum', +; +my $postfix_courierimap_alias_map = + join('\n', map "$_ $postfix_courierimap_alias_map{$_}", + keys %postfix_courierimap_alias_map ); + %info = ( 'svc' => 'svc_acct', 'desc' => 'Real-time export of accounts to SQL databases '. @@ -23,63 +52,54 @@ tie my %options, 'Tie::IxHash', 'notes' => <
    In contrast to sqlmail, this is newer and less well tested, and +currently less flexible. It is intended to export just svc_acct records only, +rather than a single export for svc_acct, svc_forward and svc_domain records, +to export in "default" formats rather than configure the MTA or POP/IMAP server +for a Freeside-specific schema, and possibly to be configured for different +mail server setups through some subclassing rather than options. + +

    Use these buttons for some useful presets: +
      +
    • +
    • +
    END ); -@saltset = ( 'a'..'z' , 'A'..'Z' , '0'..'9' , '.' , '/' ); - -#mapping needs to be configurable... -# export col => freeside col/method or callback -my %map = ( - 'username' => 'email', - 'password' => '_password', - 'crypt' => sub { - my $svc_acct = shift; - #false laziness w/shellcommands.pm - #eventually should check a "password-encoding" field - if ( length($svc_acct->_password) == 13 - || $svc_acct->_password =~ /^\$(1|2a?)\$/ ) { - $svc_acct->_password; - } else { - crypt( - $svc_acct->_password, - $saltset[int(rand(64))].$saltset[int(rand(64))] - ); - } - - }, - 'name' => 'finger', - 'maildir' => sub { $_[0]->domain. '/maildirs/'. $_[0]->username. '/' }, - 'domain' => sub { shift->domain }, - 'svcnum' => 'svcnum', -); - -my $table = 'mailbox'; #also needs to be configurable... - -my $primary_key = 'username'; +sub _map { + my $self = shift; + map { /^\s*(\S+)\s*(\S+)\s*$/ } split("\n", $self->option('schema') ); +} sub rebless { shift; } sub _export_insert { my($self, $svc_acct) = (shift, shift); + my %map = $self->_map; my %record = map { my $value = $map{$_}; - $_ => ( ref($value) - ? &{$value}($svc_acct) - : $svc_acct->$value() - ); + $_ => $svc_acct->$value(); } keys %map; my $err_or_queue = - $self->acct_sql_queue( $svc_acct->svcnum, 'insert', $table, %record ); + $self->acct_sql_queue( + $svc_acct->svcnum, + 'insert', + $self->option('table'), + %record + ); return $err_or_queue unless ref($err_or_queue); ''; @@ -91,12 +111,13 @@ sub _export_replace { sub _export_delete { my ( $self, $svc_acct ) = (shift, shift); - my $keymap = $map{$primary_key}; + my %map = $self->_map; + my $keymap = $map{$self->option('primary_key')}; my $err_or_queue = $self->acct_sql_queue( $svc_acct->svcnum, 'delete', - $table, - $primary_key => ref($keymap) ? &{$keymap}($svc_acct) : $svc_acct->$keymap() + $self->option('table'), + $self->option('primary_key') => $svc_acct->$keymap(), ); return $err_or_queue unless ref($err_or_queue); ''; diff --git a/FS/FS/svc_acct.pm b/FS/FS/svc_acct.pm index 355573b00..6ea30437a 100644 --- a/FS/FS/svc_acct.pm +++ b/FS/FS/svc_acct.pm @@ -1190,6 +1190,39 @@ sub check_password { } +=item crypt_password + +Returns an encrypted password, either by passing through an encrypted password +in the database or by encrypting a plaintext password from the database. + +=cut + +sub crypt_password { + my $self = shift; + #false laziness w/shellcommands.pm + #eventually should check a "password-encoding" field + if ( length($self->_password) == 13 + || $self->_password =~ /^\$(1|2a?)\$/ ) { + $self->_password; + } else { + crypt( + $self->_password, + $saltset[int(rand(64))].$saltset[int(rand(64))] + ); + } +} + +=item virtual_maildir + +Returns $domain/maildirs/$username/ + +=cut + +sub virtual_maildir { + my $self = shift; + $self->domain. '/maildirs/'. $self->username. '/'; +} + =back =head1 SUBROUTINES -- cgit v1.2.1 From 3abe6ab40fa3ecee7b5c4038c556ccf4a4ab4227 Mon Sep 17 00:00:00 2001 From: ivan Date: Wed, 26 May 2004 13:07:47 +0000 Subject: fix table name --- FS/FS/part_export/acct_sql.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FS/FS/part_export/acct_sql.pm b/FS/FS/part_export/acct_sql.pm index 8e102fcc1..dfc37d083 100644 --- a/FS/FS/part_export/acct_sql.pm +++ b/FS/FS/part_export/acct_sql.pm @@ -69,7 +69,7 @@ mail server setups through some subclassing rather than options. this.form.primary_key.value = "username"; '>
  • -- cgit v1.2.1 From d99c56a3a435d202c4503f6f62895d8111ac41f3 Mon Sep 17 00:00:00 2001 From: ivan Date: Wed, 26 May 2004 18:59:29 +0000 Subject: require the version of File::Temp with the OO interface --- FS/FS/cust_bill.pm | 12 ++++++------ httemplate/docs/upgrade-1.4.2.html | 1 + 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/FS/FS/cust_bill.pm b/FS/FS/cust_bill.pm index 576e4c846..3b76dd257 100644 --- a/FS/FS/cust_bill.pm +++ b/FS/FS/cust_bill.pm @@ -5,7 +5,7 @@ use vars qw( @ISA $conf $money_char ); use vars qw( $invoice_lines @buf ); #yuck use Date::Format; use Text::Template; -use File::Temp; +use File::Temp 0.14; use FS::UID qw( datasrc ); use FS::Record qw( qsearch qsearchs ); use FS::Misc qw( send_email ); @@ -1143,9 +1143,9 @@ sub print_ps { chdir($dir); system("pslatex $file.tex >/dev/null 2>&1") == 0 - or die "pslatex failed: $!"; + or die "pslatex $file.tex failed: $!"; system("pslatex $file.tex >/dev/null 2>&1") == 0 - or die "pslatex failed: $!"; + or die "pslatex $file.tex failed: $!"; system('dvips', '-q', '-t', 'letter', "$file.dvi", '-o', "$file.ps" ) == 0 or die "dbips failed: $!"; @@ -1190,9 +1190,9 @@ sub print_pdf { #! LaTeX Error: Unknown graphics extension: .eps. system("pslatex $file.tex >/dev/null 2>&1") == 0 - or die "pslatex failed: $!"; + or die "pslatex $file.tex failed: $!"; system("pslatex $file.tex >/dev/null 2>&1") == 0 - or die "pslatex failed: $!"; + or die "pslatex $file.tex failed: $!"; #system('dvipdf', "$file.dvi", "$file.pdf" ); system( @@ -1200,7 +1200,7 @@ sub print_pdf { "| gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=$file.pdf ". " -c save pop -" ) == 0 - or die "dvips failed: $!"; + or die "dvips | gs failed: $!"; open(PDF, "<$file.pdf") or die "can't open $file.pdf: $! (error in LaTeX template?)\n"; diff --git a/httemplate/docs/upgrade-1.4.2.html b/httemplate/docs/upgrade-1.4.2.html index eb40df8b3..a24661142 100644 --- a/httemplate/docs/upgrade-1.4.2.html +++ b/httemplate/docs/upgrade-1.4.2.html @@ -16,6 +16,7 @@
  • Install Crypt::PasswdMD5
  • Install Net::Whois::Raw
  • CGI.pm minimum version 2.47 is required. You will probably need to install a current CGI.pm from CPAN if you are using Perl 5.005 or earlier. +
  • File::Temp minimum version 0.14 is required. You will probably need to install a currrent File::Temp from CPAN if you are using Perl 5.6 or earlier.
  • If using Apache::ASP, add PerlSetVar RequestBinaryRead Off to your Apache configuration and make sure you are using Apache::ASP minimum version 2.55.
  • Run make aspdocs or make masondocs.
  • Copy aspdocs/ or masondocs/ to your web server's document space. -- cgit v1.2.1 From 535811854078c1720ab5250f1a1669306796df95 Mon Sep 17 00:00:00 2001 From: ivan Date: Thu, 27 May 2004 09:14:50 +0000 Subject: adding sqlradius.import --- bin/sqlradius.import | 144 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 bin/sqlradius.import diff --git a/bin/sqlradius.import b/bin/sqlradius.import new file mode 100644 index 000000000..9cb518e7f --- /dev/null +++ b/bin/sqlradius.import @@ -0,0 +1,144 @@ +#!/usr/bin/perl -Tw + +use strict; +use vars qw(%part_svc %domain_part_svc); +#use Date::Parse; +use DBI; +use Term::Query qw(query); +use FS::UID qw(adminsuidsetup); #datasrc +use FS::Record qw(qsearch qsearchs); +use FS::svc_acct; +use FS::part_svc; +use FS::svc_domain; + +my $user = shift or die &usage; +adminsuidsetup $user; + +#push @FS::svc_acct::shells, qw(/bin/sync /sbin/shutdown /bin/halt /sbin/halt); #others? + +$FS::svc_Common::noexport_hack = 1; + +### + +%part_svc=map { $_->svcpart, $_ } qsearch('part_svc',{'svcdb'=>'svc_acct'}); + +die "No services with svcdb svc_acct!\n" unless %part_svc; + +print "\n\n", &menu_svc, "\n", <svcpart, $_ } + qsearch('part_svc', { 'svcdb' => 'svc_domain'} ); + +die "No services with svcdb svc_domain!\n" unless %domain_part_svc; + +print "\n\n", &menu_svc, "\n", <connect( $datasrc, $db_user, $db_pass ) + or die $DBI::errstr; + +my $sth = $dbh->prepare('SELECT DISTINCT UserName, Realm FROM radcheck') + or die $dbh->errstr; +$sth->execute or die $sth->errstr; + +my $row; +while ( $row = $sth->fetchrow_arrayref ) { + my( $r_username, $realm ) = @$row; + + my( $username, $domain ); + if ( $r_username =~ s/([^@]+)\@([^@]+)$// ) { + $username = $1; + $domain = $2; + } else { + $username = $r_username; + $domain = $realm; + } + my %svc_domain = ( 'svcpart' => $domain_svcpart, + 'domain' => $domain, ); + my $svc_domain = qsearchs('svc_domain', \%svc_domain ) + || new FS::svc_domain \%svc_domain; + unless ( $svc_domain->domsvc ) { + my $error = $svc_domain->insert; + if ( $error ) { + die "can't insert domain $domain: $error\n"; + } + } + + my( $password, $finger, $group ) = ( '', '', '' ); + + my $rc_sth = $dbh->prepare( + 'SELECT Attribute, Value, Name, GroupName'. + ' FROM radcheck'. + ' WHERE UserName = ? and Realm = ?' + ) or die $dbh->errstr; + $rc_sth->execute($r_username, $realm) or die $rc_sth->errstr; + + foreach my $rc_row ( @{$rc_sth->fetchall_arrayref} ) { + my($attribute, $value, $name, $groupname) = @$row; + if ( $attribute =~ /^(Crypt-)?Password$/ ) { + $password = $value; + $finger = $name; + $group = $groupname; + } else { + #handle other params! + } + } + + my $svc_acct = new FS::svc_acct ( + 'svcpart' => $sqlradius_svcpart, + 'username' => $username, + 'domsvc' => $svc_domain->domsvc, + '_password' => $password, + 'finger' => $finger, + ); + + my($error); + #$error = $svc_acct->insert; + $error = $svc_acct->check; + if ( $error ) { + if ( $error =~ /duplicate/i ) { + warn "$r_username: $error"; + } else { + die "$r_username: $error"; + } + } + +} + +sub usage { + die "Usage:\n\n sqlradius.import user\n"; +} + -- cgit v1.2.1