Browse Source

simplify shell structure

Xuu 7 months ago
parent
commit
6dd2053188
66 changed files with 1668 additions and 134 deletions
  1. 2 1
      .gitignore
  2. 1 1
      Makefile
  3. 23 1
      cmd/skillet/config.go
  4. 119 108
      cmd/skillet/skillet.go
  5. 1 1
      go.mod
  6. 2 0
      go.sum
  7. 0 1
      shell
  8. 1 0
      shell/cmd
  9. 13 0
      shell/commands-available/!
  10. 12 0
      shell/commands-available/!last
  11. 89 0
      shell/commands-available/!trace2
  12. 35 0
      shell/commands-available/>>>
  13. 29 0
      shell/commands-available/about
  14. 41 0
      shell/commands-available/alias
  15. 10 0
      shell/commands-available/cal
  16. 4 0
      shell/commands-available/calc
  17. 3 0
      shell/commands-available/date
  18. 112 0
      shell/commands-available/dig
  19. 23 0
      shell/commands-available/dig6
  20. 23 0
      shell/commands-available/dnscheck
  21. 12 0
      shell/commands-available/feature-request
  22. 3 0
      shell/commands-available/fortune
  23. 31 0
      shell/commands-available/grep
  24. 25 0
      shell/commands-available/help
  25. 21 0
      shell/commands-available/http
  26. 21 0
      shell/commands-available/https
  27. 11 0
      shell/commands-available/md5sum
  28. 20 0
      shell/commands-available/nl-zuid
  29. 18 0
      shell/commands-available/note
  30. 81 0
      shell/commands-available/path
  31. 22 0
      shell/commands-available/peer
  32. 23 0
      shell/commands-available/ping
  33. 22 0
      shell/commands-available/ping6
  34. 18 0
      shell/commands-available/quote
  35. 80 0
      shell/commands-available/reader
  36. 6 0
      shell/commands-available/rollcall
  37. 24 0
      shell/commands-available/route
  38. 14 0
      shell/commands-available/rss
  39. 31 0
      shell/commands-available/run
  40. 7 0
      shell/commands-available/say
  41. 11 0
      shell/commands-available/sha1sum
  42. 15 0
      shell/commands-available/slack
  43. 39 0
      shell/commands-available/stats
  44. 19 0
      shell/commands-available/status
  45. 33 0
      shell/commands-available/taunt
  46. 32 0
      shell/commands-available/tcpconnect
  47. 23 0
      shell/commands-available/tinyurl
  48. 25 0
      shell/commands-available/trace
  49. 141 0
      shell/commands-available/trace3
  50. 25 0
      shell/commands-available/trace6
  51. 18 0
      shell/commands-available/translate
  52. 49 0
      shell/commands-available/twitter
  53. 20 0
      shell/commands-available/unalias
  54. 51 0
      shell/commands-available/untinyurl
  55. 9 0
      shell/commands-available/weather
  56. 8 0
      shell/commands-available/whoami
  57. 11 0
      shell/commands-available/wiki
  58. 0 0
      shell/commands-enabled/.placeholder
  59. 24 0
      shell/commands-enabled/dnscheck
  60. 1 0
      shell/commands-enabled/rollcall
  61. 7 0
      shell/commands-enabled/tst
  62. 1 0
      shell/commands-enabled/whoami
  63. 1 0
      shell/db/note/key
  64. 0 0
      shell/db/taunts
  65. 72 0
      shell/run
  66. 0 21
      skillet.pem

+ 2 - 1
.gitignore

@@ -2,4 +2,5 @@
 config.inc
 bin/*
 /debian/BUILD
-*.private.pem
+
+*.pem

+ 1 - 1
Makefile

@@ -5,7 +5,7 @@ VERSION := $(shell cat VERSION)
 DATE := $(shell date -u +%FT%TZ)
 
 run: bin/skillet
-	cd shell && ../bin/skillet -vv connect -u /tmp/skillet4.sock
+	cd shell && ../bin/skillet -vv connect -u /tmp/skillet.sock
 
 clean:
 	rm -f bin/*

+ 23 - 1
cmd/skillet/config.go

@@ -33,6 +33,9 @@ Options:
   -vv                                            Log debug to console.
   -c <ConfigDir>, --config=<ConfigDir>           Set Config Directory.
   -u <UnixSocket>                                Listen for commands on unix socket.
+  --tls                                          Enable TLS
+  --tls-cert <cert>                              Use TLS Cert
+  --tls-key <key>                                Use TLS Key
 
 Config:
   The config file is read from the following locations:
@@ -42,15 +45,22 @@ Config:
 `
 var defaultConfig = `
 [irc]
+# config for connecting to server here.
+
+[irc.opts]
+# config to pass to shell here.
 `
 
 var automaticEnv = []string{
-	"irc.ssl",
+	"irc.tls",
+	"irc.tlscert",
+	"irc.tlskey",
 	"irc.host",
 	"irc.nick",
 	"irc.chan",
 	"irc.pass",
 	"irc.oper",
+	"irc.unix",
 }
 
 var args map[string]interface{}
@@ -89,6 +99,18 @@ func initArgs() {
 		log.SetFlags(log.Lshortfile | log.LstdFlags)
 		log.Debug("Very Verbose Logging.")
 	}
+	if _, ok := args["--tls"]; ok {
+		viper.Set("irc.tls", true)
+	}
+	if s, ok := args["--tls-cert"]; ok {
+		viper.Set("irc.tls_cert", s)
+	}
+	if s, ok := args["--tls-key"]; ok {
+		viper.Set("irc.tls_key", s)
+	}
+	if s, ok := args["-u"]; ok {
+		viper.Set("irc.unix", s)
+	}
 }
 func initConfig() {
 	var err error

+ 119 - 108
cmd/skillet/skillet.go

@@ -25,6 +25,26 @@ import (
 var defaultEnv []string
 
 func main() {
+	ctx, cancel := context.WithCancel(context.Background())
+
+	trap := make(chan os.Signal, 1)
+	signal.Notify(trap, syscall.SIGINT, syscall.SIGTERM)
+
+	go func() {
+		for {
+			select {
+			case <-trap:
+				cancel()
+			case <-ctx.Done():
+				return
+			}
+		}
+	}()
+
+	run(ctx)
+}
+
+func run(ctx context.Context) {
 	NODE, err := os.Hostname()
 	if err != nil {
 		log.Error(err)
@@ -36,25 +56,35 @@ func main() {
 	CHAN := viper.GetString("irc.chan")
 	PASS := viper.GetString("irc.pass")
 	OPER := viper.GetString("irc.oper")
-	SSL := viper.GetBool("irc.ssl")
+	TLS := viper.GetBool("irc.tls")
+	CMDTIMEOUT := time.Duration(viper.GetInt64("irc.cmd.timeout")) * time.Second
+	if CMDTIMEOUT == 0 {
+		CMDTIMEOUT = 30 * time.Second
+	}
 
 	cfg := irc.NewConfig(NICK)
 
-	if SSL {
-		cert, err := tls.LoadX509KeyPair("../skillet.pem", "../skillet.private.pem")
-		if err != nil {
-			log.Fatal(err)
-		}
-
-		cfg.SSL = SSL
+	if TLS {
+		cfg.SSL = TLS
 		cfg.SSLConfig = &tls.Config{
 			ServerName:         HOST,
-			Certificates:       []tls.Certificate{cert},
 			InsecureSkipVerify: true, // nolint: gosec
 		}
+		if viper.IsSet("irc.tlscert") && viper.IsSet("irc.tlskey") {
+			cert, key := viper.GetString("irc.tlscert"), viper.GetString("irc.tlskey")
+			log.Debugf("Add Client Cert [%v %v]", cert, key)
+			x509, err := tls.LoadX509KeyPair(cert, key)
+			if err != nil {
+				log.Fatal(err)
+			}
+
+			cfg.SSLConfig.Certificates = append(cfg.SSLConfig.Certificates, x509)
+		}
 	}
 
 	cfg.Server = HOST
+	cfg.Me.Ident = NICK
+	cfg.Me.Name = "A Skillet to serve hot and fresh grub."
 	cfg.NewNick = func(n string) string { return n + "^" }
 	cfg.Version = fmt.Sprintf("%v @ %v (v%v)", NICK, NODE, AppVersion)
 	cfg.Recover = func(c *irc.Conn, l *irc.Line) {
@@ -67,19 +97,22 @@ func main() {
 		fmt.Sprintf("SKILLET_IRC_CHAN=%v", CHAN),
 		fmt.Sprintf("SKILLET_IRC_NICK=%v", NICK),
 		fmt.Sprintf("SKILLET_IRC_OPER=%v", OPER),
+		fmt.Sprintf("SKILLET_IRC_HOST=%v", HOST),
 	)
 
-	ignore := true
-
 	cl := irc.Client(cfg)
 	cl.EnableStateTracking()
 
+	ctx, quit := context.WithCancel(ctx)
+
 	cl.HandleFunc(
 		irc.REGISTER,
 		func(conn *irc.Conn, _ *irc.Line) {
 			log.Println("CONNECTED ")
-			conn.Raw(fmt.Sprintf("PASS %s", PASS))
-			log.Println("Sent authentication")
+			if PASS != "" {
+				conn.Raw(fmt.Sprintf("PASS %s", PASS))
+				log.Println("Sent authentication")
+			}
 		})
 
 	cl.HandleFunc(
@@ -97,7 +130,6 @@ func main() {
 			if strings.EqualFold(CHAN, target) && strings.EqualFold(NICK, line.Nick) {
 				conn.Notice(target, fmt.Sprintf("%v@%v (v%v) reporting for duty!", line.Nick, NODE, AppVersion))
 				log.Noticef("JOIN %v: %v@%v (v%v) reporting for duty!", target, line.Nick, NODE, AppVersion)
-				ignore = false
 			}
 		})
 
@@ -111,10 +143,6 @@ func main() {
 	cl.HandleFunc(
 		irc.PRIVMSG,
 		func(conn *irc.Conn, line *irc.Line) {
-			if ignore {
-				return
-			}
-
 			log.Infof("~> GOT %v", line.Text())
 
 			target := line.Target()
@@ -125,10 +153,13 @@ func main() {
 			isIdentd := !strings.HasPrefix(line.Ident, "~")
 			isOper := strings.EqualFold(OPER, line.Nick) || strings.EqualFold(OPER, target)
 
-			hook := "hooks-enabled/pubmsg"
+			hook := "run"
 			args := []string{line.Nick, line.Ident + "@" + line.Host, line.Target(), "", line.Text()}
 
-			cmd := exec.Command(hook, args...)
+			ctx, cancel := context.WithTimeout(ctx, CMDTIMEOUT)
+			defer cancel()
+
+			cmd := exec.CommandContext(ctx, hook, args...)
 
 			var stderr io.ReadCloser
 			var stdout io.ReadCloser
@@ -214,7 +245,7 @@ func main() {
 				}
 			}()
 
-			go writeChan(conn, line.Target(), stdout)
+			go writeChan(conn, target, stdout)
 
 			log.Debug("~> Waiting...")
 			err = cmd.Wait()
@@ -223,106 +254,56 @@ func main() {
 			}
 		})
 
+	cl.HandleFunc(
+		irc.NOTICE,
+		func(_ *irc.Conn, line *irc.Line) {
+			log.Info(line.Target(), "> ", line.Text())
+		})
+
 	cl.HandleFunc(
 		irc.ERROR,
 		func(_ *irc.Conn, line *irc.Line) {
-			log.Debug(line)
+			log.Info("E> ", line.Text())
 		})
 
-	quit := make(chan bool)
 	cl.HandleFunc(
 		irc.DISCONNECTED,
-		func(_ *irc.Conn, line *irc.Line) {
-			log.Notice("Disconnected", line)
-			close(quit)
+		func(_ *irc.Conn, _ *irc.Line) {
+			log.Notice("Received Disconnect")
+			quit()
 		})
 
 	if err := cl.Connect(); err != nil {
 		log.Errorf("Connection error: %s", err.Error())
-		close(quit)
+		quit()
 	}
 
-	trap := make(chan os.Signal, 1)
-	signal.Notify(trap, syscall.SIGINT, syscall.SIGTERM)
-
-	// hdlr := func(w http.ResponseWriter, r *http.Request) {
-	// 	fmt.Fprintf(w, "Hello %v", 4)
-	// }
-
-	// go func() {
-	// 	srv := &http.Server{
-	// 		Handler:      http.HandlerFunc(hdlr),
-	// 		Addr:         ":9060",
-	// 		WriteTimeout: 15 * time.Second,
-	// 		ReadTimeout:  15 * time.Second,
-	// 	}
-
-	// 	log.Info("Starting Server", "addr", srv.Addr)
-
-	// 	go func() {
-	// 		<-quit
-
-	// 		ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-	// 		defer cancel()
-
-	// 		_ = srv.Shutdown(ctx)
-	// 	}()
-
-	// 	err := srv.ListenAndServe()
-	// 	if err != nil {
-	// 		log.Critical(err)
-	// 	}
-	// }()
-
 	handleServerConnection := func(c net.Conn) {
 		defer c.Close()
-
 		writeChan(cl, CHAN, c)
 	}
 
-	unixOn := false
-	var unixCancel context.CancelFunc
-	var unixDone chan struct{}
-	if unix, ok := args["-u"].(string); ok {
-		unixOn = true
-		unixCancel, unixDone = ListenAndServe(context.TODO(), unix, handleServerConnection)
+	var unixDone <-chan struct{}
+	if unix := viper.GetString("irc.unix"); unix != "" {
+		unixDone = ListenAndServe(ctx, unix, handleServerConnection)
 	}
 
 	// Wait for disconnect
 QUIT:
-	for {
-		select {
-		case <-quit:
-			log.Notice("QUIT Closed")
-			break QUIT
-		case <-trap:
-			log.Notice("Shutting Down")
-			cl.Notice(CHAN, fmt.Sprintf("So long and thanks for all the fish! -Douglas Adams -%v@%v", NICK, NODE))
-			cl.Quit("So long and thanks for all the fish! -Douglas Adams -%s@%v v%v", NICK, NODE, AppVersion)
-			break QUIT
-		}
+	for range ctx.Done() {
+		log.Notice("Shutting Down")
+		cl.Notice(CHAN, fmt.Sprintf("So long and thanks for all the fish! -Douglas Adams -%v@%v", NICK, NODE))
+		cl.Quit("So long and thanks for all the fish! -Douglas Adams -%s@%v v%v", NICK, NODE, AppVersion)
+		break QUIT
 	}
 
-	if unixOn {
-		unixCancel()
+	quit()
+	if unixDone != nil {
 		<-unixDone
 	}
-
-	for {
-		select {
-		case <-quit:
-			log.Error("graceful quit")
-			return
-
-		case <-time.After(5 * time.Second):
-			log.Error("force quit")
-			return
-		}
-	}
 }
 
-func ListenAndServe(ctx context.Context, addr string, hdlr func(net.Conn)) (context.CancelFunc, chan struct{}) {
-	ctx, stop := context.WithCancel(ctx)
+func ListenAndServe(ctx context.Context, addr string, hdlr func(net.Conn)) <-chan struct{} {
 	done := make(chan struct{})
 
 	addr, err := filepath.Abs(addr)
@@ -331,13 +312,12 @@ func ListenAndServe(ctx context.Context, addr string, hdlr func(net.Conn)) (cont
 	}
 
 	go func() {
-		log.Noticef("Listening on SOCKET")
+		log.Noticef("Listen on SOCKET %s", addr)
 		defer close(done)
 
 		ln, err := net.ListenUnix("unix", &net.UnixAddr{Name: addr, Net: "unix"})
 		if err != nil {
 			log.Error(err)
-			stop()
 			return
 		}
 		defer os.Remove(addr)
@@ -346,25 +326,28 @@ func ListenAndServe(ctx context.Context, addr string, hdlr func(net.Conn)) (cont
 		go func() {
 			for {
 				if ctx.Err() != nil {
-					log.Notice("sopped listen")
+					log.Noticef("Stopped listen on SOCKET %s", addr)
 					return
 				}
 				c, err := ln.Accept()
 				if err != nil {
-					log.Debug(err)
+					if ctx.Err() != nil {
+						continue
+					}
+
+					log.Error(err)
 					continue
 				}
 
-				// handle the connection
 				go hdlr(c)
 			}
 		}()
 
 		<-ctx.Done()
-		log.Notice("stopping")
+		log.Noticef("Stopping listen on SOCKET %s", addr)
 	}()
 
-	return stop, done
+	return done
 }
 
 func writeChan(conn *irc.Conn, target string, in io.ReadCloser) {
@@ -376,17 +359,44 @@ func writeChan(conn *irc.Conn, target string, in io.ReadCloser) {
 
 	for scanner.Scan() {
 		line := scanner.Text()
-		log.Debug("R>", line)
+		if line == "" {
+			continue
+		}
+
+		var cmd []string
 		if strings.HasPrefix(line, "+") {
-			tgt := strings.Fields(line[1:])
-			if len(tgt) == 2 {
-				log.Notice(tgt)
-				mode, target = tgt[0], tgt[1]
+			cmd = strings.Fields(line[1:])
+			if len(cmd) < 2 {
+				continue
+			}
+			log.Debugf("C> %v", cmd)
+
+			switch cmd[0] {
+			case irc.INVITE:
+				for _, u := range cmd[1:] {
+					conn.Invite(u, target)
+				}
+
+			case irc.JOIN:
+				for _, ch := range cmd[1:] {
+					conn.Join(ch, target)
+				}
+
+			case irc.PART:
+				for _, ch := range cmd[1:] {
+					conn.Part(ch, target)
+				}
+
+			case irc.QUIT:
+				conn.Quit(strings.Join(cmd[1:], " "))
+
+			case "RAW":
+				conn.Raw(strings.Join(cmd[1:], " "))
+
+			case irc.NOTICE, irc.PRIVMSG:
+				mode, target = cmd[0], cmd[1]
 			}
 
-			continue
-		}
-		if line == "" {
 			continue
 		}
 
@@ -399,6 +409,7 @@ func writeChan(conn *irc.Conn, target string, in io.ReadCloser) {
 			log.Debugf("P> %s %s", target, line)
 			conn.Privmsg(target, line)
 		}
+
 	}
 
 	err = scanner.Err()

+ 1 - 1
go.mod

@@ -3,7 +3,7 @@ module sour.is/x/skillet
 go 1.13
 
 require (
-	bou.ke/monkey v1.0.1 // indirect
+	bou.ke/monkey v1.0.2 // indirect
 	github.com/BurntSushi/toml v0.3.1 // indirect
 	github.com/bouk/monkey v1.0.1 // indirect
 	github.com/davecgh/go-spew v1.1.1 // indirect

+ 2 - 0
go.sum

@@ -1,5 +1,7 @@
 bou.ke/monkey v1.0.1 h1:zEMLInw9xvNakzUUPjfS4Ds6jYPqCFx3m7bRmG5NH2U=
 bou.ke/monkey v1.0.1/go.mod h1:FgHuK96Rv2Nlf+0u1OOVDpCMdsWyOFmeeketDHE7LIg=
+bou.ke/monkey v1.0.2 h1:kWcnsrCNUatbxncxR/ThdYqbytgOIArtYWqcQLQzKLI=
+bou.ke/monkey v1.0.2/go.mod h1:OqickVX3tNx6t33n1xvtTtu85YN5s6cKwVug+oHMaIA=
 github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
 github.com/bouk/monkey v1.0.1 h1:82kWEtyEjyfkRZb0DaQ5+7O5dJfe3GzF/o97+yUo5d0=

+ 0 - 1
shell

@@ -1 +0,0 @@
-Subproject commit 3712eae4fc03d4064e5a86c2a0963e9b1ab7878f

+ 1 - 0
shell/cmd

@@ -0,0 +1 @@
+commands-enabled/

+ 13 - 0
shell/commands-available/!

@@ -0,0 +1,13 @@
+#!/bin/sh
+
+if [ "$1" = "-h" ]
+then
+    echo "Find last sayed thing matching."
+    echo "Usage : !dash"
+    exit 0
+fi
+search="$*"
+if [ -n "$search" ]
+then
+    grep -i "$search" logs/all_raw_messages | grep -v ' :!' | tail -n 1
+fi

+ 12 - 0
shell/commands-available/!last

@@ -0,0 +1,12 @@
+#!/bin/sh
+[ -z "$1" ] && echo "Who ?" && exit
+if [ "$1" = '-h' ]
+then
+   echo "$(basename "$0"): Retrouve le dernier passage d'une personne"
+   echo "N'a besoin que d'une partie de son nom pour le retrouver"
+   echo "Exemple: $(basename "$0") ju"
+   exit 0
+fi
+find logs/users -type f -a -iname "*$(echo "$1" | grep -o '[a-zA-Z0-9]*' | head -n 1)*" -print0 \
+   | xargs -0 tail -n 1 \
+   | sed 's/^==> logs\/users\//==> /g' \

+ 89 - 0
shell/commands-available/!trace2

@@ -0,0 +1,89 @@
+#!/bin/bash
+
+CMD="${0##*!}"
+
+MAXHOP=4
+NODE=$(uname -n)
+BIND4="172.22.141.171"
+BIND6="fdea:a15a:77b9:ffff::246"
+
+PING4CMD="ping -I $BIND4"
+TRACE4CMD="traceroute -s $BIND4"
+PING6CMD="ping6 -I $BIND6"
+TRACE6CMD="traceroute6 -s $BIND6"
+
+
+if   [[ "$1" =~ ^[0-9\.]{7,15}$ ]]; then
+   PING="$PING4CMD"
+   TRACE="$TRACE4CMD"
+elif [[ "$1" =~ ^[0-9a-fA-F\:]{3,45}$ ]]; then
+     PING="$PING6CMD"
+     TRACE="$TRACE6CMD"
+elif [[ "$1" =~ ^[a-z0-9\.-]{2,30}\.[a-z0-9]{2,4}$ ]]; then
+   if [[ "$CMD" = *6 ]]; then
+     PING="$PING6CMD"
+     TRACE="$TRACE6CMD"
+   else
+     PING="$PING4CMD"
+     TRACE="$TRACE4CMD"
+   fi
+elif [[ "$1" = "-h" || "$1" = "help" ]]; then
+  echo "Usage: !$CMD <<ip/dns>>"
+  exit
+else
+  exit
+fi
+
+echo -n "$NODE -> $1":
+
+TEMP=$(mktemp)
+$PING -n -w1 -c1 "$1" > $TEMP
+
+check=$(cat $TEMP|grep ttl|cut -f6,7 -d' '|sed -e 's/ttl=\(.*\)/\1/;s/time=\(.*\)/\1ms/')
+
+if [ -z "$check" ]; then
+  ERR="unreachable"
+  ret_hops=$MAXHOP
+
+  grep -q 'Time to live exceeded' $TEMP && ERR="ttl-exceeded"
+else
+  ERR=""
+  ret_hops=$(echo "$check"|cut -d' ' -f1)
+  ts=$(echo "$check"|cut -d' ' -f2)
+  if [ "$ret_hops" -gt 128 ]; then ret_hops=$(expr $ret_hops - 191); fi;  # Sometime the ping response ttl is 255..
+  if [ "$ret_hops" -gt 64 ]; then ret_hops=$(expr $ret_hops - 63); fi;  # Sometime the ping response ttl is 128..
+
+
+  ret_hops=$(expr 65 - $ret_hops)
+  if [ "$ret_hops" -le "0" ]; then ERR="Unresponsive"; hops=$MAXHOP;
+  else
+   LAG="$ts"
+  fi
+fi
+
+if [ "$ret_hops" -le "0" ]; then ERR="unreachable"; ret_hops=$MAXHOP; fi
+if [ "$ret_hops" -ge "255" ]; then ERR="Too many hops"; ret_hops=$MAXHOP; fi
+
+
+$TRACE -I -n -m $(expr 3 + $ret_hops) "$1" | tail -n +2 | sed -e 's/^[[:space:]]*//' | cut -f3 -d' '  > $TEMP
+
+grep -q '!A' $TEMP && ERR="denied"
+grep -q '!H' $TEMP && ERR="unresponsive"
+grep -q '!T' $TEMP && ERR="timeout"
+grep -q '!Q' $TEMP && ERR="bandwidth"
+grep -q '!U' $TEMP && ERR="port-unreachable"
+grep -q '!N' $TEMP && ERR="net-unreachable"
+grep -q '!P' $TEMP && ERR="proto-unreachable"
+
+NPATH=$(cat $TEMP | xargs echo | sed 's/\*\(\ \*\)\+/\*\*\*/')
+hops=$(echo $NPATH | wc -w)
+
+if [ -n "$ERR" ]
+then echo " err: $ERR path: $NPATH"
+else echo " hops: $hops:$ret_hops lag: $LAG path: $NPATH"
+fi
+
+rm $TEMP
+exit
+
+

+ 35 - 0
shell/commands-available/>>>

@@ -0,0 +1,35 @@
+#!/usr/bin/env python
+import re
+import sys
+import urllib
+
+session = "agVzaGVsbHISCxIHU2Vzc2lvbhiH-Py56U0M"
+
+def usage():
+    print "Python REPL"
+    print "Usage: >>> '1,2,3'.split(',')"
+    sys.exit(0)
+
+if len(sys.argv) == 1 or sys.argv[1] == '-h':
+    usage()
+
+args = urllib.urlencode({'statement': ' '.join(sys.argv[1:]),
+                         'session': session})
+
+result = urllib.urlopen("http://shell.appspot.com/shell.do?%s" % args).read()
+sys.stderr.write("Got : %s\n" % result)
+if re.search("Status: 200 OK", result.split("\r\n")[0]):
+    sys.stderr.write("Removing the '200 OK' bug\n")
+    result = "\n".join(result.split("\r\n")[6:])
+if re.search("Status: 500", result.split("\r\n")[0]):
+    sys.stderr.write("We got a Status: 500\n")
+    print "EPIC FAIL"
+elif result[0:9] == "Traceback":
+    sys.stderr.write("Got an exception\n")
+    print result.split("\n")[-2]
+elif result[0:9 + 5] == "<pre>Traceback":
+    sys.stderr.write("Got an exception\n")
+    print result[5:].split("\n")[-2]
+else:
+    print "\n".join(result.split("\n")[:5])[:1024]
+

+ 29 - 0
shell/commands-available/about

@@ -0,0 +1,29 @@
+#!/bin/sh
+usage()
+{
+    echo "Seek information about anything on Wolfram Alpha"
+    echo "Usage: about SOMETHING"
+    exit
+}
+
+[ "$1" = -h -o -z "$1" ] && usage
+
+wget -qO- "http://api.wolframalpha.com/v2/query?input=$*&format=plaintext&appid=7UP545-RL2T8AR5UV" \
+    | xml2 \
+    | grep '@title=\|plaintext=' \
+    | while read line
+do
+    if echo "$line" | grep -q '@title='
+    then
+        TITLE="$(echo "$line" | sed 's/^.*@title=//g')"
+    fi
+    if echo "$line" | grep -q 'plaintext='
+    then
+        TEXT="$(echo "$line" | sed 's/^.*plaintext=//g')"
+    fi
+    if [ -n "$TITLE" -a -n "$TEXT" ]
+    then
+        echo "$TITLE: $TEXT"
+        TEXT=''
+    fi
+done

+ 41 - 0
shell/commands-available/alias

@@ -0,0 +1,41 @@
+#!/bin/sh -f
+if [ "$1" = '-h' ]
+then
+   echo "$(basename "$0"): Alias une commande. Usage :"
+   echo "List existing aliases : alias"
+   echo "Show an alias : alias NAME"
+   echo "Create an alias: alias NAME WHAT TO DO"
+   echo "Delete an alias : unalias NAME"
+   echo "Supports arguments in alias : |ARGS| in an alias is replaced by \
+arguments given to it when called"
+   exit 0
+fi
+
+if [ -z "$1" ]
+then
+    ls -1 db/aliases | tr '\n' ' '
+    exit 0
+fi
+
+command="$(echo "$1" | sed 's|/|__SLASH__|g')"
+shift
+args="$*"
+
+if [ -z "$args" ]
+then
+    if [ -f "db/aliases/$command" ]
+    then
+        cat "db/aliases/$command"
+    else
+        echo "$command is not an existing alias, try 'alias' to list them all."
+    fi
+    exit 0
+fi
+
+mkdir -p db/aliases
+
+echo "$args" > "db/aliases/$command"
+
+
+
+

+ 10 - 0
shell/commands-available/cal

@@ -0,0 +1,10 @@
+#!/usr/bin/env python
+import sys
+import datetime
+import calendar
+
+if len(sys.argv) > 1 and sys.argv[1] == '-h':
+    print "Displays a calendar"
+    sys.exit(0)
+now = datetime.datetime.now()
+calendar.TextCalendar().prmonth(now.year, now.month)

+ 4 - 0
shell/commands-available/calc

@@ -0,0 +1,4 @@
+#!/bin/sh -f
+[ "$1" = -h ] && echo "An arbitrary precision calculator" && echo "Usage: calc 1 + 1" && exit
+ulimit -t 1
+echo $* | bc -l

+ 3 - 0
shell/commands-available/date

@@ -0,0 +1,3 @@
+#!/bin/sh
+[ "$1" = "-h" ] && echo "Print the date and time" && exit
+[ -z "$*" ] && date

+ 112 - 0
shell/commands-available/dig

@@ -0,0 +1,112 @@
+#!/bin/bash --restricted
+
+CMD="${0##*/}"
+
+if [[ "$CMD" = *4 ]]; then
+   VERSION="4"
+   TYPE="A"
+else
+   VERSION="6"
+   TYPE="AAAA"
+fi
+
+DIG="dig +short"
+
+CHAOS=""
+DEFAULT_NS="1"
+ADDRESS="G"
+
+while (( "$#" != "0" )); do
+
+  if [[ "$1" = "-h" || "$1" = "help" ]]; then
+    echo "Usage: [!@]dig[6] <host/ip> [@nameserver]"
+    exit
+
+  elif [[ "$1" = \@* ]]; then
+    NS="$1"
+    DEFAULT_NS="0"
+    >&2 echo "got ns: $NS"
+
+  elif [[ "$1" =~ ^[0-9\./]{7,15}$ ]]; then
+    IP="$1"
+    TYPE="-x"
+    >&2 echo "got ip4: $IP"
+    if [[ "$IP" =~ (^127\.)|(^192\.168\.)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.) ]]; then ADDRESS="D"; fi
+
+  elif [[ "$1" != "AAAA" && "$1" =~ ^[0-9a-fA-F\:]{3,45}$ ]]; then
+    IP="$1"
+    TYPE="-x"
+    >&2 echo "got ip6: $IP"
+    if [[ "$IP" =~ (^[fF][cCdD]) ]]; then ADDRESS="D"; fi
+
+  elif [[ "$1" =~ [_a-z0-9\.-]{1,}\.[a-z0-9]{2,9}$ ]]; then
+    IP="$1"
+    >&2 echo "got dns: $IP"
+    if [[ "$IP" =~ (dn42$) ]]; then ADDRESS="D"; fi
+    if [[ "$IP" =~ (hack$) ]]; then ADDRESS="D"; fi
+    if [[ "$IP" =~ (\.ff[a-z0-9]*$)|(\.freifunk$) ]]; then ADDRESS="D"; fi
+    if [[ "$IP" =~ (\.rzl$)|(\.adm$)|(\.icvpn$)|(\.helgo) ]]; then ADDRESS="D"; fi
+    if [[ "$IP" =~ (\.ano$)|(\.[0-9]{2,3}$) ]]; then ADDRESS="D"; fi
+
+  elif [[ "$1" = "dn42" ]]; then IP="$1"; ADDRESS="D"
+  elif [[ "$1" = "hack" ]]; then IP="$1"; ADDRESS="D"
+  else
+    case "$1" in
+      a|aaaa|afsdb|apl|caa|cdnskey|cds|cert|cname|dhcid|dlv|dname|dnskey|ds|hip|ipseckey|key|kx|loc|mx|naptr|ns|nsec|nsec3|nsec3param|openpgpkey|ptr|rrsig|rp|sig|smimea|soa|srv|sshfp|ta|tkey|tlsa|tsig|txt|uri)
+        TYPE="$1"
+        >&2 echo "got type: $TYPE"
+      ;;
+      A|AAAA|AFSDB|APL|CAA|CDNSKEY|CDS|CERT|CNAME|DHCID|DLV|DNAME|DNSKEY|DS|HIP|IPSECKEY|KEY|KX|LOC|MX|NAPTR|NS|NSEC|NSEC3|NSEC3PARAM|OPENPGPKEY|PTR|RRSIG|RP|SIG|SMIMEA|SOA|SRV|SSHFP|TA|TKEY|TLSA|TSIG|TXT|URI)
+        TYPE="$1"
+        >&2 echo "got type: $TYPE"
+      ;;
+      chaos)
+         ADDRESS="D"
+         CHAOS="CHAOS"
+         TYPE="TXT"
+         IP="id.server"
+         break
+      ;;
+      CHAOS)
+         ADDRESS="D"
+         CHAOS="CHAOS"
+         TYPE="TXT"
+         IP="id.server"
+         break
+      ;;
+      *)
+        IP="$1"
+        TYPE="${TYPE:-'TXT'}"
+        >&2 echo "got non-dns: $IP"
+      ;;
+    esac
+  fi
+shift
+done
+
+
+if [ "$DEFAULT_NS" = "1" ]
+then
+  case "$ADDRESS$VERSION" in
+      D6) NS="@fd42:d42:d42:53::1" ;;
+      D4) NS="@172.23.0.53" ;;
+      G6) NS="@2001:4860:4860::8888" ;;
+      G4) NS="@8.8.8.8" ;;
+       *) NS="asdf" ;;
+  esac
+fi
+
+NODE=$(uname -n)
+echo -n "$NODE -> dig $CHAOS $TYPE $IP $NS : "
+
+if [ -z "$IP" ]; then echo bad ip; exit; fi
+
+>&2 echo $DIG $CHAOS "$TYPE" "$IP" "$NS"
+dig=$($DIG $CHAOS "$TYPE" "$IP" "$NS" | sort |head -n 3| tr '\n' ' ')
+
+if [ -z "$dig" ]; then
+    echo  no record.
+    exit
+fi
+
+echo "$dig"

+ 23 - 0
shell/commands-available/dig6

@@ -0,0 +1,23 @@
+#!/bin/bash --restricted
+
+if   [[ "$1" =~ ^[0-9a-fA-F\:]{3,45}$ ]]; then
+   dig=$(dig -x "$1" +short)
+
+elif [[ "$1" =~ ^[a-z0-9\.-]{2,30}\.[a-z0-9]{2,4}$ ]]; then
+   dig=$(dig +short AAAA "$1" | tr '\n' ' ')
+
+elif [[ "$1" = "-h" || "$1" = "help" ]]; then
+  echo "Usage: !dig6 <host/ip>"
+  exit
+
+else
+
+  exit
+fi
+
+if [ -z "$dig" ]; then
+    echo dig6 "$1": no record
+    exit
+fi
+
+echo dig6 "$1": "$dig"

+ 23 - 0
shell/commands-available/dnscheck

@@ -0,0 +1,23 @@
+#!/bin/bash
+
+PASTE_SH=https://git.dn42.us/dn42/go-paste/raw/master/public/paste.sh
+REGISTRY_DNS=https://git.dn42.us/dn42/registry/raw/object-fix/data/dns/
+
+check_servers() {
+	ZONE=$1
+	echo "Checking ${ZONE}:"
+	wget -q "${REGISTRY_DNS}${ZONE}" -O- | grep nserver | cut -d: -f2-100 | sed 's/^\s*//g' | while read -r glue; do
+		NAME=$(echo "${glue}" | cut -d' ' -f1)
+		ADDR=$(echo "${glue}" | cut -d' ' -f2)
+		SOA=$(dig +short +time=1 +tries=1 dn42 soa "@${ADDR}")
+		TXT=$(dig +short +time=1 +tries=1 dn42 txt "@${ADDR}" | sed 's/"//g' | grep '^hash=')
+		printf '%-25s %-30s %s %s\n' "${NAME}" "(${ADDR}):" "${SOA}" "${TXT}"
+	done
+}
+
+echo "Checking dns servers... (please wait) $HOST"
+{
+	check_servers delegation-servers.dn42
+	check_servers recursive-servers.dn42
+} | bash -c "$(wget -q "${PASTE_SH}" -O-)" | grep url: | cut -d: -f2-1000 | sed 's/\s*//g'
+

+ 12 - 0
shell/commands-available/feature-request

@@ -0,0 +1,12 @@
+#!/bin/sh
+if [ "$1" = "-h" -o -z "$1" ]
+then
+    echo "Send a feature request to my creator"
+    echo "Usage: feature-request I need this cause it's cool ! ..."
+    exit
+fi
+
+RANDOM=$(($(dd if=/dev/urandom count=1 2> /dev/null | cksum | cut -d' ' -f1) % 32768))
+
+echo "$*" | mail -s "[IRCBOT] Feature Request $RANDOM" mandark.dev@gmail.com \
+    && echo "Feature request $RANDOM sent !" || echo "Fail :p"

+ 3 - 0
shell/commands-available/fortune

@@ -0,0 +1,3 @@
+#!/bin/sh
+[ "$1" = -h ] && echo "fortune - print a random, hopefully interesting, adage"
+[ -z "$*" ] && fortune

+ 31 - 0
shell/commands-available/grep

@@ -0,0 +1,31 @@
+#!/usr/bin/env python
+import os
+import re, sre_constants
+import sys
+from pipe import * # http://pypi.python.org/pypi/pipe/1.3
+
+if len(sys.argv) < 3:
+    print "grep: Grep dans les logs de quelqu'un"
+    print "N'a besoin que d'une partie de son nom pour le retrouver"
+    print "Usage: grep USERNAME SEARCH"
+    print "Exemple: grep shaz b[iy]te"
+    print "         grep CaptSea .*"
+    sys.exit(0)
+
+who = sys.argv[1]
+search = ' '.join(sys.argv[2:])
+
+try:
+    lines = os.listdir('logs/users') \
+        | where(lambda user: re.search(who, user, re.IGNORECASE) is not None) \
+        | select(lambda user: open('logs/users/%s' % user) \
+                     | where(lambda line: re.search(search, ' '.join(line.split()[4:]), re.IGNORECASE) is not None) \
+                     | select(lambda line: line.split(None, 4)) \
+                     | where(lambda line: len(line) == 5) \
+                     | select(lambda line: "%s %s <%s> %s" % (line[0], line[1], user, line[4]))) \
+                     | traverse | sort | tail(6)
+except sre_constants.error as e:
+    print e
+else:
+    for line in lines:
+        print line,

+ 25 - 0
shell/commands-available/help

@@ -0,0 +1,25 @@
+#!/bin/sh
+command="$(echo "$1" | sed 's#/#__SLASH__#g')"
+
+usage()
+{
+    echo help commands: $(ls -1 commands-enabled | grep -v :\\\|log | grep -v '~' | grep -v '#' | sed 's#__SLASH__#/#g')
+}
+
+if [ "$command" = "-h" -o -z "$command" ]
+then
+    usage
+else
+    if [ -x "commands-enabled/$command" ]
+    then
+        commands-enabled/$command -h
+    else
+        if [ -f "db/aliases/$command" ]
+        then
+            echo "$command is an alias to :"
+            cat db/aliases/$command
+        else
+            echo "Don't know $command"
+        fi
+    fi
+fi

+ 21 - 0
shell/commands-available/http

@@ -0,0 +1,21 @@
+#!/bin/bash
+
+[ -z "$1" ] && exit
+port="${2-80}"
+
+if   [[ "$1" =~ ^[0-9a-fA-F\:]{3,45}$ ]]; then
+  :
+
+elif [[ "$1" =~ ^[a-z0-9\.-]{2,30}\.[a-z0-9]{2,4}$ ]]; then
+  :
+
+elif [[ "$1" = "-h" || "$1" = "help" ]]; then
+  echo "Usage: !http <host> [port]"
+  exit
+
+else
+  exit
+fi
+
+echo -n http "$1/$port":
+http --ignore-stdin --timeout 5 --check-status --follow --verify no -h "http://$1:$port" 1> /dev/null  && echo ' CONNECT' || echo ' FAILED'

+ 21 - 0
shell/commands-available/https

@@ -0,0 +1,21 @@
+#!/bin/bash
+
+[ -z "$1" ] && exit
+port="${s-443}"
+
+if   [[ "$1" =~ ^[0-9a-fA-F\:]{3,45}$ ]]; then
+  :
+
+elif [[ "$1" =~ ^[a-z0-9\.-]{2,30}\.[a-z0-9]{2,4}$ ]]; then
+  :
+
+elif [[ "$1" = "-h" || "$1" = "help" ]]; then
+  echo "Usage: !https <host> [<port>]"
+  exit
+
+else
+  exit
+fi
+
+echo -n https "$1/$port":
+http --ignore-stdin --timeout 5 --check-status --follow --verify no -h "https://$1:$port" 1> /dev/null && echo ' CONNECT' || echo ' FAILED'

+ 11 - 0
shell/commands-available/md5sum

@@ -0,0 +1,11 @@
+#!/bin/sh
+usage()
+{
+    echo "Compute MD5 message digest"
+    echo "Usage: md5sum blah blah balh"
+    exit
+}
+
+[ "$1" = -h -o -z "$1" ] && usage
+
+echo -n $* | md5sum | cut -d' ' -f1

+ 20 - 0
shell/commands-available/nl-zuid

@@ -0,0 +1,20 @@
+#!/usr/bin/fish
+
+
+set user $argv[1]
+
+if not [ $user ]
+  echo "Usage: !nl-zuid [--all] [ircNick] -- For more information go to https://nl-zuid.dn42. Look up peer information with !nl-zuid <irc name>"
+  exit
+end
+
+if [ $user = "--all" ]
+    set user ''
+exit
+end 
+
+
+http --verify no \
+     --ignore-stdin \
+     --pretty none \
+     -b GET "https://nl-zuid.dn42/peers.json?irc=$user" | /opt/skillet/bin/nl-zuid.users

+ 18 - 0
shell/commands-available/note

@@ -0,0 +1,18 @@
+#!/bin/sh -f
+mkdir -p db/note
+key=$(echo "$1" | sed 's/\//_/g')
+if [ -z "$key" -o "$key" = -f ]
+then
+        echo "Take notes, like :"
+        echo "you: note key value"
+        echo "you: note key"
+        echo "the_biatch: value"
+        exit
+fi
+
+if [ -z "$2" ]
+then
+        cat "db/note/$key"
+else
+        echo "$2" > "db/note/$key"
+fi

+ 81 - 0
shell/commands-available/path

@@ -0,0 +1,81 @@
+#!/bin/bash
+
+CMD="${0##*/}"
+
+. settings
+
+if [[ "$CMD" = *6 ]]; then
+   VERSION="6"
+   DIG="dig +short AAAA"
+else
+   VERSION="4"
+   DIG="dig +short A"
+fi
+
+ADDRESS="G"
+
+if [[ "$1" = "-h" || "$1" = "help" ]]; then
+    echo "Usage: [!@]route[6] <host/ip>"
+    exit
+
+elif [[ "$1" =~ ^[0-9\./]{7,15}$ ]]; then
+    IP="$1"
+    route_ip="$IP"
+
+    >&2 echo "got ip4: $IP"
+    if [[ "$IP" =~ (^127\.)|(^192\.168\.)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.) ]]; then ADDRESS="D"; fi
+
+elif [[ "$1" =~ ^[0-9a-fA-F\:\.]{3,45}$ ]]; then
+    IP="$1"
+    route_ip="$IP"
+
+    >&2 echo "got ip6: $IP"
+    VERSION=6
+    if [[ "$IP" =~ (^[fF][cCdD]) ]]; then ADDRESS="D"; fi
+
+elif [[ "$1" =~ [_a-z0-9\.-]{2,}\.[a-z0-9]{2,9}$ ]]; then
+    IP="$1"
+    >&2 echo "got dns: $IP"
+
+    if [[ "$IP" =~ (dn42$) ]]; then ADDRESS="D"; fi
+    if [[ "$IP" =~ (hack$) ]]; then ADDRESS="D"; fi
+    if [[ "$IP" =~ (\.ff[a-z0-9]*$)|(\.freifunk$) ]]; then ADDRESS="D"; fi
+    if [[ "$IP" =~ (\.rzl$)|(\.adm$)|(\.icvpn$)|(\.helgo) ]]; then ADDRESS="D"; fi
+    if [[ "$IP" =~ (\.ano$)|(\.[0-9]{2,3}$) ]]; then ADDRESS="D"; fi
+
+    IP=$($DIG "$IP")
+fi
+
+  case "$ADDRESS$VERSION" in
+      G4) SRC=""
+          ROUTE="birdc"
+      ;;
+      D4) SRC="$LOCAL_IP4"
+          ROUTE="birdc"
+      ;;
+      D6) SRC="$LOCAL_IP6"
+          ROUTE="birdc6"
+      ;;
+      G6) SRC=""
+          ROUTE="birdc6"
+      ;;
+       *) exit ;;
+  esac
+
+>&2 echo "using $ROUTE"
+
+NODE=$(uname -n)
+
+CMD="${0##*!}"
+
+MAXHOP=4
+NODE=$(uname -n)
+
+>&2 echo "IP: $IP"
+echo -n "$NODE -> $1:"
+
+if [ -z "$IP" ]; then echo "unable to resolve"; exit; fi
+
+path=$(sudo $ROUTE show route for "$IP" primary all | grep BGP.as_path | cut -d':' -f2)
+echo "$path"
+

+ 22 - 0
shell/commands-available/peer

@@ -0,0 +1,22 @@
+#!/usr/bin/fish
+
+set ip $argv[1]
+
+if not [ $ip ]
+  echo "Usage: @peer <ip> -- For more information go to dn42.us/peers"
+  exit
+end
+
+set id (http -b --form \
+     --verify no \
+     --ignore-stdin \
+     --pretty none \
+   POST https://dn42.us/peers/req \
+        req_ip=$ip \
+        req_hidden=1 \
+        accept:text/environment \
+   | grep REQ_ID | cut -d'"' -f2)
+
+if [ $id ]
+  echo "Find results for $ip here: https://dn42.us/peers/req/$id"
+end

+ 23 - 0
shell/commands-available/ping

@@ -0,0 +1,23 @@
+#!/bin/bash --restricted
+
+if [[ "$1" =~ ^[0-9\.]{7,16}$ ]]; then
+  :
+elif [[ "$1" =~ ^[a-z0-9\.-]{2,30}\.[a-z0-9]{2,4}$ ]]; then
+  :
+elif [[ "$1" = "-h" || "$1" = "help" ]]; then
+  echo "Usage: !ping <host/ip>"
+  exit
+else
+  exit
+fi
+
+
+ping=$(ping -c 2 "$1" | grep rtt | cut -d '=' -f 2|cut -d '/' -f2)
+
+if [[ -z "$ping" ]]; then
+  echo ping "$1": no response
+  exit
+fi
+
+echo ping "$1": $ping ms
+

+ 22 - 0
shell/commands-available/ping6

@@ -0,0 +1,22 @@
+#!/bin/bash --restricted
+
+if [[ "$1" =~ ^[0-9a-fA-F\:]{3,45}$ ]]; then
+  :
+elif [[ "$1" =~ ^[a-zA-Z0-9\.-]{2,30}\.[a-z0-9]{2,4}$ ]]; then
+  :
+elif [[ "$1" = "-h" || "$1" = "help" ]]; then
+  echo "Usage: !ping6 <host/ip>"
+  exit
+else
+  echo "Pl0x don't hax me."
+  exit
+fi
+
+ping=$(ping6 -c 2 "$1" | grep rtt | cut -d '=' -f 2|cut -d '/' -f2)
+
+if [[ -z "$ping" ]]; then
+  echo ping6 "$1": no response
+  exit
+fi
+
+echo ping6 "$1": "$ping" ms

+ 18 - 0
shell/commands-available/quote

@@ -0,0 +1,18 @@
+#!/bin/sh -f
+
+mkdir -p db/quotes
+
+case "$1" in
+    add) 
+	shift	
+	echo "$*" >> db/quotes/quotes
+	;;
+    -h)
+	echo "Add a quote : quote add BLAH BLAH"
+	echo "Get a random quote : quote"
+	;;
+    *)
+	cat db/quotes/quotes | shuf | head -n 1
+	;;
+esac
+   

+ 80 - 0
shell/commands-available/reader

@@ -0,0 +1,80 @@
+#!/bin/sh
+mkdir -p db/reader/feeds/
+
+usage()
+{
+    cat <<EOF
+reader is an RSS reader that push on the channel.
+Usage : reader [list|add|del]
+    list: List currently reading feeds
+    add: Add a new feed
+    del: Remove the given feed
+EOF
+    exit
+}
+
+restart_daemon()
+{
+    if [ -s db/reader/reader.pid ]
+    then
+	pid=$(cat db/reader/reader.pid)
+        [ -n "$pid" -a "$pid" -gt "0" ] && kill -9 $pid
+    fi
+    pkill -f '[r]ss_follower'
+    ./rss_follower.py --pidfile db/reader/reader.pid --daemonize --depth 3 \
+	-i 120 $(cat db/reader/feeds/*/url)
+}
+
+del()
+{
+    feed="$1"
+    path="$(printf "%s" "$feed" | sed 's/[^a-zA-Z0-9_:-]/./g')"
+
+    if [ -d "db/reader/feeds/$path" ]
+    then
+	rm -fr "db/reader/feeds/$path"
+    else
+	echo 'No such feed !' 
+    fi
+    restart_daemon
+}
+
+add()
+{
+    feed="$1"
+    path="$(printf "%s" "$feed" | sed 's/[^a-zA-Z0-9_:-]/./g')"
+
+    mkdir "db/reader/feeds/$path"
+    printf "%s\n" "$feed" > "db/reader/feeds/$path/url"
+    restart_daemon
+}
+
+list()
+{
+    feeds="$(ls -1 db/reader/feeds/)"
+    if [ -z "$feeds" ]
+    then
+	echo "No feeds registered, you can add some using $0 add URL"
+    else
+	cat db/reader/feeds/*/url
+    fi
+}
+
+case "$1" in
+    del)
+	shift
+	del "$*"
+	;;
+    list)
+	list
+	;;
+    add)
+	shift
+	add "$*"
+	;;
+    restart)
+	restart_daemon
+	;;
+    *)
+	usage
+esac

+ 6 - 0
shell/commands-available/rollcall

@@ -0,0 +1,6 @@
+#!/bin/bash
+
+. settings
+
+HOST=$(hostname)
+echo "$HOST at $LOCAL_IP4 / $LOCAL_IP6"

+ 24 - 0
shell/commands-available/route

@@ -0,0 +1,24 @@
+#!/bin/bash --restricted
+
+node=$(uname -n)
+
+if [[ "$1" =~ ^[0-9\.]{7,16}$ ]]; then
+  ver=""
+elif [[ "$1" =~ ^[0-9a-fA-F\:\.]{3,45}$ ]]; then
+  ver="-6"
+elif [[ "$1" = "-h" || "$1" = "help" ]]; then
+  echo "Usage: !route <host/ip>"
+  exit
+else
+  exit
+fi
+
+
+ping=$(ip $ver route get "$1" | tr -d '\n')
+
+if [[ -z "$ping" ]]; then
+  ping="no route"
+fi
+
+echo "$node -> $ping"
+

+ 14 - 0
shell/commands-available/rss

@@ -0,0 +1,14 @@
+#!/usr/bin/env python
+try:
+    import feedparser
+except ImportError:
+    print "You need http://code.google.com/p/feedparser/downloads/list"
+import sys
+
+feed = feedparser.parse(sys.argv[1])
+limit = 5
+
+for entry in feed['entries']:
+    if limit > 0:
+        print entry['title'], entry['link']
+        limit -= 1

+ 31 - 0
shell/commands-available/run

@@ -0,0 +1,31 @@
+#!/bin/sh -f
+if [ "$1" = '-h' ]
+then
+   echo "$(basename "$0"): Run a command"
+   echo "Usage: run NAME"
+   echo "Example: (julien) alias pi >>> import math; print math.pi"
+   echo "         (julien) run pi"
+   echo "         (the-biatch) 3.1415926535897931"
+   exit 0
+fi
+
+mkdir -p db/aliases
+
+alias=$(printf "%s" "$1" | sed 's#/#__SLASH__#g')
+args=$(printf "%s" "$*" | sed 's/^ *[^ ]* *//g' )
+
+if [ -f "db/aliases/$alias" ]
+then
+    line=$(cat "db/aliases/$alias" | sed "s/|ARGS|/$(echo "$args" | sed 's/\\/\\\\/g;s/&/\\&/g;s#/#\\/#g')/g")
+    command=$(printf "%s" "${line%% *}" | sed 's#/#__SLASH__#g')
+    if [ -x "commands-enabled/$command" ]
+    then
+        args=$(echo "$line" | sed 's/^ *[^ ]* *//g' )
+        printf '%s\n' "Alias running command '$command' with '$args'" >&2
+        commands-enabled/$command $args
+    fi
+fi
+
+
+
+

+ 7 - 0
shell/commands-available/say

@@ -0,0 +1,7 @@
+#!/bin/sh -f
+usage()
+{
+    echo "I just repeat..."
+    echo "Usage: say something"
+}
+[ "$1" = -h -o -z "$1" ] && usage || printf "%s\n" "$*"

+ 11 - 0
shell/commands-available/sha1sum

@@ -0,0 +1,11 @@
+#!/bin/sh
+usage()
+{
+    echo "Compute SHA1 message digest"
+    echo "Usage: sha1sum blah blah balh"
+    exit
+}
+
+[ "$1" = -h -o -z "$1" ] && usage
+
+echo -n $* | sha1sum | cut -d' ' -f1

+ 15 - 0
shell/commands-available/slack

@@ -0,0 +1,15 @@
+#!/bin/sh
+if [ "$1" = '-h' ]
+then
+   echo "$(basename "$0"): Cherche des URL dans les logs"
+   echo "Get an optional argument to filter out the result"
+   exit 0
+fi
+if [ ! -z "$*" ] 
+then
+    grep 'http://' logs/users/*  | grep -i "$*" | cut -d/ -f3- | sed -r 's/([^:]*):([^ ]* [^ ]*) [^ ]* [^ ]* (.*)/\2 \1 \3/g' | sort | tail -n 7
+else
+    grep 'http://' logs/users/*  | cut -d/ -f3- | sed -r 's/([^:]*):([^ ]* [^ ]*) [^ ]* [^ ]* (.*)/\2 \1 \3/g' | sort | tail -n 7
+fi
+
+

+ 39 - 0
shell/commands-available/stats

@@ -0,0 +1,39 @@
+#!/usr/bin/env python
+import os
+import re
+import sys
+from pipe import * # http://pypi.python.org/pypi/pipe/1.3
+from subprocess import Popen, PIPE
+
+if len(sys.argv) > 1 and sys.argv[1] == '-h':
+     print "stats: Calcule des status sur quelqu'un"
+     print "N'a besoin que d'une partie de son nom pour le retrouver (perl regex)"
+     print "Exemple: stats oa"
+     sys.exit(0)
+
+search = re.search('[a-zA-Z0-9*.]*', sys.argv[1] if len(sys.argv) > 1 else '.*')
+if search is None or search.group(0) == '':
+    print "Stats de qui ?"
+    sys.exit(0)
+else :
+    search = search.group(0)
+
+def wc(logfile):
+     return int(Popen(['wc', '-l', os.path.join('logs/users', logfile)],
+                      stdout=PIPE).communicate()[0].split()[0])
+
+stats = os.listdir('logs/users') \
+    | where(lambda user: re.search(search, user, re.IGNORECASE) is not None) \
+    | select(lambda user: (user, wc(user))) \
+    | as_dict
+
+if len(stats) > 0:
+     stats.iteritems() \
+         | sort(cmp=lambda x, y: y[1] - x[1]) \
+         | select(lambda stat: "%s: %d" % (stat[0], stat[1])) \
+         | take(10) \
+         | concat \
+         | lineout
+
+if len(stats) > 1:
+     print 'Total: %d' % sum(stats.values())

+ 19 - 0
shell/commands-available/status

@@ -0,0 +1,19 @@
+#!/usr/bin/env python
+import re
+import sys
+import DNS
+
+
+if len(sys.argv) == 1 or sys.argv[1] == "-h":
+    print 'Get last status of someone on twitter'
+    print "Usage: %s sizeof" % sys.argv[0]
+    sys.exit(0)
+
+try:
+    username = re.search('[a-zA-Z0-9*.]*', sys.argv[1]).group(0)
+    DNS.DiscoverNameServers();
+    r = DNS.Request('%s.twitter.any.io' % username, qtype='txt');
+    ans = r.req()
+    print ans.answers[0]['data'][0]
+except Exception as ex:
+    print "Humph, I can't find this twitter user ..."

+ 33 - 0
shell/commands-available/taunt

@@ -0,0 +1,33 @@
+#!/bin/sh
+
+touch db/taunts
+
+usage()
+{
+    echo "To add a taunt: taunt add I knew you couldn't do it !"
+    echo "To query a random taunt: taunt"
+    echo "To grep for a taunt: taunt search mother"
+}
+
+taunt_add()
+{
+    echo "$*" >> db/taunts
+    echo "Oh Yeah !"
+}
+
+taunt_rand()
+{
+    shuf db/taunts | head -n 1
+}
+
+taunt_search()
+{
+    grep -i "$*" db/taunts
+}
+
+case "$1" in
+     add) shift; taunt_add $@ ;;
+     search) shift; taunt_search $@ ;;
+     "") taunt_rand ;;
+     *) usage ;;
+esac

+ 32 - 0
shell/commands-available/tcpconnect

@@ -0,0 +1,32 @@
+#!/bin/bash --restricted
+
+CMD="${0##*/}"
+
+[ -z "$1" ] && exit
+[ -z "$2" ] && exit
+
+NODE=$(uname -n)
+
+if   [[ "$1" =~ ^[0-9\.]{7,15}$ ]]; then
+   TCP='nc -4'
+elif [[ "$1" =~ ^[0-9a-fA-F\:]{3,45}$ ]]; then
+   TCP='nc -6'
+elif [[ "$1" =~ ^[a-z0-9\.-]{2,30}\.[a-z0-9]{2,4}$ ]]; then
+   if [[ "$CMD" = *4 ]]; then
+     TCP='nc -4'
+   else
+     TCP='nc -6'
+   fi
+elif [[ "$1" = "-h" || "$1" = "help" ]]; then
+  echo "Usage: !$CMD <<ip/dns>> <<port>>"
+  exit
+else
+  exit
+fi
+
+TXT="$NODE $CMD -> $1/$2":
+if $TCP -w 5 -z "$1" "$2"; then
+  echo "$TXT CONNECT"
+else
+   echo "$TXT FAILED"
+fi

+ 23 - 0
shell/commands-available/tinyurl

@@ -0,0 +1,23 @@
+#!/usr/bin/env python
+
+from urllib import urlopen, urlencode
+import sys
+import re
+
+def _tiny(match):
+    url = match.group()
+    if len(url) >= 30:
+        return urlopen("http://tinyurl.com/api-create.php",
+                              data=urlencode(dict(url=url))).read().strip()
+    else:
+        return url
+
+def tiny(string):
+    return re.sub('http://[^ ]+', _tiny, string)
+
+
+if len(sys.argv) == 2 and sys.argv[1] == '-h':
+    print "tinyurl: Shorten urls, you can give a whole text, it will find urls"
+    print "and shorten only longest ones"
+else:
+    print tiny(' '.join(sys.argv[1:]))

+ 25 - 0
shell/commands-available/trace

@@ -0,0 +1,25 @@
+#!/bin/bash
+
+MAXHOP=16
+
+if   [[ "$1" =~ ^[0-9\.]{7,15}$ ]]; then
+   :
+elif [[ "$1" =~ ^[a-z0-9\.-]{2,30}\.[a-z0-9]{2,4}$ ]]; then
+   :
+elif [[ "$1" = "-h" || "$1" = "help" ]]; then
+  echo Usage: !trace 8.8.8.8
+  exit
+else
+  exit
+fi
+
+hops=$(traceroute  -n -m $MAXHOP "$1" | tail -1 | sed -e 's/^[[:space:]]*//' | cut -f1 -d' ')
+
+if [ -z "$hops" ]; then
+    echo trace "$1": no route found
+    exit
+fi
+
+[[ "$hops" -ge "$MAXHOP" ]] && echo trace "$1": more than $hops hops, I cannot see the final hop.
+[[ "$hops" -lt "$MAXHOP" ]] && echo trace "$1": $hops hops
+

+ 141 - 0
shell/commands-available/trace3

@@ -0,0 +1,141 @@
+#!/bin/bash
+
+CMD="${0##*/}"
+
+. settings
+
+if [[ "$CMD" = *4 ]]; then
+   VERSION="4"
+   DIG="dig +short A"
+else
+   VERSION="6"
+   DIG="dig +short AAAA"
+fi
+
+ADDRESS="G"
+
+if [[ "$1" = "-h" || "$1" = "help" ]]; then
+    echo "Usage: [!@]ping[6] <host/ip>"
+    exit
+
+elif [[ "$1" =~ ^[0-9\./]{7,15}$ ]]; then
+    IP="$1"
+    route_ip="$IP"
+
+    >&2 echo "got ip4: $IP"
+    VERSION=4
+    if [[ "$IP" =~ (^127\.)|(^192\.168\.)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.) ]]; then ADDRESS="D"; fi
+
+elif [[ "$1" =~ ^[0-9a-fA-F\:\.]{3,45}$ ]]; then
+    IP="$1"
+    route_ip="$IP"
+
+    >&2 echo "got ip6: $IP"
+    VERSION=6
+    if [[ "$IP" =~ (^[fF][cCdD]) ]]; then ADDRESS="D"; fi
+
+elif [[ "$1" =~ [_a-z0-9\.-]{1,}\.[a-z0-9]{2,9}$ ]]; then
+    IP="$1"
+    >&2 echo "got dns: $IP"
+
+    if [[ "$IP" =~ (dn42$) ]]; then ADDRESS="D"; fi
+    if [[ "$IP" =~ (hack$) ]]; then ADDRESS="D"; fi
+    if [[ "$IP" =~ (\.ff[a-z0-9]*$)|(\.freifunk$) ]]; then ADDRESS="D"; fi
+    if [[ "$IP" =~ (\.rzl$)|(\.adm$)|(\.icvpn$)|(\.helgo) ]]; then ADDRESS="D"; fi
+    if [[ "$IP" =~ (\.ano$)|(\.[0-9]{2,3}$) ]]; then ADDRESS="D"; fi
+
+    route_ip=$($DIG "$IP")
+fi
+
+  case "$ADDRESS$VERSION" in
+      G4) SRC=""
+          ROUTE="ip route get"
+          PING="ping"
+          TRACE="traceroute"
+      ;;
+      D4) SRC="$LOCAL_IP4"
+          ROUTE="ip route get"
+          PING="ping -I $SRC"
+          TRACE="traceroute -s $SRC"
+      ;;
+      D6) SRC="$LOCAL_IP6"
+          ROUTE="ip -6 route get"
+          PING="ping6 -I $SRC"
+          TRACE="traceroute6 -s $SRC"
+      ;;
+      G6) SRC=""
+          ROUTE="ip -6 route get"
+          PING="ping6"
+          TRACE="traceroute6"
+      ;;
+       *) exit ;;
+  esac
+
+>&2 echo "using $PING"
+
+NODE=$(uname -n)
+
+if [ -z "$IP" ]; then echo bad ip; exit; fi
+
+CMD="${0##*!}"
+
+MAXHOP=4
+NODE=$(uname -n)
+
+echo -n "$NODE -> $1: "
+
+if [ -z "$route_ip" ]; then echo "unable to resolve"; exit; fi
+
+
+route=$($ROUTE "$route_ip")
+if [[ "$route" =~ (^unreachable.*) ]]; then echo "unreachable path"; exit; fi
+
+
+TEMP=$(mktemp)
+$PING -n -w1 -c1 "$1" > "$TEMP"
+
+check=$(cat "$TEMP"|grep ttl|cut -f6,7 -d' '|sed -e 's/ttl=\(.*\)/\1/;s/time=\(.*\)/\1ms/')
+
+if [ -z "$check" ]; then
+  ERR="unreachable"
+  ret_hops="$MAXHOP"
+
+  grep -q 'Time to live exceeded' "$TEMP" && ERR="ttl-exceeded"
+else
+  ERR=""
+  ret_hops=$(echo "$check"|cut -d' ' -f1)
+  ts=$(echo "$check"|cut -d' ' -f2)
+  if [ "$ret_hops" -gt 128 ]; then ret_hops=$(expr "$ret_hops" - 191); fi;  # Sometime the ping response ttl is 255..
+  if [ "$ret_hops" -gt 64 ]; then ret_hops=$(expr "$ret_hops" - 63); fi;  # Sometime the ping response ttl is 128..
+  ret_hops=$(expr 65 - "$ret_hops")
+
+  if [ "$ret_hops" -le "0" ]; then ERR="Unresponsive"; hops="$MAXHOP";
+  else
+   LAG="$ts"
+  fi
+fi
+
+if [ "$ret_hops" -le "0" ]; then ERR="unreachable"; ret_hops="$MAXHOP"; fi
+if [ "$ret_hops" -ge "255" ]; then ERR="Too many hops"; ret_hops="$MAXHOP"; fi
+
+
+$TRACE -I -n -m $(expr 3 + "$ret_hops") "$1" | tail -n +2 | sed -e 's/^[[:space:]]*//' | cut -f3 -d' '  > "$TEMP"
+
+grep -q '!A' "$TEMP" && ERR="denied"
+grep -q '!H' "$TEMP" && ERR="unresponsive"
+grep -q '!T' "$TEMP" && ERR="timeout"
+grep -q '!Q' "$TEMP" && ERR="bandwidth"
+grep -q '!U' "$TEMP" && ERR="port-unreachable"
+grep -q '!N' "$TEMP" && ERR="net-unreachable"
+grep -q '!P' "$TEMP" && ERR="proto-unreachable"
+
+NPATH=$(cat "$TEMP" | xargs echo | sed 's/\*\(\ \*\)\+/\*\*\*/')
+hops=$(echo "$NPATH" | wc -w)
+
+if [ -n "$ERR" ]
+  then echo " err: $ERR path: $NPATH"
+  else echo " hops: $hops:$ret_hops lag: $LAG path: $NPATH"
+fi
+
+rm "$TEMP"
+exit

+ 25 - 0
shell/commands-available/trace6

@@ -0,0 +1,25 @@
+#!/bin/bash
+
+MAXHOP=16
+
+if   [[ "$1" =~ ^[0-9a-fA-F\.\:]{3,45}$ ]]; then
+   :
+elif [[ "$1" =~ ^[a-z0-9\.-]{2,30}\.[a-z0-9]{2,4}$ ]]; then
+   :
+elif [[ "$1" = "-h" || "$1" = "help" ]]; then
+  echo "Usage: !trace6 <dns/ip>"
+  exit
+else
+  exit
+fi
+
+hops=$(traceroute6 -n -m $MAXHOP "$1" | tail -1 | sed -e 's/^[[:space:]]*//' | cut -f1 -d' ')
+
+if [ -z "$hops" ]; then
+    echo trace6 "$1": no route found
+    exit
+fi
+
+[[ "$hops" -ge "$MAXHOP" ]] && echo trace6 "$1": more than $hops hops, I cannot see the final hop.
+[[ "$hops" -lt "$MAXHOP" ]] && echo trace6 "$1": $hops hops
+

+ 18 - 0
shell/commands-available/translate

@@ -0,0 +1,18 @@
+#!/bin/sh
+usage()
+{
+    echo "Usage: translate from-to blah blah"
+    echo "Example: translate en-fr shit"
+}
+
+[ "$1" = -h -o -z "$1" ] && usage && exit
+
+from=fr
+to=en
+if echo "$1" | grep -q -- '-'
+then
+    from="$(echo $1 | cut -d- -f1)"
+    to="$(echo $1 | cut -d- -f2)"
+    shift
+fi
+wget -qO- "http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q=$*&langpair=$from|$to" | sed 's/.*"translatedText":"\([^"]*\)".*}/\1\n/';

+ 49 - 0
shell/commands-available/twitter

@@ -0,0 +1,49 @@
+#!/bin/sh -f
+
+#
+# To use this module you should have bti installed (aptitude install bti if
+# you're on Debian, else, ... dunno ...)
+#
+# To let this module work you have to configure bti :
+# 1) Just create a file bti.conf in the directory conf/ near to hooks/
+# 2) GOTO http://twitter.com/apps/new and create an app
+#    -> Give write rights
+#    -> Set 'Application type' to 'Client'
+# 2') Double and triple check, AFTER having created the application but BEFORE
+#     step 3, in https://dev.twitter.com/apps that WRITE permissin is given to
+#     you app (I checked it in step 2 but twitter forgot it ... so double check)
+# 3) Copy the consumer_key and consumer_secret in bti.conf like :
+#    consumer_key=ASDFASDFASDFADSF
+#    consumer_secret=QWERTQWERTQWERT
+# 4) manually run this shell script typing ./commands-enabled/twitter
+#    An url will be given an a PIN should be asked, the PIN is found behind
+#    the url.
+# 5) Once the pin given, the script will give you an access_token_key and an
+#    access_token_secret, write them near to the consumer_key and
+#    consumer_secret in the bti.conf file.
+#
+#
+#
+
+if [ ! -f conf/bti.conf ]
+then
+    echo "The twitter command need some configuration, please read it source."
+    exit
+fi
+
+if [ "$1" = -h -o -z "$1" ]
+then
+    echo "Usage: twitter blah blah ..."
+    echo "URLs are shortened using tinyurl, you will be warned if teh"
+    echo "shortened message is longer than 140 chars, so don't worry."
+    exit
+fi
+
+message="$(./commands-available/tinyurl "$*")"
+length=$(printf "%s" "$message" | wc -l)
+if [ "$length" -gt 140 ]
+then
+    echo "Too long ..."
+else
+    printf "%s\n" "$message" | bti --host twitter --account slackzomgffs --action update --config conf/bti.conf
+fi

+ 20 - 0
shell/commands-available/unalias

@@ -0,0 +1,20 @@
+#!/bin/sh -f
+if [ "$1" = '-h' ]
+then
+    commands-enabled/alias -h
+    exit 0
+fi
+
+if [ -z "$1" ]
+then
+    ls -1 db/aliases | tr '\n' ' '
+    exit 0
+fi
+
+command="$(echo "$1" | sed 's|/|__SLASH__|g')"
+rm -f "db/aliases/$command"
+
+
+
+
+

+ 51 - 0
shell/commands-available/untinyurl

@@ -0,0 +1,51 @@
+#!/usr/bin/env python
+
+import urllib2
+import sys
+import socket
+import re
+
+socket.setdefaulttimeout(5)
+
+class NoRedirectHandler(urllib2.HTTPRedirectHandler):
+    def http_error_302(self, req, fp, code, msg, headers):
+        infourl = urllib2.addinfourl(fp, headers, req.get_full_url())
+        infourl.status = code
+        infourl.code = code
+        return infourl
+    http_error_300 = http_error_302
+    http_error_301 = http_error_302
+    http_error_303 = http_error_302
+    http_error_307 = http_error_302
+
+opener = urllib2.build_opener(NoRedirectHandler())
+urllib2.install_opener(opener)
+
+class HeadRequest(urllib2.Request):
+    def get_method(self):
+        return "HEAD"
+
+def follow(url):
+    try:
+        response = urllib2.urlopen(HeadRequest(url)).info()
+        if 'Location' in response:
+            return follow(response['Location'])
+    except:
+        pass
+    return url
+
+if len(sys.argv) > 1 and '-h' in sys.argv[1]:
+    print "Expand a tinyurl"
+    sys.exit(0)
+
+def _untiny(match):
+    return follow(match.group())
+
+def untiny(string):
+    return re.sub('http://[^ ]+', _untiny, string)
+
+if len(sys.argv) > 1:
+    print untiny(' '.join(sys.argv[1:]))
+else:
+    for line in sys.stdin:
+        print untiny(line.strip())

+ 9 - 0
shell/commands-available/weather

@@ -0,0 +1,9 @@
+#!/bin/sh
+usage()
+{
+    echo "Obtain weather conditions and forecasts"
+    echo "Ussage 'weather [METAR]'"
+    echo "    METAR: Defaults to LFPO"
+}
+
+[ "$1" = -h ] && usage || weather -i ${1:-LFPO} --quiet -m

+ 8 - 0
shell/commands-available/whoami

@@ -0,0 +1,8 @@
+#!/bin/bash
+
+. settings
+
+echo "You are nick: $SKILLET_NICK ident: $SKILLET_IDENT host: $SKILLET_HOST"
+echo "+ NOTICE $SKILLET_IRC_CHAN"
+printenv | grep SKILLET | tr '\n' ' '
+echo

+ 11 - 0
shell/commands-available/wiki

@@ -0,0 +1,11 @@
+#!/bin/sh
+usage()
+{
+    echo 'Query something on en.Wikipedia.org ...'
+    echo "Usage: $(basename "$0") sex"
+    exit
+}
+
+[ "$1" = -h -o -z "$1" ] && usage
+result="$(dig +short txt $(echo $* | sed -e 's/ /_/g' | grep -o '[a-zA-Z0-9_()]*' | head -n1).wp.dg.cx | tr -d \\ | grep -v '^;;')"
+[ -n "$result" ] && echo "$result" || echo "Humph, I can't find anything about this ..."

+ 0 - 0
shell/commands-enabled/.placeholder


+ 24 - 0
shell/commands-enabled/dnscheck

@@ -0,0 +1,24 @@
+#!/bin/bash
+
+echo "Checking dns servers... (please wait) $HOST"
+
+PASTE_SH=https://git.dn42.us/dn42/go-paste/raw/master/public/paste.sh
+REGISTRY_DNS=https://git.dn42.us/dn42/registry/raw/object-fix/data/dns/
+
+check_servers() {
+	ZONE=$1
+	echo "Checking ${ZONE}:"
+	wget -q "${REGISTRY_DNS}${ZONE}" -O- | grep nserver | cut -d: -f2-100 | sed 's/^\s*//g' | while read -r glue; do
+		NAME=$(echo "${glue}" | cut -d' ' -f1)
+		ADDR=$(echo "${glue}" | cut -d' ' -f2)
+		SOA=$(dig +short +time=1 +tries=1 dn42 soa "@${ADDR}")
+		TXT=$(dig +short +time=1 +tries=1 dn42 txt "@${ADDR}" | sed 's/"//g' | grep '^hash=')
+		printf '%-25s %-30s %s %s\n' "${NAME}" "(${ADDR}):" "${SOA}" "${TXT}"
+	done
+}
+
+{
+	check_servers delegation-servers.dn42
+	check_servers recursive-servers.dn42
+} | bash -c "$(wget -q "${PASTE_SH}" -O-)" | grep url: | cut -d: -f2-1000 | sed 's/\s*//g'
+

+ 1 - 0
shell/commands-enabled/rollcall

@@ -0,0 +1 @@
+../commands-available/rollcall

+ 7 - 0
shell/commands-enabled/tst

@@ -0,0 +1,7 @@
+#!/bin/bash
+
+echo "Checking dns servers... (please wait) $HOST"
+sleep 4
+tail -n 1 /etc/resolv.conf
+sleep 2
+echo "Complete!"

+ 1 - 0
shell/commands-enabled/whoami

@@ -0,0 +1 @@
+../commands-available/whoami

+ 1 - 0
shell/db/note/key

@@ -0,0 +1 @@
+value

+ 0 - 0
shell/db/taunts


+ 72 - 0
shell/run

@@ -0,0 +1,72 @@
+#!/bin/bash -f
+
+#
+# This is a basic example hook for incoming messges (pubmsg, privmsg)
+#
+# Its role is simple, this hook will try to run executables in the
+# 'commands-enabled' folder. But if the executable is not found, it
+# will try to run the catchall binary 'run'
+#
+# Example:
+#   If someone says: 'eval 1 + 1'
+#   Then if commands-enabled/eval exists this hook will try to execute :
+#       commands-enabled/eval 1 + 1
+#   else if commands-enabled/run exists, this hook will try to execute :
+#       commands-enabled/run eval 1 + 1
+#
+# Exemple : hooks-enabled/pubmsg 'mandark' '~mandark@mandark.fr' '#zomgffs' '' 'say Hello world !'
+
+#>&2 echo "$*"
+
+. settings
+
+now=$(date "+%Y-%m-%d %H:%M:%S")
+hook="$0"
+s_user="$(printf %s "$1" | sed 's#/#__SLASH__#g')"
+s_host="$2"
+t_user="$3" # The channel, for "pubmsg" hook
+t_host="$4"
+shift 4
+sentence="$*"
+command="$(echo "${1%% *}" | sed 's#/#__SLASH__#g')"
+args="$(echo "$1" | sed 's/[^ ]*//')"
+
+>&2 echo "$command $args"
+>&2 echo "ENABLE_CHAN $ENABLE_CHAN"
+
+if [ ! -z "$ENABLE_CHAN" ]; then
+  if [ "$s_user" != "$t_user" ]; then
+    if [[ "$ENABLE_CHAN" =~ (^|[[:space:]])"$t_user"($|[[:space:]]) ]]; then
+      :
+    else
+      exit 2
+    fi
+  fi
+fi
+
+method="$(echo "$command" | cut -c1)"
+
+if [ "$method" = '!' ]; then
+  command="$(echo "$command" | cut -c2-)"
+  method="+NOTICE $s_user"
+elif [ "$method" = '@' ]; then
+  command="$(echo "$command" | cut -c2-)"
+  method="+NOTICE $t_user"
+else
+  exit 2
+fi
+
+if [ -x "commands-enabled/$command" ] && [ -f "commands-enabled/$command" ]
+then
+    printf '%s\n' "Running command '$command' with '$args'" >&2
+    echo "$method"
+    "commands-enabled/$command" $args
+elif [ -x "commands-enabled/run" ]
+then
+    printf '%s\n' "Running command run with '$command $args'" >&2
+    echo "$method"
+    commands-enabled/run "$command" $args
+else
+  printf '%s\n' "No command run with '$command $args'" >&2
+  exit 2
+fi

+ 0 - 21
skillet.pem

@@ -1,21 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDeDCCAmACCQC5gSalRVJQQzANBgkqhkiG9w0BAQsFADB+MQswCQYDVQQGEwJV
-UzENMAsGA1UECAwEVXRhaDEXMBUGA1UEBwwOU2FsdCBMYWtlIENpdHkxHDAaBgNV
-BAoME1ggVXJiYW4gVW5kZXJncm91bmQxFzAVBgNVBAsMDkNvbW11bmljYXRpb25z
-MRAwDgYDVQQDDAdza2lsbGV0MB4XDTE2MDMyNTE2MjAwM1oXDTI2MDMyMzE2MjAw
-M1owfjELMAkGA1UEBhMCVVMxDTALBgNVBAgMBFV0YWgxFzAVBgNVBAcMDlNhbHQg
-TGFrZSBDaXR5MRwwGgYDVQQKDBNYIFVyYmFuIFVuZGVyZ3JvdW5kMRcwFQYDVQQL
-DA5Db21tdW5pY2F0aW9uczEQMA4GA1UEAwwHc2tpbGxldDCCASIwDQYJKoZIhvcN
-AQEBBQADggEPADCCAQoCggEBAOZusXD5RxVJAs1Atre7cOaEVHg2KzV69mhKJahp
-D8X9B1GGrUiQn9g3GitAjTR0bs2oJ81abpj1fH2jPZaPvR665t2Mn5NZhygRuRns
-cVv6VGjFwtllOHJUBJJAKrS3QUhVpPCpffig4VtQK8quHfEakee8aGtuKS50i/9C
-b5kk0WmMHxnioRpl9quUEuEkdxYFM6vg8c+8ybIV2zegR3lyGpflJh247Z0oxN24
-In8vlRCmF8VSeswyCsYAnBmYMQ5pE8Cz/Jyfb1ISRSB8sbE61+TvbnPKgSj/hmdF
-c8XcA52/POtwoYM4eLgrxgc8LQ+ueAqAWLoXemOPn50uYUkCAwEAATANBgkqhkiG
-9w0BAQsFAAOCAQEAQhTgfz6gm/gM+CdNQkZyMspm4NA6/W0Vmw3trt/EsSqnIpn4
-otHaVhbuiaJuyP1rzCzGdZkurEPhUvFA8GIftf0y7eyrYSbTCxoqhMaRa50Ml/20
-mOmWhtrxkWSRxTYECbV/1uBFstGI+0U5JVBgm3xO8lwgagn/ibMOMtvRPSkLE9cP
-QNY7fbCystJ2AftRCea58RdyT2vnLSPq/bHPHfkeS2dksPQ3XCdmUALyQ4VipN+l
-Yf56zqdl++els3AVnNXoCrJJx5SfNIZtjXZtFgR/re+MyK1LE/q2Oto7vjSDWYF0
-YBI9AGftyIMq4f9dsayLoV116ukwnFMrw1hpFw==
------END CERTIFICATE-----