Get the latest version of randomplay as a tarball (v0.60, released 10/15/06).

Randomplay is a command-line based shuffle music player that remembers songs between sessions.Randomplay plays your music collection (or execute any arbitrary commands on any arbitrary filetypes) in random order, remembering songs played across sessions. It also has many features to make command-line music playing more convenient, including recursive regexp searching for tracks and the ability to specify a certain number of tracks, bytes, or minutes to play. Randomplay will also generate a list of music files to be loaded onto a portable music player device. It includes a ‘random weighting’ feature, so your favorite songs are more likely to come up in the random shuffle.Randomplay is a convenient tool for the user who does everything in an xterm window or console and is constantly devising complex find/grep/sed command lines to play just the right set of songs.

Following are some example invocations of randomplay to give a general sense of its flexibility; see the manpage for more complete information:

Play all ogg files in dir1 and dir2 under your home directory, and dir3 under the base directory specified in ~/.randomplayrc, which have not been played for 15 days in random order with 5 seconds between songs:

randomplay --days=15 --pause=5 --player ogg=ogg123 ~/dir1 ~/dir2 =dir3

Play all ogg, wav, and mp3 files under the current directory (or base directory, if specified in .randomplayrc file) which have not been played for 10 days in alphabetical order, switch the ‘skip to next song’ keystroke to ‘G’ or ‘g’ and ‘quit’ to ‘q’ or ‘c’:

randomplay --norandom --key next=Gg --key quit=qc

Play all files under the current directory with the strings “frisell” and “bill” in the filename, in any order, (saves having to hunt down a file in a hierarchy), ignore whether the file has been played recently, but stop playing after 15 minutes:

 randomplay --regexp 'frisell bill' -0 --maxtime=15m

Display 100M worth of music files, randomly sorted, without recording the history of tracks, using the default music directory (or the current directory if not specified):

randomplay --maxsize=100M --noremember --names-only

Play the last 10 songs played over again:

randomplay --last=10

Play songs test.ogg, test2.ogg, test3.ogg, and all files in musicdir in random order without weighting preferred songs:

randomplay --noweight test.ogg test2.ogg test3.ogg musicdir

Copy 128M of songs into a Neuros Audio Player, using positron:

positron add `randomplay --names-only --maxsize=128M`

Pick a random jpeg or png file that has not been displayed in the last week from the ‘images’ directory and display it with ImageMagick ‘display’ command:

randomplay --player jpg=display --player gif=display --days 7 ~/images

randomplay is listed on freshmeat.net.

You can download randomplay as a Debian package, or get it directly from the Debian archive.

You can take a look at randomplay, the main script, with nice highlighting, also see the changelog.

randomplay 0.48 released

I’ve released randomplay 0.48. randomplay is my command-line ‘itch a scratch’ music player. It is most useful for maintaining a random shuffle over many sessions—for example, I use it to make sure I don’t ever hear the same song in any three month period.

The new version fixes a bug that prevented randomplay from advancing to the next track when the player subprocess itself spawned a child process (e.g., with ‘play’ which spawns ‘sox’). I use a bit of a hack to kill the child task and it’s children, but the standard way of doing this in perl—kill HUP => -$$ doesn’t seem to work when randomplay is called from a shell script and the child process’ output is redirected to null. Here’s the code in question (with the fix to kill children and grandchildren recursively):

 # KillAll recursively kills the request process ID and all of its children/grandchildren/etc. # This is a bit of a hack--there should be a better way to do this, but I haven't found one. # Normally, kill HUP => -$$ should do the job, except this doesn't work when randomplay itself # is called from a shell script and all output from child processes is redirected to null. # This subroutine assumes that shelling out to ps is going to work, which may not be totally # safe--at the very least, it reduces the portability of the script. # Any suggestions for a better way to do this are welcome. sub KillAll { my $pid = shift; local $SIG{HUP} = 'IGNORE'; # don't want to kill ourselves here--shouldn't happen, but just in case. if (open PS, "ps -o pid,ppid |") { eof PS; # Force ps to run now. Otherwise it would run at the first read operation. kill HUP => $pid; foreach my $line () { KillAll($1) if ($line =~ /^\s*(\d+)\s*(\d+)\s*$/ and ($2 eq $pid)); } close PS; } else { # if we can't read the process table, just try killing the child process group kill HUP => -$$; } } 

Thanks to Christopher Zimmermann for the patch to kill children recursively.

Scowcroft on Bush

Fascinating New Yorker interview with Brent Scowcroft, National Security Advisor to Bush 41. I wonder how the author, Jeffrey Goldberg, gets this degree of access: he’s apparently emailing back and forth with Bush 41, having coffee with Colin Powell, and engaging in frank discussion with Scowcroft for a significant period of time. This sort of reporting is the antithesis of what you see in most newspapers, where the reporter probably spends no more than a few hours piecing together information that is widely available. This is also consistent with everything I’ve seen in the New Yorker for the past few months I’ve been subscribing—high quality writing and primary source information that you won’t pick up just from reading blogs.

In any case, it’s interesting to see all these conservative ideologues from the Reagan-Bush era turn on the neoconservatives. If Brent Scowcroft thinks the war in Iraq is misguided, does the current administration have any hope at all?

Google Print Italy

I was just experimenting with Google Print and discovered that a book I contributed to has been translated into Italian! Here’s the first page and last page of my essay. That’s kind of a funny way to find out you’ve been translated. I wonder if it the translation is accurate.

In any case, I can safely say that I am a member of that overwhelming majority of authors who can only benefit from Google Print. Not that I receive any royalties for that piece, but it’s still nice to think someone might discover that book who would otherwise never have heard of it.

(Incidentally — do Google Print links persist over time? I guess we’ll find out).

Feed with Comments

Due to popular request, I’m now providing a separate RSS feed that includes comments. If you subscribe to my blog and would prefer to see people’s comments, just point your aggregator at http://adam.rosi-kessel.org/weblog/comments.rss.

Is Wolfgang Kueter a jerk or… how to configure iptables?

I’m trying to accomplish what I believe should be a simple task with iptables—replace my DSL router with a linux box. The linux box also routes packets to other machines on the LAN based on destination IP address (the box receives packets for multiple IP addresses from the Internet) and port number, and blocks other packets based on originator IP and port number, but as I understand the firewalling and inbound routing chains are totally separate from the outbound NAT functionality. In any case, the inbound stuff works perfectly now.

It seems simple enough to set up a box, where eth0 faces the Internet and eth1 faces the LAN, to act as a gateway or proxy to the LAN:

 iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE 

And that actually works perfectly, except that a Windows box inside my LAN is unable to connect to a VPN outside the LAN, while it worked fine with the Buffalo router I had in place before. All other services are properly accessible through the gateway.

So I posted a description of my situation to comp.security.firewalls. I admit that I have, at best, a basic understanding of iptables, but I have read the manpage and documentation and gotten it to do 99% of what I need with the exception of this VPN issue.

In response, a “Wolfgang Kueter” called me clueless multiple times, said that I had no idea what I was doing, and that I “misunderstand almost everything,” and that I should pay a professional to do it for me and read books on TCP/IP and the IPSec protocol specification itself. Other newsgroup postings by this fellow have a similar tone, e.g. building a security suite (Q: What combination of software firewall, anti-virus, etc., are you using and have you noticed any discernable effect on performance? A: None, because they are useless crap. … I don’t use such crap, so how could I?).

Steve suggests that Web 2.0 should have some way to tag people like this as jerks, and their reputation would then follow them around on the web. Since that technology doesn’t yet exist, the next best thing, I suppose, is to just blog about it and hope this entry turns up in a search on the person’s name. Abrasive responses to legitimate requests for help from people hoping to learn something don’t do anything to advance the free software movement. I suppose this kind of person will always exist, but I wish they didn’t.

I don’t want to be petty about this sort of thing, but I actually don’t think I need to hire a professional or read books about TCP/IP and the IPSec protocol specification itself to configure a Linux box as a residential gateway. Does anyone disagree?