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 mkdir($debian_dir, 0755);
54 system("mkdir -p $pam_dir");
55 if ($baseproduct eq "usermin") {
56 system("mkdir -p $init_dir");
57 foreach $d (@rc_dirs) {
58 system("mkdir -p $d");
61 system("mkdir -p $usr_dir");
63 # Un-tar the package to the correct locations
64 system("gunzip -c tarballs/$product-$ver.tar.gz | (cd $tmp_dir ; tar xf -)") &&
66 system("mv $tmp_dir/$product-$ver/* $usr_dir");
67 rmdir("$tmp_dir/$product-$ver");
68 system("mv $usr_dir/$baseproduct-pam $pam_file");
69 system("cd $usr_dir && (find . -name '*.cgi' ; find . -name '*.pl') | perl perlpath.pl /usr/bin/perl -");
70 system("cd $usr_dir && rm -f mount/freebsd-mounts*");
71 system("cd $usr_dir && rm -f mount/openbsd-mounts*");
72 if ($product eq "webmin") {
73 system("cd $usr_dir && rm -f mount/macos-mounts*");
74 system("cd $usr_dir && rm -f webmin-gentoo-init");
75 system("cd $usr_dir && rm -rf format bsdexports hpuxexports sgiexports zones rbac");
78 # Need to create init script
79 system("mv $usr_dir/$baseproduct-init $init_dir/$baseproduct");
80 foreach $d (@rc_dirs) {
81 system("ln -s ../init.d/$baseproduct $d/S99$baseproduct");
84 system("echo deb >$usr_dir/install-type");
85 system("echo $product >$usr_dir/deb-name");
86 system("cd $usr_dir && chmod -R og-w .");
88 system("cd $usr_dir && chown -R root:bin .");
90 $size = int(`du -sk $tmp_dir`);
92 # Create the control file
93 open(CONTROL, ">$control_file");
101 Depends: bash, perl, libnet-ssleay-perl, openssl, libauthen-pam-perl, libpam-runtime, libio-pty-perl, libmd5-perl
102 Pre-Depends: bash, perl
103 Installed-Size: $size
104 Maintainer: Jamie Cameron <jcameron\@webmin.com>
105 Provides: $baseproduct
107 if ($product eq "webmin") {
109 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
110 Description: A web-based administration interface for Unix systems.
111 Using Webmin you can configure DNS, Samba, NFS, local/remote
112 filesystems and more using your web browser. After installation,
113 enter the URL https://localhost:10000/ into your browser and
114 login as root with your root password.
119 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
120 Description: A web-based user account administration interface for Unix systems.
121 After installation, enter the URL http://localhost:20000/ into your browser and login as any user on your system.
126 # Create the copyright file
127 $nowstr = strftime("%a, %d %b %Y %H:%M:%S %z", localtime(time()));
128 open(COPY, ">$copyright_file");
130 This package was debianized by Jamie Cameron <jcameron\@webmin.com> on
133 It was downloaded from: http://www.webmin.com/
135 Upstream author: Jamie Cameron <jcameron\@webmin.com>
140 open(BSD, "$usr_dir/LICENCE");
147 # Get the changes for each module and version
149 foreach $f (sort { $a cmp $b } ( glob("*/CHANGELOG"), "CHANGELOG" )) {
150 # Get the module name and type
151 local $mod = $f =~ /^(\S+)\/CHANGELOG/ ? $1 : "core";
152 next if ($mod ne "core" && -l $mod);
154 if ($mod eq "core") {
155 $desc = "$ucproduct Core";
160 $m =~ s/CHANGELOG/module.info/;
161 &read_file($m, \%minfo);
162 next if (!$minfo{'longdesc'});
163 $desc = $minfo{'desc'};
166 # Read its change log file
171 if (/^----\s+Changes\s+since\s+(\S+)\s+----/) {
174 elsif ($inversion && /\S/) {
175 push(@{$changes->{$inversion}->{$desc}}, $_);
180 # Create the changelog file from actual changes, plus the historical changelog
181 open(CHANGELOG, ">$changelog_file");
182 foreach $v (sort { $a <=> $b } (keys %$changes)) {
183 if ($ver > $v && sprintf("%.2f0", $ver) == $v) {
187 $forv = sprintf("%.2f0", $v+0.01);
189 @st = stat("tarballs/webmin-$forv.tar.gz");
190 $vtimestr = strftime("%a, %d %b %Y %H:%M:%S %z", localtime($st[9]));
191 print CHANGELOG "$baseproduct ($forv) stable; urgency=low\n";
192 print CHANGELOG "\n";
193 foreach $desc (keys %{$changes->{$v}}) {
194 foreach $c (@{$changes->{$v}->{$desc}}) {
195 @lines = &wrap_lines("$desc : $c", 65);
196 print CHANGELOG " * $lines[0]\n";
197 foreach $l (@lines[1 .. $#lines]) {
198 print CHANGELOG " $l\n";
202 print CHANGELOG "\n";
203 print CHANGELOG "-- Jamie Cameron <jcameron\@webmin.com> $vtimestr\n";
204 print CHANGELOG "\n";
208 # Get the temp-directory creator script
209 open(TEMP, "maketemp.pl");
214 $maketemp =~ s/\\/\\\\/g;
215 $maketemp =~ s/`/\\`/g;
216 $maketemp =~ s/\$/\\\$/g;
218 # Create the pre-install script
219 # No need for an OS check, as all debians are supported.
220 open(SCRIPT, ">$preinstall_file");
226 if [ "\$1" != "upgrade" ]; then
227 if [ "\$WEBMIN_PORT\" != \"\" ]; then
232 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
233 if [ "\$?" != "0" ]; then
234 echo Port \$port is already in use
240 system("chmod 755 $preinstall_file");
242 # Create the post-install script
243 open(SCRIPT, ">$postinstall_file");
246 inetd=`grep "^inetd=" /etc/$baseproduct/miniserv.conf 2>/dev/null | sed -e 's/inetd=//g'`
247 if [ "\$1" = "upgrade" ]; then
248 # Upgrading the package, so stop the old webmin properly
249 if [ "\$inetd" != "1" ]; then
250 /etc/init.d/$baseproduct stop >/dev/null 2>&1 </dev/null
253 cd /usr/share/$baseproduct
254 config_dir=/etc/$baseproduct
255 var_dir=/var/$baseproduct
258 if [ "\$WEBMIN_PORT\" != \"\" ]; then
264 if [ -r /etc/shadow ]; then
267 crypt=`grep "^root:" /etc/passwd | cut -f 2 -d :`
277 export config_dir var_dir perl autoos port login crypt host ssl nochown autothird noperlpath nouninstall nostart allow atboot
278 ./setup.sh >/tmp/.webmin/$product-setup.out 2>&1
279 if [ "$product" = "webmin" ]; then
280 grep sudo= /etc/$product/miniserv.conf >/dev/null 2>&1
281 if [ "\$?" = 1 ]; then
282 # Allow sudo-based logins for Ubuntu
283 echo sudo=1 >>/etc/$product/miniserv.conf
286 rm -f /var/lock/subsys/$baseproduct
287 if [ "$inetd" != "1" ]; then
288 if [ -x "`which invoke-rc.d 2>/dev/null`" ]; then
289 invoke-rc.d $baseproduct start >/dev/null 2>&1 </dev/null
291 /etc/init.d/$baseproduct start >/dev/null 2>&1 </dev/null
294 cat >/etc/$baseproduct/uninstall.sh <<EOFF
296 printf "Are you sure you want to uninstall $ucproduct? (y/n) : "
299 if [ "\\\$answer" = "y" ]; then
300 echo "Removing $ucproduct package .."
301 dpkg --remove $product
305 chmod +x /etc/$baseproduct/uninstall.sh
306 port=`grep "^port=" /etc/$baseproduct/miniserv.conf | sed -e 's/port=//g'`
307 perl -e 'use Net::SSLeay' >/dev/null 2>/dev/null
309 if [ "\$?" = "0" ]; then
310 grep ssl=1 /etc/$baseproduct/miniserv.conf >/dev/null 2>/dev/null
311 if [ "\$?" = "0" ]; then
315 if [ "\$sslmode" = "1" ]; then
316 echo "$ucproduct install complete. You can now login to https://\$host:\$port/"
318 echo "$ucproduct install complete. You can now login to http://\$host:\$port/"
320 if [ "$product" = "webmin" ]; then
321 echo "as root with your root password, or as any user who can use sudo"
322 echo "to run commands as root."
324 echo "as any user on the system."
328 system("chmod 755 $postinstall_file");
330 # Create the pre-uninstall script
331 open(SCRIPT, ">$preuninstall_file");
334 if [ "\$1" != "upgrade" ]; then
335 grep root=/usr/share/$baseproduct /etc/$baseproduct/miniserv.conf >/dev/null 2>&1
336 if [ "\$?" = 0 ]; then
337 # Package is being removed, and no new version of webmin
338 # has taken it's place. Run uninstalls and stop the server
339 if [ "$product" = "webmin" ]; then
340 echo "Running uninstall scripts .."
341 (cd /usr/share/$baseproduct ; WEBMIN_CONFIG=/etc/$baseproduct WEBMIN_VAR=/var/$baseproduct LANG= /usr/share/$baseproduct/run-uninstalls.pl)
343 /etc/init.d/$baseproduct stop >/dev/null 2>&1 </dev/null
344 /etc/$baseproduct/stop >/dev/null 2>&1 </dev/null
350 system("chmod 755 $preuninstall_file");
352 # Create the post-uninstall script
353 open(SCRIPT, ">$postuninstall_file");
356 if [ "\$1" != "upgrade" ]; then
357 grep root=/usr/share/$baseproduct /etc/$baseproduct/miniserv.conf >/dev/null 2>&1
358 if [ "\$?" = 0 ]; then
359 # Package is being removed, and no new version of webmin
360 # has taken it's place. Delete the config files
361 rm -rf /etc/$baseproduct /var/$baseproduct
366 system("chmod 755 $postuninstall_file");
368 # Run the actual build command
369 system("fakeroot dpkg --build $tmp_dir deb/${product}_${ver}_all.deb") &&
371 #system("rm -rf $tmp_dir");
372 print "Wrote deb/${product}_${ver}_all.deb\n";
373 $md5 = `md5sum tarballs/$product-$ver.tar.gz`;
374 $md5 =~ s/\s+.*\n//g;
375 @st = stat("tarballs/$product-$ver.tar.gz");
377 # Create the .diff file, which just contains the debian directory
378 $diff_orig_dir = "$tmp_dir/$product-$ver-orig";
379 $diff_new_dir = "$tmp_dir/$product-$ver";
380 mkdir($diff_orig_dir, 0755);
381 mkdir($diff_new_dir, 0755);
382 system("cp -r $debian_dir $diff_new_dir");
383 system("cd $tmp_dir && diff -r -N -u $product-$ver-orig $product-$ver >$webmin_dir/deb/${product}_${ver}.diff");
384 $diffmd5 = `md5sum deb/${product}_${ver}.diff`;
385 $diffmd5 =~ s/\s+.*\n//g;
386 @diffst = stat("deb/${product}_${ver}.diff");
388 # Create the .dsc file
389 open(DSC, ">deb/${product}_$ver.plain");
395 Maintainer: Jamie Cameron <jcameron\@webmin.com>
397 Standards-Version: 3.6.1
398 Build-Depends-Indep: debhelper (>= 4.1.16), debconf (>= 0.5.00), perl
399 Uploaders: Jamie Cameron <jcameron\@webmin.com>
401 $md5 $st[7] ${product}-${ver}.tar.gz
402 $diffmd5 $diffst[7] ${product}_${ver}.diff
406 unlink("deb/${product}_$ver.dsc");
407 system("gpg --output deb/${product}_$ver.dsc --clearsign deb/${product}_$ver.plain");
408 unlink("deb/${product}_$ver.plain");
409 print "Wrote source deb/${product}_$ver.dsc\n";
412 # Add to our repository
413 chdir("/usr/local/webadmin/deb/repository");
414 system("reprepro -Vb . includedeb sarge ../${product}_${ver}_all.deb");
417 # read_file(file, &assoc, [&order], [lowercase])
418 # Fill an associative array with name=value pairs from a file
422 open(ARFILE, $_[0]) || return 0;
425 local $hash = index($_, "#");
426 local $eq = index($_, "=");
427 if ($hash != 0 && $eq >= 0) {
428 local $n = substr($_, 0, $eq);
429 local $v = substr($_, $eq+1);
430 $_[1]->{$_[3] ? lc($n) : $n} = $v;
431 push(@{$_[2]}, $n) if ($_[2]);
435 if (defined($main::read_file_cache{$_[0]})) {
436 %{$main::read_file_cache{$_[0]}} = %{$_[1]};
441 # wrap_lines(text, width)
442 # Given a multi-line string, return an array of lines wrapped to
449 foreach $rest (split(/\n/, $_[0])) {
451 while($rest =~ /^(.{1,$w}\S*)\s*([\0-\377]*)$/) {
457 # Empty line .. keep as it is