#!/usr/bin/perl -W use strict; use MD5; use Fcntl; use Net::FTP; use File::stat; use Getopt::Std; my %opts; getopts("hm:r:",\%opts); my $release = $opts{r}; my $main_ftp = "ftp.openbsd.org"; my $mirror = $opts{m} || $main_ftp; my $ftp = shift; my @free = (); my @numrel = (); my $suff = shift; my @arrsuff = (); my $config = "r57obsdiso.conf"; my $sys_df = "/bin/df"; my $sys_mk = "/usr/bin/mkisofs"; sub help { print qq~ \\* You can create ISO-image OpenBSD(i386) for more - read help, written by _blf: http://rst.void.ru/papers/openbsd_iso_howto.txt (russian no doubt ;) ftp-mirror list: http://www.openbsd.org/ftp.html [\~] Usage: $0 -m [ftp site] -r [release], e.g. $0 -m ftp.chg.ru -r 3.9 [\~] Default mirror ftp://ftp.openbsd.org/pub/OpenBSD/ [\~] Default release - current If you want to get current release from master site: just type $0 without arguments (c)oded by x97Rang, RST/GHC, 2006 http://rst.void.ru http://ghc.ru *\\ ~; exit; } sub error { print "[!] Fatal error: $_[0], $_[1]\n"; exit; } sub check_release {if(!($opts{r} =~ /^\d{1,2}\.\d{1}$/)){print"[-] Error: Wrong release, type number, e.g. 3.7, or not use this option for get current release\n";exit;} } sub head { print "\n --------------- OpenBSD ISO creator by RST/GHC --------------- \n\n"; } sub check_os { print"[+] Your OS: $^O"; if($^O ne "freebsd" && $^O ne "openbsd" && $^O ne "linux") { print"[!] Error: Work only OpenBSD, FreeBSD and Linux\n"; exit; } } sub warning { print qq( [~] Note: Hope your system files: df is /bin/df mkisofs is /usr/bin/mkisofs else - you must create file ./r57obsdiso.conf adn write next e.g. ---8><------r57obsdiso.conf----------- df = /usr/local/bin/df mkisofs = /usr/local/bin/mkisofs --------------------------------><8--- ); } sub check_conf { my $conf_line = shift; if(-e "$config" and -s "$config") { print "[+] Found not empty $config, get info...\n"; } else { print "[~] Note: config not foud, hope that's ok\n"; return; } sysopen(CONF, "$config", O_RDONLY) or die "[!] Error: Couldn't open config file for reading: $!\n"; while () { if($conf_line = m/df\s+=\s+(.+df)$/){ $sys_df = $1; } if($conf_line = m/mkisofs\s+=\s+(.+mkisofs)$/){ $sys_mk = $1; } } close(CONF); print "[~] Note: df is $sys_df\n"; print "[~] Note: mkisofs is $sys_mk\n"; } sub ready { print "[+] Ftp site: $mirror\n"; if($release) { print"[+] Release : $release\n"; } else { &get_current; } if(!(-e "$sys_df")) { print "[!] Error: Cannot find $sys_df\n"; exit; } if(!(-e "$sys_mk")) { print "[!] Error: Cannot find $sys_mk\n"; exit; } print "[+] Check disk space"; open(SP, "$sys_df -k . |") or die "[!] Error: Couldn't run $sys_df: $!\n"; while() { @free = split(/\s+/,"$_\n"); } close(SP); if($free[3] < 800000) { print "\n[!] Error: ISO needs ~ 800M free disk space, you have only $free[3]K\n\n"; exit;} else { print " - avail $free[3]K\n";} } sub get_current { my $ftp = Net::FTP->new("$main_ftp", Timeout => 30, Passive => 1, Debug => 0) or die "[!] Error: Cannot connect to $main_ftp: $@"; $ftp->login("anonymous",'-anonymous@') or die "[!] Error: Cannot login: ", $ftp->message; $ftp->cwd("/pub/OpenBSD/") or die "[!] Error: Cannot change working directory: ", $ftp->message; my @res = $ftp->ls or die "[!] Error: Cannot list directory: ", $ftp->message; $ftp->quit; for(@res){ if($_ =~ /^(\d{1,2}\.\d{1})$/) { push(@numrel,$1); } } if(!(@numrel)){ print "[!] Error: Cannot find current release on master ftp site, give up\n"; exit; } $release = $numrel[$#numrel]; print"[+] Current release OpenBSD is $release\n"; } sub make_dirs { print "[~] Create release directories...\n"; my $first = "openbsd-release-$release"; my $second = "openbsd-release-$release/$release"; my $third = "openbsd-release-$release/$release/i386"; mkdir("$first",0755) or &error($first,$!); mkdir("$second",0755) or &error($second,$!); mkdir("$third",0755) or &error($third,$!); } sub check_size { my $file = $_[0]; my $line = shift; my $size = shift; my $loc_file = shift; print "[~] Try check size file '$file'\n"; if(!(-e "CKSUM")){ print "[!] Error: Cannot find local file 'CKSUM', check failed\n"; exit;} sysopen(SF, "CKSUM", O_RDONLY) or die "[!] Error: Couldn't open 'CKSUM' for reading: $!\n"; while ($line=) { if($line =~ m/(\d+)\s+(\d+)\s+($file)?(\s+)$/) { $size = $2; } } close(SF); my $sb = stat($file); $loc_file = $sb->size; if($loc_file == $size){print"[+] Size '$file' - OK\n";} else { print "[-] Warning: size wrong, CKSUM - $size, stat of file $loc_file\n[-] Type 'ok' for confirm ignoring: "; while() { if ($_ =~ /^ok$/){ return;} else {print "[-] Exit: You can compare files manually\n"; exit; }}} } sub check_md5 { my $val = $_[0]; my $sum = shift; my $line = shift; my $md5 = new MD5; print "[~] Try check MD5 sum file '$val'\n"; if(!(-e "MD5")){ print "[!] Error: Cannot find local file 'MD5', check failed\n"; exit;} sysopen(MD5F, "MD5", O_RDONLY) or die "[!] Error: Couldn't open 'MD5' for reading: $!\n"; while ($line=) { if($line =~ m/\(($val)\).+(\w{32})/) { $sum = $2; } } close(MD5F); $md5->reset(); sysopen(CURF, "$val", O_RDONLY) or die "[!] Error: Couldn't open '$val' for account md5 sum: $!\n"; $md5->addfile("CURF"); my $checksum = $md5->hexdigest(); close(CURF); if($sum eq $checksum) {print "[+] md5 sum file '$val' - OK\n"; } else { print "[-] Warning: md5 sum wrong, from MD5 file - $sum, real md5 sum - $checksum\n[-] Type 'ok' for confirm ignoring: "; while() { if ($_ =~ /^ok$/){ return;} else {print "[-] Exit: You can check md5 sum files manually\n"; exit; }}} } sub fetch { my $cur_file = $_[0]; print "[~] Try get file '$cur_file'...\n"; $ftp->get("$cur_file") or die "[!] Error: Cannot get file from server: ", $ftp->message; if(-e "$cur_file"){ print "[+] Fetch '$cur_file' success\n"; } else { print "[!] Error: Cannot find local file '$cur_file', fetch failed\n"; exit;} } sub get_files { my @temp =(); my $res = shift; my $i = 0; @arrsuff = split('', $release); for(@arrsuff){ if($_ =~ /\d{1}/) { push(@temp, $_); } } for(@temp){$i++;} if($i == 2) { $suff = "$temp[0]$temp[1]"; } elsif($i == 3) { $suff = "$temp[0]$temp[1]$temp[2]"; } # cheers |-) $ftp = Net::FTP->new("$mirror", Timeout => 30, Passive => 1, Debug => 0) or die "[!] Error: Cannot connect to $mirror: $@"; $ftp->login("anonymous",'-anonymous@') or die "[!] Error: Cannot login", $ftp->message; $ftp->cwd("/pub/OpenBSD/$release/i386/") or die "[!] Error: Cannot change working directory: ", $ftp->message; &fetch("CKSUM"); &fetch("MD5"); $ftp->binary(); &fetch("cdrom$suff.fs"); &check_size("cdrom$suff.fs"); &check_md5("cdrom$suff.fs"); $res = rename("cdrom$suff.fs", "openbsd-release-$release/cdrom$suff.fs"); if($res != 1) {&error("Cannot move cdrom$suff.fs","$!");} $ftp->cwd("/pub/OpenBSD/$release/") or die "[!] Error: Cannot change working directory: ", $ftp->message; &fetch("src.tar.gz"); $res = rename("src.tar.gz", "openbsd-release-$release/$release/src.tar.gz"); if($res != 1) {&error("Cannot move src.tar.gz","$!");} &fetch("sys.tar.gz"); $res = rename("sys.tar.gz", "openbsd-release-$release/$release/sys.tar.gz"); if($res != 1) {&error("Cannot move sys.tar.gz","$!");} &fetch("ports.tar.gz"); $res = rename("ports.tar.gz", "openbsd-release-$release/$release/ports.tar.gz"); if($res != 1) {&error("Cannot move ports.tar.gz","$!");} &fetch("root.mail"); $res = rename("root.mail", "openbsd-release-$release/$release/root.mail"); if($res != 1) {&error("Cannot move root.mail","$!");} $ftp->cwd("/pub/OpenBSD/$release/i386/") or die "[!] Error: Cannot change working directory: ", $ftp->message; &fetch("base$suff.tgz"); &check_size("base$suff.tgz"); &check_md5("base$suff.tgz"); $res = rename("base$suff.tgz", "openbsd-release-$release/$release/i386/base$suff.tgz"); if($res != 1) {&error("Cannot move base$suff.tgz","$!");} &fetch("bsd"); &check_size("bsd"); &check_md5("bsd"); $res = rename("bsd", "openbsd-release-$release/$release/i386/bsd"); if($res != 1) {&error("Cannot move bsd","$!");} &fetch("bsd.rd"); &check_size("bsd.rd"); &check_md5("bsd.rd"); $res = rename("bsd.rd", "openbsd-release-$release/$release/i386/bsd.rd"); if($res != 1) {&error("Cannot move bsd.rd","$!");} &fetch("comp$suff.tgz"); &check_size("comp$suff.tgz"); &check_md5("comp$suff.tgz"); $res = rename("comp$suff.tgz", "openbsd-release-$release/$release/i386/comp$suff.tgz"); if($res != 1) {&error("Cannot move comp$suff.tgz","$!");} &fetch("etc$suff.tgz"); &check_size("etc$suff.tgz"); &check_md5("etc$suff.tgz"); $res = rename("etc$suff.tgz", "openbsd-release-$release/$release/i386/etc$suff.tgz"); if($res != 1) {&error("Cannot move etc$suff.tgz","$!");} &fetch("game$suff.tgz"); &check_size("game$suff.tgz"); &check_md5("game$suff.tgz"); $res = rename("game$suff.tgz", "openbsd-release-$release/$release/i386/game$suff.tgz"); if($res != 1) {&error("Cannot move game$suff.tgz","$!");} &fetch("man$suff.tgz"); &check_size("man$suff.tgz"); &check_md5("man$suff.tgz"); $res = rename("man$suff.tgz", "openbsd-release-$release/$release/i386/man$suff.tgz"); if($res != 1) {&error("Cannot move man$suff.tgz","$!");} &fetch("misc$suff.tgz"); &check_size("misc$suff.tgz"); &check_md5("misc$suff.tgz"); $res = rename("misc$suff.tgz", "openbsd-release-$release/$release/i386/misc$suff.tgz"); if($res != 1) {&error("Cannot move misc$suff.tgz","$!");} &fetch("xbase$suff.tgz"); $res = rename("xbase$suff.tgz", "openbsd-release-$release/$release/i386/xbase$suff.tgz"); if($res != 1) {&error("Cannot move xbase$suff.tgz","$!");} &fetch("xetc$suff.tgz"); $res = rename("xetc$suff.tgz", "openbsd-release-$release/$release/i386/xetc$suff.tgz"); if($res != 1) {&error("Cannot move xetc$suff.tgz","$!");} &fetch("xfont$suff.tgz"); $res = rename("xfont$suff.tgz", "openbsd-release-$release/$release/i386/xfont$suff.tgz"); if($res != 1) {&error("Cannot move xfont$suff.tgz","$!");} &fetch("xserv$suff.tgz"); $res = rename("xserv$suff.tgz", "openbsd-release-$release/$release/i386/xserv$suff.tgz"); if($res != 1) {&error("Cannot move xserv$suff.tgz","$!");} &fetch("xshare$suff.tgz"); $res = rename("xshare$suff.tgz", "openbsd-release-$release/$release/i386/xshare$suff.tgz"); if($res != 1) {&error("Cannot move xshare$suff.tgz","$!");} rename("CKSUM", "openbsd-release-$release/$release/i386/CKSUM"); rename("MD5", "openbsd-release-$release/$release/i386/MD5"); $ftp->quit; } sub create_iso { print "[~] Try create ISO...\n"; system("$sys_mk -b cdrom$suff.fs -R -r -J -o openbsd-$release-release-i386.iso openbsd-release-$release"); if($? == 0){ print "[+] ISO image successfull done.\n[+] Use OpenBSD, Good Luck.\n";} } if($opts{h}){&help;} if(defined $opts{r}){&check_release;} &head; &check_os; &warning; &check_conf; &ready; &make_dirs; &get_files; &create_iso;