Jim's Depository

this code is not written
 

When your friend’s laptop is at full disk, stop them from trying to make space by going through their tiny documents and deleting things that will be missed or finding that pesky Library folder that contains a bunch of gunk they never wanted and deleting that.

Go to the Mac App Store and download Free Disk Space. It will show what is really taking up all the space and should be dealt with.

Personally, I’ve used Space Gremlin for years, but Free Disk Space is free and does the job.

Update: Apparently Free Disk Space decided money is good. They are $10 now,

I’ve been using USB cameras on tiny repurposed routers, beagle bones, and raspberry pis for some time. I’d like to deploy more cameras, but I am on a tight power budget where every watt matters and my DC power controller that allocates the power is out of ports and I don’t really want to build another one.

Enter “power over ethernet” (PoE) cameras. These hang on an ethernet cable and receive their power from that cable so I only have to run out a cat5 and I’m set. I can buy ethernet switches with PoE and control which devices are powered at any given time.

Danger: most lower cost “smart” switches allow you to control the port power, but only through their silly web interfaces, they don’t allow it over SNMP until you pay for an enterprise device. It appears SMC has a model that will allow SNMP control.

In the made up land of retail pricing, PoE cameras are a little pricey compared to their less capable friends. Fortunately China is a really big place and lots of things are made and sold there. I found 720P PoE cameras for $25 each delivered half a planet away.

Good: They have pretty good picture quality, aluminum “weather proof” enclosures, IR lights for night time, and you can order with four different focal lengths. H.264 over rstp.

Bad: They really sad documentation, on a mini-CD, like I own a tray loading CD drive. Are hardwired to boot on 192.168.0.103 despite documentation that gives a different address, have an open telnet port with a root account backdoor with fixed password, respond with a web interface only in Chinese that doesn’t let you configure the camera in Chrome and Safari. Chrome will offer to guess at translations and turn the text back near English.

That “Bad” entry took me about 3 hours to work out. I do not have the root password, but apparently some tech support responses give it to you.

Proceeding onward, I got Microsoft to give me a demo copy of Windows 8.1 and spun that up in a VirtualBox. If you hit the camera with Internet Explorer, enable Active-X downloads from unknown and untrusted developers and basically give total control of your machine over to unabashedly anonymous people, then you get a web interface that can be used in English and can tell the camera to use DHCP or some static address of your choosing. (I use DHCP for everything and then tell my DHCP server to give a static address to certain MACs.)

The rstp streams can be found at rtsp://camera.example.com:554/user=ACCOUNT&password=PASSWORD&channel=1&stream=0.sdp?real_stream--rtp-caching=100 for the high res stream, and stream=1 for the low res.

Unresolved: I’d like to find a URL to pull a single frame. Perhaps if I figure out how to query the ONVIF interface enough it will tell me.

Further thoughts: It is hard to fathom how someone can sell me a computer, with a camera for $25, in a nice aluminum case and ship it half a planet on demand. Because I need individual control of the power on the switch ports, I’m spending almost that much on the hole in the switch!

The following modules need to be added to the Debian init ramdisk to support root on a 9p disk:

./kernel/fs/9p/9p.ko
./kernel/net/9p/9pnet.ko
./kernel/net/9p/9pnet_rdma.ko
./kernel/net/9p/9pnet_virtio.ko

To add these modules, you will extract an init ramdisk (which is just a compressed cpio archive), add the files, and run a depmod -a in it. Then re-archive it.

The commands I used to make mine are:

#!/bin/sh

set -e

mkdir /tmp/9p-ramdisk
cd /tmp/9p-ramdisk
zcat /boot/initrd.img-3.16.0-4-amd64 | cpio -id

mkdir lib/modules/3.16.0-4-amd64/kernel/fs/9p
mkdir lib/modules/3.16.0-4-amd64/kernel/net/9p

cp /lib/modules/3.16.0-4-amd64/kernel/fs/9p/9p.ko lib/modules/3.16.0-4-amd64/kernel/fs/9p/9p.ko 
cp /lib/modules/3.16.0-4-amd64/kernel/net/9p/9pnet.ko lib/modules/3.16.0-4-amd64/kernel/net/9p/9pnet.ko 
cp /lib/modules/3.16.0-4-amd64/kernel/net/9p/9pnet_rdma.ko lib/modules/3.16.0-4-amd64/kernel/net/9p/9pnet_rdma.ko 
cp /lib/modules/3.16.0-4-amd64/kernel/net/9p/9pnet_virtio.ko lib/modules/3.16.0-4-amd64/kernel/net/9p/9pnet_virtio.ko 

depmod -b /tmp/9p-ramdisk

find . | cpio -o -H newc | gzip > /boot/initrd.img-3.16.0-4-amd64-9p

Update: This works, but seems to be a bad idea. When I try to do aptitude update it fails with lines like this…

E: Unable to determine file size for fd 7 - fstat (2: No such file or directory)
E: Problem opening /var/lib/apt/lists/ftp.debian.org_debian_dists_jessie_contrib_binary-amd64_Packages
E: The package lists or status file could not be parsed or opened.
E: Unable to determine file size for fd 8 - fstat (2: No such file or directory)
E: Problem opening /var/lib/apt/lists/ftp.debian.org_debian_dists_jessie_contrib_binary-amd64_Packages
E: The package lists or status file could not be parsed or opened.

… which seems to say that 9p has a problem with some operation aptitude needs.

Back to disk images for me.

Yep, I ran into the same issue last week. There is an open ticket to track it: https://bugs.launchpad.net/qemu/+bug/1336794

If you have an old HP plotter, you will find that the Mac OS X drivers available from HP’s support site can not be installed because they are in an old VISE .hqx format installer.

If you go and get a generic PPD for the printer, and stick it gzipped in /Library/Printers/PPDs/Contents/Resources then you will be able to select it as a printer type when you add the printer.

Attached is the one I found and used. It needs more work, I am getting postscript errors at the end of prints which can use a lot of paper. But it is working.

Update: It looks like you can disable postscript error printing with…

defaults write com.apple.print DoPostScriptErrorHandler NO

…and re-enable it with…

defaults delete com.apple.print DoPostScriptErrorHandler

Update2: The defaults thing does not appear to work.

Update3: Using HP JetDirect as the protocol instead of LPR seems to have fixed the PostScript error problem.

Attachments

I’d just like to mention that when you use QEMU from a Macintosh running OS X, using the regular Terminal.app terminal, the terminal type will be listed as xterm-256. This will make your monitor console be black on black no mater what you do, except that making the background transparent will make the text somewhat visible.

The “solution” is to change your terminal type to regular old xterm. I’m doing something likes this on my QEMU commands…

$ TERM=xterm qemu-system-i386 ...the-rest-of-my-arguments…

I made a video of my cat chasing the shadow of her tail. It got posted to a social media site. I have contributed to videos of kittens.

If you find yourself making ajax requests for HTML pages, then using jquery to massage them or extract data before displaying it, you should be aware that you may be attempting to load the <img> resources from the page. This can be a performance killer or information leak.

Consider…

function parseSomeDudesPage( pageText) {
    var page = $(pageText);   // <<<<------   This is the problem
    ... do a bunch of stuff with page...
}

...
   $.get('http://somedudeswebsite.com/blah/blah.html', parseSomeDudesPage);
...

That line marked as the problem will parse the text into DOM nodes which will be in your main document. The browser may decide to start fetching the images contained in pageText, (Safari 8.0.2 does). Depending how you fetched the document you could be getting images, broken links, or security domain violations for pulling http: resources into your https: page.

I think the solution is to keep the nodes out of your main document by creating a new one. Reading this stackoverflow comment and not caring about old browsers in my application I went with…

function parseSomeDudesPage( pageText) {
    var page = (new DOMParser).parseFromString( pageText, 'text/html');
    ... do a bunch of stuff with page which is a new document and doesn't trigger <img> loading.
}

Since you have a new document, you won’t be able to move nodes from page to your main document, but I tend to create nodes anyway, so I don’t miss the ability.

A quick warning: When you upgrade your Debian installation to Jessie, you may find the grub2 can no longer install itself and you are left with an unbootable system. (Been there, done that, managed to save myself.)

Preconditions:

  • Your disks have been MBR partitioned so far in the past that there isn’t a megabyte hiding between the MBR and your first partition.

  • Your /boot is sitting on something which requires more than a tiny amount of code to access. In my case ext3 on an LVM partition.

When grub2 tries to update you will get messages about core.img being too big. At this point you may be screwed.

Am I safe?

If you are MBR partitioned, then check where your first partition is. If it starts at block 2048, you have plenty of space. If it is 63, you are in trouble.

If you are GUID partitioned, make sure you have a 1MB partition for boot loader.

How I recovered:

Since I was using LVM I plowed all the data off of my /dev/sda spindle using pvmove (many times), that involved de-mirroring things since I only had three spindles in the machine. Then I could repartition the drive. I went to GUID partitioning, where you explicitly make a boot loader partition for the use of grub2.

Then I could create an LVM physical volume on the remaining space of /dev/sda and shuffle all my data back into mirrors. The process was more complicated since I went through and reformatted each of the drives in case one blows and the BIOS chooses another, but all told it is possible to perform without a reboot.

I have a web site which displays a remote camera view. I like to update the <img> once a minute or so without forcing a page reload and all of its flicker. I’ve done many horrible things over the years, mostly related to adding a query parameter to the end of the URL and accepting that I will trash the cache and perform redundant downloads when the image is not changing.

The <img> tag is 21 years old, surely if it can drink in the USA it has had a .refresh() method added. brief check of specifications: and no.

stackoverflow is littered with questions and solutions about how to reload an <img>, most of them involve cache busting serial numbers in the query parameters.

Notable exceptions:

  • Some answers recommend using a hash tag serial, since this should leave the URL to the server unchanged. This works in some browsers, but doesn’t cause a reload in others. Sometimes there is a combination of HTTP Cache-control headers that will cause a reload, sometimes not. Too touchy to use.

  • You can use an <iframe> containing just the URI of your image to force a reload using an actual, supported mechanism! When that completes you can bludgeon your <img> tag enough to use the new version. See Method #4. I have dispensed with replacing the <img> element and just set the src to null and back. This keeps Safari and Chrome from flickering in January of 2015.

The <iframe> method is my new favorite. It requires Javascript, but I’m not sure how you would be deciding to refresh without Javascript, so that isn’t a loss. From Safari, it does cause two requests for the resource, but the second will be a 304 if you are using any sane caching mechanisms, and the first will only be a 200 if it really changed. (We are in 2015 and I don’t worry so much about the extra request since the servers are all SPDY and its not like its a new TCP connection or blocking anything else.)

Note to W3C: Add .reload() method which tells an <img> to reconsider the caching information and make a new request if required. I suppose a force boolean argument wouldn’t be too much. But nothing more complicated.

After too many years of femtoblogger succumbing to PHP language drift, I’ve been idly reimplementing it in Go.

I’ve been through several iterations wherein I tried to force sophisticated abstractions onto Go, with rather poor success. I finally realized that Go deliberately eschews abstraction. I gave up abstracting and just wrote out the code in as many minor variations as required to do the job, and it was a much more pleasant experience.

In the end I’m looking at about 2,000 lines of Go (not counting imports I didn’t write) which has most of the functionality of the 3,000 lines of PHP. So, within a power of two, they appear to be a wash.

femtoblogger has gained some important ground:

  1. It is statically type checked. Typos and errors won’t be lurking around to explode at run time.

  2. I have an executable which will continue to run until I break it. No more will the web site disintegrate when I update PHP on the server because the language drifted or a Debian packager changed a setting.

  3. I feel better about its security. PHP always made me slightly nervous.

  4. I’ve ditched WYSIWYG editing for markdown. The HTML folk have had plenty of time to make editing work, it’s not my problem if they can’t get their act together without thousands of lines of Javascript repair code.

So here’s to another 7 years of femtoblogger. Who knows what I’ll rewrite it in when 2021 comes around.

more articles