Scripting with Racket

June 21, 2016
blog author


Senior Mulesoft Developer

Recently, I had the opportunity to have my computer upgraded. As I had a lot of personal files, I thought it might be a good idea to securely delete them before shipping the computer back. This served two features, one, it was fun, and two, it gave me time to make sure the new computer had all the files copied and that I wasn't missing anything from the old computer. So, I did a little research. A little googling revealed I needed to write random bytes over the file 8 times to meet government standards on preventing the recovery of deleted files. Which lead me to this command: dd if=/dev/urandom of=some_file bs=some_file_size count=1 conv=notrunc Which is fine, just hit the up arrow and enter 8 times, right? That was too much work, so it turned into this script: for i in {1..8}; do dd if=/dev/urandom of=some_file bs=some_file_size count=1 conv=notrunc; done That was better, but still has the unfortunate feature of needing to replace the file name and file size every time, and those are in the middle of the line which isn't very convenient to edit. Additionally, I was realizing I needed to securely delete entire directory trees, so I was going to need something to traverse directories with this command. At this point, I reached for Racket[1]. A little background, I'm a fan of lisps in general and I have used lisp or scheme in several different domains over the years. I ran across PLT Scheme several years ago, and really liked it for it's teachpacks, and development environment. Normally I just use GNU Emacs for that, but this development environment was nice enough I thought I'd try to stick to it. A few years ago, though, PLT Scheme (and it's IDE known as DrScheme) changed their name to Racket (and hence to DrRacket). Racket is generally a scheme which is in the family of lisps. I won't go into how it's different, it's probably not noticeable in most cases anyway. So, for reference I looked around to see how others were using racket for getting random bytes from the system and ran across a nice gist[2] which has some good examples. I mostly just built a script around that information, although mine doesn't handle the differences in OSs, it was sufficient for my needs. I've put the code here So, starting from the top: #lang racket/base (require racket/list racket/sequence) Racket has the ability to handle multiple languages, the first line just says we are using the 'racket' language, the second phrase just lists some of the additional library code I will access. Next we encounter a constant representing the maximum number of times to overwrite the file and another that represents a range of numbers which I use for looping - not the "racket" way of looping, but sufficient to get the point across. get-random-bytes is just a function to read from /dev/urandom like the `dd` script above. The next function, wipe-file does the actual work of overwriting a file with random bits eight times. The final two functions manage lists of files and directories, and handles some exceptions which might occur; two in this case, but that list is not exhaustive. So, I ended up with 44 lines of racket code to handle wiping entire directories or individual files or both from the command line. One additional feature of racket is a compiler tool that will compile this code to the native code on your platform. So, raco exe wipe.rkt will create wipe.exe on a Microsoft Windows machine, on a Mac, or just wipe on a Linux OS. Now that I have this new computer and the old one sent back, I'll probably not need this code for quite a while, but the hour I spent writing it was a lot of fun! Resources: [1] Racket [2] random bytes with racket