2 # Build a Debian package of Webmin
6 if ($ARGV[0] eq "--webmail" || $ARGV[0] eq "-webmail") {
10 if ($0 =~ /useradmin|usermin/ || `pwd` =~ /useradmin|usermin/) {
12 $product = "usermin-webmail";
17 $baseproduct = "usermin";
22 $baseproduct = "webmin";
25 $ucproduct = ucfirst($baseproduct);
26 $tmp_dir = "/tmp/debian";
27 $debian_dir = "$tmp_dir/DEBIAN";
28 $control_file = "$debian_dir/control";
29 $usr_dir = "$tmp_dir/usr/share/$baseproduct";
30 $pam_dir = "$tmp_dir/etc/pam.d";
31 $init_dir = "$tmp_dir/etc/init.d";
32 @rc_dirs = ( "$tmp_dir/etc/rc2.d", "$tmp_dir/etc/rc3.d", "$tmp_dir/etc/rc5.d" );
33 $pam_file = "$pam_dir/$baseproduct";
34 $preinstall_file = "$debian_dir/preinst";
35 $postinstall_file = "$debian_dir/postinst";
36 $preuninstall_file = "$debian_dir/prerm";
37 $postuninstall_file = "$debian_dir/postrm";
38 $copyright_file = "$debian_dir/copyright";
39 $changelog_file = "$debian_dir/changelog";
40 $conffiles_file = "$debian_dir/conffiles";
42 -d "tarballs" || die "makedebian.pl must be run in the $ucproduct root directory";
43 -r "/etc/debian_version" || die "makedebian.pl must be run on Debian";
44 chop($webmin_dir = `pwd`);
46 @ARGV == 1 || @ARGV == 2 ||
47 die "usage: makedebian.pl [--webmail] <version> [release]";
52 -r "tarballs/$product-$ver.tar.gz" || die "tarballs/$product-$ver.tar.gz not found";
54 # Create the base directories
55 print "Creating Debian package of ",ucfirst($product)," ",$ver,$rel," ...\n";
56 system("rm -rf $tmp_dir");
57 mkdir($tmp_dir, 0755);
58 chmod(0755, $tmp_dir);
59 mkdir($debian_dir, 0755);
60 system("mkdir -p $pam_dir");
61 system("mkdir -p $init_dir");
62 foreach $d (@rc_dirs) {
63 system("mkdir -p $d");
65 system("mkdir -p $usr_dir");
67 # Un-tar the package to the correct locations
68 system("gunzip -c tarballs/$product-$ver.tar.gz | (cd $tmp_dir ; tar xf -)") &&
70 system("mv $tmp_dir/$product-$ver/* $usr_dir");
71 rmdir("$tmp_dir/$product-$ver");
72 system("mv $usr_dir/$baseproduct-debian-pam $pam_file");
73 system("cd $usr_dir && (find . -name '*.cgi' ; find . -name '*.pl') | perl perlpath.pl /usr/bin/perl -");
74 system("cd $usr_dir && rm -f mount/freebsd-mounts*");
75 system("cd $usr_dir && rm -f mount/openbsd-mounts*");
76 if ($product eq "webmin") {
77 system("cd $usr_dir && rm -f mount/macos-mounts*");
78 system("cd $usr_dir && rm -f webmin-gentoo-init");
79 system("cd $usr_dir && rm -rf format bsdexports hpuxexports sgiexports zones rbac");
80 system("cd $usr_dir && rm -rf acl/Authen-SolarisRBAC-0.1*");
84 system("mv $usr_dir/$baseproduct-init $init_dir/$baseproduct");
85 foreach $d (@rc_dirs) {
86 system("ln -s ../init.d/$baseproduct $d/S99$baseproduct");
88 system("echo deb >$usr_dir/install-type");
89 system("echo $product >$usr_dir/deb-name");
90 system("cd $usr_dir && chmod -R og-w .");
92 system("cd $usr_dir && chown -R root:bin .");
94 $size = int(`du -sk $tmp_dir`);
96 # Create the control file
97 open(CONTROL, ">$control_file");
104 Depends: bash, perl, libnet-ssleay-perl, openssl, libauthen-pam-perl, libpam-runtime, libio-pty-perl, apt-show-versions
105 Pre-Depends: bash, perl
106 Installed-Size: $size
107 Maintainer: Jamie Cameron <jcameron\@webmin.com>
108 Provides: $baseproduct
110 if ($product eq "webmin") {
112 Replaces: webmin-adsl, webmin-apache, webmin-bandwidth, webmin-bind, webmin-burner, webmin-cfengine, webmin-cluster, webmin-core, webmin-cpan, webmin-dhcpd, webmin-exim, webmin-exports, webmin-fetchmail, webmin-firewall, webmin-freeswan, webmin-frox, webmin-fsdump, webmin-grub, webmin-heartbeat, webmin-htaccess, webmin-inetd, webmin-jabber, webmin-ldap-netgroups, webmin-ldap-user-simple, webmin-ldap-useradmin, webmin-lilo, webmin-logrotate, webmin-lpadmin, webmin-lvm, webmin-mailboxes, webmin-mon, webmin-mysql, webmin-nis, webmin-openslp, webmin-postfix, webmin-postgresql, webmin-ppp, webmin-pptp-client, webmin-pptp-server, webmin-procmail, webmin-proftpd, webmin-pserver, webmin-quota, webmin-samba, webmin-sarg, webmin-sendmail, webmin-shorewall, webmin-slbackup, webmin-smart-status, webmin-snort, webmin-software, webmin-spamassassin, webmin-squid, webmin-sshd, webmin-status, webmin-stunnel, webmin-updown, webmin-usermin, webmin-vgetty, webmin-webalizer, webmin-wuftpd, webmin-wvdial, webmin-xinetd
113 Description: web-based administration interface for Unix systems
114 Using Webmin you can configure DNS, Samba, NFS, local/remote filesystems
115 and more using your web browser. After installation, enter the URL
116 https://localhost:10000/ into your browser and login as root with your root
122 Replaces: usermin-at, usermin-changepass, usermin-chfn, usermin-commands, usermin-cron, usermin-cshrc, usermin-fetchmail, usermin-forward, usermin-gnupg, usermin-htaccess, usermin-htpasswd, usermin-mailbox, usermin-man, usermin-mysql, usermin-plan, usermin-postgresql, usermin-proc, usermin-procmail, usermin-quota, usermin-schedule, usermin-shell, usermin-spamassassin, usermin-ssh, usermin-tunnel, usermin-updown, usermin-usermount
123 Description: web-based user account administration interface for Unix systems
124 After installation, enter the URL http://localhost:20000/ into your browser
125 and login as any user on your system.
130 # Create the copyright file
131 $nowstr = strftime("%a, %d %b %Y %H:%M:%S %z", localtime(time()));
132 open(COPY, ">$copyright_file");
134 This package was debianized by Jamie Cameron <jcameron\@webmin.com> on
137 It was downloaded from: http://www.webmin.com/
139 Upstream author: Jamie Cameron <jcameron\@webmin.com>
144 open(BSD, "$usr_dir/LICENCE");
151 # Create the config files file, for those we don't want to replace
152 open(CONF, ">$conffiles_file");
153 print CONF "/etc/pam.d/$baseproduct\n";
156 # Get the changes for each module and version
158 foreach $f (sort { $a cmp $b } ( glob("*/CHANGELOG"), "CHANGELOG" )) {
159 # Get the module name and type
160 local $mod = $f =~ /^(\S+)\/CHANGELOG/ ? $1 : "core";
161 next if ($mod ne "core" && -l $mod);
163 if ($mod eq "core") {
164 $desc = "$ucproduct Core";
169 $m =~ s/CHANGELOG/module.info/;
170 &read_file($m, \%minfo);
171 next if (!$minfo{'longdesc'});
172 $desc = $minfo{'desc'};
175 # Read its change log file
180 if (/^----\s+Changes\s+since\s+(\S+)\s+----/) {
183 elsif ($inversion && /\S/) {
184 push(@{$changes->{$inversion}->{$desc}}, $_);
189 # Create the changelog file from actual changes, plus the historical changelog
190 open(CHANGELOG, ">$changelog_file");
191 foreach $v (sort { $a <=> $b } (keys %$changes)) {
192 if ($ver > $v && sprintf("%.2f0", $ver) == $v) {
196 $forv = sprintf("%.2f0", $v+0.01);
198 @st = stat("tarballs/webmin-$forv.tar.gz");
199 $vtimestr = strftime("%a, %d %b %Y %H:%M:%S %z", localtime($st[9]));
200 print CHANGELOG "$baseproduct ($forv) stable; urgency=low\n";
201 print CHANGELOG "\n";
202 foreach $desc (keys %{$changes->{$v}}) {
203 foreach $c (@{$changes->{$v}->{$desc}}) {
204 @lines = &wrap_lines("$desc : $c", 65);
205 print CHANGELOG " * $lines[0]\n";
206 foreach $l (@lines[1 .. $#lines]) {
207 print CHANGELOG " $l\n";
211 print CHANGELOG "\n";
212 print CHANGELOG "-- Jamie Cameron <jcameron\@webmin.com> $vtimestr\n";
213 print CHANGELOG "\n";
217 # Get the temp-directory creator script
218 open(TEMP, "maketemp.pl");
223 $maketemp =~ s/\\/\\\\/g;
224 $maketemp =~ s/`/\\`/g;
225 $maketemp =~ s/\$/\\\$/g;
227 # Create the pre-install script
228 # No need for an OS check, as all debians are supported.
229 open(SCRIPT, ">$preinstall_file");
235 if [ "\$1" != "upgrade" ]; then
236 if [ "\$WEBMIN_PORT\" != \"\" ]; then
241 perl -e 'use Socket; socket(FOO, PF_INET, SOCK_STREAM, getprotobyname("tcp")); setsockopt(FOO, SOL_SOCKET, SO_REUSEADDR, pack("l", 1)); bind(FOO, pack_sockaddr_in(\$ARGV[0], INADDR_ANY)) || exit(1); exit(0);' \$port
242 if [ "\$?" != "0" ]; then
243 echo Port \$port is already in use
249 system("chmod 755 $preinstall_file");
251 # Create the post-install script
252 open(SCRIPT, ">$postinstall_file");
255 inetd=`grep "^inetd=" /etc/$baseproduct/miniserv.conf 2>/dev/null | sed -e 's/inetd=//g'`
256 if [ "\$1" = "upgrade" ]; then
257 # Upgrading the package, so stop the old webmin properly
258 if [ "\$inetd" != "1" ]; then
259 /etc/init.d/$baseproduct stop >/dev/null 2>&1 </dev/null
262 cd /usr/share/$baseproduct
263 config_dir=/etc/$baseproduct
264 var_dir=/var/$baseproduct
267 if [ "\$WEBMIN_PORT\" != \"\" ]; then
273 if [ -r /etc/shadow ]; then
276 crypt=`grep "^root:" /etc/passwd | cut -f 2 -d :`
286 export config_dir var_dir perl autoos port login crypt host ssl nochown autothird noperlpath nouninstall nostart allow atboot
288 if [ ! -d \$tempdir ]; then
291 ./setup.sh >$tempdir/$product-setup.out 2>&1
292 if [ "$product" = "webmin" ]; then
293 grep sudo= /etc/$product/miniserv.conf >/dev/null 2>&1
294 if [ "\$?" = 1 ]; then
295 # Allow sudo-based logins for Ubuntu
296 echo sudo=1 >>/etc/$product/miniserv.conf
299 rm -f /var/lock/subsys/$baseproduct
300 if [ "$inetd" != "1" ]; then
301 if [ -x "`which invoke-rc.d 2>/dev/null`" ]; then
302 invoke-rc.d $baseproduct start >/dev/null 2>&1 </dev/null
304 /etc/init.d/$baseproduct start >/dev/null 2>&1 </dev/null
307 if [ "$product" = "usermin" ]; then
308 insserv $baseproduct >/dev/null 2>&1
310 cat >/etc/$baseproduct/uninstall.sh <<EOFF
312 printf "Are you sure you want to uninstall $ucproduct? (y/n) : "
315 if [ "\\\$answer" = "y" ]; then
316 echo "Removing $ucproduct package .."
317 dpkg --remove $product
321 chmod +x /etc/$baseproduct/uninstall.sh
322 port=`grep "^port=" /etc/$baseproduct/miniserv.conf | sed -e 's/port=//g'`
323 perl -e 'use Net::SSLeay' >/dev/null 2>/dev/null
325 if [ "\$?" = "0" ]; then
326 grep ssl=1 /etc/$baseproduct/miniserv.conf >/dev/null 2>/dev/null
327 if [ "\$?" = "0" ]; then
331 if [ "\$sslmode" = "1" ]; then
332 echo "$ucproduct install complete. You can now login to https://\$host:\$port/"
334 echo "$ucproduct install complete. You can now login to http://\$host:\$port/"
336 if [ "$product" = "webmin" ]; then
337 echo "as root with your root password, or as any user who can use sudo"
338 echo "to run commands as root."
340 echo "as any user on the system."
344 system("chmod 755 $postinstall_file");
346 # Create the pre-uninstall script
347 open(SCRIPT, ">$preuninstall_file");
350 if [ "\$1" != "upgrade" ]; then
351 grep root=/usr/share/$baseproduct /etc/$baseproduct/miniserv.conf >/dev/null 2>&1
352 if [ "\$?" = 0 ]; then
353 # Package is being removed, and no new version of webmin
354 # has taken it's place. Run uninstalls and stop the server
355 if [ "$product" = "webmin" ]; then
356 echo "Running uninstall scripts .."
357 (cd /usr/share/$baseproduct ; WEBMIN_CONFIG=/etc/$baseproduct WEBMIN_VAR=/var/$baseproduct LANG= /usr/share/$baseproduct/run-uninstalls.pl)
359 /etc/init.d/$baseproduct stop >/dev/null 2>&1 </dev/null
360 /etc/$baseproduct/stop >/dev/null 2>&1 </dev/null
366 system("chmod 755 $preuninstall_file");
368 # Create the post-uninstall script
369 open(SCRIPT, ">$postuninstall_file");
372 if [ "\$1" != "upgrade" ]; then
373 grep root=/usr/share/$baseproduct /etc/$baseproduct/miniserv.conf >/dev/null 2>&1
374 if [ "\$?" = 0 ]; then
375 # Package is being removed, and no new version of webmin
376 # has taken it's place. Delete the config files
377 rm -rf /etc/$baseproduct /var/$baseproduct
382 system("chmod 755 $postuninstall_file");
384 # Run the actual build command
385 system("fakeroot dpkg --build $tmp_dir deb/${product}_${ver}${rel}_all.deb") &&
387 #system("rm -rf $tmp_dir");
388 print "Wrote deb/${product}_${ver}${rel}_all.deb\n";
389 $md5 = `md5sum tarballs/$product-$ver$rel.tar.gz`;
390 $md5 =~ s/\s+.*\n//g;
391 @st = stat("tarballs/$product-$ver.tar.gz");
393 # Create the .diff file, which just contains the debian directory
394 $diff_orig_dir = "$tmp_dir/$product-$ver-orig";
395 $diff_new_dir = "$tmp_dir/$product-$ver";
396 mkdir($diff_orig_dir, 0755);
397 mkdir($diff_new_dir, 0755);
398 system("cp -r $debian_dir $diff_new_dir");
399 system("cd $tmp_dir && diff -r -N -u $product-$ver-orig $product-$ver >$webmin_dir/deb/${product}_${ver}${rel}.diff");
400 $diffmd5 = `md5sum deb/${product}_${ver}${rel}.diff`;
401 $diffmd5 =~ s/\s+.*\n//g;
402 @diffst = stat("deb/${product}_${ver}${rel}.diff");
404 # Create the .dsc file
405 open(DSC, ">deb/${product}_$ver$rel.plain");
411 Maintainer: Jamie Cameron <jcameron\@webmin.com>
413 Standards-Version: 3.6.1
414 Build-Depends-Indep: debhelper (>= 4.1.16), debconf (>= 0.5.00), perl
415 Uploaders: Jamie Cameron <jcameron\@webmin.com>
417 $md5 $st[7] ${product}-${ver}.tar.gz
418 $diffmd5 $diffst[7] ${product}_${ver}.diff
422 unlink("deb/${product}_$ver$rel.dsc");
423 system("gpg --output deb/${product}_$ver$rel.dsc --clearsign deb/${product}_$ver$rel.plain");
424 unlink("deb/${product}_$ver$rel.plain");
425 print "Wrote source deb/${product}_$ver$rel.dsc\n";
428 if (-d "/usr/local/webadmin/deb/repository") {
429 # Add to our repository
430 chdir("/usr/local/webadmin/deb/repository");
431 system("reprepro -Vb . remove $dir $product");
432 system("reprepro -Vb . includedeb $dir ../${product}_${ver}${rel}_all.deb");
433 chdir("/usr/local/webadmin");
436 # Create PGP signature
437 unlink("sigs/${product}_${ver}${rel}_all.deb-sig.asc");
438 system("gpg --armor --output sigs/${product}_${ver}${rel}_all.deb-sig.asc --default-key jcameron\@webmin.com --detach-sig deb/${product}_${ver}${rel}_all.deb");
440 # read_file(file, &assoc, [&order], [lowercase])
441 # Fill an associative array with name=value pairs from a file
445 open(ARFILE, $_[0]) || return 0;
448 local $hash = index($_, "#");
449 local $eq = index($_, "=");
450 if ($hash != 0 && $eq >= 0) {
451 local $n = substr($_, 0, $eq);
452 local $v = substr($_, $eq+1);
453 $_[1]->{$_[3] ? lc($n) : $n} = $v;
454 push(@{$_[2]}, $n) if ($_[2]);
458 if (defined($main::read_file_cache{$_[0]})) {
459 %{$main::read_file_cache{$_[0]}} = %{$_[1]};
464 # wrap_lines(text, width)
465 # Given a multi-line string, return an array of lines wrapped to
472 foreach $rest (split(/\n/, $_[0])) {
474 while($rest =~ /^(.{1,$w}\S*)\s*([\0-\377]*)$/) {
480 # Empty line .. keep as it is