#!/usr/bin/perl

# Copyright (C) 2000-2010 NEC Corporation
# All Rights Reserved.

##001107 v5.1 ドメイン実装方式対応(wbmc03-001) S.Oku
##001108 v5.1 システム全体のバックアップ/リストア対応(wbmc03-002) Hori
##001110 v5.1 シンボリック対応修正 haramoto
##001120 v5.1 mailtar コマンド対応(wbmc03-002 バグ対応) Hori
##001204 v5.1 mailtar コマンドエラー処理対応(wbmc03-B17 バグ対応) Hori
##001219 v5.1 バックアップ機能強化対応 Hori (～001227)
##010126 v4.0.1 Sambaワークグループ指定対応(wbmc04-039)	Hori
##010126 v4.0.1 ファイル転送中断の戻るページ対応 Hori
##010126 v4.0.1 バックアップ先ディレクトリ作成失敗時処理中断対応 Hori
##010426 v4.0.1 クラスタ対応 Hori
##010510 v4.0.1 /etc/clusterpro バックアップ対象外 Hori
##010517 v4.0.1 smbclient コマンドの先頭がハイフンパスワード対応 Hori
##010705 v4.1.0  \Q ～ \E 対応 S.Oku
##010705 v4.1.1 中断ボタン押下時の戻る場所不正対応 Hori
##010709 v4.1.1 中断ボタン押下時の後処理不正対応 Hori
##010724 v4.1.1 Sambaバックアップのファイル転送の中断処理不正対応 Hori
##020930 v5.0.1 cronでのバックアップ時に送るmailに対応 matumura
##030303 v5.1.0 Sambaバックアップを中断したときに unmount するように変更 Oyama
##040224 v5.1.1 SambaのUnmount処理の問題点対応(Sambaの設定が残る) Ishiyama
##040921 v6.0.1 -s オプション指定時、7bit jis で出力するように変更 oyama
##041028 v6.0.1 StarDefence対応 oyama
##050830 v6.0.4 Samba の mkdir IPADDR 失敗時に umount する処理を追加 oyama
##051011 v6.0.8 StarDefence のディレクトリ(/home/local)を除外 oyama
##070129 v7.0.1 StarDefence対応処理の削除 sakai

#
# バックアップコマンド
#
# usage: wbmc_backup [-c conffilename] [-l] [-m] -i item
#        -c     コンフィグレーションファイル
#        -l     メッセージをログに出力
#        -l無し メッセージをSTDERRに出力
#        -m     実行メッセージを出力
#        -i     バックアップ対象のアイテム名
#        -p     即実行時の戻るページ			## 001219
#        -s     mail用のメッセージを出す		## 020930
#
# 戻り値: 成功:0
#         失敗:1
#

require "/opt/nec/wbmc/lib/wbmc.pl";
require join ("/", $WBMC_ADM_DIR, "service/11sendmail/fml", "fml.pl");

use utf8;
use encoding 'utf8', Filter=>1;
use Encode;

# added for smbmount/smbunmount (2002.5.21) by kima
require join ("/", $WBMC_ADM_DIR, "system/disk", "disk.pl");

$| = 1;
$old = select(STDERR); $| = 1; select($old);

# 決め打ち
$conf_file = "$WBMC_CONF_DIR/backup.conf";
$conf_lock = "backup.conf";
$tag_name = "wbmc_backup";
$log_file = "/var/log/wbmc";
$UMOUNT_RETRY = 5; # SmbUnMount のリトライ回数

$domain_conf = "$WBMC_CONF_DIR/domain.conf";
$domain_conf_lock = "domain.conf";
$cluster_type = &cluster_typechk();
$cluster_master = &cluster_masterchk();		# 010426 add


## バックアップファイル分割対応 2002.5.23 kima
## wbmc/adm/sysyem/backup/restore.cgi と対応を取る
require join ("/", $WBMC_ADM_DIR,"system/backup/split_backup.pl");


# 引数処理
$item = "";
$errtolog = 0; # 0:STDERR, 1:LOG 
$msgout = 0;
$argerr = 0;
$argerrmsg = "";
$pageout = "";		## 001219
$tar_status = 0;	## 001227
$send_mail_flg = 0;	## 020930
for ($i = 0; $i < @ARGV; $i++) {
	if ($ARGV[$i] eq "-c") {
		if ($i == $#ARGV) {
			$argerrmsg = "'$ARGV[$i]'";
			$argerr = 1;
			next;
		}
		$conf_file = $ARGV[$i + 1];
		$i++;
	} elsif ($ARGV[$i] eq "-i") {
		if ($i == $#ARGV) {
			$argerrmsg = "'$ARGV[$i]'";
			$argerr = 1;
			next;
		}
		$item = $ARGV[$i + 1];
		$i++;
	} elsif ($ARGV[$i] eq "-l") {
		$errtolog = 1;
	} elsif ($ARGV[$i] eq "-m") {
		$msgout = 1;
	} elsif ($ARGV[$i] eq "-s") {
		$send_mail_flg = 1;
#		binmode(STDOUT, ':encoding(7bit-jis)');
#		binmode(STDERR, ':encoding(7bit-jis)');
	} elsif ($ARGV[$i] eq "-p") {		## 001219 kokokara
		if ($i == $#ARGV) {
			$argerrmsg = "'$ARGV[$i]'";
			$argerr = 1;
			next;
		}
		$pageout = $ARGV[$i + 1];
		$i++;							## 001219 kokomade
	} else {
		$argerrmsg = "'$ARGV[$i]'";
		$argerr = 1;
	}
}
if ( $send_mail_flg != 1 ){
#	binmode(STDOUT, ':encoding(euc-jp)');
#	binmode(STDERR, ':encoding(euc-jp)');
}
if ($send_mail_flg == 1) {print("バックアップ開始\n");}
if ($argerr) {
	&writeError("invalid argment $argerrmsg", "");
	if ($send_mail_flg == 1) {print("invalid argment $argerrmsg\n");}
	if ($send_mail_flg == 1) {print("バックアップに失敗しました。\n");}
	exit(1);
}

# サーバ形態対応	001219
if (!($workmode = &getConfParam("WbMC", "WorkMode"))) {
	&writeError("read file error INITCONF.INI", "$item");
	if ($send_mail_flg == 1) {print("read file error INITCONF.INI\n");}
	if ($send_mail_flg == 1) {print("バックアップに失敗しました。\n");}
	exit(1);
}

# コンフィグから設定値を読み込む
if (!&readFile($conf_file, $conf_lock, *conf)) {
	&writeError("read file error '$conf_file'", "$item");
	if ($send_mail_flg == 1) {print("read file error '$conf_file'\n");}
	if ($send_mail_flg == 1) {print("バックアップに失敗しました。\n");}
	exit(1);
}

# 010426 kokokara
# フェイルオーバクラスタのスレーブは実行不可
if ($cluster_type eq "cluster" && $cluster_master eq "slave") {
	if ($item eq "home" || $item eq "mail" || $item eq "fml") {
		&writeError("no start failover group", "$item");
		if ($send_mail_flg == 1) {print("no start failover group\n");}
		if ($send_mail_flg == 1) {print("バックアップに失敗しました。\n");}
		exit(1);
	}
}
# 010426 kokomade

$item_flag = 0;
for ($i = 0; $i < @conf; $i++) {
	if ($conf[$i] =~ /^\s*$item\s*{\s*$/) {
		$item_flag = 1;
	}
	if ($item_flag && $conf[$i] =~ /^\s*}\s*$/) {
		$item_flag = 0;
	}
	if ($item_flag && $conf[$i] =~ /^\s*TARGET\s*=\s*(.*)\s*$/) {
		$target_dir = &getValue($1);
	}
	if ($item_flag && $conf[$i] =~ /^\s*PRE_BACKUP\s*=\s*"(.*)"\s*$/) {
		$pre_backup = &getValue($1);
	}
	if ($item_flag && $conf[$i] =~ /^\s*POST_BACKUP\s*=\s*"(.*)"\s*$/) {
		$post_backup = &getValue($1);
	}
	if ($item_flag && $conf[$i] =~ /^\s*BACKUP\s*=\s*(.*)\s*$/) {
		$backup_dir = &getValue($1);
	}
	if ($item_flag && $conf[$i] =~ /^\s*ROTATE\s*=\s*(.*)\s*$/) {
		$rotate_max = &getValue($1);
	}
        if ($item_flag && $conf[$i] =~ /^\s*BACKUPMODE\s*=\s*(.*)\s*$/) {
                $backupmode = &getValue($1);
				@line = split(/\s+/, $backupmode);
        }
# wbmc04-039 kokokara
        if ($item_flag && $conf[$i] =~ /^\s*WORKGROUP\s*=\s*(.*)\s*$/) {
                $workgroup = &getValue($1);
				$workgroup_arg = &encodeCmdArg($workgroup);
        }
# wbmc04-039 kokomade
        if ($item_flag && $conf[$i] =~ /^\s*WINMACHINE\s*=\s*(.*)\s*$/) {
                $winmachine = &getValue($1);
				$winmachine_arg = &encodeCmdArg($winmachine);
        }
        if ($item_flag && $conf[$i] =~ /^\s*SHARE\s*=\s*(.*)\s*$/) {
                $share = &getValue($1);
				$share_arg = &encodeCmdArg($share);
        }
        if ($item_flag && $conf[$i] =~ /^\s*SMBUSER\s*=\s*(.*)\s*$/) {
                $smbuser = &getValue($1);
				$smbuser_arg = &encodeCmdArg($smbuser);
        }
        if ($item_flag && $conf[$i] =~ /^\s*SMBPASSWD\s*=\s*"(.*)"\s*$/) {
                $smbpasswd = &getValue($1);
				$smbpasswd_arg = &encodeCmdArg($smbpasswd);
        }
        if ($item_flag && $conf[$i] =~ /^\s*FTPSERVER\s*=\s*(.*)\s*$/) {
                $ftpserver = &getValue($1);
				$ftpserver_arg = &encodeCmdArg($ftpserver);
        }
        if ($item_flag && $conf[$i] =~ /^\s*FTPUSER\s*=\s*(.*)\s*$/) {
                $ftpuser = &getValue($1);
				$ftpuser_arg = &encodeCmdArg($ftpuser);
        }
        if ($item_flag && $conf[$i] =~ /^\s*FTPPASSWD\s*=\s*"(.*)"\s*$/) {
                $ftppasswd = &getValue($1);
				$ftppasswd_arg = &encodeCmdArg($ftppasswd);
        }
        if ($item_flag && $conf[$i] =~ /^\s*FTPBACKUP\s*=\s*"(.*)"\s*$/) {
                $ftpbackup = &getValue($1);
                $ftpbackup_arg = $ftpbackup;
        }
        if ($item_flag && $conf[$i] =~ /^\s*DOMAINBACKUPTYPE\s*=\s*(.*)\s*$/) {
                $domainbackuptype = &getValue($1);
        }
        if ($item_flag && $conf[$i] =~ /^\s*DOMAINNAME\s*=\s*(.*)\s*$/) {
                $domainname = &getValue($1);
				@domainlist = split(/\s+/, $domainname);
        }
	    if ($item_flag && $conf[$i] =~ /^\s*FMLBACKUPTYPE\s*=\s*(.*)\s*$/) {
                $fmlbackuptype = &getValue($1);
	    }
	    if ($item_flag && $conf[$i] =~ /^\s*FMLNAME\s*=\s*(.*)\s*$/) {
                $fmlname = &getValue($1);
				@fmllist = split(/\s+/, $fmlname);
	    }
	    if ($item_flag && $conf[$i] =~ /^\s*SPOOL\s*=\s*(.*)\s*$/) {
                $spool = &getValue($1);
	    }
		# 010426 kokokara
	    if ($item_flag && $conf[$i] =~ /^\s*SYMLINK\s*=\s*(.*)\s*$/) {
				$cluster_symlink = &getValue($1);
				@symlinklist = split(/\s+/, $cluster_symlink);
	    }
		# 010426 kokomade
}

# 設定値が無い場合は既定値を設定
if ($backup_dir eq "" || $backupmode =~ /SMB/ || $backupmode =~ /FTP/) {
	$backup_dir = "/var/backup";
}
if ($rotate_max eq "") {
	$rotate_max = 3;
}

# バックアップ対象のディレクトリが存在しない場合は終了
if ($target_dir eq "") {
	&writeError("no target", $item);
	if ($send_mail_flg == 1) {print("no target\n");}
	if ($send_mail_flg == 1) {print("バックアップに失敗しました。\n");}
	exit(1);
}

#バックアップディレクトリが無ければ作成
if (! -d $backup_dir) {
	if (!mkdir($backup_dir, 0755)) {
		&writeError("mkdir error", $item);
		if ($send_mail_flg == 1) {print("mkdir error\n");}
		if ($send_mail_flg == 1) {print("バックアップに失敗しました。\n");}
		exit(1);	## 010129
	}
}

# ドメイン対応:ドメインコンフィグから読み込む
if ($item eq "home" || $item eq "mail") {
	if ($domainbackuptype eq "ALL") {
		@domainlist = ();
		if (!&readFile($domain_conf, $domain_conf_lock, *conf)) {
			&writeError("read file error 'domain_conf'", "$item");
			if ($send_mail_flg == 1) {print("read file error 'domain_conf'\n");}
			if ($send_mail_flg == 1) {print("バックアップに失敗しました。\n");}
			exit(1);
		}
		# ドメイン名取得
		$get_flg = 0;
		for ($i = 0; $i < @conf; $i++) {
			if ($conf[$i] =~ /^\s*#/) {
				next;
			}

			if ($conf[$i] =~ /^\s*<DOMAINNAME\s*(.*)>\s*$/) {
				$domainname = $1;
				$domainname =~ s/\s*$//;
				$domainname =~ s/^\s*//;
				$get_flg = 1;
			} elsif ($get_flg && ($conf[$i] =~ /^\s*<\/DOMAINNAME\s*>\s*$/ ||		## 001219
								 ($conf[$i] =~ /^\s+/ && $WBMC_MGRVER =~ /^1\./ && $WBMC_MGRNAME =~ /Management Console for Appliance Server/))) {	## 001219
				$get_flg = 0;
				if (($domain_mode eq "REAL")&&($cluster_type)) {
					next;
				}
				if ($item eq "home") {
					# ドメイン作成
					push(@domainlist, $domainname);
				}
				if ($item eq "mail" && $mail eq "on") {
					# ドメイン作成
					push(@domainlist, $domainname);
				}
			} elsif ($get_flg && $conf[$i] =~ /^\s*MODE\s*(.*)\s*$/) {
				$domain_mode = $1;
				$domain_mode =~ s/\s*$//;
				$domain_mode =~ s/^\s*//;
			} elsif ($get_flg && $conf[$i] =~ /^\s*MAIL_SERVICE\s*(.*)\s*$/) {
				$mail = $1;
				$mail =~ s/\s*$//;
				$mail =~ s/^\s*//;
			}
		}
	}
	$domaincnt = @domainlist;

	if ($item eq "mail") {
		@target_dir_list = ();
		@target_dir_list = split(/\s+/, $target_dir);
		$target_dir_master = $target_dir_list[0];
		$target_dir_spool = "";
		for ($i = 1; $i < @target_dir_list; $i++) {
			$target_dir_spool .= " $target_dir_list[$i]";
		}
		if ($spool) {
			$domaincnt++;
		}
	} else {
		$target_dir_master = $target_dir;
	}

	if ($domaincnt eq 0) {
		&writeError("no target domain", "$item");
		if ($send_mail_flg == 1) {print("no target domain");}
		if ($send_mail_flg == 1) {print("バックアップに失敗しました。\n");}
		exit(1);
	}
} elsif ($item eq "fml") {
	# メーリングリスト対応
	if ($fmlbackuptype eq "ALL") {
		@fmllist = ();
#		&getListName(*fmlname);
		@fmlname = &getAllDomainName();
		for ($i = 0; $i < @fmlname; $i++) {
			push(@fmllist, $fmlname[$i]);
		}
	}
	$domaincnt = @fmllist;
	@domainlist = @fmllist;		# 010426 add
	$target_dir_master = $target_dir;
	if ($domaincnt eq 0) {
		&writeError("no target fml", "$item");
		if ($send_mail_flg == 1) {print("no target fml\n");}
		if ($send_mail_flg == 1) {print("バックアップに失敗しました。\n");}
		exit(1);
	}
} elsif ($item eq "sysconf") {
#	$target_dir_master = $target_dir;	# 010426 del
	$domaincnt = 1;
} else {
	$domaincnt = 1;
}

# ターゲットが存在するかチェック	010426 add
if ($item eq "sysconf" || $item eq "conf" || $item eq "log") {
	$target_dir =~ s/[\s,]+/ /g;
	@target_dir_chk = split(/ /, $target_dir);
	$target_dir = "";
	for($i = 0; $i < @target_dir_chk; $i++) {
		$dir_chk = $target_dir_chk[$i];
		$dir_chk =~ s/\*//;
		if (-e $dir_chk) {
			$target_dir .= " $target_dir_chk[$i]";
		}
	}
}

# CLUSTERPRO Lite! 対応で /etc/clusterpro は対象外		010510 add
if (-e "/etc/clusterpro") {
	if ($item eq "sysconf" || $item eq "conf") {
		# ディレクトリの一覧を得る
		if (!opendir(DIR, "/etc")) {
			&writeError("no directory", "$item");
			if ($send_mail_flg == 1) {print("no directory\n");}
			if ($send_mail_flg == 1) {print("バックアップに失敗しました。\n");}
			exit(1);
		}
		@dirs = readdir(DIR);
		closedir(DIR);
		@dirs = sort(@dirs);
		$target_etcdir = "";
		foreach $dir (@dirs) {
			if (($dir eq ".") || ($dir eq "..")) {
				next;
			}
			if ($dir =~ /clusterpro/){
				next;
			}
			$target_etcdir .= " /etc/$dir";
		}
		$target_dir =~ s/\/etc /$target_etcdir /;
	}
}

# バックアップ方式毎のドメイン毎
for ($j = 0; $j < @line; $j++) {
	$backupmode = $line[$j];
	for ($k = 0; $k < $domaincnt; $k++) {
		if ($backupmode eq "LOCAL") {

			if ($item eq "home" || $item eq "mail") {
				if ($item eq "mail" && $spool && $k eq @domainlist) {
					$backup_file = "backup_${item}_spool";
					$rotate_file = "$backup_dir/.current_${item}_spool";
					$rotate_file_lock = ".current_${item}_spool";
				} else {
					$backup_file = "backup_${item}_${domainlist[$k]}";
					$rotate_file = "$backup_dir/.current_${item}_${domainlist[$k]}";
					$rotate_file_lock = ".current_${item}_${domainlist[$k]}";
				}
			} elsif ($item eq "fml") {
				$backup_file = "backup_${item}_${fmllist[$k]}";
				$rotate_file = "$backup_dir/.current_${item}_${fmllist[$k]}";
				$rotate_file_lock = ".current_${item}_${fmllist[$k]}";
			} else {
				$backup_file = "backup_$item";
				$rotate_file = "$backup_dir/.current_$item";
				$rotate_file_lock = ".current_$item";
			}

		} elsif ($backupmode eq "SMB") {

			#if (!&readFile("/etc/sysconfig/network-scripts/ifcfg-eth0", "ifcfg-eth0", *file)) {
            $device = &getNetworkDevice();
			if (!&readFile("/etc/sysconfig/network-scripts/ifcfg-$device", "ifcfg-$device", *file)) {
				&writeError("read file error", $item);
				if ($send_mail_flg == 1) {print("read file error\n");}
				if ($send_mail_flg == 1) {print("バックアップに失敗しました。\n");}
				exit(1);
			}
			for ($i = 0; $i < @file; $i++) {
				if ($file[$i] =~ /^\s*IPADDR\s*=\s*(.*)\s*$/) {
					$ipaddr = $1;
				}
			}

			if ($item eq "home" || $item eq "mail") {
				if ($item eq "mail" && $spool && $k eq @domainlist) {
					$backup_file = "backup_smb_${item}_spool";
					$rotate_file = "$backup_dir/.current_smb_${item}_spool";
					$rotate_file_lock = ".current_smb_${item}_spool";
				} else {
					$backup_file = "backup_smb_${item}_${domainlist[$k]}";
					$rotate_file = "$backup_dir/.current_smb_${item}_${domainlist[$k]}";
					$rotate_file_lock = ".current_smb_${item}_${domainlist[$k]}";
				}
			} elsif ($item eq "fml") {
				$backup_file = "backup_smb_${item}_${fmllist[$k]}";
				$rotate_file = "$backup_dir/.current_smb_${item}_${fmllist[$k]}";
				$rotate_file_lock = ".current_smb_${item}_${fmllist[$k]}";
			} else {
				$backup_file = "backup_smb_$item";
				$rotate_file = "$backup_dir/.current_smb_$item";
				$rotate_file_lock = ".current_smb_$item";
			}

		} elsif ($backupmode eq "FTP") { # obsolete ?

			if ($item eq "home" || $item eq "mail") {
				if ($item eq "mail" && $spool && $k eq @domainlist) {
					$backup_file = "backup_ftp_${item}_spool";
					$rotate_file = "$backup_dir/.current_ftp_$item_spool";
					$rotate_file_lock = ".current_ftp_$item_spool";
				} else {
					$backup_file = "backup_ftp_${item}_${domainlist[$k]}";
					$rotate_file = "$backup_dir/.current_ftp_${item}_${domainlist[$k]}";
					$rotate_file_lock = ".current_ftp_${item}_${domainlist[$k]}";
				}
			} elsif ($item eq "fml") {
				$backup_file = "backup_ftp_${item}_${fmllist[$k]}";
				$rotate_file = "$backup_dir/.current_ftp_${item}_${fmllist[$k]}";
				$rotate_file_lock = ".current_ftp_${item}_${fmllist[$k]}";
			} else {
				$backup_file = "backup_ftp_$item";
				$rotate_file = "$backup_dir/.current_ftp_$item";
				$rotate_file_lock = ".current_ftp_$item";
			}
		}

		# ローテート用ナンバー読み込み
		if (!&readFile($rotate_file, $rotate_file_lock, *current)) {
			$backup_num = 0;
			$backup_num_current = -1;			## 001221
		} else {
			$backup_num = $current[0] + 1;
			$backup_num_current = $current[0];	## 001221
		}

		# MAX と比較
		if ($rotate_max <= $backup_num) {
			$backup_num = 0;
		}

        $suffix = ".tgz";
		$tgzfile = "${backup_file}_${backup_num}${suffix}";

		# split したファイルを出力するディレクトリ
		# local の場合は $backup_dir
		# smb の場合は $backup_dir_smbmnt/$ipaddr (default : /mnt/_tmp_smbmnt.xxxxxxxx.xx/$ipaddr)
		$backup_out_dir = $backup_dir;

		if ($backupmode eq "LOCAL") {
			# 作成するファイルと同名ファイルを削除
		  $backup_out_dir = $backup_dir;
		  &remove_old_bakcup($backup_out_dir, $tgzfile);
		}

		if($backupmode eq "SMB") {
		  if(!mkdir($backup_dir_smbmnt, 0755)) {
		    &writeError("mkdir error backup_dir_smbmnt : $backup_dir_smbmnt ($item)");
		    if ($send_mail_flg == 1) {print("mkdir error backup_dir_smbmnt : $backup_dir_smbmnt\n");}
		    if ($send_mail_flg == 1) {print("バックアップに失敗しました。\n");}
		    exit(1);
		  }
		  $backup_out_dir = "$backup_dir_smbmnt/$ipaddr";
		  my $result_smbmnt = &SmbMount($winmachine, $share, $backup_dir_smbmnt, $smbuser_arg, $smbpasswd_arg, $workgroup_arg);
		  $result_smbmnt = decode('utf8', $result_smbmnt);
		  print "&SmbMount : $result_smbmnt\n";
		  # 2004/02/24 add by Ishiyama
		  my $err = &delSmb($winmachine, $share, $backup_dir_smbmnt);
		  if ($err) {
		    &writeError("&delSmb error : $err");
		  }
		  #
		  &remove_old_bakcup($backup_out_dir, $tgzfile);
		  $result_smbmnt = &SmbUnMount($backup_dir_smbmnt);
		  if($result_smbmnt) {
		    my $umount_count = 0;
		    while($result_smbmnt && $umount_count < $UMOUNT_RETRY) {
		      if($result_smbmnt) {
			&writeError("&SmbUnMount retry: $result_smbmnt");
		      }
		      sleep(5);
		      $result_smbmnt = &SmbUnMount($backup_dir_smbmnt);
		      $umount_count++;
		    }
		  }
		  if($result_smbmnt) {
		    &writeError("&SmbUnMount : $result_smbmnt");
		    if ($send_mail_flg == 1) {
#		      print("&SmbUnMount : $result_smbmnt");
		      &writeError("&SmbUnMount : $result_smbmnt");
		    }
                  }
		}

		# 001219 kokokara
		$mode = "";
		$hostname = "";
		if ($WBMC_MGRVER =~ /^1\./ && ($item eq "home" || $item eq "mail") && $WBMC_MGRNAME =~ /Management Console for Appliance Server/) {
			if (!&GetDomainParam($domainlist[$k], "MODE", *mode)) {
				&writeError("cannot read file MODE", "$item");
				if ($send_mail_flg == 1) {print("cannot read file MODE\n");}
				if ($send_mail_flg == 1) {print("バックアップに失敗しました。\n");}
				exit(1);
			}
			if (!&GetDomainParam($domainlist[$k], "HOSTNAME", *hostname)) {
				&writeError("cannot read file HOSTNAME", "$item");
				if ($send_mail_flg == 1) {print("cannot read file HOSTNAME\n");}
				if ($send_mail_flg == 1) {print("バックアップに失敗しました。\n");}
				exit(1);
			}
		}
		# 001219 kokomade

		# 010426 kokokara
		# フェイルオーバクラスタのマスタでのみ実行
		@symlink_dir_list = ();
		if ($cluster_type eq "cluster" && $cluster_master eq "master") {
			for($l = 0; $l < @symlinklist; $l++) {
				$chkdir = "$symlinklist[$l]";
				# /home/web
				if ($item eq "home") {
					$chkdir = "$symlinklist[$l]/$domainlist[$k]";
				}
				# /home/mail
				if ($item eq "mail") {
					# spool 限定 2 つめ
					if ($spool && $k eq @domainlist) {
						if ($l != 1) {
							next;
						}
					} else {
						if ($l > 0) {
							last;
						}
						$chkdir = "$symlinklist[$l]/$domainlist[$k]";
					}
				}
				@symlink_dir = ();
				if ($err = &chksymlink($chkdir, *symlink_dir)) {
					&writeError("$err", "$item");
					if ($send_mail_flg == 1) {print("$err\n");}
					if ($send_mail_flg == 1) {print("バックアップに失敗しました。\n");}
					exit(1);
				}
				for($i = 0; $i < @symlink_dir; $i++) {
					if (&dupchksymlink($symlink_dir[$i], @symlink_dir_list)) {
						if ($item eq "fml") {
							push(@symlink_dir_list, "$symlink_dir[$i]/${fmllist[$k]}");
						} else {
							push(@symlink_dir_list, $symlink_dir[$i]);
						}
					}
				}
			}
		}
		# 010426 kokomade

		# ドメイン用バックアップ対象ディレクトリ設定
		if ($item eq "home" || $item eq "mail") {
			# 実ディレクトリ対応
#			if (!&GetDomainParam($domainlist[$k], "MODE", *mode)) {		##001110
#				&writeError("cannot read file MODE", "$item");			##001110
#				exit(1);												##001110
#			}															##001110
#			if (!&GetDomainParam($domainlist[$k], "HOSTNAME", *hostname)) {
#				&writeError("cannot read file HOSTNAME", "$item");
#				exit(1);
#			}
#			if ($mode eq "REAL") {
#				$target_dir = "$target_dir_master/${hostname}.${domainlist[$k]}";
#			} else {
#				if (@symlink_dir_list eq 0) {		# 010426 del
					# 001219 kokokara
					if ($mode eq "REAL" && $WBMC_MGRVER =~ /^1\./ && $WBMC_MGRNAME =~ /Management Console for Appliance Server/) {
						$target_dir = "$target_dir_master/${hostname}.${domainlist[$k]}";
					} else {
						$target_dir = "$target_dir_master/${domainlist[$k]}";
					}
					# 001219 kokomade
#				} else {							# 010426 del
					# フェイルオーバクラスタ時
					for ($l = 0; $l < @symlink_dir_list; $l++) {
						$target_dir .= " $symlink_dir_list[$l]";			# 010426 rep
					}
#				}									# 010426 del
#			}
			if ($item eq "mail" && $spool && $k eq @domainlist) {
				$target_dir = $target_dir_spool;
                # 010426 kokokara
				# フェイルオーバクラスタ時
				for ($l = 0; $l < @symlink_dir_list; $l++) {
					$target_dir .= " $symlink_dir_list[$l]";
				}
                # 010426 kokomade
			}
		} elsif ($item eq "fml") {
			# 010426 kokokara
			if ($cluster_type eq "cluster") {
				$target_dir = $target_dir_master;
			} else {
				$target_dir = "$target_dir_master/${fmllist[$k]}";
			}
			# フェイルオーバクラスタ時
			for ($l = 0; $l < @symlink_dir_list; $l++) {
				$target_dir .= " $symlink_dir_list[$l]";
			}
		} elsif ($item eq "conf" || $item eq "sysconf") {
			# フェイルオーバクラスタ時
			@slink_list = ();
			for ($l = 0; $l < @symlink_dir_list; $l++) {
				$target_dir .= " $symlink_dir_list[$l]";
				# slink 取得 or aquota.group or aquota.user
				if ($item eq "sysconf") {
					if ($symlink_dir_list[$l] =~ /^(.*)\/.wbmc\/.wbmcsys\//	||
						$symlink_dir_list[$l] =~ /^(.*)\/web\//				||
						$symlink_dir_list[$l] =~ /^(.*)\/mail\//) {
						if (&dupchksymlink($1, @slink_list)) {
							push(@slink_list, $1);
							if (-f "$1/.wbmc/slink") {
								$target_dir .= " $1/.wbmc/slink";
							}
							if (-e "$1/aquota.group") {
								$target_dir .= " $1/aquota.group";
							}
							if (-e "$1/aquota.user") {
								$target_dir .= " $1/aquota.user";
							}
						}
					}
				}
			}
			# 010426 kokomade
		}

		# メーリングリスト対応：ロック
		if ($item eq "fml") {
#			if (&lockFml($fmllist[$k], $WBMC_LOCK_R_NB, *lockcf, *lockph)) {
			@lockcf = ();
			if (&lockDomainFml($fmllist[$k], $WBMC_LOCK_R_NB, *lockcf)) {
				&writeError("lockFml failed $fmllist[$k]", "$item");
				if ($send_mail_flg == 1) {print("lockFml failed $fmllist[$k]\n");}
				if ($send_mail_flg == 1) {print("バックアップに失敗しました。\n");}
				exit(1);
			}
		}

		# 引数に-mあり:メッセージは画面に表示
		#       -m無し:メッセージは表示しない

		# アーカイブ作成
		print "------ Start $backupmode -----\n";
#		print "------ TARGET $target_dir -----\n";
		# mailtar 存在チェック 001219 kokokara
		# mailtar コマンド	(システム全ファイル)
		#	appliance3.0 ～
		#	appliance2.0 MailServer	(Standalone/MailCluster) SEC (Standalone)
		# tar コマンド		(システム全ファイル)
		#	appliance2.0 WebServer	(Standalone/WebLoadbalance)
		$mailtar_flg = "off";
		if ($WBMC_MGRVER =~ /^1\./ && $WBMC_MGRNAME =~ /Management Console for Appliance Server/) {
			if (($workmode eq "Standalone" && $WBMC_MACHINE_TYPE eq "mail") ||
				 $workmode eq "MailCluster"	||
				 ($workmode eq "Standalone" && $WBMC_MACHINE_TYPE eq "pre")) {
				$mailtar_flg = "ok";
			}
		} else {
			$mailtar_flg = "ok";
		}
		# 001219 kokomade

		# Samba back up の方式変更にともない mount/unmount する
		# 2002.5.21 kima
		if($backupmode eq "SMB") {
		  if(!mkdir($backup_dir_smbmnt, 0755)) {
		    &writeError("mkdir error backup_dir_smbmnt : $backup_dir_smbmnt ($item)");
		    if ($send_mail_flg == 1) {print("mkdir error backup_dir_smbmnt : $backup_dir_smbmnt\n");}
		    if ($send_mail_flg == 1) {print("バックアップに失敗しました。\n");}
		    exit(1);
		  }
		  &SmbMount($winmachine, $share, $backup_dir_smbmnt, $smbuser_arg, $smbpasswd_arg, $workgroup_arg);
		  # ここで IPADDR の値にしたがってディレクトリを掘る
		  if((! -d "$backup_dir_smbmnt/$ipaddr") && !mkdir("$backup_dir_smbmnt/$ipaddr", 0755)) {
		    &writeError("mkdir error backup_dir_smbmnt/IPADDR : $backup_dir_smbmnt/$ipaddr ($item)");
		    if ($send_mail_flg == 1) {print("mkdir error backup_dir_smbmnt/IPADDR : $backup_dir_smbmnt/$ipaddr\n");}
		    if ($send_mail_flg == 1) {print("バックアップに失敗しました。\n");}
		    #2005/08/30 mkdir 失敗時 umount 処理追加 oyama
		    my $result_smbmnt = &SmbUnMount($backup_dir_smbmnt);
		    if($result_smbmnt) {
		      my $umount_count = 0;
		      while($result_smbmnt && $umount_count < $UMOUNT_RETRY) {
		        if($result_smbmnt) {
			  &writeError("&SmbUnMount retry : $result_smbmnt");
		        }
		        sleep(5);
		        $result_smbmnt = &SmbUnMount($backup_dir_smbmnt);
		        $umount_count++;
		      }
		    }
		    my $err = &delSmb($winmachine, $share, $backup_dir_smbmnt);
		    if ($err) {
		      &writeError("&delSmb error : $err");
		    }
		    #2005/08/30 end
		    exit(1);
		  }
		}

#2004/10/26 StarDefence対応 oyama
#2007/01/29 StarDefence対応処理の削除 sakai
#                system("/etc/init.d/webdef stop >/dev/null 2>&1");

                if ($pre_backup ne "" ) {
			&writeLog("exec \"$pre_backup\" before backup.", $tag_name, $log_file);
	                system("$pre_backup >/dev/null 2>&1");
                }

		if ($item eq "mail" || ($item eq "sysconf" && $mailtar_flg eq "ok")) {
# delete -P option 001202 seki
# --exclude /home/local directory 051011 oyama 
			$pid = open(CMD, "/opt/nec/mailtar/mailtar cvfz - --ignore-failed-read --exclude-from=/etc/opt/nec/wbmc/exclude $target_dir | $split_cmd - ${backup_out_dir}/$tgzfile$split_postfix 2>&1 |");
		} else {
# delete -P option 001202 seki
# update /bin/tar -> /opt/nec/baktar/baktar 001227
# add --exclude option 051011 oyama
			$pid = open(CMD, "/opt/nec/baktar/baktar cvfz - --ignore-failed-read --exclude-from=/etc/opt/nec/wbmc/exclude $target_dir | $split_cmd - ${backup_out_dir}/$tgzfile$split_postfix 2>&1 |");
		}

		# 001219 kokokara
		$newpage = "./$pageout?$item";
		$killmode = "tgz";
		if ($send_mail_flg == 1) {
			print("バックアップ実行中\n");
		}
		else {
			print "バックアップ実行中．．．<A HREF=\"./kill_pid2.cgi?$pid+$newpage+$killmode+$backup_dir+$tgzfile+${backup_out_dir}\">中断</A>\n";
		}
		# 001219 kokomade

		# メーリングリスト対応：アンロック
		if ($item eq "fml") {
#			&unlockFml($lockcf, $lockph);
			$lockf = "";
			&unlockDomainFml($lockf);
		}

		$errmessage = "";
		$cnt = 0;
		while (<CMD>) {
			if (/\/opt\/nec\/baktar\/baktar: / || /\/opt\/nec\/mailtar\/mailtar: /) {	# wbmc03-B17 update	001227
				if (/Removing leading/i) {
					next;
				}
				if (/Archive contains future timestamp/i) {
					next;
				}
		        # tarメッセージを赤文字で表示
				print "<FONT COLOR=red>$_</FONT>";
				$errmessage = $_;
			}
			if (/^baktar: / || /^mailtar: /) {							# wbmc03-B17 update		001227
				$errmessage = $_;
				last;
			}
			if ($msgout) {
				if (($cnt % 100) == 0) {
					if ($send_mail_flg == 1) {
						print("$cnt: $_");
					}
					else {
						print "$cnt: $_";
					}
				}
				$cnt++;
			}
		}
		close(CMD);

#2004/10/26 StarDefence対応 oyama
#2007/01/29 StarDefence対応処理の削除 sakai
#                system("/etc/init.d/webdef start >/dev/null 2>&1");

                if ($post_backup ne "" ) {
			&writeLog("exec \"$post_backup\" after backup.", $tag_name, $log_file);
	                system("$post_backup >/dev/null 2>&1");
                }

		if ($?) {
			if ($errmessage eq "") {
				&writeError("tar: Unknown error", $item);
				if ($send_mail_flg == 1) {print("tar: Unknown error\n");}
				goto error;
			} else {
				&writeError($errmessage, $item);
				if ($send_mail_flg == 1) {print("$errmessage\n");}
				goto error;
			}
		} elsif ($errmessage) {			## 001227
			$tar_status = 1;			## 001227
		}

		chdir("$backup_out_dir");

		# バックアップ完了後に目印用のファイルを置く
		# restore 時に目印にする。2002.5.22 kima
		system("/bin/touch $backup_out_dir/$tgzfile");

        # バックアップ時のシステム情報を $tgzfile に格納する
        if ( 1 ) {
		    my $tmpfile = "$backup_out_dir/$tgzfile";
            $tmpfile =~ s/${suffix}$//;
            @infofile = ( "/etc/opt/nec/wbmc/updateVersion" );
            foreach my $f ( @infofile ) {
                if ( -e $f ) {
                    system("/bin/tar --append -f $tmpfile $f >/dev/null 2>&1");
                }
            }
            if ( -e $tmpfile ) {
                system("/bin/gzip -f -S .tgz $tmpfile >/dev/null 2>&1");
            }
        }

		if ($backupmode eq "LOCAL") {
			# パーミッション変更
            if (&chmod_backup_files(0600, $backup_out_dir, "$tgzfile") != 0) {
                &writeError("chmod error LOCAL", $item);
			    if ($send_mail_flg == 1) {print("chmod error LOCAL\n");}
		        goto error;
		    }
		} elsif ($backupmode eq "SMB") {
			# パーミッション変更
            if (&chmod_backup_files(0600, $backup_out_dir, "$tgzfile") != 0) {
		        &writeError("chmod error SMB $tgzfile", $item);
			    if ($send_mail_flg == 1) {print("chmod error SMB $tgzfile\n");}
		        goto error;
		    }

			system("/bin/touch $backup_dir/samba_running");	## 中断処理判断 app 4.1 add

		} elsif ($backupmode eq "FTP") {

			# パーミッション変更
			if (!chmod(0666, "$backup_dir/$tgzfile")) {
				&writeError("chmod error", $item);
				if ($send_mail_flg == 1) {print("chmod error\n");}
				goto error;
			}

			# ファイル転送
			$pid = open(CMD, "/usr/bin/lftp $ftpserver_arg -u $ftpuser_arg,$ftppasswd_arg -e \"cd $ftpbackup_arg;mput $tgzfile*;exit\" 2>&1 |");
			#$newpage = "./$pageout";	# app 4.1 del
			runpid($pid, $newpage, "ファイル転送中");	# 010129	010426 rep
			$errmessage = "";
			while (<CMD>) {
				if ($msgout) {
					print $_;
				}
				if (/bytes transferred/i) {
					next;
				}
				$errmessage = $_;
			}
			close(CMD);
			if ($errmessage ne "") {
				&writeError($errmessage, $item);
				if ($send_mail_flg == 1) {print("$errmessage\n");}
				goto error;
			}
			# ファイル削除
			#unlink ("$tgzfile");
		    system("/bin/rm -fr $backup_dir/$tgzfile*");
		}

		# 001221 kokokara  app 4.1 rep
		if (-f "$backup_dir/samba_running" || $backupmode eq "LOCAL" || $backupmode eq "FTP") {
			$current[0] = $backup_num;
			if (!&writeFile($rotate_file, $rotate_file_lock, @current)) {
				&writeLog("write file error", $tag_name, $log_file);
				if ($send_mail_flg == 1) {print("write file error $log_file)\n");}
			}
		}
		system("/bin/rm -fr $backup_dir/samba_running");
		# 001221 kokomade app 4.1 rep

		# Samba back up の方式変更にともない mount/unmount する
		# 2002.5.21 kima
		if($backupmode eq "SMB") {
		  chdir($backup_dir);

		  my $result_smbmnt = &SmbUnMount($backup_dir_smbmnt);
		  if($result_smbmnt) {
		    my $umount_count = 0;
		    while($result_smbmnt && $umount_count < $UMOUNT_RETRY) {
		      if($result_smbmnt) {
			&writeError("&SmbUnMount retry : $result_smbmnt");
		      }
		      sleep(5);
		      $result_smbmnt = &SmbUnMount($backup_dir_smbmnt);
		      $umount_count++;
		    }
		  }
		  # 2004/02/24 add by Ishiyama
		  my $err = &delSmb($winmachine, $share, $backup_dir_smbmnt);
		  if ($err) {
		    &writeError("&delSmb error : $err");
		  }
		  #

		  if(-d $backup_dir_smbmnt && !rmdir($backup_dir_smbmnt)) {
		    &writeError("rmdir error backup_dir_smbmnt : $backup_dir_smbmnt ($item)");
		    if ($send_mail_flg == 1) {print("rmdir error backup_dir_smbmnt : $backup_dir_smbmnt\n");}
		  }
		}


	}
}

## 正常終了			001227
if ($tar_status == 0) {
	if ($send_mail_flg == 1) {print("バックアップが終了しました。\n");}
	exit(0);
} else {
	if ($send_mail_flg == 1) {print("バックアップに失敗しました。\n");}
	exit(2);
}

# ファイルを削除して終了
error:
	chdir("$backup_out_dir");				# 001222
	unlink("$tgzfile");
	chdir("$backup_dir");
        if($backupmode eq "SMB") {
	  my $result_smbmnt = &SmbUnMount($backup_dir_smbmnt);
	  if ($send_mail_flg == 1) {
		print("&SmbUnMount : $result_smbmnt\n");
	  }
	  else {
	  	print "&SmbUnMount : $result_smbmnt\n";
	  }
	  # 2004/02/24 add by Ishiyama
	  my $err = &delSmb($winmachine, $share, $backup_dir_smbmnt);
	  if ($err) {
		&writeError("&delSmb error : $err");
	  }
	  #
	  if(-d $backup_dir_smbmnt && !rmdir($backup_dir_smbmnt)) {
	    &writeError("rmdir error backup_dir_smbmnt : $backup_dir_smbmnt ($item)");
	    if ($send_mail_flg == 1) {print("rmdir error backup_dir_smbmnt : $backup_dir_smbmnt\n");}
	  }
	}
	if ($send_mail_flg == 1) {print("バックアップに失敗しました。\n設定、ネットワーク状態を確認してください。\n");}
	exit(1);

#-----------------------------------------------------------------------
sub writeError {
	local($msg, $item) = @_;

	$msg = decode('utf8', $msg);
	$msg =~ s/\s*$//;
	if ($item ne "") {
		$msg = "[$item]$msg";
	}
	if ($errtolog) {
		$msg = encode('utf8', $msg);
		&writeLog($msg, $tag_name, $log_file);
	} else {
		$msg = encode('utf8', $msg);
		print STDERR "$tag_name:$msg\n";
	}
}

sub getValue {
	local($str) = @_;

	$str =~ s/^[\s]*//;
	$str =~ s/[\s]*$//;
	if ($str =~ /^"(.*)"$/) {
		$str = $1;
	}

	return($str);
}

sub runpid
{
#	my($pid) = @_;	010129 del
	# wbmc04-039 *argv add
	# 010426 タイトル引数追加(第3パラメータ)
	my($pid, $newpage, $title, $killmode, $backup_dir, $tgzfile, $winmachine_arg, $share_arg, $smbpasswd_arg, $smbuser_arg, $ipaddr, $rotate_file, $rotate_file_lock, $workgroup_arg) = @_;		# app 4.1 rep

	local(*IN);
	my($i,@ilnes,$flg,@line,$cnt);

#	my($newpage) = "./index.cgi?$item";		010129 del
	# wbmc04-039 *argv add
	if ($send_mail_flg == 1) {
		print("$title\n");
	}
	else {
		print "$title．．．<A HREF=\"./kill_pid2.cgi?$pid+$newpage+$killmode+$backup_dir+$tgzfile+$winmachine_arg+$share_arg+$smbpasswd_arg+$smbuser_arg+$ipaddr+$rotate_file+$rotate_file_lock+$workgroup_arg\">中断</A>\n";	# app 4.1 rep
	}
	$cnt = 0;
	for (;;){
		# プロセス一覧を読み取る
		open(IN, "/bin/ps -efwwwww |");
		<IN>;
		@lines = <IN>;
		close(IN);

		$flg = 0;
		for ($i = 0; $i <= $#lines; $i++) {
			@line = split(/ +/, $lines[$i]);
			if ($line[2] eq $pid) {
				$flg = 1;
				last;
			}
		}
		if ($flg eq 0) {
			last;
		}
		sleep 1;
		$cnt++;
		if ($cnt eq 5) {
			print "．\n";
			$cnt = 0;
		} else {
			print "．";
		}
	}
}

# シンボリックリンク先を取得
sub chksymlink
{
	local($dirname,*symlink_dir) = @_;
	local(*DIR);
	my($i,$err,@lslist,@lsinfo);

	if (!opendir(DIR, "$dirname")) {
		$err = "not directory $dirname<BR>";
		return $err;
	}
	close(DIR);

	open(DIR, "/bin/ls -la $dirname |");
	@lslist = <DIR>;
	close(DIR);

	for ($i = 0; $i < @lslist; $i++) {
		@lsinfo = split(/\s+/, $lslist[$i]);
		if ($lsinfo[0] =~ /^l/) {
			push(@symlink_dir, $lsinfo[10]);
		}
	}
	return "";
}

sub dupchksymlink
{
	local($symlink,@list) = @_;
	my($i);

	for ($i = 0; $i < @list; $i++) {
		if ($list[$i] eq $symlink) {
			return 0;
		}
	}
	return 1;
}

