#!/usr/bin/ruby
# -*- encoding: utf-8 -*-

require 'logger'
log = Logger.new(STDOUT)
log.level = Logger::WARN

log.debug("Created logger")
log.info("Program started")
log.warn("Nothing to do!")

require 'socket'

#デーモンには出来ないのでnohup を使うことにした。
#def daemon
#	fork do
#		Process::setsid
#		fork do
#			#Dir::chdir("/home/cms/fusr/test")
#			#File::umask(0)
#			#STDIN.close
#			#STDOUT.close
#			#STDERR.close
#			yield
#		end
#	end
#	exit!
#end

#ホストはWEBサーバーを利用
#HOSTNAME = 'codoo2hk.corede.net'
HOSTNAME = '192.168.11.25'
HOSTNAME2 = '192.168.1.22'
if ARGV[0] == '-p'
	#PORT = 3390
	PORT = ARGV[1]
	if ARGV[1].to_i < 3390 || ARGV[1].to_i > 3399
		printf("Usage: cms3-server -p PORT-No(3390 - 3399)\n")
		exit
	end
else
	printf("Usage: cms3-server -p PORT-No(3390 - 3399)\n")
	exit
end

#CMS のログインユーザの環境変数を利用する。
Sysname= ENV['SYSNAME']
Tabfile = ENV['TABFILE']
Version = ENV['KEIVER']
DiffDir='/home/cms/diff'
target=""

#このサーバーを起動したユーザのカレントディレクトリを取得する。
pwdy = Dir::getwd()
#puts pwdy
sp = [" "] 

#CMS3プロトコル開始
cms3 = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
sockaddr = Socket.sockaddr_in(PORT, HOSTNAME)
cms3.bind(sockaddr)

#デーモンは使わない
#daemon do
#	loop do

#ループする
while true

	#同時に接続可能なユーザは５クライアント
	cms3.listen(5)
	conn, addr = cms3.accept
	puts "Connect:#{Socket.unpack_sockaddr_in(sockaddr)}"

	#ユーザ名を取得（CMSホームディレクトリ名）
	dirname = Dir::pwd
	base = File::basename(dirname)
	#base = Sysname

	count = 0
	data = conn.recv(1024)

	#CMS3プロトコルの送受信を行う
	for i in data.split("\r\n")
#---------------------------------------------------------------------------
		len = i.length()
		#ユーザIDが空ではないか
		if i[0,5] == "USER "
			begin
				len = i.length()
				if i[0,len] == "USER " +  base
					edit_user=i[5,len]
					#puts "<" + edit_user + ">"
					if edit_user == base
						#break if data.empty?
						#puts "|" + edit_user + "|"
						conn.write '+OK USER' + '
'
					else
						conn.write '+NT USER' + '
'
						break
					end
				else
					conn.write '+NT USER' + '
'
					#puts "(" + i[0,len] + ")"
					break
				end
				rescue
				puts "USER Error"
			end
		end
#---------------------------------------------------------------------------
		len = i.length()
		#ユーザIDとパスワードを検査
		if i[0,5] == "PASS "
			begin
				#ユーザIDからSログインパスワードを取得する
				password=`awk 'BEGIN {FS=";"} /^'#{base}';/ {print $5}' #{DiffDir}/cmssetq`
				if password.chomp == i[5,len] 
					conn.write '+OK PASS' + '
'
				else
					conn.write '+NG PASS' + '
'
				end
				rescue
				puts "PASS Error"
			end
		end
#---------------------------------------------------------------------------
		#LISTのための処理
		if i[0,6] == "STAT 0"
			conn.write '+NT STAT 0' + " #{pwdy}" + '
'
		end
		#NEWFILEのための処理
		if i[0,6] == "STAT 1"
			len = i.length()
			begin 
				if File.exist?(i[7,len]) == true
					target=i[7,len]
					conn.write '+OK STAT 1 ' + i[7,len] + '
'
				else
					conn.write '+NG STAT 1 ' + '
'
				end
				rescue
				puts "Stat 1 Error"
			end
		end
#--------------------------------------------------------------------------------------
		#WHOのための処理
		if i[0,6] == "STAT 2"
			len = i.length()
			begin 
				target2=[i[7,len].sub(/\./,"_")]
				#リビジョンファイルがロックされているかどうか
				check=`grep "lock" #{DiffDir}/lock/#{Sysname}/#{target2}/lkfile#{Version}`
				#もしロックされている場合はその情報をGETLOGファイルから読み取り報告する
				if check.chomp == "lock" 
					op=`grep '#{Sysname};.*;#{i[7,len]};' #{DiffDir}/log/getlog.#{Version} | tail -1 | awk 'BEGIN {FS=";"}{print "[", $1,":" $2,$3,$4,$5"] to ",$6}'`
					#puts op
					if op.length() < 1
						conn.write '-OK STAT 2 ' + i[7,len] + ' GET -> ' + op + '
'
					else
						conn.write '-OK STAT 2 ' + i[7,len] + ' GET -> ' + op
					end
				else
					#conn.write '-NG STAT 2 ' + '
'
					conn.write '-NT STAT 2 ' + i[7,len] + ' Available GET ' + '
'
				end	
			rescue
			puts "Stat 2 Error"
			log.fatal("Caught exception; exiting")
			log.fatal(err)
			end
		end
		if i[0,6] == "STAT 3"
			len = i.length()
			begin 
				if File.exist?(i[7,len]) == true
					target=i[7,len]
					conn.write '+OK STAT 3 ' + i[7,len] + '
'
				else
					conn.write '+NG STAT 3' + '
'
				end
				rescue
				puts "Stat 1 Error"
			end
		end
#--------------------------------------------------------------------------------------
		#GETのための処理
		if i[0,6] == "STAT 4"
			len = i.length()
			begin 
				target4=[i[7,len].sub(/\./,"_")]
				#リビジョンファイルがロックされているかどうか
				check=`grep "lock" #{DiffDir}/lock/#{Sysname}/#{target4}/lkfile#{Version}`
				#もしロックされている場合はその情報をGETLOGファイルから読み取り報告する
				if check.chomp == "lock" 
					op=`grep '#{Sysname};.*;#{i[7,len]};' #{DiffDir}/log/getlog.#{Version} | tail -1 | awk 'BEGIN {FS=";"}{print "[", $1,":" $2,$3,$4,$5"] to ",$6}'`
					if op.length() < 1
						conn.write '+NT STAT 4 ' + i[7,len] + ' GET -> ' + op + '
'
					else
						conn.write '+NT STAT 4 ' + i[7,len] + ' GET -> ' + op
					end
				else
					conn.write '+OK STAT 4 ' + i[7,len] + ' Available GET ' + '
'
				end	
			rescue
			puts "Stat 2 Error"
			log.fatal("Caught exception; exiting")
			log.fatal(err)
			end
		end
#--------------------------------------------------------------------------------------
		#ここでLIST（ファイルのリスト表示)は行わない
		if i[0,6] == "LIST 0"
			begin
				conn.write '+OK LIST 0' + '
'
			rescue
			puts "LIST 0 Error"
			end
		end
#--------------------------------------------------------------------------------------
		#ここでLIST（ファイルのリスト表示)を行う
		if i[0,6] == "LIST 1"
			if File.exist?(Tabfile) == true
				`cp -p #{Tabfile} /home/cms/diff/tabs`
			end
			len = i.length()
			param = base + "tab"
			begin 
				list = ["+OK LIST 1"] 
				s = [""]
				rfile = open("/home/cms/diff/tabs/#{Tabfile}")
				while line = rfile.gets
					if line == 0
						break
					end
					s = line.split("\n")
					list.concat(sp)
					list.concat(s)
				end
				rfile.close()
				list.concat(sp)
				conn.write list
				conn.write '
'
				rescue
				puts "list Error"
			end
		end
#--------------------------------------------------------------------------------------
		#ここでリビジョンのLIST（ファイルのリビジョンリスト表示)を行う
		if i[0,6] == "LIST 2"
		len = i.length()
			begin 
				list2 = ["+OK LIST 2"] 
				s = [""]
				revDir=[i[7,len].sub(/\./,"_")]
				rfile = open("#{DiffDir}/lock/#{Sysname}/#{revDir}/verfile.#{Version}")
				while line = rfile.gets
					if line == 0
						break
					end
					s = line.split("\n")
					list2.concat(sp)
					list2.concat(s)
				end
				rfile.close()
				list2.concat(sp)
				conn.write list2
				conn.write '
'
				printf("%s\n",list2)
				rescue
				puts "Exec VGET LIST Error"
			end
		end
#--------------------------------------------------------------------------------------
		#ここでPUTは行わない
		if i[0,6] == "STOR 0"
			conn.write '+OK STOR 0' + '
'
		end
		#ここでPUTを実行する
		if i[0,6] == "STOR 1"
			len = i.length()
			begin 
				pfile=`echo #{i[6,len]} | awk 'BEGIN {FS=":"}{print $1}'`
				p=`echo #{i[6,len]} | awk 'BEGIN {FS=":"}{print $2}'`
				memo = p.chomp
				param = pfile.chomp + " " + base + " " + "#{Version}" + " " + "#{memo}"
				check=`cms3-put.ksh #{param}`
				if check.chomp == "-OK PUT"
					conn.write '+OK STOR 1' + '
'
				else
					conn.write '+NT STOR 1' + check.chomp + '
'
				end
				rescue
				puts "Exec put 1 Error"
			end
		end
#--------------------------------------------------------------------------------------
		#ここでNEWFILEを実行する
		if i[0,6] == "STOR 2"
			len = i.length()
			begin 
				pfile=`echo #{i[6,len]} | awk 'BEGIN {FS=":"}{print $1}'`
				p=`echo #{i[6,len]} | awk 'BEGIN {FS=":"}{print $2}'`
				memo = p.chomp
				param = pfile.chomp + " " + base + " " + "#{Version}" + " " + "#{memo}"
				check=`cms3-newfile.ksh #{param}`
				if check.chomp == "-OK NEW"
					conn.write '+OK STOR 2' + '
'
				else
					conn.write '+NT STOR 2' + '
'
				end
				rescue
				puts "Exec newfile Error"
			end
		end
#--------------------------------------------------------------------------------------
		#ここでGETは行わない
		if i[0,6] == "RETR 0"
			conn.write '+OK RETR 0' + '
'
			begin 
				rescue
				puts "Exec get Error"
			end
		end
#--------------------------------------------------------------------------------------
		#ここでGETを実行する
		if i[0,6] == "RETR 1"
			len = i.length()
			begin 
				param = i[6,len] + " " + base + " " + "#{Version}"
				check=`cms3-get.ksh #{param}`
				if check.chomp == "-OK GET"
					conn.write '+OK RETR 1' + check.chomp + '
'
				else
					conn.write '+NT RETR 1' + check.chomp + '
'
				end
				rescue
				puts "Exec get Error"
			end
		end
#--------------------------------------------------------------------------------------
		#ここでUNGETを実行する
		if i[0,6] == "RETR 2"
			len = i.length()
			begin 
				op=`grep '#{Sysname};.*;#{i[7,len]};.*;GET' #{DiffDir}/log/getlog.#{Version} | tail -1 | awk 'BEGIN {FS=";"}{print $3}'`
				if op.chomp == base
					param = i[6,len] + " " + base + " " + "#{Version}"
					check=`cms3-unget.ksh #{param}`
					if check.chomp == "-OK UNG"
						conn.write '+OK RETR 2 ' + check.chomp + '
'
					else
						conn.write '+NT RETR 2 ' + check.chomp + '
'
					end
				else
					conn.write '+NT RETR 2 ' + op.chomp + '
'
				end
				rescue
				puts "Exec unget Error"
			end
		end
#--------------------------------------------------------------------------------------
		#ここでUNVGETを実行する
		if i[0,6] == "RETR 4"
			len = i.length()
			begin 
				rfile=`echo #{i[6,len]} | awk 'BEGIN {FS=":"}{print $1}'`
				r=`echo #{i[6,len]} | awk 'BEGIN {FS=":"}{print $2}' | awk 'BEGIN {FS="."}{print $2}'`
				revision = r.chomp
				param = rfile.chomp + " " + base + " " + "#{Version}" + " " + "#{revision}"
				check=`cms3-unvget.ksh #{param}`
				if check.chomp == "-OK UNV"
					conn.write '+OK RETR 4 ' + check.chomp + '
'
				else
					conn.write '+NT RETR 4 ' + check.chomp + '
'
				end
				rescue
				puts "Exec unget Error"
			end
		end
#--------------------------------------------------------------------------------------
		#ここでVGETを実行する
		if i[0,6] == "RETR 3"
			len = i.length()
			begin 
				rfile=`echo #{i[6,len]} | awk 'BEGIN {FS=":"}{print $1}'`
				r=`echo #{i[6,len]} | awk 'BEGIN {FS=":"}{print $2}' | awk 'BEGIN {FS="."}{print $2}'`
				revision = r.chomp
				param = rfile.chomp + " " + base + " " + "#{Version}" + " " + "#{revision}"
				check=`cms3-vget.ksh #{param}`
				if check.chomp == "-OK VGT"
					conn.write '+OK RETR 3' + check.chomp + '
'
				else
					conn.write '+OK RETR 3' + check.chomp + '
'
				end
				rescue
				puts "Exec vget Error"
			end
		end
#--------------------------------------------------------------------------------------
		if i == "QUIT "
			begin
				conn.write '+OK QUIT ' + '
'
				rescue
				puts "QUIT 0 Error"
			end
		end
#--------------------------------------------------------------------------------------
		count = count + 1
	end
conn.close
end

