#!/usr/bin/perl   
#               -w ワーニングを出す
# /usr/local/bin/ddns4nifty/ddo/ddns-ddo-120829.pl
# ddo!.jpのddnsに対応 2012/07/01-->07 完成か?バッチでは走った。
# niftyのプログラムを元に修正
#
# IPが変更になった場合にうまく更新出来ないバグを修正 2012/8/29 
#
# new ip 読み込み他をサブルーチン化する 2009/02/26--->2009/03/01
# wgetで正しく更新されたことを確認した後、その旨を書き出す
#                                  2009/02/26--->2009/03/01
# マッチパターンにマッチしなかった場合にif文での判断を修正(2009/03/03)
# 
# 完成 
# perlのワーニング(-w)を止めた+コメント文の表現を修正(2009/03/10)
# IPアドレスが何回目で正しく得られているかを出力する(2009/03/18)
# wgetがが何回目で正しく得られているかを出力する(2009/03/18)
#
# 
#

use strict; # 宣言した変数以外を使えなくする

my $ddoid="DDO_ID";
my $ddopass="DDO_PASSWORD";

my $file="/usr/local/bin/ddns4nifty/ddo/ipaddr.txt";
my $update="/usr/local/bin/ddns4nifty/ddo/update.log";
my $no_update="/usr/local/bin/ddns4nifty/ddo/no_update.log";
my $ip_change_log="/usr/local/bin/ddns4nifty/ddo/ip_change_log.txt";
my $ip_change_log_temp="/usr/local/bin/ddns4nifty/ddo/ip_change_log_temp";
my $update_d_t="/usr/local/bin/ddns4nifty/ddo/update_d_t.txt";
my $wget;
my $ipaddr ;
my $oldipaddr;
my $ipaddr_success ; # 正しくIPアドレスが更新されたか? 0:正しく更新 1:エラー
my $i ;
my $i_count ;# ip addressが何回目に得られたか
my $ii_count ;# wgetが何回目に得られたか
my $ok_pattern = "SUCCESS";
my $ok_update="";
my $line ;
my $null="";

$| = 1;   # ゼロ以外が代入されると出力をバッファリングしなくなる。


# ###########################  メインプログラム  ###############################
open FH, "<",$file || die "Error: ipaddr.txt $!\n" ; #ファイルを入力で開く
$oldipaddr = <FH>  ;                 # 記録されているIPアドレスを入力
close FH;


LABEL1: for($i=1 ; $i<4 ; $i++ ) { ;  # IPアドレスの更新チェック、
#                                       最大3回IPアドレスを求める
    $ipaddr=&newip();     # 新しいipアドレスに変更されているかチェック
    $i_count=$i ;
#    print "Debug 58\n";
    last LABEL1 if($ipaddr ne $null ) ;  # 新しいIPアドレスが正しく
#                                        得られていればループを抜ける
} ; # end for
#    print "Debug 62\n";


if( $ipaddr eq $null ) { ;         # 正しくIPアドレスが得られたか? *********
     &no_new_ip( $no_update ) ;    # 新しいIPアドレスが得られないエラー。
#                     3回トライしました、でもipアドレスが得られません。
#    print "Debug 68\n";
} # end if
elsif(  $ipaddr eq $oldipaddr )  { # IPアドレスに変更なし ---------------------
  &noipchange( $i,$ip_change_log,$ddoid,$ddopass,$ipaddr,$ok_pattern,$file,$ip_change_log_temp,$i_count,$update,$no_update, $update_d_t);  

#    print "Debug 73\n";
}  # end elsif
else {  #  ----------------------------------------------------------------------
  for ( $i=1 ; $i<4 ; $i++) {      # IPアドレスに変更有り、
#                                    最大3回IPアドレスの更新を試みる 
#    print "Debug 78\n";

#     2012/7/7変更 サブルーチン化する
#
      $ipaddr_success=&ip_update_func($i,$ip_change_log,$ddoid,$ddopass,$ipaddr,$ok_pattern,$file,$ip_change_log_temp,$i_count,$update); #2012/7/7 追加
#      print $ipaddr_success; # Debug

      if($ipaddr_success eq 0) {
#        print "Debug 86\n";
        exit; #正しく更新されて、終了
      }

  } # end of for



#   ---------------------  正しくIPアドレスが更新されなかった場合 --------------
    &time_prt($update);               # 時刻の呼び出しとプリント
    open (OUT,">> $update");          # 更新記録を書き込むupdate.log fileを開く
    print OUT "3回試みましたが正しくIPアドレスが更新されませんでした\n" ; 
#                                 IPアドレスが正しく更新されなかった。
    close(OUT);

    &time_prt($ip_change_log);            # 時刻の呼び出しとプリント
    open IN,"<",$ip_change_log_temp;      # サーバーの更新ログが記録されている
#                                         # 仮ファイルを開く
    open (OUT,">> $ip_change_log");       # $ip_change_log.txtに変更に失敗した
#                                         # サーバーログを書き込むファイルを開く
    print OUT "\n";                       # 時刻を記述した後に
#                                         #「改行コード」を加える
    while ($line = <IN>) { ;              # 1行づつ読み込む
      print OUT "$line" ;                 # 1行づつ書き出す(append)、
#                              元の行に「改行コード」があるため、改行は記述せず
    } ; # end while
    print OUT "New IP ADDRESS=$ipaddr new_ip_count=$i_count new_wget=$ii_count\n\n" ; 
#                                 変更されなかったIPアドレスなど書き出す
    close IN ;
    close (OUT) ;
#    print "Debug 116\n";
}  # end of else -----------------------------------------------------------------


# #######################  メインプログラム エンド  #####################


# -----------------------  新しいipアドレスを求める ------------------------
sub newip  {
    my $ip;
    my $wget_s = `wget -O- -q http://info.ddo.jp/remote_addr.php` ; 
#                      2012/07/01 ddo.jp アドレスを得る(無料サイト)

    $wget_s =~/[0-9]+(\.[0-9]+){3}/;     # IPアドレスとのマッチパターン
    $ip = $&;                            # マッチしたIPアドレスを入力
    # print "Debug 131 newip=:$ip\n";    # デバッグ用 IPアドレス出力
    return $ip ;
}



# -----------  新しいIPアドレスが得られなかった -------------
sub no_new_ip {
  my $no_up=$_[0];
  &time_prt($no_up);                   # 時刻の呼び出しとプリント
  open (OUT,">>$no_up");
  print OUT "3回トライしました。でもipアドレスが得られません。\n" ; 
#                                   新しいIPアドレスが得られないエラー
  close(OUT);
}




# ------------------  IPアドレスに変更なし -------------------------
sub noipchange { 
#   引数が一つの場合は$_[0]を、
#   引数が複数の場合は@_[0],@_[1],----@_[n]を使う

my $i=$_[0] ;                 # カウンター for
my $ip_change_log=$_[1] ;     # ip_change_log.txt
my $ddoid=$_[2] ;             # ddo!のID
my $ddopass=$_[3] ;           # ddo!のパスワード
my $ipaddr=$_[4] ;            # 得られたIPアドレス ルーチン内変数
my $ok_pattern=$_[5] ;        # 
my $file=$_[6] ;              # ipaddr.txt 保存ファイル
my $ip_change_log_temp=$_[7] ; # ip_change_log_tmp
my $i_count=$_[8] ;           # カウンター
my $update=$_[9] ;            # update.log
my $no_update=$_[10] ;        # no_update.log
my $update_d_t=$_[11] ;       # update_d_t.txt 変更日時の保存file
# 
my $wget;
my $ii_count;
my $line ;
my $ok_update="";



  if ( &date_time_chk( $update_d_t ) eq  0 ) {  # 7日以上IPアドレスが変わっていない?
#    7日未満でIPアドレスを更新しない
#    print "Debug 177 no_update file :$no_update\n";
    &time_prt($no_update);                     # 時刻の呼び出しとプリント
    open (OUT,">>$no_update");
    print OUT "ip address is not changed:$ipaddr i_count=$i_count\n" ;
#                                        IPアドレスに変更無し
    print OUT "" ;
    close(OUT);
  } # end of if
  else {  # 7日以上経過した場合 IPアドレスの強制更新と記録
      $ipaddr_success=&ip_update_func($i,$ip_change_log,$ddoid,$ddopass,$ipaddr,$ok_pattern,$file,$ip_change_log_temp,$i_count,$update, $update_d_t); #2012/7/7 追加
      if($ipaddr_success eq 0) {
#        print "Debug 188\n";
        exit; # 強制更新が正しく行われて終了
      } # end of if
  } # end of else
} # end of sub noipchange



# -------------------  時刻のプリント -----------------------------
sub  time_prt {
  my $no_up2=$_[0]; # 引数が一つの場合は$_[0]を、
#                    引数が複数の場合は@_[0],@_[1],----@_[n]を使う
  my $sec;
  my $min;
  my $hour;
  my $mday;
  my $mon;
  my $year;
  my $wday;
  my $yday;
  my $isdst;
  my $tt;

  $tt=time();
  ($sec, $min, $hour, $mday, $mon, $year,
    $wday, $yday, $isdst) = localtime($tt);
  $year=$year+1900;
  $mon=$mon+1;
  open (OUT,">> $no_up2");
  printf OUT "%02d/%02d/%02d     %02d:%02d:%02d   ", $year,$mon,$mday,$hour,$min,$sec  ;
  close(OUT);

}

# --------------  自動更新用、日付時刻のファイルへの書出 --------------------
#
# 2012/07/06 追加
#

sub  date_time_prt {
  my $date_t=$_[0]; # 出力するファイル名
#                    引数が一つの場合は$_[0]を、
#                    引数が複数の場合は@_[0],@_[1],----@_[n]を使う

my  $tt=time();
  open (OUT,"> $date_t");
    printf OUT $tt ; # 日付時刻をファイルに書き出す
  close(OUT);

} ; # end of sub date_time_prt

# --------------  日付時刻が7日を過ぎているか判断 --------------------
#
# 2012/07/06 追加
#

sub  date_time_chk {
  my $date_t_in=$_[0];  # 入力するファイル名
#  my $date_t_out=@_[1]; # 出力するファイル名
#                    引数が一つの場合は$_[0]を、
#                    引数が複数の場合は@_[0],@_[1],----@_[n]を使う

my  $tt_now=time(); # 現在の日付時刻
my  $tt   ; # 比較する日付時刻

  open (IN,"< $date_t_in"); # ファイルから日時を読み出す
    $tt = <IN> ; 
  close(IN);
  # print "Debug 256 update_d_t.txt =$tt\n" ;
  if ($tt_now >= $tt+7*24*3600 ) { 
#  if ($tt_now >= $tt+3600 ) { 
    # print "Debug 259 IP change by force\n" ;
    return  1 ; # 7日以上過ぎていればフラグを立てる
  } # end of if
  else {
    return  0 ; # 7日未満であればフラグクリアー
  }  # end of else

}  # end of sub date_time_chk

    

# ------------ IPアドレスの更新 ---------------------------
#
#
sub ip_update_func {
# 引数が一つの場合は$_[0]を、
# 引数が複数の場合は@_[0],@_[1],----@_[n]を使う
my $i=$_[0] ;# for loop の回数
my $ip_change_log=$_[1] ;
my $ddoid=$_[2] ;
my $ddopass=$_[3] ;
my $ipaddr=$_[4] ;
my $ok_pattern=$_[5] ;
my $file=$_[6] ;
my $ip_change_log_temp=$_[7] ;
my $i_count=$_[8] ;
my $update=$_[9] ;
my $update_d_t=$_[10] ; # 日時を記録したファイル
#
my $wget;
my $ii_count;
my $line ;
my $ok_update="";


$wget=`wget -O $ip_change_log_temp  -o $ip_change_log_temp http://free.ddo.jp/dnsupdate.php?dn=$ddoid&pw=$ddopass`;
#                                2012/07/01 ddo.jpのアドレス更新(無料サイト)
$ii_count=$i ;# for loop の回数 何度目にwgetが得られたか
sleep(1) ;                                # 1秒待つ
open IN,"<",$ip_change_log_temp;   # サーバーの更新ログが
#                                    記録されている仮ファイルを開く
LABEL3:   while ($line = <IN>) { ;        # ok パターンを探す
            if ( $line    =~/SUCCESS/ ) {;   # ok パターンにマッチ
#              print "Debug 302 ok_pattern_\n" ;
              $ok_update ="SUCCESS";
              last LABEL3 ; # while文を終了
            } ; # end if
          } ; # end while
close IN ;

#          print "Debug 309 $ok_update\n" ;

if ( $ok_update eq $ok_pattern ) { 
#              正しくIPアドレスが更新された場合 -------
#  print "Debug  313\n";
  open FH,">",$file|| die "Error: ipaddr.txt $!\n" ;
  print FH "$ipaddr" ;   # 変更された新しいIPアドレスをfileに書き出す
  close FH;

  &time_prt($ip_change_log);      # 時刻の呼び出しとプリント
  open IN,"<",$ip_change_log_temp;# サーバーの更新ログが
#                                   記録されている仮ファイルを開く
  open (OUT,">> $ip_change_log"); # $ip_change_log.txtにサーバーログを書き込むファイルを開く
  print OUT "\n";                 # 時刻を記述した後に「改行コード」を加える
  while ($line = <IN>) { ;        # 1行づつ読み込む
    print OUT "$line" ;           # 1行づつ書き出す(append)、
#                      元の行に「改行コード」があるため、改行は記述せず
  }  # end while
 print OUT "New IP ADDRESS=$ipaddr new_ip_count=$i_count new_wget=$ii_count\n\n" ; #   変更された新しいIPアドレスをfileに書き出す
 close IN ;
 close (OUT) ;

 &time_prt($update);    # 時刻の呼び出しとプリント
 open (OUT,">> $update");  # 更新記録を書き込むupdate.log fileを開く
 print OUT "ip addres is changed:$ipaddr\n" ; 
#                  IPアドレスが更新された旨を書き出す
 close(OUT);

#            #####  更新日時を記録 以下1行 2012/7/6追加 
 &date_time_prt($update_d_t); # 更新日時を記録
 
 return 0 ;                   # 正常に更新された。
 }  # end if
return 1;     # 正常にIPアドレスが更新されなかった
}  # end of sub ip_update_func