1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
|
#!/usr/bin/perl -Tw
#
# $Id: fs-migrate-svc_acct_sm,v 1.4 2002-06-21 09:13:16 ivan Exp $
#
# jeff@cmh.net 01-Jul-20
#to delay loading dbdef until we're ready
#BEGIN { $FS::Record::setup_hack = 1; }
use strict;
use Term::Query qw(query);
#use DBI;
#use DBIx::DBSchema;
#use DBIx::DBSchema::Table;
#use DBIx::DBSchema::Column;
#use DBIx::DBSchema::ColGroup::Unique;
#use DBIx::DBSchema::ColGroup::Index;
use FS::Conf;
use FS::UID qw(adminsuidsetup datasrc checkeuid getsecrets);
use FS::Record qw(qsearch qsearchs);
use FS::svc_domain;
use FS::svc_forward;
use vars qw( $conf $old_default_domain %part_domain_svc %part_acct_svc %part_forward_svc $svc_acct $svc_acct_sm $error);
die "Not running uid freeside!" unless checkeuid();
my $user = shift or die &usage;
getsecrets($user);
$conf = new FS::Conf;
$old_default_domain = $conf->config('domain');
#needs to match FS::Record
#my($dbdef_file) = "/usr/local/etc/freeside/dbdef.". datasrc;
###
# This section would be the appropriate place to manipulate
# the schema & tables.
###
## we need to add the domsvc to svc_acct
## we must add a svc_forward record....
## I am thinking that the fields svcnum (int), destsvc (int), and
## dest (varchar (80)) are appropriate, with destsvc/dest an either/or
## much in the spirit of cust_main_invoice
###
# massage the data
###
my($dbh)=adminsuidsetup $user;
$|=1;
$FS::svc_Common::noexport_hack = 1;
$FS::svc_domain::whois_hack = 1;
%part_domain_svc=map { $_->svcpart, $_ } qsearch('part_svc',{'svcdb'=>'svc_domain'});
%part_acct_svc=map { $_->svcpart, $_ } qsearch('part_svc',{'svcdb'=>'svc_acct'});
%part_forward_svc=map { $_->svcpart, $_ } qsearch('part_svc',{'svcdb'=>'svc_forward'});
die "No services with svcdb svc_domain!\n" unless %part_domain_svc;
die "No services with svcdb svc_acct!\n" unless %part_acct_svc;
die "No services with svcdb svc_forward!\n" unless %part_forward_svc;
my($svc_domain) = qsearchs('svc_domain', { 'domain' => $old_default_domain });
if (! $svc_domain || $svc_domain->domain != $old_default_domain) {
print <<EOF;
Your database currently does not contain a svc_domain record for the
domain $old_default_domain. Would you like me to add one for you?
EOF
my($response)=scalar(<STDIN>);
chop $response;
if ($response =~ /^[yY]/) {
print "\n\n", &menu_domain_svc, "\n", <<END;
I need to create new domain accounts. Which service shall I use for that?
END
my($domain_svcpart)=&getdomainpart;
$svc_domain = new FS::svc_domain {
'domain' => $old_default_domain,
'svcpart' => $domain_svcpart,
'action' => 'M',
};
# $error=$svc_domain->insert && die "Error adding domain $old_default_domain: $error";
$error=$svc_domain->insert;
die "Error adding domain $old_default_domain: $error" if $error;
}else{
print <<EOF;
This program cannot function properly until a svc_domain record matching
your conf_dir/domain file exists.
EOF
exit 1;
}
}
print "\n\n", &menu_acct_svc, "\n", <<END;
I may need to create some new pop accounts and set up forwarding to them
for some users. Which service shall I use for that?
END
my($pop_svcpart)=&getacctpart;
print "\n\n", &menu_forward_svc, "\n", <<END;
I may need to create some new forwarding for some users. Which service
shall I use for that?
END
my($forward_svcpart)=&getforwardpart;
sub menu_domain_svc {
( join "\n", map "$_: ".$part_domain_svc{$_}->svc, sort keys %part_domain_svc ). "\n";
}
sub menu_acct_svc {
( join "\n", map "$_: ".$part_acct_svc{$_}->svc, sort keys %part_acct_svc ). "\n";
}
sub menu_forward_svc {
( join "\n", map "$_: ".$part_forward_svc{$_}->svc, sort keys %part_forward_svc ). "\n";
}
sub getdomainpart {
$^W=0; # Term::Query isn't -w-safe
my $return = query "Enter part number:", 'irk', [ keys %part_domain_svc ];
$^W=1;
$return;
}
sub getacctpart {
$^W=0; # Term::Query isn't -w-safe
my $return = query "Enter part number:", 'irk', [ keys %part_acct_svc ];
$^W=1;
$return;
}
sub getforwardpart {
$^W=0; # Term::Query isn't -w-safe
my $return = query "Enter part number:", 'irk', [ keys %part_forward_svc ];
$^W=1;
$return;
}
#migrate data
my(@svc_accts) = qsearch('svc_acct', {});
foreach $svc_acct (@svc_accts) {
my(@svc_acct_sms) = qsearch('svc_acct_sm', {
domuid => $svc_acct->getfield('uid'),
}
);
# Ok.. we've got the svc_acct record, and an array of svc_acct_sm's
# What do we do from here?
# The intuitive:
# plop the svc_acct into the 'default domain'
# and then represent the svc_acct_sm's with svc_forwards
# they can be gussied up manually, later
#
# Perhaps better:
# when no svc_acct_sm exists, place svc_acct in 'default domain'
# when one svc_acct_sm exists, place svc_acct in corresponding
# domain & possibly create a svc_forward in 'default domain'
# when multiple svc_acct_sm's exists (in different domains) we'd
# better use the 'intuitive' approach.
#
# Specific way:
# as 'perhaps better,' but we may be able to guess which domain
# is correct by comparing the svcnum of domains to the username
# of the svc_acct
#
# The intuitive way:
my $def_acct = new FS::svc_acct ( { $svc_acct->hash } );
$def_acct->setfield('domsvc' => $svc_domain->getfield('svcnum'));
$error = $def_acct->replace($svc_acct);
die "Error replacing svc_acct for " . $def_acct->username . " : $error" if $error;
foreach $svc_acct_sm (@svc_acct_sms) {
my($domrec)=qsearchs('svc_domain', {
svcnum => $svc_acct_sm->getfield('domsvc'),
}) || die "svc_acct_sm references invalid domsvc $svc_acct_sm->getfield('domsvc')\n";
if ($svc_acct_sm->getfield('domuser') =~ /^\*$/) {
my($newdom) = new FS::svc_domain ( { $domrec->hash } );
$newdom->setfield('catchall', $svc_acct->svcnum);
$newdom->setfield('action', "M");
$error = $newdom->replace($domrec);
die "Error replacing svc_domain for (anything)@" . $domrec->domain . " : $error" if $error;
} else {
my($newacct) = new FS::svc_acct {
'svcpart' => $pop_svcpart,
'username' => $svc_acct_sm->getfield('domuser'),
'domsvc' => $svc_acct_sm->getfield('domsvc'),
'dir' => '/dev/null',
};
$error = $newacct->insert;
die "Error adding svc_acct for " . $newacct->username . " : $error" if $error;
my($newforward) = new FS::svc_forward {
'svcpart' => $forward_svcpart,
'srcsvc' => $newacct->getfield('svcnum'),
'dstsvc' => $def_acct->getfield('svcnum'),
};
$error = $newforward->insert;
die "Error adding svc_forward for " . $newacct->username ." : $error" if $error;
}
$error = $svc_acct_sm->delete;
die "Error deleting svc_acct_sm for " . $svc_acct_sm->domuser ." : $error" if $error;
};
};
$dbh->commit or die $dbh->errstr;
$dbh->disconnect or die $dbh->errstr;
print "svc_acct_sm records sucessfully migrated\n";
sub usage {
die "Usage:\n fs-migrate-svc_acct_sm user\n";
}
|