|
|
|
# trimMachines.rb
|
|
|
|
# using ruby to delete files older than X days
|
|
# w: gets mapped to source dir
|
|
# x: gets mapped to dest dir
|
|
|
|
DEBUGGING = false
|
|
|
|
ORIG_DRIVE = "w:"
|
|
COPY_DRIVE = "x:"
|
|
|
|
require "ftools"
|
|
|
|
DaysToKeep = 60
|
|
SecondsPerDay = 24 * 60 * 60
|
|
DaysToKeepInSeconds = DaysToKeep * SecondsPerDay
|
|
|
|
def loadCredentials
|
|
$credentials = {}
|
|
File.open("d:\\backupScripts\\directoryList.txt").each do | line |
|
|
dataLine = line.chomp
|
|
next if (dataLine.length > 0) and (dataLine[0].chr == "#")
|
|
if dataLine =~ /(.*),(.*),(.*),(.*),(.*),(.*),(.*)/
|
|
|
|
usr = $1
|
|
psswd = $2
|
|
machine = $3
|
|
|
|
creds = []
|
|
creds[0] = usr
|
|
creds[1] = psswd
|
|
$credentials[machine] = creds
|
|
end
|
|
end
|
|
end
|
|
|
|
# machineReady() : determines if machine is available on network
|
|
# could be gone, off, have firewall misconfigured, other things
|
|
|
|
def machineReady(machine)
|
|
ready = true
|
|
|
|
begin
|
|
TCPSocket.new(machine, 139).close
|
|
TCPSocket.new(machine, 445).close
|
|
s = UDPSocket.new
|
|
s.connect(machine,137)
|
|
s.close
|
|
s = UDPSocket.new
|
|
s.connect(machine,138)
|
|
s.close
|
|
rescue SocketError
|
|
$logFile.print "#{machine} not found on network.\n"
|
|
ready = false
|
|
rescue Errno::EBADF
|
|
$logFile.print "#{machine}'s file/print sharing ports not accessible.\n"
|
|
ready = false
|
|
rescue Errno::ETIMEDOUT
|
|
$logFile.print "Contact with #{machine} timed out. Off?\n"
|
|
ready = false
|
|
rescue Errno::ECONNREFUSED
|
|
$logFile.print "Connection with #{machine} refused.\n"
|
|
ready = false
|
|
end
|
|
ready
|
|
end
|
|
|
|
def decrypt(pss)
|
|
outStr = ""
|
|
pss.each_byte do | ch |
|
|
if (ch > 79) # 80 <= ch <= 126
|
|
newCh = (ch - 47).chr
|
|
#print "[#{ch.chr}] went to [#{newCh}]\n"
|
|
outStr << newCh
|
|
else # 33 <= ch <= 79
|
|
newCh = (ch + 47).chr
|
|
#print "[#{ch.chr}] went to [#{newCh}]\n"
|
|
outStr << newCh
|
|
end
|
|
end
|
|
outStr
|
|
end
|
|
|
|
def deleteFileIfNecessary(dirPath,file)
|
|
origDirectory = ORIG_DRIVE + dirPath
|
|
|
|
# on host: directory exists
|
|
presentOnOrigMachine = File.directory?(origDirectory)
|
|
|
|
# on host: file exists too
|
|
presentOnOrigMachine = File.exist?(origDirectory+"\\"+file) if presentOnOrigMachine
|
|
|
|
if not presentOnOrigMachine
|
|
begin
|
|
# if copy is more than NumDaysToSave days old
|
|
copyOfFile = COPY_DRIVE + dirPath + "\\" + file
|
|
if (Time.now - File.stat(copyOfFile).mtime) > DaysToKeepInSeconds
|
|
$logFile.print "Deleting file #{copyOfFile}\n"
|
|
File.rm_f(copyOfFile) if not DEBUGGING
|
|
end
|
|
rescue
|
|
# do nothing so we can continue with other files
|
|
# can get here for a couple reasons
|
|
# 1) maybe: file deleted between time mtime called and rm_f called
|
|
# 2) certain if filename contains non-ascii chars: Ruby chokes with Errno::ENOENT
|
|
# maybe more
|
|
$logFile.print "Deletion of #{copyOfFile} failed!\n"
|
|
end
|
|
end
|
|
end
|
|
|
|
def deleteDirectoryIfNecessary(dirPath,directory)
|
|
copyOfDir = COPY_DRIVE + dirPath + "\\" + directory
|
|
begin
|
|
if (Dir.new(copyOfDir).entries.length <= 2)
|
|
$logFile.print "Deleting directory #{copyOfDir}\n"
|
|
Dir.delete(copyOfDir) if not DEBUGGING
|
|
end
|
|
rescue
|
|
# can probably get here for a couple reasons
|
|
# 1) maybe: dir deleted between time entries called and delete called
|
|
# 2) maybe: if dir name contains non-ascii chars: Ruby may choke with Errno::ENOENT
|
|
# maybe more
|
|
# do nothing so we can continue with other files
|
|
end
|
|
end
|
|
|
|
def trimDirectory(dirPath,directory)
|
|
|
|
relDirName = dirPath + "\\" + directory
|
|
copyFullDirName = COPY_DRIVE + relDirName
|
|
if copyFullDirName.length > 255
|
|
$logFile.print "***Directory path too long in trimDirectory: #{copyFullDirName}\n"
|
|
return
|
|
end
|
|
Dir.foreach(copyFullDirName) do | dirEntry |
|
|
next if (dirEntry == ".") or (dirEntry == "..")
|
|
if (copyFullDirName.length + 1 + dirEntry.length) > 255
|
|
$logFile.print "***File path too long in trimDirectory: #{copyFullDirName+"\\"+dirEntry}\n"
|
|
elsif File.directory?(copyFullDirName+"\\"+dirEntry)
|
|
trimDirectory(relDirName,dirEntry)
|
|
deleteDirectoryIfNecessary(relDirName,dirEntry)
|
|
else # its a file
|
|
deleteFileIfNecessary(relDirName,dirEntry)
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
def trimMachine
|
|
trimDirectory("",".")
|
|
end
|
|
|
|
def setupAndTrimMachine(usr,psswd,src,dest)
|
|
|
|
$logFile.print "\n\n*******Start TRIMMING machine: #{src}\n\n"
|
|
print "\n\n*******Start TRIMMING machine: #{src}\n\n"
|
|
|
|
# make sure the two drives are not allocated
|
|
system("net use #{COPY_DRIVE} /delete")
|
|
system("net use #{ORIG_DRIVE} /delete")
|
|
|
|
# map source drive: \\machine\drive psswd /user:usr
|
|
$logFile.print "Mapping ORIG_DRIVE (#{ORIG_DRIVE}) to #{src}\n"
|
|
print "Mapping ORIG_DRIVE (#{ORIG_DRIVE}) to #{src}\n"
|
|
system("net use #{ORIG_DRIVE} #{src} #{psswd} /user:#{usr}")
|
|
|
|
# map dest drive: \\server\share\machine\drive
|
|
$logFile.print "Mapping COPY_DRIVE (#{COPY_DRIVE}) to #{dest}\n"
|
|
print "Mapping COPY_DRIVE (#{COPY_DRIVE}) to #{dest}\n"
|
|
system("net use #{COPY_DRIVE} #{dest}")
|
|
|
|
trimMachine
|
|
|
|
# deallocate the two drives
|
|
system("net use #{COPY_DRIVE} /delete")
|
|
system("net use #{ORIG_DRIVE} /delete")
|
|
|
|
$logFile.print "\n\n*******End TRIMMING machine: #{src}\n\n"
|
|
print "\n\n*******End TRIMMING machine: #{src}\n\n"
|
|
|
|
end
|
|
|
|
def trimMachines(server,share)
|
|
|
|
Dir.foreach("\\\\#{server}\\#{share}") do | machine |
|
|
|
|
next if machine == "."
|
|
next if machine == ".."
|
|
|
|
# do nothing if machine not available to network
|
|
next if not machineReady(machine)
|
|
|
|
creds = $credentials[machine]
|
|
|
|
# do nothing if this machine is no longer referenced in backup data file
|
|
next if creds.nil?
|
|
|
|
Dir.foreach("\\\\#{server}\\#{share}\\#{machine}") do | drive |
|
|
|
|
next if drive == "."
|
|
next if drive == ".."
|
|
|
|
srcDir = "\"\\\\#{machine}\\#{drive}\""
|
|
dstDir = "\"\\\\#{server}\\#{share}\\#{machine}\\#{drive}\""
|
|
|
|
setupAndTrimMachine(creds[0], decrypt(creds[1]), srcDir, dstDir)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
def next8pm(now)
|
|
retTime = Time.local(now.year,now.month,now.day,20,0,0)
|
|
if now.hour >= 20 # its between 8 pm and midnight
|
|
retTime = retTime + SecondsPerDay # add a day's worth of seconds
|
|
end
|
|
retTime
|
|
end
|
|
|
|
def saveOldLogs
|
|
8.downto(1) do | logNum |
|
|
logFile = "trim0#{logNum}.log"
|
|
if FileTest.exist?(logFile)
|
|
savedFile = "trim0#{logNum+1}.log"
|
|
File.rm_f(savedFile) if FileTest.exist?(savedFile)
|
|
# file move from curr log to next log
|
|
File.move(logFile,savedFile)
|
|
end
|
|
end
|
|
logFile = "trim01.log"
|
|
File.rm_f(logFile) if FileTest.exist?(logFile)
|
|
end
|
|
|
|
until true == false
|
|
|
|
if not DEBUGGING
|
|
#sleep until the next 8 pm
|
|
now = Time.now
|
|
secondsToSleep = next8pm(now) - now
|
|
print "\n\n ********* Sleeping #{secondsToSleep} seconds until 8:00 pm ********* \n\n"
|
|
sleep(secondsToSleep)
|
|
end
|
|
|
|
saveOldLogs
|
|
$logFile = File.open("trim01.log","w")
|
|
|
|
loadCredentials
|
|
|
|
trimMachines("Ironman","dept1")
|
|
trimMachines("Ironman","dept2")
|
|
trimMachines("Ironman","it")
|
|
trimMachines("Ironman","office")
|
|
|
|
$logFile.close
|
|
end
|