summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbuild-chroot116
-rwxr-xr-xcert-info128
-rwxr-xr-xfind-libs44
-rwxr-xr-xkde-logout16
-rwxr-xr-xsocket-info84
-rwxr-xr-xtabize30
-rwxr-xr-xtmp-upload124
-rwxr-xr-xudpsoundserver.py98
-rwxr-xr-xxstat21
9 files changed, 661 insertions, 0 deletions
diff --git a/build-chroot b/build-chroot
new file mode 100755
index 0000000..cd608e6
--- /dev/null
+++ b/build-chroot
@@ -0,0 +1,116 @@
+#!/bin/bash
+VERSION=0.1
+find_libs=~/scripts/find-libs
+usage() {
+ cat <<HELP
+Copies binaries and their dependencies for chroot usage.
+
+Copyright (C) 2012 Peter Wu
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+Written by Peter Wu <lekensteyn@gmail.com>
+
+Usage: $0 [OPTION] file...
+
+Options:
+ -n, --dry-run Do not copy files, just print the action that would be
+ performed.
+ -d DIR, --destdir DIR Destination directory for the files.
+ -c, --continue Continue even if a given file cannot be located.
+ -h, --help Print this help text, then exit.
+ --version Prints the version of this program, then exit.
+
+Environment:
+ DESTDIR If --destdir is not given, this environment variable is sought. If
+ this variable does not exist either, a temporary directory is
+ created which is printed on termination.
+HELP
+}
+
+opts=`getopt --name "$0" -o nd:ch \
+ --longoptions dry-run,destdir:,continue,help,version \
+ -- "$@"`
+if [ $? != 0 -o -z "$opts" ]; then
+ usage
+ exit 1
+fi
+eval set -- "$opts"
+
+DRY_RUN=false
+CONT_ON_ERR=false
+while :; do
+ case "$1" in
+ -n|--dry-run) DRY_RUN=true ;;
+ -d|--destdir) DESTDIR="$2" ; shift ;;
+ -c|--continue) CONT_ON_ERR=true ;;
+ -h|--help) usage; exit 0 ;;
+ --version) echo "$VERSION" ; exit 0 ;;
+ --) shift; break ;;
+ *) echo "Internal error!"; exit 1 ;;
+ esac
+ shift
+done
+
+if [ $# -eq 0 ]; then
+ echo "Need at least one binary or library to isolate."
+ echo "Try '$0 --help' for more information."
+ exit 1
+fi
+
+subjects=()
+for subject; do
+ realsubject="$subject"
+ #realsubject="$(readlink -e "$subject")"
+ [ -e "$realsubject" ] || realsubject="$(which "$subject" 2>/dev/null)" || true
+ if [ -n "$realsubject" ]; then
+ subjects[${#subjects[@]}]="$realsubject"
+ else
+ echo "Missing file: $subject"
+ fi
+done
+
+if ! [ $# = ${#subjects[@]} ]; then
+ echo "Some files could not be found"
+ echo "Expected $#, got ${#subjects[@]} valid args."
+ if ! $CONT_ON_ERR; then
+ echo "Aborting. To ignore this, pass the '--continue' option."
+ exit 255
+ fi
+fi
+
+info="$("$find_libs" "${subjects[@]}")"
+echo "$info"
+count=${info%% *}
+filelist="${info#* }"
+
+try_install() {
+ local file="$1"
+ # target without leading ../../etc
+ local target="$DESTDIR/$(sed 's,\(\.\./\)*,,' <<<"$file")"
+ if [ ! -e "$target" ]; then
+ if $DRY_RUN; then
+ echo "Installing $file"
+ else
+ install -v -D "$file" "$target"
+ fi
+ fi
+}
+if [ $count -gt 0 ]; then
+ tmpdir=
+ if [ -z "$DESTDIR" ]; then
+ tmpdir="$(mktemp -d)"
+ DESTDIR="$tmpdir"
+ fi
+ umask 002
+ while read file; do
+ try_install "$file"
+ done < "$filelist"
+ [ -z "$tmpdir" ] || rmdir --ignore-fail-on-non-empty "$tmpdir"
+else
+ echo "No files to copy"
+fi
+for subject in "${subjects[@]}"; do
+ try_install "$subject"
+done
+rm "$filelist"
diff --git a/cert-info b/cert-info
new file mode 100755
index 0000000..b4aa9b1
--- /dev/null
+++ b/cert-info
@@ -0,0 +1,128 @@
+#!/bin/bash
+# see also Docs/ssl-infos/tools/
+# i= &&tail -n+$((i*5000)) /tmp/top-1m.csv | head -5000 |~/scripts/cert-info csv $i
+# killall -v cert-info -s 0
+usage() {
+ [ -z "$1" ] || echo "$1" >&2
+ echo "Usage: $0 [options] hostname[:port] [hostname[:port]].." >&2
+ echo " $0 csv out-dir <file [options]" >&2
+ echo "options (may be interleaved between hosts):"
+ awk '/^parse_arg\(/{p=1}
+ /}/{if(p)exit}
+ /#/{if(p){sub(/\).*# */,"\t");print}}' "$0"
+ echo "csv file from http://s3.amazonaws.com/alexa-static/top-1m.csv.zip"
+ exit 1
+}
+
+auto_less() {
+ [ ! -t 1 ] || { "$0" "$@" | less; exit $?; }
+}
+
+main() {
+if [ "$1" = "csv" ]; then
+ [ $# -ge 2 ] || usage "Missing outdir"
+ outdir="${2:-.}/"
+ mkdir -p "$outdir"
+ tmp=$(mktemp); trap "rm -f $tmp" EXIT
+ shift 2
+ for arg; do parse_arg "$arg" || usage "Unrecognized option $arg"; done
+ i=0
+ while IFS=,; read -r no host; do
+ # strip path if any
+ host="${host%%/*}"
+ [ -n "$host" ] || continue
+ outfile="$outdir$host.txt"
+ if [ -e "$outfile" ]; then
+ echo "Skipping existing $outfile"
+ else
+ printf "%5d %s %6d %s\n" $((++i)) "$(date -R)" "$no" "$host"
+ get_cert "$host" 443 | parse_cert > "$tmp" 2>&1
+ mv "$tmp" "$outfile"
+ #[ -s "$outfile" ] || echo "# no cert for $host"
+ fi
+ done
+elif [ ! -t 0 ]; then
+ auto_less "$@"
+ for arg; do
+ parse_arg "$arg" || :
+ done
+ parse_cert
+elif [ $# -gt 0 ]; then
+ auto_less "$@"
+ for arg; do
+ ! parse_arg "$arg" || continue
+ host="${arg%%:*}"
+ port="${arg##*:}"
+ [ "$port" != "$arg" -a -n "$port" ] || port=443
+ echo "# === $host:$port ==="
+ get_cert "$host" "$port" | parse_cert
+ done
+else
+ usage
+fi
+}
+
+get_cert() {
+ local host="$1" port="$2"
+ if ! nc -z -w 2 "$host" "$port"; then
+ echo "# conn timeout for $host:$port!" >&2
+ return 1
+ fi
+ </dev/null 2>/dev/null \
+ timeout 5 openssl s_client -connect "$host:$port" -showcerts
+}
+
+parse_arg() {
+ case "$1" in
+ -) depth_1=1 ;; # less certificates [def]
+ +) depth_1=0 ;; # more certificates
+ -=) cert_only=1 ;; # less output (just raw cert)
+ +=) cert_only=0 ;; # more output (verbose details) [def]
+ -cert) include_cert=0 ;; # hide raw cert (-noout)
+ +cert) include_cert=1 ;; # include raw cert [def]
+ *) return 1 ;;
+ esac
+}
+parse_arg -
+parse_arg +=
+parse_arg +cert
+
+parse_cert() {
+ infocmd="openssl x509 -text -nameopt sep_comma_plus_space"
+ [ $include_cert -eq 1 ] || infocmd="$infocmd -noout"
+ awk -vOneOnly="$depth_1" -vCertOnly="$cert_only" \
+ -vinfocmd="$infocmd" '
+BEGIN {
+ sep="# ";
+ for (i=0; i<77; i++) {
+ sep=sep"-";
+ }
+}
+/^-----BEGIN CERTIFICATE-----$/ {
+ in_cert=1;
+}
+{
+ if (in_cert) {
+ cert = cert $0 "\n";
+ }
+}
+/^-----END CERTIFICATE-----$/ {
+ in_cert = 0;
+}
+{
+ if (!in_cert && cert) {
+ if (CertOnly) {
+ print cert;
+ } else {
+ print cert | infocmd;
+ close(infocmd);
+ print sep;
+ }
+ cert="";
+ if (OneOnly) exit;
+ }
+}
+'
+}
+
+main "$@"
diff --git a/find-libs b/find-libs
new file mode 100755
index 0000000..575490d
--- /dev/null
+++ b/find-libs
@@ -0,0 +1,44 @@
+#!/bin/bash
+libs="$(mktemp)"
+
+dbg() {
+ [ -z "$DEBUG" ] || echo "$*" >&2
+}
+
+# prints all libraries directly depending on a binary / library
+find_libs() {
+ local file="$1"
+ # regular libs
+ ldd "$file" | awk -F'> | \\(' '{if($2 ~ "^/")print $2}' | sort -u
+}
+
+# returns 1 if a library was known before, 0 otherwise
+add_lib() {
+ local lib="$1"
+ if ! grep -q -x -F "$lib" "$libs"; then
+ dbg "Adding $lib"
+ echo "$lib" >> "$libs"
+ return 0
+ fi
+ return 1
+}
+recurse_find_libs() {
+ local file="$1"
+ dbg "Checking $file"
+ while read lib; do
+ if add_lib "$lib"; then
+ recurse_find_libs "$lib"
+ fi
+ done < <(find_libs "$file")
+ dbg "Done with $file"
+}
+
+for bin; do
+ # ld-linux.so
+ while read lib; do
+ add_lib "$lib" || true
+ done < <(ldd "$bin" | awk '/^[ \t]*\//{print $1}')
+ recurse_find_libs "$bin"
+done
+
+wc -l "$libs"
diff --git a/kde-logout b/kde-logout
new file mode 100755
index 0000000..dee150a
--- /dev/null
+++ b/kde-logout
@@ -0,0 +1,16 @@
+#!/bin/sh
+# x = 0 = noconfirm, 1 = confirm
+# 0 2 0 = shutdown
+# 0 1 0 = restart
+# 0 0 0 = logoff?
+case $1 in
+l*) action=0 ;;
+r*) action=1 ;;
+s*) action=2 ;;
+*)
+ echo "Usage: $0 {logout|restart|shutdown}"
+ exit 1
+ ;;
+esac
+
+qdbus org.kde.ksmserver /KSMServer org.kde.KSMServerInterface.logout 0 $action 0
diff --git a/socket-info b/socket-info
new file mode 100755
index 0000000..5c066ea
--- /dev/null
+++ b/socket-info
@@ -0,0 +1,84 @@
+#!/bin/bash
+# Prints information about a file descriptor socket
+# Author: Peter Wu <lekensteyn@gmail.com>
+# Date: 2013-02-06
+
+rootcmd=sudo
+
+sockno=$1
+pipeno=
+
+sockfd=$(readlink "$1")
+if [[ $sockfd =~ ^socket:\[[0-9]+\]$ ]]; then
+ sockno=${sockfd#socket:[}
+ sockno=${sockno%]}
+fi
+
+# not a socket but a pipe
+if [[ $sockfd =~ ^pipe:\[[0-9]+\]$ ]]; then
+ pipeno=${sockfd#pipe:[}
+ pipeno=${pipeno%]}
+ find /proc/[0-9]*/fd -lname "pipe:\\[$pipeno\\]" -ls 2>/dev/null | \
+ awk -F/ '{
+ pid=$3;
+ print "";
+ print;
+ system("ps huwwp " pid);
+ }'
+ exit
+fi
+
+if ! [[ $sockno =~ ^[0-9]+$ ]]; then
+ echo "Numeric socket number required" >&2
+ exit 1
+fi
+
+# expects: $prot $sockno
+# arg1: field index for inode
+find_by_inode() {
+ </proc/net/$prot awk "{if (\$$1 == $sockno)print}"
+}
+
+# arg1: inode of one socket endpoint
+find_other_sock() {
+ local addr=$1
+ local vmlinux=/usr/src/linux-$(uname -r)/vmlinux
+ local file
+
+ for file in "$vmlinux" /proc/kcore; do
+ if [ ! -e "$file" ]; then
+ echo "$file: not found" >&2
+ return 1
+ fi
+ done
+
+ $rootcmd gdb -q "$vmlinux" /proc/kcore \
+ -ex "p ((struct unix_sock*)0x$addr)->peer" -ex q \
+ | grep -Po '\(struct sock \*\) 0x\K[0-9a-f]+'
+}
+
+line=
+for prot in udp tcp; do
+ line=$(find_by_inode 10)
+ [ -z "$line" ] || break
+done
+
+if [ -z "$line" ]; then
+ prot=unix
+ line=$(find_by_inode 7)
+ addr=$(cut -d: -f1 <<<"$line")
+ find_by_inode 7
+ if [[ $addr =~ ^[0-9a-f]+$ ]]; then
+ addr2=$(find_other_sock $addr)
+ line2=$(grep "^$addr2:" /proc/net/$prot)
+ [ -z "$line2" ] || line="$line"$'\n'"$line2"
+ fi
+fi
+
+if [ -n "$line" ]; then
+ (head -1 /proc/net/$prot;
+ echo "$line") | column -t
+ exit 0
+fi
+
+echo "No info found for $sockno [$sockfd]"
diff --git a/tabize b/tabize
new file mode 100755
index 0000000..467581a
--- /dev/null
+++ b/tabize
@@ -0,0 +1,30 @@
+#!/bin/sh
+# Input: space-separated
+column -t \
+| sed 's/ */&| /g' \
+| tac | awk 'BEGIN {
+ s="";
+ line="";
+}
+{
+ if (line) print line;
+ if (s == "") {
+ split($0, chars, "");
+ for (i=1; i<=length(chars); i++) {
+ if (chars[i] == "|")
+ s=s "+";
+ else
+ s=s "-";
+ }
+ } else {
+ while (length(s) < length($0)) {
+ s = s "-";
+ }
+ }
+ line = $0;
+}
+END {
+ print s;
+ s="";
+ print line;
+}' | tac
diff --git a/tmp-upload b/tmp-upload
new file mode 100755
index 0000000..913c129
--- /dev/null
+++ b/tmp-upload
@@ -0,0 +1,124 @@
+#!/bin/bash
+host=0.0.0.0
+port=1111
+
+out="$(mktemp /tmp/tmp-upload-php.XXXXXXXX)"
+cleanup() {
+ rm -v "$out"
+}
+trap cleanup EXIT
+
+# wrap
+startline=$(grep -hn -F -m 1 "# stuff ""below" "$0" | cut -d: -f1)
+tail -n+$((startline+1)) "$0" > "$out"
+
+php -d post_max_size=128M -d upload_max_filesize=128M \
+ -S "$host:$port" "$out"
+exit
+# stuff below
+<?php
+function get_mime_type($file) {
+ $finfo = new finfo(FILEINFO_MIME_TYPE | FILEINFO_MIME_ENCODING);
+ if (!is_resource($finfo)) {
+ return $finfo->file($file);
+ }
+ return false;
+}
+
+$url = $_SERVER['REQUEST_URI'];
+if ($url != '/') {
+ /* Simply returning false causes PHP to parse (index).php. Unwanted,
+ * therefore serve it here. First check whether the path is within the
+ * current working directory, then whether the file exists or not. */
+ $cwdir = realpath(".");
+ if ($cwdir === FALSE) {
+ http_response_code(500);
+ exit;
+ }
+
+ $path = realpath("." . $url);
+ if ($path === FALSE) {
+ http_response_code(404);
+ exit;
+ }
+ if (strpos($path, $cwdir . DIRECTORY_SEPARATOR) !== 0) {
+ http_response_code(403);
+ exit;
+ }
+
+ /* determine content type and size in bytes */
+ $filesize = filesize($path);
+ $mimetype = get_mime_type($path);
+ if (!$mimetype) {
+ http_response_code(500);
+ exit;
+ }
+
+ header("Content-Type: $mimetype");
+ if ($filesize !== false) {
+ header("Content-Length: $filesize");
+ }
+
+ readfile($path);
+ exit;
+}
+
+$msg = NULL;
+if (isset($_FILES["file"]["name"])) {
+ $name = trim(basename($_FILES["file"]["name"]), ".");
+ if (!$name) {
+ $msg = "No filename is given!";
+ } else if (!$_FILES["file"]["size"]) {
+ $msg = "I do not accept empty files!";
+ } else {
+ $filename = $name;
+ for ($i=1; file_exists($filename); $i++) {
+ $filename = "$filename.$i";
+ }
+ if (move_uploaded_file($_FILES["file"]["tmp_name"], $filename)) {
+ $msg = "File is saved as " . htmlspecialchars($filename);
+ } else {
+ $msg = "File could not be saved.";
+ }
+ }
+}
+?>
+<!doctype html>
+<meta charset="UTF-8">
+<meta name="viewport" content="initial-scale=1">
+<form action="/" method="POST" enctype="multipart/form-data">
+<input type="file" name="file">
+<input type="submit" value="Upload">
+</form>
+<?php
+if ($msg) echo "<p>$msg</p>";
+
+?>
+<hr>
+<pre>
+<?php
+mb_internal_encoding('UTF-8');
+date_default_timezone_set('Europe/Amsterdam');
+$dir = new DirectoryIterator('.');
+foreach ($dir as $f) {
+ if ($f->isDot()) {
+ continue;
+ }
+ $filename = $f->getFilename();
+ $len = mb_strlen($filename);
+ if ($len > 50) {
+ $dispName = mb_substr($filename, 0, 47) . '..>';
+ } else {
+ $dispName = $filename;
+ }
+
+ printf('<a href="%s">%s</a>%s %s %20d' . "\n",
+ htmlspecialchars($filename),
+ htmlspecialchars($dispName),
+ str_repeat(' ', max(0, 50 - $len)),
+ date('d-M-Y H:i', $f->getMTime()),
+ $f->getSize()
+ );
+}
+?>
+</pre>
diff --git a/udpsoundserver.py b/udpsoundserver.py
new file mode 100755
index 0000000..f8e7c58
--- /dev/null
+++ b/udpsoundserver.py
@@ -0,0 +1,98 @@
+#!/usr/bin/env python
+
+"""Listen on a UDP port and play a sound when 'M' is received
+
+Starts the server listening on UDP port PORT (3533 by default) on address HOST
+(by default all addresses). Valid commands are:
+M - play Music
+S - Stop the server
+"""
+try:
+ import socketserver
+except ImportError:
+ import SocketServer as socketserver
+from os import system,getpid
+import threading
+import sys
+
+# leave it empty to listen on all addresses
+HOST = ""
+PORT = 3533
+
+
+class UDPSvr(socketserver.BaseRequestHandler):
+ def handle(self):
+ data = self.request[0]
+ if sys.version >= '3':
+ data = str(data, "ISO-8859-1")
+ data = data.strip()
+ if data == "M":
+ ding.dong()
+ elif data == "S":
+ ding.die()
+
+class Worker(threading.Thread):
+ def __init__(self):
+ threading.Thread.__init__(self)
+ self.daemon = True
+ def run(self):
+ server.serve_forever();
+
+class Handler(threading.Thread):
+ def __init__(self):
+ threading.Thread.__init__(self)
+ self.daemon = True
+ self.play = False
+ self.must_die = False
+
+ def run(self):
+ self.event = threading.Event()
+ while True:
+ self.event.wait(1.)
+ if self.event.isSet():
+ if self.play:
+ print("Playing...")
+ system("paplay /usr/share/sounds/KDE-Im-Irc-Event.ogg")
+ # no else if to allow shutdown signals
+ if self.must_die:
+ print("Shutting down...")
+ server.shutdown()
+ break
+ self.play = False
+ self.event.clear()
+
+ def dong(self):
+ self.play = True
+ self.event.set()
+
+ def die(self):
+ self.must_die = True
+ self.event.set()
+
+def ca(num, x):
+ print("Caught SIGINT, shutting down...")
+ ding.die()
+
+import signal
+if __name__ == "__main__":
+ print("My PID is: " + str(getpid()))
+
+ if len(sys.argv) > 1:
+ HOST = sys.argv[1]
+ if len(sys.argv) > 2:
+ PORT = int(sys.argv[2])
+
+ print("Host: " + HOST)
+ print("Port: " + str(PORT))
+ server = socketserver.UDPServer((HOST, PORT), UDPSvr)
+
+ ding = Handler()
+ signal.signal(signal.SIGINT, ca)
+ worker = Worker()
+ ding.start()
+ worker.start()
+ # might not be the cleanest, but it allows Ctrl + C
+ while ding.isAlive():
+ ding.join(3600)
+
+# vim: set expandtab shiftwidth=4:
diff --git a/xstat b/xstat
new file mode 100755
index 0000000..d37c090
--- /dev/null
+++ b/xstat
@@ -0,0 +1,21 @@
+#!/bin/sh
+file="$1"
+file="$(readlink -f "$file")"
+dir="$file"
+dev=
+
+while [ -n "$dir" ] && [ -z "$dev" ]; do
+ dev=$(awk -vd="$dir" '{if($2 == d && substr($1, 1, 1) == "/")print $1}' </proc/mounts)
+ if [ "x$dir" = "x/" ]; then
+ break
+ fi
+ dir="${dir%/*}"
+ [ -n "$dir" ] || dir=/
+
+done
+
+if [ -n "$dev" ]; then
+ debugfs -R "stat $file" "$dev"
+else
+ echo "No device found for $file" >&2
+fi