Saving Flash Videos (after the plugin deletes them) (revisited)

I'm not sure if I just made a bunch of errors in my previous post or if things have changed. Either is possible. Anyway, it's now necessary to throw away duplicate file descriptor entries. I don't know if more than one thread has an open handle or what the reason is, but if you're fishing deleted flash videos out of the deleted proc file descriptor, something like the following works better than previously posted. First, the lsof command to see what Shockwave Flash stuff is still open:

lsof | grep 'Shockwave Flash'
But that has duplicates, so lets extract the file descriptor number and throw away dupes (and the row that has no parent pid):

lsof | grep 'Shockwave Flash' |
  awk '{printf "%s %s\n",$2,$5}' |
  sort -u |
  grep -v REG | 
  awk '{printf "%d %d\n",$1,$2}'
That will show the pid and file descriptor of what's probably the flv or mpeg. To turn that into a series of copy commands (make sure the things are done downloading, before doing this, btw...):

lsof | grep 'Shockwave Flash' |
  awk '{printf "%s %s\n",$2,$5}' |
  sort -u |
  grep -v REG |
  awk '{printf "cp /proc/%d/fd/%d /tmp/saved-%d.flv\n",$1,$2,$2}'
And if you're feeling brave, run that through bash...

lsof | grep 'Shockwave Flash' |
  awk '{printf "%s %s\n",$2,$5}' |
  sort -u |
  grep -v REG |
  awk '{printf "cp /proc/%d/fd/%d /tmp/saved-%d.flv\n",$1,$2,$2}' |
Check them with a file command though, they're probably not flv wrapped anymore, likely they're raw ISO/MPEG. So rename (or adjust the command) accordingly. Oh, and for youtube, just use "youtube-dl" it's pretty awesome.


CB5-311 Ubuntu (ARM Chromebook) and fixing GLX

I did an apt-get upgrade and didn't consider the sort of breakage that could occur if the system were to replace /usr/lib/xorg/modules/extensions/libglx.so with *not* the Nvidia one. I had some erroneous messages in /var/log/Xorg.0.log that made me think the problem was because of some undefined symbols in some mesa library, but that turned out to be missing symbols in the fallback software rendering, not the actual GLX module. To fix the error, I extracted the relevant parts from the original setup script and ran them again. Here's the extracted bit:

    l4tdir=`mktemp -d`
    wget -P ${l4tdir} https://developer.nvidia.com/sites/default/files/akamai/mobile/files/L4T/${l4t}
    cd ${l4tdir}
    tar xvpf ${l4t}
    cd Linux_for_Tegra/rootfs/
    tar xvpf ../nv_tegra/nvidia_drivers.tbz2
    tar cf - usr/lib | ( cd / ; tar xvf -)

    cat > install-tegra.sh << EOF
    update-alternatives --install /etc/ld.so.conf.d/arm-linux-gnueabihf_EGL.conf arm-linux-gnueabihf_egl_conf /usr/lib/arm-linux-gnueabihf/tegra-egl/ld.so.conf 1000
    update-alternatives --install /etc/ld.so.conf.d/arm-linux-gnueabihf_GL.conf arm-linux-gnueabihf_gl_conf /usr/lib/arm-linux-gnueabihf/tegra/ld.so.conf 1000

And a pastebin version because blogger butchering.


CB5-311 & Ubuntu

I recently purchased a Chromebook 13 (cb5-311, 4GB RAM, 1080p, 32G SSD) and
I've managed to get Ubuntu on it.

I tried a bunch of different chrubuntu install scripts and eventually
discovered that none of them worked using default settings because they try to
install 14.10 and that's broken.

I eventually settled on this script:

To make it work, I opened the script up and hardcoded the ubuntu_version
variable's default value to "lts" so it would pick 14.04 instead of whatever
the latest was.  I also changed the argument to umount the statefule_partition
with -l instead of -f, but I don't know if that was necessary, I just didn't
want another script to bomb out and have to start over.  I may also have put in
a touch /etc/init/whoopsie for similar reasons, but I don't recall now.

To get around the freeze due to uap0/mlan0 I did something like

    echo manual | sudo tee /etc/init/network-manager.override

This disabled network manager.  I just bring the mlan0 interface up manually
when I want it.  Later I'll probably script it.

Then I installed fvwm and generally set about customizing things.  To make up
for a lack of insert key, I made the Enter key become insert when the right alt
button is held down.  To do that, I put this in .xmodmaprc:

    keysym Alt_R = Mode_switch
    keycode 36 = Return NoSymbol Insert

So now I can use shift insert to paste by hitting alt+shift+enter.  (Order

I made a udev rule for setting permissions on the backlight so I can control
that with a script, too.  /etc/udev/rules.d/88-backlight.rules now contains
these lines:

ACTION=="add", KERNEL=="pwm-backlight", SUBSYSTEM=="backlight", RUN+="/bin/chmod 0666 /sys/devices/soc0/pwm-backlight/backlight/pwm-backlight/brightness"
ACTION=="add", KERNEL=="pwm-backlight", SUBSYSTEM=="backlight", RUN+="/bin/chgrp users /sys/devices/soc0/pwm-backlight/backlight/pwm-backlight/brightness"

I guess you can't use use GROUP and MODE to set permissions on /sys entries,
but you can use RUN to do it.

I cannot put the laptop to sleep and closing the lid does nothing, but it boots fast and can go around 12 hours before I have to recharge.  There might be other things that don't quite work, but I either don't recall or I haven't encountered them yet.


Saving Flash Videos (after the plugin deletes them)

I'd like to start off by saying WTF Flash? Why do you remove these files from the filesystem! Don't you know that mplayer handles them better than you do?

Under Linux, these files are still saved to /tmp/ as something like /tmp/FlashXXQ3ryBE but then they get deleted while they're still open so that entitled users can't save them off to somewhere else for later viewing. As long as the player holds the file open, it can still play them. And guess what? As long as the player holds the file open, you can still copy them off to somewhere else. You just need to find the file descriptor that still holds that file, copy that file out to wherever you'd like, and then you can do whatever you want with it.

First, find the file:
# lsof | grep Flash

chromium- 15637      username   20u      REG                8,1 57136676   43105 /tmp/FlashXXQ3yrBE (deleted)

Note the process ID (15637) and the file descriptor number (20u). To locate this file in /proc, it will be /proc/15637/fd/20, so do something like this:
cp /proc/15637/fd/20 /tmp/morelolcats.flv

And now you can do something like this:
mplayer /tmp/morelolcats.flv

If you like scripting, you can do something like this:
lsof | grep Flash | awk '{printf "cp /proc/%d/fd/%d /tmp/saved-%d.flv \n",$2,$4,$4}' | sh

Which works out to doing this for each one:
cp /proc/15637/fd/20 /tmp/saved-20.flv

So yeah... that was fun.


Save Flash Video under OS X (firefox)

Once upon a time, in Linux, it was possible to copy the files being downloaded and played by the Flash plugin out of /tmp and to wherever for later viewing. I was pretty sure this was possible under OS X. And wouldn't you know it, it is. But the files were harder to find. They're stored somewhere under /private/var/folders. I did this to locate them:

find /private/var/folders/ -type f -exec file {} \; 2>/dev/null | grep Macromedia

To figure out the top-level folder that contained them, a google query showed me this thread which clued me in. I don't know if someone pointed out the exact location later (tl;dr) but when I saw the bits about /private/var/folders I did a find in a terminal.


Removing Linux from OS X (to redo Bootcamp)

I wanted to remove Linux and try Windows (for some steam games) on my MacBook Air, but I had a little trouble. Using the Disk Utility (graphical program), I was only able to merge the existing JHFS+ file system with my Linux partition, but It wouldn't touch the swap. You can't just launch Boot Camp at this point because it will see the multiple partitions and refuse to run.

I tried to merge using the diskUtil command line, but it gave me the error: Merging partitions encountered error "Couldn't read partition map (-69876)".

So, I erased the volume and replaced it with a HFS+ with journaling. Then I launched the Disk Utility and it refused to let me merge them. For posterity, this is the command I used to erase:
diskutil eraseVolume JHFS+ new /dev/disk0s3

The result is that I had two Journaled HFS+ partitions that still couldn't be merged, but once I erased the volume from within the Disk Utility, it let me grow the remaining partition to fill the space. Boot Camp happily ran and created a new Windows Partition after that.


Fuck You, OS X!

The joys of a commercial operating system! I was happy to play Diablo 2 on my shiny new MacBook Air. No, not one of the cool new-new MacBook Airs, the slightly older MacBook air that still has discreet graphics. Anyway, I decided to finally bite the bullet and pay the $5 for the latest Xcode. I was happy to discover that it's now free. Then I noticed that it was free for Lion, only. So I paid the $30 and upgraded. Then I discovered that I couldn't play Diablo 2 anymore. Then I discovered that I probably could have gotten the upgrade to Lion for free, through Apple, because I bought my system so close to the release date of Lion.

Well, bitterness aside, I decided to grab wine for OS X and use that to launch a windows install of Diablo 2. Then once that was working, I decided to package it up in a .app file so that I could at least pretend it was a native app. After that, I discovered there's something called wineskin that will let you package stuff up into .app bundles. Eh, whatever, I already made the damn script, put the right files in the right places, and through some guesswork figured out how to get it to all play nicely. Then I tweaked my script so that it would search for any old wine installation within the bundle, in case I upgrade the version of wine it's using. Then I tweaked the script a bit further to have it configure the 800x600 desktop so that the game would stop fucking up my graphics and displaying incorrectly in the process. It was weird, the game would launch, it looked great, but the window was getting pushed off the screen, ever so slightly. The emulated desktop fixed that.

Since I had it configure wine, I decided to remove the stupid gecko prompt for HTML support in windows applications. Maybe battle.net makes use of the HTML display, I don't know, the game certainly didn't need it for multi-player.

Anyway, here's the bizarre stuff that I learned in the process of creating the .app. I knew that .apps were folders, but I didn't know what the structure needed to look like, so I took a peek at Torchlight. Nice and simple. I mimicked the directory structure so that I had the following:
Diablo2.app/Contents/MacOS/diablo2.icns (stole from somewhere)
Diablo2.app/Contents/MacOS/diablo2.sh (script I wrote)
Diablo2.app/Contents/Resources/diablo2.icns ->
Diablo2.app/Contents/Info.plist -> ./MacOS/Info.plist

When it was all said and done, I had the following additional items:
Diablo2.app/Contents/MacOS/1.3.24     (wine distro)
Diablo2.app/Contents/MacOS/Diablo II (from windows)
Diablo2.app/Contents/MacOS/prefix (generated)

[Edit: Here's where I got the icon set: http://www.iconeasy.com/icon/diablo-ii-icon/ No idea where they got it from, so I don't know that this is really proper attribution.]

So, here's the cool part. Parameter Expansion. The diablo2.sh I created was modeled after the Steam.app steam.sh script. And when I say modeled after, what I really mean is that I read the first executable line of the script and said, "What the hell is this?"

Here's the line in question:
STEAMROOT=$(cd "${0%/*}" && echo $PWD)

I gathered that PWD was feeding the PWD to the variable STEAMROOT, so I figured the ${0%/*} must be doing something crazy to $0. So the first thing I did was start issuing echo commands and trying things with different variables. Now, I could see that the ${0%/*} was taking whatever the value of the variable was and chopping off the trailing file name but I didn't understand what sorcery was allowing this. Turns out bash has some built-in awesomeness that I just didn't bother to notice in the 10 years or so that I've been using it. I'm so so sorry for ignoring you, bash! If you look at the man page for bash, it will explain (among other things) ${VAR%pattern}, ${VAR#pattern}, and ${VAR/pattern/substitute/}. They work much like you can imagine. The ${VAR%pattern) removes the pattern, starting its search from the right side of the value and searching towards the left, going for the least-greedy approach. The ${VAR#pattern} similarly removes the pattern, but starting from the left. The ${VAR/pattern/substitute} is something that I've needed ever since I started using Linux back in high school. It's like a sed expression. It replaces the specified pattern with the specified substition. It's all so bloody awesome.

Up until now, I had been doing this to get the directory part of a file name:
DIR="`echo $FULLPATH| rev | cut -f1- -d/ | rev`"

I just needed to do this:

I cannot count the number of times that I've shelled out to imagemagick to process a directory and have done something foolish like this:
for f in *.jpg ; do NEW_NAME="`echo $f | rev | cut -f2- -d'/' | rev`.png" convert "$f" "$NEW_NAME" ; done

And I could have just done this:
for f in *.jpg ; do convert "${f}" "${f/\.jpg/.png}; done

So, getting back to the Diablo stuff. I don't know why the steam.sh does the cd and pwd when it could just evaluate the variable, but whatever; maybe they use a side-effect later. Here's my diablo2.sh file:

On to the other package details...

Info.plist, ties everything in the package together:

PkgInfo only contains this line:

Here's a crazy script I threw together, simply invoke it and it will base64 decode the last line of it's content, reconstitute a tar.bz2 file, md5 it for integrity, and if all went well, it will extract a copy of my Diablo2.app folder, minus the wine and minus my Diablo 2 install folder. Just get any one of the pre-built wine for OS X from here: http://wine.playonlinux.com/darwin-i386/ and extract it into the MacOS folder of the Diablo2.app. Then, copy in your Diablo II from a windows install, and the script will locate all the pieces and launch. Be prepared for sounds, because the script speaks its status messages.


OS X Right Click Menu Additions

I'm sure this is documented somewhere, but I didn't find it while looking. If you use the Automator to create a service that receives files or folders in any application, it will get added to the right click menu. Now I can right click documents and choose to edit them with Vim.

I noticed this while trying to add a hotkey to the service. The hotkey didn't work, but then I noticed my edit option in the menu, so that's almost as good.

So here's how I created a right-click option for Edit with Vim under Snow Leopard:

  • Launch Automator

  • Choose The Service Template

  • Change "Service receives selected" pulldown option from "text" to "files or folders."

  • Drag "Run Shell Script" from the library into the current workflow

  • Change the "Pass input" pulldown from "to stdin" to "as arguments"

  • Delete the text from the edit box and enter the following:

  • Save it as something concise, but descriptive, like: Edit with single Vim

This time I embedded everything for the command in the shell script of the service because I'll only ever need to call this from the gui.

Edit: Update: OS X Lion treats Applications like services. If you create an Application with the Automator, it will likewise show up in your services menu.


OS X DMG Creation from a Folder

Edit: As of OS X Lion (10.7) Applications show up in your services menu, so you get a right click menu for free.

The hdiutil command is awesome. Amongst its many features is the ability to create a DMG file from a specified folder. For some reason, there's no right click option for creating DMG files from folders. Strangely enough, there is a right click compress option that will create a zip, but that's really not sufficient. If you create a zip, you can't access individual files from it like you can a compressed DMG.

Edit: For anyone who just wants the command and not fuss with the scripts, here's how you might create a zip compressed dmg file from a folder called Movies:
hdiutil create -srcfolder Movies -volname Movies -fs HFS+ \
-fsargs -c c=64,a=16,e=16 -format UDBZ ./Movies.dmg

Once again, I've used Automator to invoke a bash script. Now I can drop folders on my app and generate a compressed, read-only DMG file. I don't have lots of free space, so I use this for applications I've downloaded that come as a tar.gz/tar.bz/zip/whatever.

I'd like to point out that while it is possible to embed all of the bash script content into the Automator "Run Shell Script" feature, but then I wouldn't be able to easily invoke it from the command line and I use the command line alot.

Here's the content of my Automator "Run Shell Script" box (CreateDMGFromFolder.app):

Here's the content of my shell script (CreateDMGFromFolder):

Edit: I've updated the script in light of reading the bash man page. Parameter Expansion is bad-ass.

Here's the new shell script to replace the aforementioned (CreateDMGFromFolder):


OS X Open With Vim

Edit: After my second OS X post, I went back and created a service to perform Edit with Vim. I actually forgot about the .app that I made with automator. Then I upgraded to Lion and was all sorts of confused when two entries for Edit with Vim popped up in my context menu. Wouldn't you know it? Lion puts all automator Services and Applications into the right click context menu. So I've actually deleted this script and am using the one mentioned here.

OS X comes with vim preinstalled. Nice. It's not that retarded version Ubuntu comes with by default, either. It's the full vim. So then, why the hell can't I right click something, choose open with, and then choose vim? Why can't I pass arguments to the terminal to tell it to run arbitrary commands (such as vim) from the open with dialog?

It appears that OS X only lets you pick Apps as the target application for performing an "Open with". So, to get what I want, I have to use Automator in conjunction with a bash shell script in order to run osascript in order to pop up a new terminal with vim in it and whatever files are selected (or dropped on the app).

Here's what I have in my bash script, aptly named TellTerminal:

This script sends whatever it's arguments are to the Terminal.app and tells it to run them. Then it tells the Terminal.app to activate itself so that it jumps to the foreground. Without this, the terminal will still open, but there's a chance that it will be sitting in the background somewhere. A really, really good chance.

To invoke this script, I had to create an Automator Application (not a workspace, only the .app can be invoked as an application) and add an action 'Run shell script'. This is the shell script that it runs:

This script (which only exists in the Automator app that I've named EditWithVim.app,) loops over all the arguments that were passed to it in order to invoke vim and pass it the quoted file names. This is to avoid having a space within a file name break my script. Also, this script looks for a BashScripts directory in my user's Library directory within the user's home.

Now I can set things to be opened with vim. It's extremely convoluted, but it does seem to be working.