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";
41 -d "tarballs" || die "makedebian.pl must be run in the $ucproduct root directory";
42 -r "/etc/debian_version" || die "makedebian.pl must be run on Debian";
43 chop($webmin_dir = `pwd`);
45 @ARGV == 1 || die "usage: makedebian.pl [--webmail] <version>";
47 -r "tarballs/$product-$ver.tar.gz" || die "tarballs/$product-$ver.tar.gz not found";
49 # Create the base directories
50 print "Creating Debian package of ",ucfirst($product)," ",$ver," ...\n";
51 system("rm -rf $tmp_dir");
52 mkdir($tmp_dir, 0755);
53 chmod(0755, $tmp_dir);
54 mkdir($debian_dir, 0755);
55 system("mkdir -p $pam_dir");
56 if ($baseproduct eq "usermin") {
57 system("mkdir -p $init_dir");
58 foreach $d (@rc_dirs) {
59 system("mkdir -p $d");
62 system("mkdir -p $usr_dir");
64 # Un-tar the package to the correct locations
65 system("gunzip -c tarballs/$product-$ver.tar.gz | (cd $tmp_dir ; tar xf -)") &&
67 system("mv $tmp_dir/$product-$ver/* $usr_dir");
68 rmdir("$tmp_dir/$product-$ver");
69 system("mv $usr_dir/$baseproduct-pam $pam_file");
70 system("cd $usr_dir && (find . -name '*.cgi' ; find . -name '*.pl') | perl perlpath.pl /usr/bin/perl -");
71 system("cd $usr_dir && rm -f mount/freebsd-mounts*");
72 system("cd $usr_dir && rm -f mount/openbsd-mounts*");
73 if ($product eq "webmin") {
74 system("cd $usr_dir && rm -f mount/macos-mounts*");
75 system("cd $usr_dir && rm -f webmin-gentoo-init");
76 system("cd $usr_dir && rm -rf format bsdexports hpuxexports sgiexports zones rbac");
79 # Need to create init script
80 system("mv $usr_dir/$baseproduct-init $init_dir/$baseproduct");
81 foreach $d (@rc_dirs) {
82 system("ln -s ../init.d/$baseproduct $d/S99$baseproduct");
85 system("echo deb >$usr_dir/install-type");
86 system("echo $product >$usr_dir/deb-name");
87 system("cd $usr_dir && chmod -R og-w .");
89 system("cd $usr_dir && chown -R root:bin .");
91 $size = int(`du -sk $tmp_dir`);
93 # Create the control file
94 open(CONTROL, ">$control_file");
102 Depends: bash, perl, libnet-ssleay-perl, openssl, libauthen-pam-perl, libpam-runtime, libio-pty-perl, libmd5-perl
103 Pre-Depends: bash, perl
104 Installed-Size: $size
105 Maintainer: Jamie Cameron <jcameron\@webmin.com>
106 Provides: $baseproduct
108 if ($product eq "webmin") {
110 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
111 Description: A web-based administration interface for Unix systems.
112 Using Webmin you can configure DNS, Samba, NFS, local/remote
113 filesystems and more using your web browser. After installation,
114 enter the URL https://localhost:10000/ into your browser and
115 login as root with your root password.
120 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
121 Description: A web-based user account administration interface for Unix systems.
122 After installation, enter the URL http://localhost:20000/ into your browser and login as any user on your system.
127 # Create the copyright file
128 $nowstr = strftime("%a, %d %b %Y %H:%M:%S %z", localtime(time()));
129 open(COPY, ">$copyright_file");
131 This package was debianized by Jamie Cameron <jcameron\@webmin.com> on
134 It was downloaded from: http://www.webmin.com/
136 Upstream author: Jamie Cameron <jcameron\@webmin.com>
141 open(BSD, "$usr_dir/LICENCE");
148 # Get the changes for each module and version
150 foreach $f (sort { $a cmp $b } ( glob("*/CHANGELOG"), "CHANGELOG" )) {
151 # Get the module name and type
152 local $mod = $f =~ /^(\S+)\/CHANGELOG/ ? $1 : "core";
153 next if ($mod ne "core" && -l $mod);
155 if ($mod eq "core") {
156 $desc = "$ucproduct Core";
161 $m =~ s/CHANGELOG/module.info/;
162 &read_file($m, \%minfo);
163 next if (!$minfo{'longdesc'});
164 $desc = $minfo{'desc'};
167 # Read its change log file
172 if (/^----\s+Changes\s+since\s+(\S+)\s+----/) {
175 elsif ($inversion && /\S/) {
176 push(@{$changes->{$inversion}->{$desc}}, $_);
181 # Create the changelog file from actual changes, plus the historical changelog
182 open(CHANGELOG, ">$changelog_file");
183 foreach $v (sort { $a <=> $b } (keys %$changes)) {
184 if ($ver > $v && sprintf("%.2f0", $ver) == $v) {
188 $forv = sprintf("%.2f0", $v+0.01);
190 @st = stat("tarballs/webmin-$forv.tar.gz");
191 $vtimestr = strftime("%a, %d %b %Y %H:%M:%S %z", localtime($st[9]));
192 print CHANGELOG "$baseproduct ($forv) stable; urgency=low\n";
193 print CHANGELOG "\n";
194 foreach $desc (keys %{$changes->{$v}}) {
195 foreach $c (@{$changes->{$v}->{$desc}}) {
196 @lines = &wrap_lines("$desc : $c", 65);
197 print CHANGELOG " * $lines[0]\n";
198 foreach $l (@lines[1 .. $#lines]) {
199 print CHANGELOG " $l\n";
203 print CHANGELOG "\n";
204 print CHANGELOG "-- Jamie Cameron <jcameron\@webmin.com> $vtimestr\n";
205 print CHANGELOG "\n";
209 # Get the temp-directory creator script
210 open(TEMP, "maketemp.pl");
215 $maketemp =~ s/\\/\\\\/g;
216 $maketemp =~ s/`/\\`/g;
217 $maketemp =~ s/\$/\\\$/g;
219 # Create the pre-install script
220 # No need for an OS check, as all debians are supported.
221 open(SCRIPT, ">$preinstall_file");
227 if [ "\$1" != "upgrade" ]; then
228 if [ "\$WEBMIN_PORT\" != \"\" ]; then
233 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
234 if [ "\$?" != "0" ]; then
235 echo Port \$port is already in use
241 system("chmod 755 $preinstall_file");
243 # Create the post-install script
244 open(SCRIPT, ">$postinstall_file");
247 inetd=`grep "^inetd=" /etc/$baseproduct/miniserv.conf 2>/dev/null | sed -e 's/inetd=//g'`
248 if [ "\$1" = "upgrade" ]; then
249 # Upgrading the package, so stop the old webmin properly
250 if [ "\$inetd" != "1" ]; then
251 /etc/init.d/$baseproduct stop >/dev/null 2>&1 </dev/null
254 cd /usr/share/$baseproduct
255 config_dir=/etc/$baseproduct
256 var_dir=/var/$baseproduct
259 if [ "\$WEBMIN_PORT\" != \"\" ]; then
265 if [ -r /etc/shadow ]; then
268 crypt=`grep "^root:" /etc/passwd | cut -f 2 -d :`
278 export config_dir var_dir perl autoos port login crypt host ssl nochown autothird noperlpath nouninstall nostart allow atboot
279 ./setup.sh >/tmp/.webmin/$product-setup.out 2>&1
280 if [ "$product" = "webmin" ]; then
281 grep sudo= /etc/$product/miniserv.conf >/dev/null 2>&1
282 if [ "\$?" = 1 ]; then
283 # Allow sudo-based logins for Ubuntu
284 echo sudo=1 >>/etc/$product/miniserv.conf
287 rm -f /var/lock/subsys/$baseproduct
288 if [ "$inetd" != "1" ]; then
289 if [ -x "`which invoke-rc.d 2>/dev/null`" ]; then
290 invoke-rc.d $baseproduct start >/dev/null 2>&1 </dev/null
292 /etc/init.d/$baseproduct start >/dev/null 2>&1 </dev/null
295 cat >/etc/$baseproduct/uninstall.sh <<EOFF
297 printf "Are you sure you want to uninstall $ucproduct? (y/n) : "
300 if [ "\\\$answer" = "y" ]; then
301 echo "Removing $ucproduct package .."
302 dpkg --remove $product
306 chmod +x /etc/$baseproduct/uninstall.sh
307 port=`grep "^port=" /etc/$baseproduct/miniserv.conf | sed -e 's/port=//g'`
308 perl -e 'use Net::SSLeay' >/dev/null 2>/dev/null
310 if [ "\$?" = "0" ]; then
311 grep ssl=1 /etc/$baseproduct/miniserv.conf >/dev/null 2>/dev/null
312 if [ "\$?" = "0" ]; then
316 if [ "\$sslmode" = "1" ]; then
317 echo "$ucproduct install complete. You can now login to https://\$host:\$port/"
319 echo "$ucproduct install complete. You can now login to http://\$host:\$port/"
321 if [ "$product" = "webmin" ]; then
322 echo "as root with your root password, or as any user who can use sudo"
323 echo "to run commands as root."
325 echo "as any user on the system."
329 system("chmod 755 $postinstall_file");
331 # Create the pre-uninstall script
332 open(SCRIPT, ">$preuninstall_file");
335 if [ "\$1" != "upgrade" ]; then
336 grep root=/usr/share/$baseproduct /etc/$baseproduct/miniserv.conf >/dev/null 2>&1
337 if [ "\$?" = 0 ]; then
338 # Package is being removed, and no new version of webmin
339 # has taken it's place. Run uninstalls and stop the server
340 if [ "$product" = "webmin" ]; then
341 echo "Running uninstall scripts .."
342 (cd /usr/share/$baseproduct ; WEBMIN_CONFIG=/etc/$baseproduct WEBMIN_VAR=/var/$baseproduct LANG= /usr/share/$baseproduct/run-uninstalls.pl)
344 /etc/init.d/$baseproduct stop >/dev/null 2>&1 </dev/null
345 /etc/$baseproduct/stop >/dev/null 2>&1 </dev/null
351 system("chmod 755 $preuninstall_file");
353 # Create the post-uninstall script
354 open(SCRIPT, ">$postuninstall_file");
357 if [ "\$1" != "upgrade" ]; then
358 grep root=/usr/share/$baseproduct /etc/$baseproduct/miniserv.conf >/dev/null 2>&1
359 if [ "\$?" = 0 ]; then
360 # Package is being removed, and no new version of webmin
361 # has taken it's place. Delete the config files
362 rm -rf /etc/$baseproduct /var/$baseproduct
367 system("chmod 755 $postuninstall_file");
369 # Run the actual build command
370 system("fakeroot dpkg --build $tmp_dir deb/${product}_${ver}_all.deb") &&
372 #system("rm -rf $tmp_dir");
373 print "Wrote deb/${product}_${ver}_all.deb\n";
374 $md5 = `md5sum tarballs/$product-$ver.tar.gz`;
375 $md5 =~ s/\s+.*\n//g;
376 @st = stat("tarballs/$product-$ver.tar.gz");
378 # Create the .diff file, which just contains the debian directory
379 $diff_orig_dir = "$tmp_dir/$product-$ver-orig";
380 $diff_new_dir = "$tmp_dir/$product-$ver";
381 mkdir($diff_orig_dir, 0755);
382 mkdir($diff_new_dir, 0755);
383 system("cp -r $debian_dir $diff_new_dir");
384 system("cd $tmp_dir && diff -r -N -u $product-$ver-orig $product-$ver >$webmin_dir/deb/${product}_${ver}.diff");
385 $diffmd5 = `md5sum deb/${product}_${ver}.diff`;
386 $diffmd5 =~ s/\s+.*\n//g;
387 @diffst = stat("deb/${product}_${ver}.diff");
389 # Create the .dsc file
390 open(DSC, ">deb/${product}_$ver.plain");
396 Maintainer: Jamie Cameron <jcameron\@webmin.com>
398 Standards-Version: 3.6.1
399 Build-Depends-Indep: debhelper (>= 4.1.16), debconf (>= 0.5.00), perl
400 Uploaders: Jamie Cameron <jcameron\@webmin.com>
402 $md5 $st[7] ${product}-${ver}.tar.gz
403 $diffmd5 $diffst[7] ${product}_${ver}.diff
407 unlink("deb/${product}_$ver.dsc");
408 system("gpg --output deb/${product}_$ver.dsc --clearsign deb/${product}_$ver.plain");
409 unlink("deb/${product}_$ver.plain");
410 print "Wrote source deb/${product}_$ver.dsc\n";
412 if (!$webmail && -d "/usr/local/webadmin/deb/repository") {
413 # Add to our repository
414 chdir("/usr/local/webadmin/deb/repository");
415 system("reprepro -Vb . remove sarge $product");
416 system("reprepro -Vb . includedeb sarge ../${product}_${ver}_all.deb");
417 chdir("/usr/local/webadmin");
420 # Create PGP signature
421 unlink("sigs/${product}_${ver}_all.deb-sig.asc");
422 system("gpg --armor --output sigs/${product}_${ver}_all.deb-sig.asc --default-key jcameron\@webmin.com --detach-sig deb/${product}_${ver}_all.deb");
424 # read_file(file, &assoc, [&order], [lowercase])
425 # Fill an associative array with name=value pairs from a file
429 open(ARFILE, $_[0]) || return 0;
432 local $hash = index($_, "#");
433 local $eq = index($_, "=");
434 if ($hash != 0 && $eq >= 0) {
435 local $n = substr($_, 0, $eq);
436 local $v = substr($_, $eq+1);
437 $_[1]->{$_[3] ? lc($n) : $n} = $v;
438 push(@{$_[2]}, $n) if ($_[2]);
442 if (defined($main::read_file_cache{$_[0]})) {
443 %{$main::read_file_cache{$_[0]}} = %{$_[1]};
448 # wrap_lines(text, width)
449 # Given a multi-line string, return an array of lines wrapped to
456 foreach $rest (split(/\n/, $_[0])) {
458 while($rest =~ /^(.{1,$w}\S*)\s*([\0-\377]*)$/) {
464 # Empty line .. keep as it is