Page Menu
Home
DevCentral
Search
Configure Global Search
Log In
Files
F3768955
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
17 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/.hgignore b/.hgignore
new file mode 100644
index 0000000..1521c8b
--- /dev/null
+++ b/.hgignore
@@ -0,0 +1 @@
+dist
diff --git a/Core.tcl b/Core.tcl
new file mode 100644
index 0000000..3c6fc20
--- /dev/null
+++ b/Core.tcl
@@ -0,0 +1,29 @@
+#
+# TCL helpers
+#
+
+#Determines if $proc exists
+proc proc_exists {proc} {
+ expr {[info procs $proc] == $proc}
+}
+
+#
+# Trivial procs
+#
+
+#Determines if $v is a number
+proc isnumber {v} {
+ return [expr {! [catch {expr {int($v)}}]}]
+}
+
+#
+# MySQL
+#
+#Gets the value of the key $key from the registry
+proc registry_get {key} {
+ sql "SELECT value FROM registry WHERE `key` = '$key'"
+}
+
+#Sets the key $key to $value in the registry
+proc registry_set {key value} {
+}
diff --git a/Nasqueron/Bureautique.tcl b/Nasqueron/Bureautique.tcl
new file mode 100644
index 0000000..3ad8da4
--- /dev/null
+++ b/Nasqueron/Bureautique.tcl
@@ -0,0 +1,72 @@
+bind dcc - antidater dcc:antidater
+bind dcc - postdater dcc:postdater
+bind dcc - days dcc:days
+
+#
+# Dates calculation
+#
+
+#Removes $days from $date or if unspecified, current unixtime
+proc antidater {days {date ""}} {
+ postdater [expr $days * -1] $date
+}
+
+#Adds $days from $date or if unspecified, current unixtime
+proc postdater {days {date ""}} {
+ if {$date == ""} {
+ set date [unixtime]
+ }
+ incr date [expr 86400 * $days]
+}
+
+#.antidater 15
+#.antidater 2011-01-29 4
+proc dcc:antidater {handle idx arg} {
+ set argc [llength $arg]
+ if {$argc == 0} {
+ putdcc $idx "De combien de jours dois-je antidater ?"
+ return
+ }
+ if {$argc == 1} {
+ set date ""
+ set days $arg
+ } {
+ if [catch {set date [clock scan [lindex $arg 0]]} err] {
+ putdcc $idx $err
+ return
+ }
+ set days [lindex $arg 1]
+ }
+ if ![isnumber $days] {
+ putdcc $idx "$days n'est pas un nombre de jours"
+ return
+ }
+ putdcc $idx [clock format [antidater $days $date] -format "%Y-%m-%d"]
+ return 1
+}
+
+#.postdater 15
+#.postdater 2011-01-29 4
+proc dcc:postdater {handle idx arg} {
+ set argc [llength $arg]
+ if {$argc == 0} {
+ putdcc $idx "De combien de jours dois-je postdater ?"
+ return
+ }
+ if {$argc == 1} {
+ set date ""
+ set days $arg
+ } {
+ if [catch {set date [clock scan [lindex $arg 0]]} err] {
+ putdcc $idx $err
+ return
+ }
+ set days [lindex $arg 1]
+ }
+ if ![isnumber $days] {
+ putdcc $idx "$days n'est pas un nombre de jours"
+ return
+ }
+ putdcc $idx [clock format [postdater $days $date] -format "%Y-%m-%d"]
+ return 1
+}
diff --git a/Nasqueron/Communication.tcl b/Nasqueron/Communication.tcl
new file mode 100644
index 0000000..4202980
--- /dev/null
+++ b/Nasqueron/Communication.tcl
@@ -0,0 +1,64 @@
+package require http
+
+bind dcc - sms dcc:sms
+bind pub - !identica pub:identica
+bind pub - !pub pub:identica
+bind pub - !twit pub:identica
+
+#
+# SMS
+#
+
+#.sms
+proc dcc:sms {handle idx arg} {
+ if {$arg == "" || $arg == "config"} {
+ #Prints config
+ return 1
+ } elseif {[string range $arg 0 6] == "config "} {
+ putcmdlog "#$handle# sms config ..."
+ return 0
+ } else {
+ #Sends a SMS
+ set to [lindex $arg 0]
+ putcmdlog "#$handle# sms ..."
+ }
+ return 0
+}
+
+#
+# Identi.ca
+#
+
+proc identicapost {account message} {
+ set row [lindex [sql "SELECT account_username, account_password FROM identica_accounts WHERE account_code = '$account'"] 0]
+ set auth "Basic [base64::encode [join $row :]]"
+ set tok [::http::geturl http://identi.ca/api/statuses/update.xml -headers [list Authorization $auth] -query [::http::formatQuery status $message]]
+ ::http::cleanup $tok
+}
+
+proc dcc:identica {handle idx arg} {
+
+}
+
+proc pub:identica {nick uhost handle chan text} {
+ if {$chan == "#wikipedia-fr"} {
+ set account wikipediafr
+ } elseif {$chan == "#wolfplex"} {
+ set account wolfplex
+ } {
+ putquick "NOTICE $nick :!pub n'est pas activésur $chan"
+ return
+ }
+ if {$text == ""} {
+ putquick "NOTICE $nick :Syntaxe : !pub <texte à publier sur identi.ca et Twitter>"
+ return
+ }
+ set len [string length $text]
+ if {$len > 140} {
+ putquick "NOTICE $nick :140 caractères max, là il y en a $len."
+ return
+ }
+ identicapost $account $text
+ putquick "NOTICE $nick :Publié sur identi.ca"
+ return 1
+}
diff --git a/Nasqueron/Server.tcl b/Nasqueron/Server.tcl
new file mode 100644
index 0000000..363844c
--- /dev/null
+++ b/Nasqueron/Server.tcl
@@ -0,0 +1,73 @@
+# ===============================================
+# ========= ==== ====== ============
+# ============ ====== === === = ==========
+# ============ ===== ======== === =========
+# ============ ===== ============= ==========
+# ============ ===== ============ ===========
+# == DcK ===== ===== =========== ============
+# ============ ===== ========== =============
+# ============ ====== === === ==============
+# ============ ======= === ==========
+# ===============================================
+# ===============================================
+# == Tau Ceti Central == Server administration ==
+# == This is a very dangerous product to use ==
+# == Don't deploy it in stable environment ==
+# == Or say goodbye to the serv security ==
+# == This warning will not be repeated ==
+# == All your base are belong to us! ==
+# ===============================================
+# ===============================================
+#
+# (c) 2011 Sébastien Santoro aka Dereckson.
+# Released under BSD license.
+
+bind dcc W phpfpm dcc:phpfpm
+bind dcc W php-fpm dcc:phpfpm
+bind pub W .phpfpm pub:phpfpm
+bind pub W .php-fpm pub:phpfpm
+bind bot - tc2 bot:tc2
+
+set tc2(bot) TC2
+
+proc dcc:phpfpm {handle idx arg} {
+ tc2 dcc $idx $handle phpfpm $arg
+ return 1
+}
+
+proc pub:phpfpm {nick uhost handle chan text} {
+ tc2 pub "$chan $nick" $handle phpfpm $text
+ return 1
+}
+
+proc bot:tc2 {sourcebot command text} {
+ if [catch {
+ set success [dict get $text success]
+ set reply [dict get $text reply]
+ set bind [dict get $text bind]
+ set who [dict get $text who]
+ tc2:reply $bind $who $reply
+ }] {
+ putdebug $text
+ }
+}
+
+proc tc2 {bind who handle command arg} {
+ global tc2
+ if ![islinked $tc2(bot)] {
+ tc2:reply $bind $who "$tc2(bot) isn't linked"
+ return
+ }
+ putbot $tc2(bot) "tc2 [dict create requester $handle command $command arg $arg bind $bind who $who]"
+}
+
+proc tc2:reply {bind who message} {
+ if {$bind == "dcc"} {
+ putdcc $who $message
+ } elseif {$bind == "pub"} {
+ foreach "chan nick" $who {}
+ putserv "PRIVMSG $chan :$nick, $message"
+ } {
+ error "Unknown bind in tc2:reply: $bind (expected: dcc or pub)"
+ }
+}
diff --git a/Nasqueron/Time.tcl b/Nasqueron/Time.tcl
new file mode 100644
index 0000000..1dc8d46
--- /dev/null
+++ b/Nasqueron/Time.tcl
@@ -0,0 +1,25 @@
+utimer 8 onload
+bind cron - "* * * * *" cron:minute
+bind cron - "*/5 * * * *" cron:often
+bind cron - "0 * * * *" cron:hourly
+bind cron - "0 4 * * *" cron:daily
+
+proc onload {} {
+}
+
+#Every minute
+proc cron:minute {minute hour day month weekday} {
+}
+
+#Every 5 minutes
+proc cron:often {minute hour day month weekday} {
+ sqlrehash
+}
+
+#Every hour
+proc cron:hourly {minute hour day month weekday} {
+}
+
+#Every day, at 4am
+proc cron:daily {minute hour day month weekday} {
+}
diff --git a/Nasqueron/Tools.tcl b/Nasqueron/Tools.tcl
new file mode 100644
index 0000000..7ce78af
--- /dev/null
+++ b/Nasqueron/Tools.tcl
@@ -0,0 +1,35 @@
+# Collection of tools and gadgets, to boost
+# your productivity or to have fun.
+
+bind dcc - genpass dcc:genpass
+bind dcc - strlen dcc:strlen
+
+#
+# .genpass <master password> <domain name>
+# www.supergenpass.com/genpass legacy generator
+#
+
+proc genpass {master domain} {
+ string range [md5 "$master:$domain"] 0 8
+}
+
+proc dcc:genpass {handle idx arg} {
+ if {[llength $arg] != 2} {
+ putdcc $idx "Usage: .genpass <master password> <domain name>"
+ } {
+ putcmdlog "#$handle# genpass ..."
+ putdcc $idx [genpass [lindex $arg 0] [lindex $arg 1]]
+ }
+ return 0
+}
+
+#
+# .strlen <string>
+# Gets the specified string's length
+#
+
+proc dcc:strlen {handle idx arg} {
+ putdcc $idx [string length $arg]
+ putcmdlog "#$handle# strlen ..."
+ return 0
+}
diff --git a/TC2/Server.tcl b/TC2/Server.tcl
new file mode 100644
index 0000000..1ed421c
--- /dev/null
+++ b/TC2/Server.tcl
@@ -0,0 +1,113 @@
+# ===============================================
+# ========= ==== ====== ============
+# ============ ====== === === = ==========
+# ============ ===== ======== === =========
+# ============ ===== ============= ==========
+# ============ ===== ============ ===========
+# == DcK ===== ===== =========== ============
+# ============ ===== ========== =============
+# ============ ====== === === ==============
+# ============ ======= === ==========
+# ===============================================
+# ===============================================
+# == Tau Ceti Central == Server administration ==
+# == This is a very dangerous product to use ==
+# == Don't deploy it in stable environment ==
+# == Or say goodbye to the serv security ==
+# == This warning will not be repeated ==
+# == All your base are belong to us! ==
+# ===============================================
+# ===============================================
+#
+# (c) 2011 Sébastien Santoro aka Dereckson.
+# Released under BSD license.
+
+bind bot - tc2 bot:tc2
+
+proc bot:tc2 {sourcebot command text} {
+ #Sourcebot: Nasqueron
+ #Command: tc2
+ #Text: requester Dereckson command phpfpm arg status
+ set requester [dict get $text requester]
+ set cmd [dict get $text command]
+ set arg [dict get $text arg]
+ set bind [dict get $text bind]
+ set who [dict get $text who]
+
+ #Logs entry
+ log tc2 "$requester@$sourcebot" "$cmd $arg"
+
+ #Executes command
+ if [proc_exists tc2:command:$cmd] {
+ set reply [tc2:command:$cmd $requester $arg]
+ } {
+ set reply {0 "Unknown command: $cmd"}
+ }
+
+ #Reports result
+ putbot $sourcebot "tc2 [dict create success [lindex $reply 0] reply [lindex $reply 1] bind $bind who $who]"
+ return 1
+}
+
+proc tc2:username_isvalid {username} {
+
+}
+
+proc tc2:username_exists {username} {
+ #TODO: Windows and other OSes
+ if {[exec -- logins -oxl $username] == ""} {
+ return 0
+ } {
+ return 1
+ }
+}
+
+}
+
+#phpfpm reload
+#phpfpm status
+#phpfpm create <user>
+proc tc2:command:phpfpm {requester arg} {
+ set command [lindex $arg 0]
+
+ switch $command {
+ "reload" {
+ if [catch {exec /usr/local/etc/rc.d/php-fpm reload} output] {
+ return {0 $output}
+ } {
+ return {1 "ok, php-fpm reloaded"}
+ }
+ }
+
+ "status" {
+ catch {exec /usr/local/etc/rc.d/php-fpm status} output
+ set reply 1
+ lappend reply [string map {"\n" " "} $output]
+ putdebug $reply
+ return $reply
+ }
+
+ "create" {
+ set user [lindex $arg 1]
+ if {$user == ""} {
+ return {0 "syntax: phpfpm create <user>"}
+ }
+ if [file exists "/usr/local/etc/php-fpm/$user.conf"] {
+ return {0 "there is already a $user pool"}
+ }
+ return {0 "not yet implemented"}
+ set port [sql "SELECT MAX(pool_port) FROM tc2_phpfpm_pools]
+ if {$port == ""} {
+ set port 9000
+ } {
+ incr port
+ }
+ #string map "%REQUESTER% $requester %TIME% [unixtime] %PORT% $port %USER% $user" $template
+ }
+
+ default {
+ set reply 0
+ lappend reply "unknown command: $command"
+ }
+ }
+}
diff --git a/TC2/Time.tcl b/TC2/Time.tcl
new file mode 100644
index 0000000..82570b8
--- /dev/null
+++ b/TC2/Time.tcl
@@ -0,0 +1,33 @@
+utimer 90 onload
+bind cron - "* * * * *" cron:minute
+bind cron - "*/5 * * * *" cron:often
+bind cron - "0 * * * *" cron:hourly
+bind cron - "0 4 * * *" cron:daily
+
+proc onload {} {
+ #Drops IRC support
+ unloadmodule irc
+ unloadmodule ctcp
+ unloadmodule channels
+ unloadmodule server
+
+ #Links to Nasqueron
+ link Nasqueron
+}
+
+#Every minute
+proc cron:minute {minute hour day month weekday} {
+}
+
+#Every 5 minutes
+proc cron:often {minute hour day month weekday} {
+ sqlrehash
+}
+
+#Every hour
+proc cron:hourly {minute hour day month weekday} {
+}
+
+#Every day, at 4am
+proc cron:daily {minute hour day month weekday} {
+}
diff --git a/Tech.tcl b/Tech.tcl
new file mode 100644
index 0000000..ed2548e
--- /dev/null
+++ b/Tech.tcl
@@ -0,0 +1,216 @@
+unbind dcc n rehash *dcc:rehash
+ bind dcc T rehash dcc:rehash
+ bind dcc T s dcc:source
+unbind dcc n tcl *dcc:tcl
+ bind dcc T tcl dcc:tcl
+
+ bind dcc T sql dcc:sql
+ bind dcc T sql? dcc:sql?
+ bind dcc T sql! dcc:sql!
+ bind dcc T sql1 dcc:sql1
+ bind dcc T sql1? dcc:sql1?
+ bind dcc T sql1! dcc:sql1!
+ bind dcc T sqlrehash dcc:sqlrehash
+
+ bind dcc T tcldoc dcc:tcldoc
+
+#
+# Helpers methods
+#
+
+#Logs a timestamped message to the specified file
+proc log {logfile handle message} {
+ global username
+ set fd [open "logs/$username/$logfile.log" a]
+ puts $fd "\[[unixtime]\] <$handle> $message"
+ close $fd
+}
+
+#Prints a message to all the techs
+proc putdebug {message} {
+ foreach conn [dcclist CHAT] {
+ foreach "idx handle uhost type flags idle" $conn {}
+ #dccputchan 0 "(debug) $conn"
+ if [matchattr $handle T] {
+ putdcc $idx "\[DEBUG\] $message"
+ }
+ }
+}
+
+#
+# Tech commands
+#
+
+#Disconnect SQL, then rehash (to prevent sql connect fatal errors)
+proc dcc:rehash {handle idx arg} {
+ catch {
+ sql disconnect
+ sql2 disconnect
+ }
+ *dcc:rehash $handle $idx $arg
+}
+
+#Loads a script
+proc dcc:source {handle idx arg} {
+ if {$arg == ""} {
+ putdcc $idx "Usage: .s <script> [script2 ...]"
+ return
+ }
+ foreach file $arg {
+ if ![sourcetry $file] {
+ putdcc $idx "Can't find script $file"
+ }
+ }
+}
+
+#Tries to load a script
+proc sourcetry {file} {
+ global username
+ set scriptlist "$file $file.tcl scripts/$file scripts/$file.tcl scripts/$username/$file scripts/$username/$file.tcl"
+ foreach script $scriptlist {
+ if [file exists $script] {
+ source $script
+ return 1
+ }
+ }
+ return 0
+}
+
+#.tcl with tech.log logging
+proc dcc:tcl {handle idx arg} {
+ catch {log tech $handle $arg}
+ *dcc:tcl $handle $idx $arg
+}
+
+#
+# SQL
+#
+
+#TODO: move to Core.tcl
+proc sqlrehash {} {
+ global sql
+ catch {
+ sql disconnect
+ sql2 disconnect
+ }
+ sql connect $sql(host) $sql(user) $sql(pass)
+ sql2 connect $sql(host) $sql(user) $sql(pass)
+ sql selectdb $sql(database)
+ sql2 selectdb $sql(database)
+}
+
+proc sqlescape {data} {
+ #\ -> \\
+ #' -> \'
+ string map {"\\" "\\\\" "'" "\\'"} $data
+
+}
+
+#Adds specified data to specified SQL table
+proc sqladd {table {data1 ""} {data2 ""}} {
+ if {$data1 == ""} {
+ set fields ""
+ #Prints field to fill
+ foreach row [sql "SHOW COLUMNS FROM $table"] {
+ lappend fields [lindex $row 0]
+ }
+ return $fields
+ }
+
+ if {$data2 == ""} {
+ set sql "INSERT INTO $table VALUES ("
+ set data $data1
+ } {
+ set sql "INSERT INTO $table (`[join $data1 "`, `"]`) VALUES ("
+ set data $data2
+ }
+ set first 1
+ foreach value $data {
+ if {$first == 1} {set first 0} {append sql ", "}
+ append sql "'[sqlescape $value]'"
+ }
+ append sql ")"
+ sql $sql
+}
+
+#Reconnects to the MySQL main server (sql and sql2)
+proc dcc:sqlrehash {handle idx arg} {
+ sqlrehash
+ return 1
+}
+
+#
+# dcc:sql1 dcc:sql1? and dcc:sql1! are the main procedures
+# They will be cloned for the 9 other connections command
+#
+
+#Executes a query
+proc dcc:sql1 {handle idx arg} {
+ if {$arg == ""} {
+ putdcc $idx "Usage: .sql1 <query>"
+ return
+ }
+
+ #Executes the query and prints the query one row per line
+ set t1 [clock milliseconds]
+ if [catch {
+ foreach row [sql1 $arg] {
+ putdcc $idx $row
+ }
+ } err] {
+ putdcc $idx $err
+ }
+
+ #Warns after a long query
+ set delta_t [expr [clock milliseconds] - $t1]
+ if {$delta_t > 1999} {
+ putcmdlog "Fin de la requête SQL ($delta_t ms)."
+ }
+
+ #Logs the query
+ log sql $handle "sql1\t$arg"
+}
+
+#Dumps (SELECT * FROM <table>) a table
+proc dcc:sql1! {handle idx arg} {
+ if {$arg == ""} {
+ putdcc $idx "Usage: .sql1! <table>"
+ return
+ }
+ dcc:sql1 $handle $idx "SELECT * FROM $arg"
+}
+
+#Without parameters, list the tables (SHOW TABLES)
+#With a parameter, dump tables info (SHOW CREATE TABLE)
+proc dcc:sql1? {handle idx arg} {
+ if {$arg == ""} {
+ dcc:sql1 $handle $idx "SHOW TABLES"
+ }
+ foreach table $arg {
+ dcc:sql1 $handle $idx "SHOW CREATE TABLE $table"
+ }
+}
+
+#Clones .sql1, .sql1? and .sql1! commands into .sql, .sql? and .sql!
+proc dcc:sql {handle idx arg} [string map "sql1 sql" [info body dcc:sql1]]
+proc dcc:sql? {handle idx arg} [string map "sql1 sql" [info body dcc:sql1?]]
+proc dcc:sql! {handle idx arg} [string map "sql1 sql" [info body dcc:sql1!]]
+
+#Clones .sql1, .sql1? and .sql1! commands into .sql2, .sql3, ..., .sql10.
+for {set i 2} {$i < 11} {incr i} {
+ bind dcc T sql$i dcc:sql$i
+ bind dcc T sql$i? dcc:sql$i?
+ bind dcc T sql$i! dcc:sql$i!
+ proc dcc:sql$i {handle idx arg} [string map "sql1 sql$i" [info body dcc:sql1]]
+ proc dcc:sql$i! {handle idx arg} [string map "sql1 sql$i" [info body dcc:sql1!]]
+ proc dcc:sql$i? {handle idx arg} [string map "sql1 sql$i" [info body dcc:sql1?]]
+}
+
+#
+# Reference documentation
+#
+
+proc dcc:tcldoc {handle idx arg} {
+ putdcc $idx [exec -- grep $arg doc/tcl-commands.doc]
+ return 1
+}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Mon, Nov 25, 11:38 (1 d, 11 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2260100
Default Alt Text
(17 KB)
Attached To
Mode
rVIPER ViperServ scripts
Attached
Detach File
Event Timeline
Log In to Comment