Alie Tormusa Koroma edit
I come from a Telecoms support background, before that I was a Visual Basic programmer (I know...I'm not proud of it myself). Since entering the support and sys admin arena in 2000, I've scripted a lot and did a tinnie bit of Java along the way. While I can boast of being a Solaris Administrator, a seasoned programmer is definitely not one of my accolades.
I've been a Tcl lover since accidentally bumping into a Tcl 8.5 tutorial four years ago. I say it's accidental because a friend who is not a developer by any means was merely passing some C++ documentations over for me to copy from her memory stick. Long story short, I asked about this Tcl tutorial document and she told me it was a programming language. My development skills were almost dead and was looking to revive it at that time (the reason why I wanted the C++ documents in the first place). I decided to learn Tcl instead of C++.
I won't call it love at first touch but when I read the section of "list handling" and the power packed in them I knew I'd found the language to revive my programming past. It paid off, because shortly after I landed a job in which I programmed telecoms services using Tcl (for Mobile broadband and 4G/LTE services). Yep...Tcl is wild out there in the wild!
Today, I am the self proclaimed biggest
Wub fan in my opinion. I struggle with it but I'm new to web development all together and I can see its great potentials. I also dream to influence a Tcl/Tk conference in South Africa someday (dreams do come true I heard).
WUB (Wub Unofficial Bootstrap) Tutorial
WUB Tutorial is an attempt at creating what I called a bootstrapping documentation for Wub.
Fetchr
Is a ftp client program for fetching file from a remote server based on configurations. I used it in a cron job to regularly move
nth server logs for post processing. It is based on tcllib::ftp package and can be downloaded here:
https://drive.google.com/file/d/0B-bQQ5QcqhhdQS1MS2dyc0FGX2c/view?usp=sharing
#!/usr/bin/tcl
# author: alie_tormusa_koroma [datagnius at mail dot com] #
# descpt: ftp client for fetching file type (defined pattern), certain date from #
# a ftp server. this program is controlled by a config_file and is ideal for
# internal networks as the config file has to contain the username & password
# depend: tcllib::ftp
#
# release: fetchr verions 0.0.1
package require Tcl
package require ftp
set connState {false}
set baseDir "/opt/fetchr" # the install directory or script home
set lckFile "/var/tmp/.fetchr.lck" # name of the lock file
set fetchList "$baseDir/conf/.fetchlist" # this is where files already fetched will be logged to avoid duplicate fetching
set fetchConf "$baseDir/conf/fetchr.conf" # the configuration file
set ftpSrv {} ; set ftpuser {} ; set ftppwd {} ; set getDir {} ; set putDir {} ; set getPat {} ; set getWhen {}
# sample configuration file containing all hostnames and file pattern to fetch
if 0 {
ftpuser:ftppassword:remote_getfile_directory:local_putfile_directory:getfile_pattern:getWhen_file
ftpuser: remote ftp username
ftppassword: ftp user password
remote_getfile_directory: remote directory containing files to get
local_putfile_directory: local directory to put files
getfile_pattern: files pattern to get (e.g 2015_*.sql)
getWhen_file: file date to get (e.g today=now; yesterday=yesterday)
}
proc FtpConnect {ftpServer ftpUser ftpPasswd} {
# open connection to ftp server
puts stdout "[clock format [clock seconds] -format {%d-%m-%Y %H:%M:%S}] FtpConnect(Connect)\
[info script]::FTP Connection request received. ConnectionString($ftpUser\@$ftpServer)"
global connState {true}
return [::ftp::Open $ftpServer $ftpUser $ftpPasswd -blocksize 8192 -timeout 7200]
} ;#endOf::FtpConnect
proc ApproveFileFetch {fileName} {
global baseDir ; global fetchList ; set srhResult {yes}
if {[file exists $fetchList]} {
set srhResult {}
set aff [open $fetchList r]
set srhResult [lsearch -start 0 -inline [read $aff] $fileName*]
close $aff
if { $srhResult == {} } { set srhResult {yes} } else { set srhResult {no} }
} else {
set srhResult {no}
}
return $srhResult
} ;#endOf::ApproveFileFetch
proc LogGetFile {getFile} {
if { $getFile != "" } {
global fetchList
set fls [open $fetchList a]
puts $fls $getFile ; close $fls
}
} ;#LogGetFile
proc FTPMain {} {
global connState {false}
global baseDir lckFile fetchList fetchConf
global ftpSrv ftpuser ftppwd getDir putDir getPat getWhen
set fls [open $fetchList a+]
if {[file exists $fetchConf] && [file size $fetchConf] > 0 } {
set cfg [open $fetchConf r]
while {![eof $cfg]} {
set cfgLine [gets $cfg] ; set ftpSrv [lindex [split $cfgLine :] 0]
if { [string range $ftpSrv 0 0] != "#" } {
set ftpuser [lindex [split $cfgLine :] 1]
set ftppwd [lindex [split $cfgLine :] 2]
set getDir [lindex [split $cfgLine :] 3]
set putDir [lindex [split $cfgLine :] 4]
set getPat [lindex [split $cfgLine :] 5]
set getWhen [lindex [split $cfgLine :] 6]
# set the session attributes on the ftp server
if { $connState == {false} && $ftpuser != {} } {
puts stdout "[clock format [clock seconds] -format {%d-%m-%Y %H:%M:%S}] FTPMain(FTPConnReq)\
[info script]::RequestingFTPConn ConnectionString::ftpSrv:$ftpSrv ftpuser:$ftpuser ftppwd:hidden"
set ftp [FtpConnect $ftpSrv $ftpuser $ftppwd]
}
if { $ftp != -1 } {
puts stdout "[clock format [clock seconds] -format {%d-%m-%Y %H:%M:%S}] FTPMain(FTPConnect) [info script]\
Established connection:: LocalHost:[info hostname] => RemoteHost:$ftpSrv"
::ftp::Cd $ftp $getDir
::ftp::Type $ftp binary
foreach {iFile} [::ftp::NList $ftp $getDir] {
if { [string match *$getPat* $iFile] } {
set indxFile [join [lrange [split [lindex [split $iFile /] end] .] 0 2] .]
switch -glob [string tolower $getWhen] {
yes* {
set ystDay [lindex [split [clock format [expr [clock seconds]-86400]]] 2]
set filDay [lindex [split [clock format [::ftp::ModTime $ftp $iFile]]] 2]
if { $filDay == $ystDay && [ApproveFileFetch $indxFile] == {yes} } {
::ftp::Get $ftp $iFile $putDir ; LogGetFile $indxFile
puts stdout "[clock format [clock seconds] -format {%d-%m-%Y %H:%M:%S}] [info script] FTPMain(getYesterday) [info script]::$indxFile"
}
}
now* {
set fTime [clock format [clock seconds] -format %d]
set mTime [clock format [lindex [split $indxFile .] 1] -format %d]
if { $fTime == $mTime && [ApproveFileFetch $indxFile] == {yes} } {
::ftp::Get $ftp $iFile $putDir ; LogGetFile $indxFile
#puts stdout "GetFile_NOW:: [clock format [clock seconds] -format {%Y-%m-%d %H:%M:%S}] $indxFile"
puts stdout "[clock format [clock seconds] -format {%d-%m-%Y %H:%M:%S}] FTPMain(getNow)::$indxFile [info script]::Fetch success"
}
}
default {
set theFile [lindex [split $iFile /] end]
set cDay [string range $getWhen 0 1]
set cMth [string range $getWhen 2 end]
set fMth [lindex [clock format [lindex [split $theFile .] 1]] 1]
if { [string totitle $cMth] == [string totitle $fMth] } {
set fDay [lindex [clock format [lindex [split $theFile .] 1]] 2]
if { $fDay == $cDay && [ApproveFileFetch $indxFile] == {yes} } {
::ftp::Get $ftp $iFile $putDir ;# puts $fls $indxFile
LogGetFile $indxFile
puts stdout "[clock format [clock seconds] -format {%d-%m-%Y %H:%M:%S}] [info script] FTPMain(getDate$cDay$cMth) [info script]::$indxFile"
}
}
}
} ;#endOf::Switch_getWhen
} ;#endOf::IfStringMatch
} ;#endOf:Foreach
} else {
puts stdout "[clock format [clock seconds] -format {%d-%m-%Y %H:%M:%S}] FTPMain(Connect)\
[info script]:: Unable to connect to FTPServer($ftpSrv)"
} ;#endOf::IfConnstateTrue
} ;#endOf::IfStringRange
} ;#endOf:WhileEOF
close $cfg
if {[catch {::ftp::Close $ftp} cerr]} {
if {[file exists $lckFile]} {file delete $lckFile}
set connState {false}
}
set connState {false}
#if {[file exists $lckFile]} {file delete $lckFile}
::ftp::Close $ftp
puts stdout "[clock format [clock seconds] -format {%d-%m-%Y %H:%M:%S}] FTPMain(::Exiting::) [info script]::Fetch complete CleanExit" ; exit 0
} else {
puts stdout "[clock format [clock seconds] -format {%d-%m-%Y %H:%M:%S}] FTPMain(NoConfigFile) [info script]::$fetchConf ZeroBtyesOrMissing"
} ;#endOf:IfFileExists
::ftp::Close $ftp
if {[file exists $lckFile]} {file delete $lckFile}
puts stdout "[clock format [clock seconds] -format {%d-%m-%Y %H:%M:%S}] FTPMain(::Exiting::) [info script]::Fetch complete CleanExit" ; exit 0
}
#endOf::FTPMain
FTPMain