@vpopmailmachines );
use Net::SSH qw(ssh);
use FS::Conf;
-use FS::Record qw( fields qsearch qsearchs );
+use FS::Record qw( fields qsearch qsearchs dbh );
use FS::svc_Common;
use FS::cust_svc;
use FS::svc_acct;
If the configuration value (see L<FS::Conf>) vpopmailmachines exists, then
the command:
- [ -d $vpopdir/$domain/$source ] || {
- echo "$destination" >> $vpopdir/$domain/$username/.$qmail
- chown $vpopuid:$vpopgid $vpopdir/$domain/$username/.$qmail
+ [ -d $vpopdir/domains/$domain/$source ] && {
+ echo "$destination" >> $vpopdir/domains/$domain/$username/.$qmail
+ chown $vpopuid:$vpopgid $vpopdir/domains/$domain/$username/.$qmail
}
is executed on each vpopmailmachine via ssh (see the vpopmail documentation).
local $SIG{TSTP} = 'IGNORE';
local $SIG{PIPE} = 'IGNORE';
+ my $oldAutoCommit = $FS::UID::AutoCommit;
+ local $FS::UID::AutoCommit = 0;
+ my $dbh = dbh;
+
$error = $self->check;
return $error if $error;
$error = $self->SUPER::insert;
- return $error if $error;
+ if ($error) {
+ $dbh->rollback if $oldAutoCommit;
+ return $error;
+ }
my $svc_acct = qsearchs( 'svc_acct', { 'svcnum' => $self->srcsvc } );
my $username = $svc_acct->username;
my $domain = $svc_acct->domain;
my $destination;
if ($self->dstsvc) {
- my $dst_svc_acct = qsearchs( 'svc_acct', { 'svcnum' => $self->dstsvc } );
- $destination = $dst_svc_acct->email;
+ $destination = $self->dstsvc_acct->email;
} else {
$destination = $self->dst;
}
foreach my $vpopmailmachine ( @vpopmailmachines ) {
my($machine, $vpopdir, $vpopuid, $vpopgid) = split(/\s+/, $vpopmailmachine);
- ssh("root\@$machine","[ -d $vpopdir/$domain/$username ] || { echo \"$destination\" >> $vpopdir/$domain/$username/.qmail; chown $vpopuid:$vpopgid $vpopdir/$domain/$username/.qmail; }")
+ my $queue = new FS::queue {
+ 'svcnum' => $self->svcnum,
+ 'job' => 'Net::SSH::ssh_cmd',
+ };
+ # should be neater
+ my $error = $queue->insert("root\@$machine","[ -d $vpopdir/domains/$domain/$username ] && { echo \"$destination\" >> $vpopdir/domains/$domain/$username/.qmail; chown $vpopuid:$vpopgid $vpopdir/domains/$domain/$username/.qmail; }")
unless $nossh_hack;
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return "queueing job (transaction rolled back): $error";
+ }
+
}
+ $dbh->commit or die $dbh->errstr if $oldAutoCommit;
''; #no error
}
The corresponding FS::cust_svc record will be deleted as well.
+If the configuration value vpopmailmachines exists, then the command:
+
+ { sed -e '/^$destination/d' <
+ $vpopdir/domains/$srcdomain/$srcusername/.qmail >
+ $vpopdir/domains/$srcdomain/$srcusername/.qmail.temp;
+ mv $vpopdir/domains/$srcdomain/$srcusername/.qmail.temp
+ $vpopdir/domains/$srcdomain/$srcusername/.qmail;
+ chown $vpopuid.$vpopgid $vpopdir/domains/$srcdomain/$srcusername/.qmail; }
+
+
+is executed on each vpopmailmachine via ssh. This behaviour can be supressed
+by setting $FS::svc_forward_nossh_hack true.
+
+=cut
+
+sub delete {
+ my $self = shift;
+
+ local $SIG{HUP} = 'IGNORE';
+ local $SIG{INT} = 'IGNORE';
+ local $SIG{QUIT} = 'IGNORE';
+ local $SIG{TERM} = 'IGNORE';
+ local $SIG{TSTP} = 'IGNORE';
+ local $SIG{PIPE} = 'IGNORE';
+
+ my $oldAutoCommit = $FS::UID::AutoCommit;
+ local $FS::UID::Autocommit = 0;
+ my $dbh = dbh;
+
+ my $error = $self->SUPER::delete;
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return $error;
+ }
+
+ my $svc_acct = $self->srcsvc_acct;
+ my $username = $svc_acct->username;
+ my $domain = $svc_acct->domain;
+ my $destination;
+ if ($self->dstsvc) {
+ $destination = $self->dstsvc_acct->email;
+ } else {
+ $destination = $self->dst;
+ }
+ foreach my $vpopmailmachine ( @vpopmailmachines ) {
+ my($machine, $vpopdir, $vpopuid, $vpopgid) =
+ split(/\s+/, $vpopmailmachine);
+ my $queue = new FS::queue { 'job' => 'Net::SSH::ssh_cmd' };
+ # should be neater
+ my $error = $queue->insert("root\@$machine",
+ "sed -e '/^$destination/d' " .
+ "< $vpopdir/domains/$domain/$username/.qmail" .
+ "> $vpopdir/domains/$domain/$username/.qmail.temp; " .
+ "mv $vpopdir/domains/$domain/$username/.qmail.temp " .
+ "$vpopdir/domains/$domain/$username/.qmail; " .
+ "chown $vpopuid.$vpopgid $vpopdir/domains/$domain/$username/.qmail;"
+ )
+ unless $nossh_hack;
+
+ if ($error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return "queueing job (transaction rolled back): $error";
+ }
+
+ }
+
+ $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+ '';
+}
+
+
=item replace OLD_RECORD
Replaces OLD_RECORD with this one in the database. If there is an error,
returns the error, otherwise returns false.
-If srcsvc changes, and the configuration value vpopmailmachines exists, then
-the command:
+If the configuration value vpopmailmachines exists, then the command:
- rm $vpopdir/$domain/$username/.qmail
+ { sed -e '/^$destination/d' <
+ $vpopdir/domains/$srcdomain/$srcusername/.qmail >
+ $vpopdir/domains/$srcdomain/$srcusername/.qmail.temp;
+ mv $vpopdir/domains/$srcdomain/$srcusername/.qmail.temp
+ $vpopdir/domains/$srcdomain/$srcusername/.qmail;
+ chown $vpopuid.$vpopgid $vpopdir/domains/$srcdomain/$srcusername/.qmail; }
+
is executed on each vpopmailmachine via ssh. This behaviour can be supressed
by setting $FS::svc_forward_nossh_hack true.
-If dstsvc changes (or dstsvc is 0 and dst changes), and the configuration value
-vpopmailmachines exists, then the command:
+Also, if the configuration value vpopmailmachines exists, then the command:
- [ -d $vpopdir/$domain/$source ] || {
- echo "$destination" >> $vpopdir/$domain/$username/.$qmail
- chown $vpopuid:$vpopgid $vpopdir/$domain/$username/.$qmail
+ [ -d $vpopdir/domains/$domain/$source ] && {
+ echo "$destination" >> $vpopdir/domains/$domain/$username/.$qmail
+ chown $vpopuid:$vpopgid $vpopdir/domains/$domain/$username/.$qmail
}
is executed on each vpopmailmachine via ssh. This behaviour can be supressed
local $SIG{TSTP} = 'IGNORE';
local $SIG{PIPE} = 'IGNORE';
+ my $oldAutoCommit = $FS::UID::AutoCommit;
+ local $FS::UID::AutoCommit = 0;
+ my $dbh = dbh;
+
my $error = $new->SUPER::replace($old);
- return $error if $error;
+ if ($error) {
+ $dbh->rollback if $oldAutoCommit;
+ return $error;
+ }
+
+ my $old_svc_acct = $old->srcsvc_acct;
+ my $old_username = $old_svc_acct->username;
+ my $old_domain = $old_svc_acct->domain;
+ my $destination;
+ if ($old->dstsvc) {
+ $destination = $old->dstsvc_acct->email;
+ } else {
+ $destination = $old->dst;
+ }
+ foreach my $vpopmailmachine ( @vpopmailmachines ) {
+ my($machine, $vpopdir, $vpopuid, $vpopgid) =
+ split(/\s+/, $vpopmailmachine);
+ my $queue = new FS::queue {
+ 'svcnum' => $new->svcnum,
+ 'job' => 'Net::SSH::ssh_cmd',
+ };
+ # should be neater
+ my $error = $queue->insert("root\@$machine",
+ "sed -e '/^$destination/d' " .
+ "< $vpopdir/domains/$old_domain/$old_username/.qmail" .
+ "> $vpopdir/domains/$old_domain/$old_username/.qmail.temp; " .
+ "mv $vpopdir/domains/$old_domain/$old_username/.qmail.temp " .
+ "$vpopdir/domains/$old_domain/$old_username/.qmail; " .
+ "chown $vpopuid.$vpopgid " .
+ "$vpopdir/domains/$old_domain/$old_username/.qmail;"
+ )
+ unless $nossh_hack;
- if ( $new->srcsvc != $old->srcsvc ) {
- my $old_svc_acct = qsearchs( 'svc_acct', { 'svcnum' => $old->srcsvc } );
- my $old_username = $old_svc_acct->username;
- my $old_domain = $old_svc_acct->domain;
- foreach my $vpopmailmachine ( @vpopmailmachines ) {
- my($machine, $vpopdir, $vpopuid, $vpopgid) =
- split(/\s+/, $vpopmailmachine);
- ssh("root\@$machine","rm $vpopdir/$old_domain/$old_username/.qmail")
- unless $nossh_hack;
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return "queueing job (transaction rolled back): $error";
}
}
my $svc_acct = qsearchs( 'svc_acct', { 'svcnum' => $new->srcsvc } );
my $username = $svc_acct->username;
my $domain = $svc_acct->domain;
- my $destination;
if ($new->dstsvc) {
- my $dst_svc_acct = qsearchs( 'svc_acct', { 'svcnum' => $new->dstsvc } );
- $destination = $dst_svc_acct->email;
+ $destination = $new->dstsvc_acct->email;
} else {
$destination = $new->dst;
}
foreach my $vpopmailmachine ( @vpopmailmachines ) {
my($machine, $vpopdir, $vpopuid, $vpopgid) = split(/\s+/, $vpopmailmachine);
- ssh("root\@$machine","[ -d $vpopdir/$domain/$username ] || { echo \"$destination\" >> $vpopdir/$domain/$username/.qmail; chown $vpopuid:$vpopgid $vpopdir/$domain/$username/.qmail; }")
+ my $queue = new FS::queue {
+ 'svcnum' => $new->svcnum,
+ 'job' => 'Net::SSH::ssh_cmd',
+ };
+ # should be neater
+ my $error = $queue->insert("root\@$machine","[ -d $vpopdir/domains/$domain/$username ] && { echo \"$destination\" >> $vpopdir/domains/$domain/$username/.qmail; chown $vpopuid:$vpopgid $vpopdir/domains/$domain/$username/.qmail; }")
unless $nossh_hack;
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return "queueing job (transaction rolled back): $error";
+ }
}
#end subroutinable bits
+ $dbh->commit or die $dbh->errstr if $oldAutoCommit;
'';
}
;
return $error if $error;
- return "Unknown srcsvc"
- unless qsearchs('svc_acct', { 'svcnum' => $self->srcsvc } );
+ return "Unknown srcsvc" unless $self->srcsvc_acct;
return "Both dstsvc and dst were defined; one one can be specified"
if $self->dstsvc && $self->dst;
return "one of dstsvc or dst is required"
unless $self->dstsvc || $self->dst;
+ #return "Unknown dstsvc: $dstsvc" unless $self->dstsvc_acct || ! $self->dstsvc;
return "Unknown dstsvc"
unless qsearchs('svc_acct', { 'svcnum' => $self->dstsvc } )
|| ! $self->dstsvc;
+
if ( $self->dst ) {
$self->dst =~ /^([\w\.\-]+)\@(([\w\-]+\.)+\w+)$/
or return "Illegal dst: ". $self->dst;
''; #no error
}
+=item srcsvc_acct
+
+Returns the FS::svc_acct object referenced by the srcsvc column.
+
+=cut
+
+sub srcsvc_acct {
+ my $self = shift;
+ qsearchs('svc_acct', { 'svcnum' => $self->srcsvc } );
+}
+
+=item dstsvc_acct
+
+Returns the FS::svc_acct object referenced by the srcsvc column, or false for
+forwards not local to freeside.
+
+=cut
+
+sub dstsvc_acct {
+ my $self = shift;
+ qsearchs('svc_acct', { 'svcnum' => $self->dstsvc } );
+}
+
=back
=head1 VERSION
-$Id: svc_forward.pm,v 1.7 2001-09-06 20:41:59 ivan Exp $
+$Id: svc_forward.pm,v 1.11 2002-02-20 01:03:09 ivan Exp $
=head1 BUGS