{
'key' => 'apacheip',
- 'section' => 'apache',
- 'description' => 'The current IP address to assign to new virtual hosts',
+ 'section' => 'deprecated',
+ 'description' => '<b>DEPRECATED</b>, add an <i>apache</i> <a href="../browse/part_export.cgi">export</a> instead. Used to be the current IP address to assign to new virtual hosts',
'type' => 'text',
},
{
'key' => 'apachemachines',
- 'section' => 'apache',
- 'description' => 'Your Apache machines, one per line. This enables export of `/etc/apache/vhosts.conf\', which can be included in your Apache configuration via the <a href="http://www.apache.org/docs/mod/core.html#include">Include</a> directive.',
+ 'section' => 'deprecated',
+ 'description' => '<b>DEPRECATED</b>, add an <i>apache</i> <a href="../browse/part_export.cgi">export</a> instead. Used to be Apache machines, one per line. This enables export of `/etc/apache/vhosts.conf\', which can be included in your Apache configuration via the <a href="http://www.apache.org/docs/mod/core.html#include">Include</a> directive.',
'type' => 'textarea',
},
},
{
- 'key' => 'excludeaddr',
- 'section' => 'deprecated',
- 'description' => 'Addresses to exclude from assignment, one per line.',
+ 'key' => 'exclude_ip_addr',
+ 'section' => '',
+ 'description' => 'Exclude these from the list of available broadband service IP addresses. (One per line)',
'type' => 'textarea',
},
{
'key' => 'erpcdmachines',
- 'section' => '',
- 'description' => 'Your ERPCD authenticaion machines, one per line. This enables export of `/usr/annex/acp_passwd\' and `/usr/annex/acp_dialup\'',
+ 'section' => 'deprecated',
+ 'description' => '<b>DEPRECATED</b>, ERPCD is no longer supported. Used to be ERPCD authenticaion machines, one per line. This enables export of `/usr/annex/acp_passwd\' and `/usr/annex/acp_dialup\'',
'type' => 'textarea',
},
{
'key' => 'icradius_mysqldest',
'section' => 'deprecated',
- 'description' => '<b>DEPRECATED</b>, add an <i>sqlradius</i> https://billing.crosswind.net/freeside/browse/part_export.cgi">export</a> instead. Used to be the destination directory for the MySQL databases, on the ICRADIUS/FreeRADIUS machines. Defaults to "/usr/local/var/".',
+ 'description' => '<b>DEPRECATED</b>, add an <i>sqlradius</i> <a href="../browse/part_export.cgi">export</a> instead. Used to be the destination directory for the MySQL databases, on the ICRADIUS/FreeRADIUS machines. Defaults to "/usr/local/var/".',
'type' => 'text',
},
{
'key' => 'icradius_mysqlsource',
'section' => 'deprecated',
- 'description' => '<b>DEPRECATED</b>, add an <i>sqlradius</i> https://billing.crosswind.net/freeside/browse/part_export.cgi">export</a> instead. Used to be the source directory for for the MySQL radcheck table files, on the Freeside machine. Defaults to "/usr/local/var/freeside".',
+ 'description' => '<b>DEPRECATED</b>, add an <i>sqlradius</i> <a href="../browse/part_export.cgi">export</a> instead. Used to be the source directory for for the MySQL radcheck table files, on the Freeside machine. Defaults to "/usr/local/var/freeside".',
'type' => 'text',
},
{
'key' => 'icradius_secrets',
'section' => 'deprecated',
- 'description' => '<b>DEPRECATED</b>, add an <i>sqlradius</i> https://billing.crosswind.net/freeside/browse/part_export.cgi">export</a> instead. This option used to specify a database for ICRADIUS/FreeRADIUS export. Three lines: DBI data source, username and password.',
+ 'description' => '<b>DEPRECATED</b>, add an <i>sqlradius</i> <a href="../browse/part_export.cgi">export</a> instead. This option used to specify a database for ICRADIUS/FreeRADIUS export. Three lines: DBI data source, username and password.',
'type' => 'textarea',
},
{
'key' => 'sendmailconfigpath',
- 'section' => 'mail',
- 'description' => 'Sendmail configuration file path. Defaults to `/etc\'. Many newer distributions use `/etc/mail\'.',
+ 'section' => 'deprecated',
+ 'description' => '<b>DEPRECATED</b>, add a <i>sendmail</i> <a href="../browse/part_export.cgi">export</a> instead. Used to be sendmail configuration file path. Defaults to `/etc\'. Many newer distributions use `/etc/mail\'.',
'type' => 'text',
},
{
'key' => 'sendmailmachines',
- 'section' => 'mail',
- 'description' => 'Your sendmail machines, one per line. This enables export of `/etc/virtusertable\' and `/etc/sendmail.cw\'.',
+ 'section' => 'deprecated',
+ 'description' => '<b>DEPRECATED</b>, add a <i>sendmail</i> <a href="../browse/part_export.cgi">export</a> instead. Used to be sendmail machines, one per line. This enables export of `/etc/virtusertable\' and `/etc/sendmail.cw\'.',
'type' => 'textarea',
},
{
'key' => 'sendmailrestart',
- 'section' => 'mail',
- 'description' => 'If defined, the command which is run on sendmail machines after files are copied.',
+ 'section' => 'deprecated',
+ 'description' => '<b>DEPRECATED</b>, add a <i>sendmail</i> <a href="../browse/part_export.cgi">export</a> instead. Used to define the command which is run on sendmail machines after files are copied.',
'type' => 'text',
},
{
'key' => 'vpopmailmachines',
'section' => 'deprecated',
- 'description' => '<b>DEPRECATED</b>, add a <i>cp</i> <a href="../browse/part_export.cgi">export</a> instead. This option used to contain your vpopmail pop toasters, one per line. Each line is of the form "machinename vpopdir vpopuid vpopgid". For example: <code>poptoaster.domain.tld /home/vpopmail 508 508</code> Note: vpopuid and vpopgid are values taken from the vpopmail machine\'s /etc/passwd',
+ 'description' => '<b>DEPRECATED</b>, add a <i>vpopmail</i> <a href="../browse/part_export.cgi">export</a> instead. This option used to contain your vpopmail pop toasters, one per line. Each line is of the form "machinename vpopdir vpopuid vpopgid". For example: <code>poptoaster.domain.tld /home/vpopmail 508 508</code> Note: vpopuid and vpopgid are values taken from the vpopmail machine\'s /etc/passwd',
'type' => 'textarea',
},
my $self = shift;
my $conf = new FS::Conf;
- my @excludeaddr = $conf->config('excludeaddr');
+ my @excludeaddr = $conf->config('exclude_ip_addr');
my @used = (
map { $_->NetAddr->addr }
;
tie my %bind_options, 'Tie::IxHash',
- #'machine' => { label=>'named machine' },
- 'named_conf' => { label => 'named.conf location',
- default=> '/etc/bind/named.conf' },
- 'zonepath' => { label => 'path to zone files',
- default=> '/etc/bind/', },
+ #'machine' => { label=>'named machine' },
+ 'named_conf' => { label => 'named.conf location',
+ default=> '/etc/bind/named.conf' },
+ 'zonepath' => { label => 'path to zone files',
+ default=> '/etc/bind/', },
+ 'bind_release' => { label => 'ISC BIND Release',
+ type => 'select',
+ options => [qw(BIND8 BIND9)],
+ default => 'BIND8' },
+ 'bind9_minttl' => { label => 'The minttl required by bind9 and RFC1035.',
+ default => '1D' },
;
tie my %bind_slave_options, 'Tie::IxHash',
- #'machine' => { label=> 'Slave machine' },
- 'master' => { label=> 'Master IP address(s) (semicolon-separated)' },
- 'named_conf' => { label => 'named.conf location',
- default => '/etc/bind/named.conf' },
+ #'machine' => { label=> 'Slave machine' },
+ 'master' => { label=> 'Master IP address(s) (semicolon-separated)' },
+ 'named_conf' => { label => 'named.conf location',
+ default => '/etc/bind/named.conf' },
+ 'bind_release' => { label => 'ISC BIND Release',
+ type => 'select',
+ options => [qw(BIND8 BIND9)],
+ default => 'BIND8' },
+ 'bind9_minttl' => { label => 'The minttl required by bind9 and RFC1035.',
+ default => '1D' },
;
tie my %http_options, 'Tie::IxHash',
'radius' => { label=>'Export RADIUS attributes', type=>'checkbox', },
;
+tie my %forward_shellcommands_options, 'Tie::IxHash',
+ 'user' => { lable=>'Remote username', default=>'root' },
+ 'useradd' => { label=>'Insert command',
+ default=>'',
+ },
+ 'userdel' => { label=>'Delete command',
+ default=>'',
+ },
+ 'usermod' => { label=>'Modify command',
+ default=>'',
+ },
+;
#export names cannot have dashes...
%exports = (
'desc' => 'Real-time export via remote SSH (i.e. useradd, userdel, etc.)',
'options' => \%shellcommands_options,
'nodomain' => 'Y',
- 'notes' => 'Run remote commands via SSH. Usernames are considered unique (also see shellcommands_withdomain). You probably want this if the commands you are running will not accept a domain as a parameter. You will need to <a href="../docs/ssh.html">setup SSH for unattended operation</a>.<BR><BR>Use these buttons for some useful presets:<UL><LI><INPUT TYPE="button" VALUE="Linux/NetBSD" onClick=\'this.form.useradd.value = "useradd -c $finger -d $dir -m -s $shell -u $uid -p $crypt_password $username"; this.form.useradd_stdin.value = ""; this.form.userdel.value = "userdel -r $username"; this.form.userdel_stdin.value=""; this.form.usermod.value = "usermod -c $new_finger -d $new_dir -m -l $new_username -s $new_shell -u $new_uid -p $new_crypt_password $old_username"; this.form.usermod_stdin.value = "";\'><LI><INPUT TYPE="button" VALUE="FreeBSD" onClick=\'this.form.useradd.value = "pw useradd $username -d $dir -m -s $shell -u $uid -g $gid -c $finger -h 0"; this.form.useradd_stdin.value = "$_password\n"; this.form.userdel.value = "pw userdel $username -r"; this.form.userdel_stdin.value=""; this.form.usermod.value = "pw usermod $old_username -d $new_dir -m -l $new_username -s $new_shell -u $new_uid -c $new_finger -h 0"; this.form.usermod_stdin.value = "$new__password\n";\'><LI><INPUT TYPE="button" VALUE="Just maintain directories (use with sysvshell or bsdshell)" onClick=\'this.form.useradd.value = "cp -pr /etc/skel $dir; chown -R $uid.$gid $dir"; this.form.useradd_stdin.value = ""; this.form.usermod.value = "[ -d $old_dir ] && mv $old_dir $new_dir || ( chmod u+t $old_dir; mkdir $new_dir; cd $old_dir; find . -depth -print | cpio -pdm $new_dir; chmod u-t $new_dir; chown -R $uid.$gid $new_dir; rm -rf $old_dir )"; this.form.usermod_stdin.value = ""; this.form.userdel.value = "rm -rf $dir"; this.form.userdel_stdin.value="";\'></UL>',
+ 'notes' => 'Run remote commands via SSH. Usernames are considered unique (also see shellcommands_withdomain). You probably want this if the commands you are running will not accept a domain as a parameter. You will need to <a href="../docs/ssh.html">setup SSH for unattended operation</a>.<BR><BR>Use these buttons for some useful presets:<UL><LI><INPUT TYPE="button" VALUE="Linux/NetBSD" onClick=\'this.form.useradd.value = "useradd -c $finger -d $dir -m -s $shell -u $uid -p $crypt_password $username"; this.form.useradd_stdin.value = ""; this.form.userdel.value = "userdel -r $username"; this.form.userdel_stdin.value=""; this.form.usermod.value = "usermod -c $new_finger -d $new_dir -m -l $new_username -s $new_shell -u $new_uid -p $new_crypt_password $old_username"; this.form.usermod_stdin.value = "";\'><LI><INPUT TYPE="button" VALUE="FreeBSD" onClick=\'this.form.useradd.value = "pw useradd $username -d $dir -m -s $shell -u $uid -g $gid -c $finger -h 0"; this.form.useradd_stdin.value = "$_password\n"; this.form.userdel.value = "pw userdel $username -r"; this.form.userdel_stdin.value=""; this.form.usermod.value = "pw usermod $old_username -d $new_dir -m -l $new_username -s $new_shell -u $new_uid -c $new_finger -h 0"; this.form.usermod_stdin.value = "$new__password\n";\'><LI><INPUT TYPE="button" VALUE="Just maintain directories (use with sysvshell or bsdshell)" onClick=\'this.form.useradd.value = "cp -pr /etc/skel $dir; chown -R $uid.$gid $dir"; this.form.useradd_stdin.value = ""; this.form.usermod.value = "[ -d $old_dir ] && mv $old_dir $new_dir || ( chmod u+t $old_dir; mkdir $new_dir; cd $old_dir; find . -depth -print | cpio -pdm $new_dir; chmod u-t $new_dir; chown -R $new_uid.$new_gid $new_dir; rm -rf $old_dir )"; this.form.usermod_stdin.value = ""; this.form.userdel.value = "rm -rf $dir"; this.form.userdel_stdin.value="";\'></UL>The following variables are available for interpolation (prefixed with new_ or old_ for replace operations): <UL><LI><code>$username</code><LI><code>$_password</code><LI><code>$quoted_password</code> - unencrypted password quoted for the shell<LI><code>$crypt_password</code> - encrypted password<LI><code>$uid</code><LI><code>$gid</code><LI><code>$finger</code> - GECOS, already quoted for the shell (do not add additional quotes)<LI><code>$dir</code> - home directory<LI><code>$shell</code><LI><code>$quota</code><LI>All other fields in <a href="../docs/schema.html#svc_acct">svc_acct</a> are also available.</UL>',
},
'shellcommands_withdomain' => {
'desc' => 'Real-time export via remote SSH.',
'options' => \%shellcommands_withdomain_options,
- 'notes' => 'Run remote commands via SSH. username@domain (rather than just usernames) are considered unique (also see shellcommands). You probably want this if the commands you are running will accept a domain as a parameter, and will allow the same username with different domains. You will need to <a href="../docs/ssh.html">setup SSH for unattended operation</a>.',
+ 'notes' => 'Run remote commands via SSH. username@domain (rather than just usernames) are considered unique (also see shellcommands). You probably want this if the commands you are running will accept a domain as a parameter, and will allow the same username with different domains. You will need to <a href="../docs/ssh.html">setup SSH for unattended operation</a>.<BR><BR>The following variables are available for interpolation (prefixed with <code>new_</code> or <code>old_</code> for replace operations): <UL><LI><code>$username</code><LI><code>$domain</code><LI><code>$_password</code><LI><code>$quoted_password</code> - unencrypted password quoted for the shell<LI><code>$crypt_password</code> - encrypted password<LI><code>$uid</code><LI><code>$gid</code><LI><code>$finger</code> - GECOS, already quoted for the shell (do not add additional quotes)<LI><code>$dir</code> - home directory<LI><code>$shell</code><LI><code>$quota</code><LI>All other fields in <a href="../docs/schema.html#svc_acct">svc_acct</a> are also available.</UL>',
},
'ldap' => {
'sqlmail' => {
'desc' => 'Real-time export to SQL-backed mail server',
'options' => \%sqlmail_options,
- 'nodomain' => 'N',
+ 'nodomain' => '',
'notes' => 'Database schema can be made to work with Courier IMAP and Exim. Others could work but are untested. (...extended description from pc-intouch?...)',
},
'domain_shellcommands' => {
'desc' => 'Run remote commands via SSH, for domains.',
'options' => \%domain_shellcommands_options,
- 'notes' => 'Run remote commands via SSH, for domains. You will need to <a href="../docs/ssh.html">setup SSH for unattended operation</a>.',
+ 'notes' => 'Run remote commands via SSH, for domains. You will need to <a href="../docs/ssh.html">setup SSH for unattended operation</a>.<BR><BR>Use these buttons for some useful presets:<UL><LI><INPUT TYPE="button" VALUE="qmail catchall .qmail-domain-default maintenance" onClick=\'this.form.useradd.value = "[ \"$uid\" -a \"$gid\" -a \"$dir\" -a \"$qdomain\" ] && [ -e $dir/.qmail-$qdomain-default ] || { touch $dir/.qmail-$qdomain-default; chown $uid:$gid $dir/.qmail-$qdomain-default; }"; this.form.userdel.value = ""; this.form.usermod.value = "";\'></UL>The following variables are available for interpolation (prefixed with <code>new_</code> or <code>old_</code> for replace operations): <UL><LI><code>$domain</code><LI><code>$qdomain</code> - domain with periods replaced by colons<LI><code>$uid</code> - of catchall account<LI><code>$gid</code> - of catchall account<LI><code>$dir</code> - home directory of catchall account<LI>All other fields in <a href="../docs/schema.html#svc_domain">svc_domain</a> are also available.</UL>',
},
#'nodomain' => 'Y',
'notes' => 'Database schema can be made to work with Courier IMAP and Exim. Others could work but are untested. (...extended description from pc-intouch?...)',
},
+
+ 'forward_shellcommands' => {
+ 'desc' => 'Run remote commands via SSH, for forwards',
+ 'options' => \%forward_shellcommands_options,
+ 'notes' => 'Run remote commands via SSH, for forwards. You will need to <a href="../docs/ssh.html">setup SSH for unattended operation</a>.<BR><BR>Use these buttons for some useful presets:<UL><LI><INPUT TYPE="button" VALUE="text vpopmail maintenance" onClick=\'this.form.useradd.value = "[ -d /home/vpopmail/domains/$domain/$username ] && { echo \"$destination\" > /home/vpopmail/domains/$domain/$username/.qmail; chown vpopmail:vchkpw /home/vpopmail/domains/$domain/$username/.qmail; }"; this.form.userdel.value = "rm /home/vpopmail/domains/$domain/$username/.qmail"; this.form.usermod.value = "mv /home/vpopmail/domains/$old_domain/$old_username/.qmail /home/vpopmail/domains/$new_domain/$new_username; [ \"$old_destination\" != \"$new_destination\" ] && { echo \"$new_destination\" > /home/vpopmail/domains/$new_domain/$new_username/.qmail; chown vpopmail:vchkpw /home/vpopmail/domains/$new_domain/$new_username/.qmail; }";\'></UL>The following variables are available for interpolation (prefixed with <code>new_</code> or <code>old_</code> for replace operations): <UL><LI><code>$username</code><LI><code>$domain</code><LI><code>$destination</code> - forward destination<LI>All other fields in <a href="../docs/schema.html#svc_forward">svc_forward</a> are also available.</UL>',
+ },
},
'svc_www' => {
'www_shellcommands' => {
'desc' => 'Run remote commands via SSH, for virtual web sites.',
'options' => \%www_shellcommands_options,
- 'notes' => 'Run remote commands via SSH, for virtual web sites. You will need to <a href="../docs/ssh.html">setup SSH for unattended operation</a>.',
+ 'notes' => 'Run remote commands via SSH, for virtual web sites. You will need to <a href="../docs/ssh.html">setup SSH for unattended operation</a>.<BR><BR>The following variables are available for interpolation (prefixed with <code>new_</code> or <code>old_</code> for replace operations): <UL><LI><code>$zone</code><LI><code>$username</code><LI><code>$homedir</code><LI>All other fields in <a href="../docs/schema.html#svc_www">svc_www</a> are also available.</UL>',
},
'apache' => {
no strict 'refs';
${$_} = $svc_domain->getfield($_) foreach $svc_domain->fields;
}
+ ( $qdomain = $domain ) =~ s/\./:/g; #see dot-qmail(5): EXTENSION ADDRESSES
-# my $domain_record = $svc_www->domain_record; # or die ?
-# my $zone = $domain_record->reczone; # or die ?
-# unless ( $zone =~ /\.$/ ) {
-# my $svc_domain = $domain_record->svc_domain; # or die ?
-# $zone .= '.'. $svc_domain->domain;
-# }
-
-# my $svc_acct = $svc_www->svc_acct; # or die ?
-# my $username = $svc_acct->username;
-# my $homedir = $svc_acct->dir; # or die ?
+ if ( $svc_domain->catchall ) {
+ no strict 'refs';
+ my $svc_acct = $svc_domain->catchall_svc_acct;
+ ${$_} = $svc_acct->getfield($_) foreach qw(uid gid dir);
+ } else {
+ ${$_} = '' foreach qw(uid gid dir);
+ }
#done setting variables for the command
${"old_$_"} = $old->getfield($_) foreach $old->fields;
${"new_$_"} = $new->getfield($_) foreach $new->fields;
}
-# my $old_domain_record = $old->domain_record; # or die ?
-# my $old_zone = $old_domain_record->reczone; # or die ?
-# unless ( $old_zone =~ /\.$/ ) {
-# my $old_svc_domain = $old_domain_record->svc_domain; # or die ?
-# $old_zone .= '.'. $old_svc_domain->domain;
-# }
-#
-# my $old_svc_acct = $old->svc_acct; # or die ?
-# my $old_username = $old_svc_acct->username;
-# my $old_homedir = $old_svc_acct->dir; # or die ?
-#
-# my $new_domain_record = $new->domain_record; # or die ?
-# my $new_zone = $new_domain_record->reczone; # or die ?
-# unless ( $new_zone =~ /\.$/ ) {
-# my $new_svc_domain = $new_domain_record->svc_domain; # or die ?
-# $new_zone .= '.'. $new_svc_domain->domain;
-# }
-
-# my $new_svc_acct = $new->svc_acct; # or die ?
-# my $new_username = $new_svc_acct->username;
-# my $new_homedir = $new_svc_acct->dir; # or die ?
+ ( $old_qdomain = $old_domain ) =~ s/\./:/g; #see dot-qmail(5): EXTENSION ADDRESSES
+ ( $new_qdomain = $new_domain ) =~ s/\./:/g; #see dot-qmail(5): EXTENSION ADDRESSES
+
+ if ( $old->catchall ) {
+ no strict 'refs';
+ my $svc_acct = $old->catchall_svc_acct;
+ ${"old_$_"} = $svc_acct->getfield($_) foreach qw(uid gid dir);
+ } else {
+ ${"old_$_"} = '' foreach qw(uid gid dir);
+ }
+ if ( $new->catchall ) {
+ no strict 'refs';
+ my $svc_acct = $new->catchall_svc_acct;
+ ${"new_$_"} = $svc_acct->getfield($_) foreach qw(uid gid dir);
+ } else {
+ ${"new_$_"} = '' foreach qw(uid gid dir);
+ }
#done setting variables for the command
--- /dev/null
+package FS::part_export::forward_shellcommands;
+
+use strict;
+use vars qw(@ISA);
+use FS::part_export;
+
+@ISA = qw(FS::part_export);
+
+sub rebless { shift; }
+
+sub _export_insert {
+ my($self) = shift;
+ $self->_export_command('useradd', @_);
+}
+
+sub _export_delete {
+ my($self) = shift;
+ $self->_export_command('userdel', @_);
+}
+
+sub _export_command {
+ my ( $self, $action, $svc_forward ) = (shift, shift, shift);
+ my $command = $self->option($action);
+
+ #set variable for the command
+ no strict 'vars';
+ {
+ no strict 'refs';
+ ${$_} = $svc_forward->getfield($_) foreach $svc_forward->fields;
+ }
+
+ my $svc_acct = qsearchs( 'svc_acct', { 'svcnum' => $self->srcsvc } );
+ $username = $svc_acct->username;
+ $domain = $svc_acct->domain;
+ if ($self->dstsvc) {
+ $destination = $self->dstsvc_acct->email;
+ } else {
+ $destination = $self->dst;
+ }
+
+ #done setting variables for the command
+
+ $self->shellcommands_queue( $svc_forward->svcnum,
+ user => $self->option('user')||'root',
+ host => $self->machine,
+ command => eval(qq("$command")),
+ );
+}
+
+sub _export_replace {
+ my( $self, $new, $old ) = (shift, shift, shift);
+ my $command = $self->option('usermod');
+
+ #set variable for the command
+ no strict 'vars';
+ {
+ no strict 'refs';
+ ${"old_$_"} = $old->getfield($_) foreach $old->fields;
+ ${"new_$_"} = $new->getfield($_) foreach $new->fields;
+ }
+
+ my $old_svc_acct = qsearchs( 'svc_acct', { 'svcnum' => $self->srcsvc } );
+ $old_username = $old_svc_acct->username;
+ $old_domain = $old_svc_acct->domain;
+ if ($self->dstsvc) {
+ $old_destination = $self->dstsvc_acct->email;
+ } else {
+ $old_destination = $self->dst;
+ }
+
+ my $new_svc_acct = qsearchs( 'svc_acct', { 'svcnum' => $self->srcsvc } );
+ $new_username = $new_svc_acct->username;
+ $new_domain = $new_svc_acct->domain;
+ if ($self->dstsvc) {
+ $new_destination = $self->dstsvc_acct->email;
+ } else {
+ $new_destination = $self->dst;
+ }
+
+ #done setting variables for the command
+
+ $self->shellcommands_queue( $new->svcnum,
+ user => $self->option('user')||'root',
+ host => $self->machine,
+ command => eval(qq("$command")),
+ );
+}
+
+#a good idea to queue anything that could fail or take any time
+sub shellcommands_queue {
+ my( $self, $svcnum ) = (shift, shift);
+ my $queue = new FS::queue {
+ 'svcnum' => $svcnum,
+ 'job' => "FS::part_export::forward_shellcommands::ssh_cmd",
+ };
+ $queue->insert( @_ );
+}
+
+sub ssh_cmd { #subroutine, not method
+ use Net::SSH '0.07';
+ &Net::SSH::ssh_cmd( { @_ } );
+}
+
+#sub shellcommands_insert { #subroutine, not method
+#}
+#sub shellcommands_replace { #subroutine, not method
+#}
+#sub shellcommands_delete { #subroutine, not method
+#}
+
use strict;
use vars qw( @ISA $whois_hack $conf $smtpmachine
@defaultrecords $soadefaultttl $soaemail $soaexpire $soamachine
- $soarefresh $soaretry $qshellmachine $nossh_hack
+ $soarefresh $soaretry
);
use Carp;
use Mail::Internet 1.44;
use Mail::Header;
use Date::Format;
use Net::Whois 1.0;
-use Net::SSH;
use FS::Record qw(fields qsearch qsearchs dbh);
use FS::Conf;
use FS::svc_Common;
$soarefresh = $conf->config('soarefresh');
$soaretry = $conf->config('soaretry');
- $qshellmachine = $conf->exists('qmailmachines')
- ? $conf->config('shellmachine')
- : '';
};
=head1 NAME
appropriate records are added to the domain_record table (see
L<FS::domain_record>).
-If a machine is defined in the I<shellmachine> configuration value, the
-I<qmailmachines> configuration file exists, and the I<catchall> field points
-to an an account with a home directory (see L<FS::svc_acct>), the command:
-
- [ -e $dir/.qmail-$qdomain-defualt ] || {
- touch $dir/.qmail-$qdomain-default;
- chown $uid:$gid $dir/.qmail-$qdomain-default;
- }
-
-is executed on shellmachine via ssh (see L<dot-qmail/"EXTENSION ADDRESSES">).
-This behaviour can be supressed by setting $FS::svc_domain::nossh_hack true.
-
-a machine is defined
-in the
-
=cut
sub insert {
$dbh->commit or die $dbh->errstr if $oldAutoCommit;
- if ( $qshellmachine && $self->catchall && ! $nossh_hack ) {
-
- my $svc_acct = qsearchs( 'svc_acct', { 'svcnum' => $self->catchall } )
- or warn "WARNING: inserted unknown catchall: ". $self->catchall;
- if ( $svc_acct && $svc_acct->dir ) {
- my $qdomain = $self->domain;
- $qdomain =~ s/\./:/g; #see manpage for 'dot-qmail': EXTENSION ADDRESSES
- my ( $uid, $gid, $dir ) = (
- $svc_acct->uid,
- $svc_acct->gid,
- $svc_acct->dir,
- );
-
- my $queue = new FS::queue {
- 'svcnum' => $self->svcnum,
- 'job' => 'Net::SSH::ssh_cmd',
- };
- $error = $queue->insert("root\@$qshellmachine", "[ -e $dir/.qmail-$qdomain-default ] || { touch $dir/.qmail-$qdomain-default; chown $uid:$gid $dir/.qmail-$qdomain-default; }" );
-
- }
- }
-
''; #no error
}
}
+sub catchall_svc_acct {
+ my $self = shift;
+ if ( $self->catchall ) {
+ qsearchs( 'svc_acct', { 'svcnum' => $self->catchall } );
+ } else {
+ '';
+ }
+}
+
=item whois
Returns the Net::Whois::Domain object (see L<Net::Whois>) for this domain, or
=head1 BUGS
-All BIND/DNS fields should be included (and exported).
-
Delete doesn't send a registration template.
All registries should be supported.
=head1 SEE ALSO
L<FS::svc_Common>, L<FS::Record>, L<FS::Conf>, L<FS::cust_svc>,
-L<FS::part_svc>, L<FS::cust_pkg>, L<Net::Whois>, L<ssh>,
-L<dot-qmail>, schema.html from the base documentation, config.html from the
-base documentation.
+L<FS::part_svc>, L<FS::cust_pkg>, L<Net::Whois>, schema.html from the base
+documentation, config.html from the base documentation.
=cut
package FS::svc_forward;
use strict;
-use vars qw( @ISA $nossh_hack $conf $shellmachine @qmailmachines
- @vpopmailmachines );
-use Net::SSH qw(ssh);
+use vars qw( @ISA );
use FS::Conf;
use FS::Record qw( fields qsearch qsearchs dbh );
use FS::svc_Common;
@ISA = qw( FS::svc_Common );
-#ask FS::UID to run this stuff for us later
-$FS::UID::callback{'FS::svc_forward'} = sub {
- $conf = new FS::Conf;
- if ( $conf->exists('qmailmachines') ) {
- $shellmachine = $conf->config('shellmachine')
- } else {
- $shellmachine = '';
- }
- if ( $conf->exists('vpopmailmachines') ) {
- @vpopmailmachines = $conf->config('vpopmailmachines');
- } else {
- @vpopmailmachines = ();
- }
-};
-
=head1 NAME
FS::svc_forward - Object methods for svc_forward records
The additional fields pkgnum and svcpart (see L<FS::cust_svc>) should be
defined. An FS::cust_svc record will be created and inserted.
-If the configuration value (see L<FS::Conf>) vpopmailmachines exists, then
-the command:
-
- [ -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).
-This behaviour can be supressed by setting $FS::svc_forward::nossh_hack true.
-
=cut
sub insert {
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) {
- $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 {
- '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 {
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;
'';
}
Replaces OLD_RECORD with this one in the database. If there is an error,
returns the error, otherwise returns false.
-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.
-
-Also, if the configuration value vpopmailmachines exists, then the command:
-
- [ -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
-by setting $FS::svc_forward_nossh_hack true.
-
=cut
sub replace {
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 ( $error ) {
- $dbh->rollback if $oldAutoCommit;
- return "queueing job (transaction rolled back): $error";
- }
- }
-
- #false laziness with stuff in insert, should subroutine
- my $svc_acct = qsearchs( 'svc_acct', { 'svcnum' => $new->srcsvc } );
- my $username = $svc_acct->username;
- my $domain = $svc_acct->domain;
- if ($new->dstsvc) {
- $destination = $new->dstsvc_acct->email;
- } else {
- $destination = $new->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","[ -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;
'';
}
=back
-=head1 VERSION
-
-$Id: svc_forward.pm,v 1.12 2002-05-31 17:50:37 ivan Exp $
-
=head1 BUGS
-The remote commands should be configurable.
-
=head1 SEE ALSO
L<FS::Record>, L<FS::Conf>, L<FS::cust_svc>, L<FS::part_svc>, L<FS::cust_pkg>,
-L<FS::svc_acct>, L<FS::svc_domain>, L<Net::SSH>, L<ssh>, L<dot-qmail>,
-schema.html from the base documentation.
+L<FS::svc_acct>, L<FS::svc_domain>, schema.html from the base documentation.
=cut
FS/part_export/cp.pm
FS/part_export/cyrus.pm
FS/part_export/domain_shellcommands.pm
+FS/part_export/forward_shellcommands.pm
FS/part_export/http.pm
FS/part_export/infostreet.pm
FS/part_export/ldap.pm
t/part_export-cp.t
t/part_export-cyrus.t
t/part_export-domain_shellcommands.t
+t/part_export-forward_shellcommands.t
t/part_export-http.t
t/part_export-infostreet.t
t/part_export-ldap.t
--- /dev/null
+BEGIN { $| = 1; print "1..1\n" }
+END {print "not ok 1\n" unless $loaded;}
+use FS::part_export::forward_shellcommands;
+$loaded=1;
+print "ok 1\n";
#TEMPLATE = mason
ASP_GLOBAL = /usr/local/etc/freeside/asp-global
+MASON_HANDLER = /usr/local/etc/freeside/handler.pl
+MASONDATA = /usr/local/etc/freeside/masondata
#deb, others?
FREESIDE_DOCUMENT_ROOT = /var/www/freeside
[ "${TEMPLATE}" = "asp" -a ! -e ${ASP_GLOBAL} ] && mkdir ${ASP_GLOBAL} || true
[ "${TEMPLATE}" = "asp" ] && chown -R freeside ${ASP_GLOBAL} || true
[ "${TEMPLATE}" = "asp" ] && cp htetc/global.asa ${ASP_GLOBAL} || true
+ [ "${TEMPLATE}" = "mason" ] && cp htetc/handler.pl ${MASON_HANDLER} || true
+ [ "${TEMPLATE}" = "mason" -a ! -e ${MASONDATA} ] && mkdir ${MASONDATA} || true
+ [ "${TEMPLATE}" = "mason" ] && chown -R freeside ${MASONDATA} || true
perl-modules:
cd FS; \
# Create Mason objects
#
-my $parser = new HTML::Mason::Parser;
-my $interp = new HTML::Mason::Interp (parser=>$parser,
- comp_root=>'/var/www/masondocs',
- data_dir=>'/home/ivan/freeside_current/masondata',
- out_mode=>'stream',
- );
-my $ah = new HTML::Mason::ApacheHandler ( interp => $interp,
- #auto_send_headers => 0,
- );
+
+#my $parser = new HTML::Mason::Parser;
+#my $interp = new HTML::Mason::Interp (parser=>$parser,
+# comp_root=>'/var/www/masondocs',
+# data_dir=>'/usr/local/etc/freeside/masondata',
+# out_mode=>'stream',
+# );
+my $ah = new HTML::Mason::ApacheHandler (
+ #interp => $interp,
+ #auto_send_headers => 0,
+ comp_root=>'/var/www/masonside',
+ data_dir=>'/usr/local/etc/freeside/masondata',
+ #out_mode=>'stream',
+);
# Activate the following if running httpd as root (the normal case).
# Resets ownership of all files created by Mason at startup.
#
-chown (Apache->server->uid, Apache->server->gid, $interp->files_written);
+#chown (Apache->server->uid, Apache->server->gid, $interp->files_written);
sub handler
{
*CGI::redirect = sub {
my( $self, $location ) = @_;
-
+ use vars qw($m);
#http://www.masonhq.com/docs/faq/#how_do_i_do_an_external_redirect
$m->clear_buffer;
# The next two lines are necessary to stop Apache from re-reading
--- /dev/null
+#!/usr/bin/perl
+#
+# This is a basic, fairly fuctional Mason handler.pl.
+#
+# For something a little more involved, check out session_handler.pl
+
+package HTML::Mason;
+
+# Bring in main Mason package.
+use HTML::Mason;
+
+# Bring in ApacheHandler, necessary for mod_perl integration.
+# Uncomment the second line (and comment the first) to use
+# Apache::Request instead of CGI.pm to parse arguments.
+use HTML::Mason::ApacheHandler;
+# use HTML::Mason::ApacheHandler (args_method=>'mod_perl');
+
+# Uncomment the next line if you plan to use the Mason previewer.
+#use HTML::Mason::Preview;
+
+use strict;
+
+# List of modules that you want to use from components (see Admin
+# manual for details)
+#{ package HTML::Mason::Commands;
+# use CGI;
+#}
+
+# Create Mason objects
+#
+my $parser = new HTML::Mason::Parser;
+my $interp = new HTML::Mason::Interp (parser=>$parser,
+ comp_root=>'/var/www/masondocs',
+ data_dir=>'/home/ivan/freeside_current/masondata',
+ out_mode=>'stream',
+ );
+my $ah = new HTML::Mason::ApacheHandler ( interp => $interp,
+ #auto_send_headers => 0,
+ );
+
+# Activate the following if running httpd as root (the normal case).
+# Resets ownership of all files created by Mason at startup.
+#
+chown (Apache->server->uid, Apache->server->gid, $interp->files_written);
+
+sub handler
+{
+ my ($r) = @_;
+
+ # If you plan to intermix images in the same directory as
+ # components, activate the following to prevent Mason from
+ # evaluating image files as components.
+ #
+ #return -1 if $r->content_type && $r->content_type !~ m|^text/|i;
+
+ #rar
+ { package HTML::Mason::Commands;
+ use strict;
+ use vars qw( $cgi $p );
+ use CGI;
+ #use CGI::Carp qw(fatalsToBrowser);
+ use Date::Format;
+ use Date::Parse;
+ use Time::Local;
+ use Tie::IxHash;
+ use HTML::Entities;
+ use IO::Handle;
+ use IO::File;
+ use String::Approx qw(amatch);
+ use Chart::LinesPoints;
+ use HTML::Widgets::SelectLayers 0.02;
+ use FS::UID qw(cgisuidsetup dbh getotaker datasrc driver_name);
+ use FS::Record qw(qsearch qsearchs fields dbdef);
+ use FS::Conf;
+ use FS::CGI qw(header menubar popurl table itable ntable idiot eidiot
+ small_custview myexit http_header);
+ use FS::Msgcat qw(gettext geterror);
+
+ use FS::agent;
+ use FS::agent_type;
+ use FS::domain_record;
+ use FS::cust_bill;
+ use FS::cust_bill_pay;
+ use FS::cust_credit;
+ use FS::cust_credit_bill;
+ use FS::cust_main;
+ use FS::cust_main_county;
+ use FS::cust_pay;
+ use FS::cust_pkg;
+ use FS::cust_refund;
+ use FS::cust_svc;
+ use FS::nas;
+ use FS::part_bill_event;
+ use FS::part_pkg;
+ use FS::part_referral;
+ use FS::part_svc;
+ use FS::part_svc_router;
+ use FS::pkg_svc;
+ use FS::port;
+ use FS::queue qw(joblisting);
+ use FS::raddb;
+ use FS::session;
+ use FS::svc_acct;
+ use FS::svc_acct_pop qw(popselector);
+ use FS::svc_acct_sm;
+ use FS::svc_domain;
+ use FS::svc_forward;
+ use FS::svc_www;
+ use FS::router;
+ use FS::part_router_field;
+ use FS::router_field;
+ use FS::addr_block;
+ use FS::part_sb_field;
+ use FS::sb_field;
+ use FS::svc_broadband;
+ use FS::type_pkgs;
+ use FS::part_export;
+ use FS::part_export_option;
+ use FS::export_svc;
+ use FS::msgcat;
+
+ *CGI::redirect = sub {
+ my( $self, $location ) = @_;
+
+ #http://www.masonhq.com/docs/faq/#how_do_i_do_an_external_redirect
+ $m->clear_buffer;
+ # The next two lines are necessary to stop Apache from re-reading
+ # POSTed data.
+ $r->method('GET');
+ $r->headers_in->unset('Content-length');
+ $r->content_type('text/html');
+ #$r->err_header_out('Location' => $location);
+ $r->header_out('Location' => $location);
+ $r->header_out('Content-Type' => 'text/html');
+ $m->abort(302);
+
+ '';
+ };
+
+ $cgi = new CGI;
+ &cgisuidsetup($cgi);
+ #&cgisuidsetup($r);
+ $p = popurl(2);
+ }
+
+ $r->content_type('text/html');
+ #eorar
+
+ my $headers = $r->headers_out;
+ $headers->{'Pragma'} = $headers->{'Cache-control'} = 'no-cache';
+ #$r->no_cache(1);
+ $headers->{'Expires'} = '0';
+
+# $r->send_http_header;
+
+ my $status = $ah->handle_request($r);
+
+ $status;
+}
+
+1;
<% my $conf = new FS::Conf; my @config_items = $conf->config_items; %>
<% foreach my $section ( qw(required billing username password UI session
- shell mail apache BIND
+ shell BIND
),
'', 'deprecated') { %>
<A NAME="<%= $section || 'unclassified' %>"></A>
<FONT SIZE="-2">
<% foreach my $nav_section ( qw(required billing username password UI session
- shell mail apache BIND
+ shell BIND
),
'', 'deprecated') { %>
<% if ( $section eq $nav_section ) { %>
<form name="OneTrueForm" action="config-process.cgi" METHOD="POST" onSubmit="SafeOnsubmit()">
<% foreach my $section ( qw(required billing username password UI session
- shell mail apache BIND
+ shell BIND
),
'', 'deprecated') { %>
<A NAME="<%= $section || 'unclassified' %>"></A>
<FONT SIZE="-2">
<% foreach my $nav_section ( qw(required billing username password UI session
- shell mail apache BIND
+ shell BIND
),
'', 'deprecated') { %>
<% if ( $section eq $nav_section ) { %>
<li>A <b>transactional</b> database engine <a href="http://search.cpan.org/search?mode=module&query=DBD%3A%3A">supported</a> by Perl's <a href="http://dbi.perl.org">DBI</a>.
<ul>
<li><a href="http://www.postgresql.org/">PostgreSQL</a> is recommended (v7or later).
- <li>MySQL versions before 4.1 do not support standard SQL subqueries and are <b>NOT SUPPORTED</b>. If you are a developer who wishes to contribute MySQL 3.x/4.0 support, see <a href="http://pouncequick.420.am/rt/Ticket/Display.html?id=438">ticket #438</a> in the bug-tracking system and ask on the -devel mailing list.
-<!-- <li>MySQL has been reported to work.
- <b>MySQL's default <a href="http://www.mysql.com/doc/M/y/MyISAM.html">MyISAM</a> and <a href="http://www.mysql.com/doc/I/S/ISAM.html">ISAM</a> table types are not supported</b>. If you want to use MySQL, you <b>must</b> use one of the new <a href="http://www.mysql.com/doc/T/a/Table_types.html">transaction-safe table types</a> such as <a href="http://www.mysql.com/doc/B/D/BDB.html">BDB</a> or <a href="http://www.mysql.com/doc/I/n/InnoDB.html">InnoDB</a>, and set it as the default table type using the <code>--default-table-type=BDB</code> or <code>--default-table-type=InnoDB</code> <a href="http://www.mysql.com/documentation/mysql/bychapter/manual_MySQL_Database_Administration.html#Command-line_options">mysqld command-line option</a> or by setting <code>default-table-type=BDB</code> or <code>default-table-type=InnoDB</code> in the <a href="http://www.mysql.com/documentation/mysql/bychapter/manual_MySQL_Database_Administration.html#Option_files">my.cnf option file</a>. -->
+ <li><a href="http://www.mysql.com/">MySQL</a> <b>MINIMUM VERSION 4.1</b> is untested but may work. Versions before 4.1 do not support standard SQL subqueries and are <b>NOT SUPPORTED</b>. If you are a developer who wishes to contribute MySQL 3.x/4.0 support, see <a href="http://pouncequick.420.am/rt/Ticket/Display.html?id=438">ticket #438</a> in the bug-tracking system and ask on the -devel mailing list.
+<!-- <li>MySQL has been reported to work. -->
+ <b>MySQL's default <a href="http://www.mysql.com/doc/M/y/MyISAM.html">MyISAM</a> and <a href="http://www.mysql.com/doc/I/S/ISAM.html">ISAM</a> table types are not supported</b>. If you want to use MySQL, you <b>must</b> use one of the new <a href="http://www.mysql.com/doc/T/a/Table_types.html">transaction-safe table types</a> such as <a href="http://www.mysql.com/doc/B/D/BDB.html">BDB</a> or <a href="http://www.mysql.com/doc/I/n/InnoDB.html">InnoDB</a>, and set it as the default table type using the <code>--default-table-type=BDB</code> or <code>--default-table-type=InnoDB</code> <a href="http://www.mysql.com/documentation/mysql/bychapter/manual_MySQL_Database_Administration.html#Command-line_options">mysqld command-line option</a> or by setting <code>default-table-type=BDB</code> or <code>default-table-type=InnoDB</code> in the <a href="http://www.mysql.com/documentation/mysql/bychapter/manual_MySQL_Database_Administration.html#Option_files">my.cnf option file</a>.
</ul>
<li>Perl modules (<a href="http://theoryx5.uwinnipeg.ca/CPAN/perl/CPAN.html">CPAN</a> will query, download and build perl modules automatically)
<ul>
<li><a href="http://search.cpan.org/search?dist=String-Approx">String-Approx</a>
<li><a href="http://search.cpan.org/search?dist=Text-Template">Text-Template</a>
<li><a href="http://search.cpan.org/search?dist=DBI">DBI</a>
- <li><a href="http://search.cpan.org/search?mode=module&query=DBD">DBD for your database engine</a> (<a href="http://search.cpan.org/search?dist=DBD-Pg">DBD::Pg</a> for PostgreSQL<!--, <a href="http://search.cpan.org/search?dist=DBD-mysql">DBD::mysql</a> for MySQL-->)
+ <li><a href="http://search.cpan.org/search?mode=module&query=DBD">DBD for your database engine</a> (<a href="http://search.cpan.org/search?dist=DBD-Pg">DBD::Pg</a> for PostgreSQL, <a href="http://search.cpan.org/search?dist=DBD-mysql">DBD::mysql</a> for MySQL)
<li><a href="http://search.cpan.org/search?dist=DBIx-DataSource">DBIx-DataSource</a>
<li><a href="http://search.cpan.org/search?dist=DBIx-DBSchema">DBIx-DBSchema</a>
<li><a href="http://search.cpan.org/search?dist=Net-SSH">Net-SSH</a>
<li><a href="http://search.cpan.org/search?dist=String-ShellQuote">String-ShellQuote</a>
<li><a href="http://search.cpan.org/search?dist=Net-SCP">Net-SCP</a>
- <li><a href="http://www.apache-asp.org/">Apache::ASP</a> or <a href="http://www.masonhq.com/">HTML::Mason</a> (use version 1.0x - Freeside is not yet compatible with version 1.1x)
+ <li><a href="http://www.apache-asp.org/">Apache::ASP</a> or <a href="http://www.masonhq.com/">HTML::Mason</a>
<li><a href="http://search.cpan.org/search?dist=Tie-IxHash">Tie-IxHash</a>
<li><a href="http://search.cpan.org/search?dist=Time-Duration">Time-Duration</a>
<li><a href="http://search.cpan.org/search?dist=HTML-Widgets-SelectLayers">HTML-Widgets-SelectLayers</a>
Shall the new user be allowed to create databases? (y/n) y
Shall the new user be allowed to create more new users? (y/n) n
CREATE USER</pre>
-<!-- <li> with <a href="http://www.mysql.com/documentation/mysql/bychapter/manual_MySQL_Database_Administration.html#User_Account_Management">MySQL</a>:
+ <li> with <a href="http://www.mysql.com/documentation/mysql/bychapter/manual_MySQL_Database_Administration.html#User_Account_Management">MySQL</a>:
<pre>
$ mysqladmin -u root password '<i>set_a_root_database_password</i>'
$ mysql -u root -p
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,INDEX,ALTER,CREATE,DROP on freeside.* TO freeside@localhost IDENTIFIED BY '<i>set_a_freeside_database_password</i>';</pre>
--->
</ul>
<!-- <li>Unpack the tarball: <pre>gunzip -c fs-x.y.z.tar.gz | tar xvf -</pre>-->
<li>Edit the top-level Makefile:
<ul>
- <li>Set <tt>DATASOURCE</tt> to your <a href="http://search.cpan.org/doc/TIMB/DBI-1.28/DBI.pm">DBI data source</a>, for example, <tt>DBI:Pg:dbname=freeside</tt> for PostgresSQL<!-- or <tt>DBI:mysql:freeside</tt> for MySQL-->. See the <a href="http://search.cpan.org/doc/TIMB/DBI-1.28/DBI.pm">DBI manpage</a> and the <a href="http://search.cpan.org/search?mode=module&query=DBD%3A%3A">manpage for your DBD</a> for the exact syntax of your DBI data source.
+ <li>Set <tt>DATASOURCE</tt> to your <a href="http://search.cpan.org/doc/TIMB/DBI-1.28/DBI.pm">DBI data source</a>, for example, <tt>DBI:Pg:dbname=freeside</tt> for PostgresSQL or <tt>DBI:mysql:freeside</tt> for MySQL. See the <a href="http://search.cpan.org/doc/TIMB/DBI-1.28/DBI.pm">DBI manpage</a> and the <a href="http://search.cpan.org/search?mode=module&query=DBD%3A%3A">manpage for your DBD</a> for the exact syntax of your DBI data source.
<li>Set <tt>DB_PASSWORD</tt> to the freeside database user's password.
</ul>
<li>Add the freeside database to your database engine:
<pre>
$ su freeside
$ createdb freeside</pre>
-<!-- (with MySQL:)
+ (with MySQL:)
<pre>
$ mysqladmin -u freeside -p create freeside </pre>
--->
<li>Build and install the Perl modules:
<pre>
$ make perl-modules
</pre></font>
</ul></td>
<td><ul>
- <li>(use version 1.0x - Freeside is not yet compatible with version 1.1x)
<li>Run <tt>make masondocs</tt>
<li>Copy <tt>masondocs/</tt> to your web server's document space.
- <li>Copy <tt>htetc/handler.pl</tt> to your web server's configuration directory.
- <li>Edit <tt>handler.pl</tt> and set an appropriate <tt>data_dir</tt>, such as <tt>/usr/local/etc/freeside/mason-data</tt>
+ <li>Copy <tt>htetc/handler.pl</tt> to an appropriate directory (use htetc/handler.pl-1.0x for Mason versions before 1.10).
+ <li>Edit <tt>handler.pl</tt> and set an appropriate <tt>data_dir</tt>, such as <tt>/usr/local/etc/freeside/masondata</tt>
<li>Configure Apache to use the <tt>handler.pl</tt> file and to execute .cgi files using HTML::Mason. For example:
<font size="-1"><pre>
PerlModule HTML::Mason
PerlHandler HTML::Mason
</Files>
<Perl>
-require "/usr/local/apache/conf/handler.pl";
+require "/usr/local/etc/freeside/handler.pl";
</Perl>
</Directory>
</pre></font>
foreach my $select_option ( @{$optinfo->{options}} ) {
#if ( ref($select_option) ) {
#} else {
- $selected = $select_option eq $value ? ' SELECTED' : '';
+ my $selected = $select_option eq $value ? ' SELECTED' : '';
$html .= qq!<OPTION VALUE="$select_option"$selected>!.
qq!$select_option</OPTION>!;
#}
my $action = $part_router_field->routerfieldpart ? 'Edit' : 'Add';
my $p1 = popurl(1);
-print header("$action Router Extended Field Definition", '');
+print header("$action Router Extended Field Definition",
+ menubar('Main Menu' => $p,
+ 'View all Extended Fields' => $p. 'browse/generic.cgi?part_router_field')
+ );
print qq!<FONT SIZE="+1" COLOR="#ff0000">Error: !, $cgi->param('error'),
"</FONT>"
<FORM ACTION="<%=$p1%>process/generic.cgi" METHOD=POST>
<INPUT TYPE="hidden" NAME="table" VALUE="part_router_field">
-<INPUT TYPE="hidden" NAME="redirect_ok"
- VALUE="<%=$p1%>part_router_field.cgi">
<INPUT TYPE="hidden" NAME="routerfieldpart" VALUE="<%=
$routerfieldpart%>">
Field #<B><%=$routerfieldpart or "(NEW)"%></B><BR><BR>
my $error;
my $p2 = popurl(2);
+my $p3 = popurl(3);
my $table = $cgi->param('table');
my $dbdef = dbdef or die "Cannot fetch dbdef!";
}
my $redirect_ok = (($cgi->param('redirect_ok')) ?
- $cgi->param('redirect_ok') : $p2."view/$table.cgi");
+ $cgi->param('redirect_ok') : $p3."browse/generic.cgi?$table");
my $redirect_error = (($cgi->param('redirect_error')) ?
$cgi->param('redirect_error') : $cgi->referer());
$cgi->param('error', $error);
print $cgi->redirect($redirect_error . '?' . $cgi->query_string);
} else {
- print $cgi->redirect($redirect_ok . '?' .$pkey_val);
+ print $cgi->redirect($redirect_ok);
}
%>
} #else do nothing
} else {
$error = $new->insert;
+ $routernum = $new->routernum;
}
check($error);
# Yay, everything worked!
$dbh->commit or die $dbh->errstr;
-print $cgi->redirect(popurl(3). "edit/router.cgi?$routernum");
+print $cgi->redirect(popurl(3). "browse/router.cgi");
%>
Router #<%=$routernum or "(NEW)"%>
<BR><BR>Name <INPUT TYPE="text" NAME="routername" SIZE=32 VALUE="<%=$hashref->{routername}%>">
+
+<BR><BR>
+Custom fields:
+<BR>
<%=table() %>
<%
$card =~ /^(\d{13,16})$/ or eidiot "Illegal card number\n";
my($payinfo)=$1;
- [ qsearch('cust_main',{'payinfo'=>$payinfo, 'payby'=>'CARD'})
+ [ qsearch('cust_main',{'payinfo'=>$payinfo, 'payby'=>'CARD'}),
qsearch('cust_main',{'payinfo'=>$payinfo, 'payby'=>'DCRD'})
];
}
-<-- mason kludge -->
+<!-- mason kludge -->
<%
my $conf = new FS::Conf;