Google Ads
By Claire @ 2009.01.22 [Thu] | 11:08 PM

It’s a good thing I’m not trying to make a living off blog-writing, or else I’d be living in a cardboard box by now.

Life is busy, work is extra busy, things are moving at a fast pace…so ABetterGeek has gone by the wayside a bit. Don’t worry; I’ll post soon.

Before the end of 2009, at least.

I just got an iPhone and switched to AT&T after five years on Verizon Wireless. Don’t get me wrong - I really liked Verizon. It’s just that I left my previous employer several months ago, and I knew that resigning a contract meant they’d validate my employment status, realize I was no longer employed there, and cancel my 20% discount.

Fortunately, I discovered that Purdue has a deal with AT&T, so I was able to get 20% off both the voice and data portions of my wireless plan. I knew I wanted a smartphone, and after playing around with the options, there was no denying that the iPhone beat the competition in usability, speed, and general awesomeness.

After I bought my 60GB iPod Photo in 2004, I swore up and down that it was the last Apple product I would buy new - yet here I am, with a shiny new iPhone. So sue me…things change.

Anyhow, I’m big on hacking and tweaking my stuff. My last Verizon phone was a Motorola V325, and I hacked the hell out of it to make it work how I wanted. Naturally, I jailbroke my iPhone within 24 hours of my purchase, so that I could better customize stuff like sounds and the UI.

I’ve been using one of the themes from Super Mario World for the past five years on each of my phones, so I knew I wanted to upload it to my iPhone. Turns out that adding ringtones takes a little work, but it can be done - for free, and with free software. iTunes will only let you create ringtones from songs you’ve downloaded from the iTunes Store. I’m going to show you how to create ringtones from any audio file, whether it’s WAV, MP3, AAC, or anything else.

First off, you need Audacity. This is a free, open-source sound editor that’s been around for awhile. You want to make sure to get the latest beta version, as it includes support for exporting to AAC (.m4a) format. Once you have Audacity, you also need to get the ffmpeg libraries, which will support exporting to multiple formats (including AAC). If this link is dead, try the version here.

You’ll notice that the file format of the downloaded libraries is a little odd (the second link will take you to a .7z version) - if you don’t already have it, 7-Zip will allow you to extract the files. Once you have the files extracted, copy them into the Plugins directory of your Audacity program folder - it should be something like C:\Program Files\Audacity 1.3 Beta (Unicode)\Plug-Ins.

If you want to make MP3 ringtones for phones other than the iPhone, you need the LAME libraries, available here.

Now you can load up Audacity (it’s in your Start Menu once you’ve installed it). The first thing you need to do is tell it where the ffmpeg libraries reside. Click the Edit menu, and select Preferences. Go down to Import/Export, where you’ll see a box about ffmpeg in the top left corner:

ffmpeg-prefs-1

Click Find Library, and browse to the Plugins folder where you extracted the files. You’ll see that a single dll appears - click it, and click Open. You’ll now see something like this:

ffmpeg-prefs-2

Now that Audacity is set up for exporting to AAC, we can start making our ringtones. It’s pretty screenshot-heavy, so click the jump to see the rest.

Read the rest of this entry »

If you’ve visited my site more than once, you might start to notice that the silly little tagline next to the logo in my header changes, in both content and appearance.

This is accomplished by way of a fancy little bit of PHP. The image generation uses the GD library (with FreeType support), and the fonts are all TrueType.

Again, since my Linode didn’t come with anything preinstalled, I needed to install GD first. It seemed like it might be a bit of a pain - the PHP manual page indicates I was going to have to recompile PHP. Fortunately, this was not the case.

I just had to download it from Ubuntu’s package manager…

apt-get install php5-gd

…and add it to the “extensions” section of php.ini…

nano /etc/php5/apache2/php.ini
 
extension=gd.so

…and restart Apache.

apache2ctl -k graceful

Once that’s out of the way, creating the image was remarkably simple - especially since I found a ready-made script that did exactly what I wanted.

The code is pretty long, so hit the jump to see the rest.

Read the rest of this entry »

By Claire @ 2008.12.13 [Sat] | 10:43 PM

I spent the better part of today redesigning the site. The new WP 2.7 interface kind of motivated me to revamp things.

Let me know what you think, if you find something broken, etc.

By Claire @ 2008.12.12 [Fri] | 07:05 PM

I just installed WordPress 2.7 today. Boy, is it exciting! The entire interface is different, and things can be accomplished much more quickly.

One of the neat features is the ability to add and remove plugins from the web interface. Unfortunately, WordPress only works with FTP and FTPS (FTP over SSL) by default. I don’t have an FTP server installed on my Linode, so I decided to see if I could use SSH instead.

Turns out it’s possible, but it sure was a beast to get up and running. I’ll go through what I did, in case anyone else had as much trouble with this as I did.

First off, you need to install PEAR. This is a nifty little utility that can automatically compile PHP extensions.

Keep in mind that I’m working in Ubuntu 8.04.1 here, and my Linode installation is very stripped down.

First, you need to install the command-line interface for PHP, which allows you to run PHP scripts from a terminal.

apt-get install php5-cli

Seeing as my installation of Ubuntu is devoid of pretty much any extras, I needed to install wget too.

apt-get install wget

Once that’s done, we can install PEAR.

cd /
wget http://pear.php.net/go-pear -O go-pear.php
php go-pear.php

Once the PEAR installation script is running, you need to configure the locations of each of the components. I chose to stick everything in /pear, but you may want to put it somewhere else. I’d recommend keeping option 3 to my setting, though.

1    /
2    /pear/temp
3    /bin
4    /pear
5    /pear/docs
6    /pear/data
7    /pear/tests

Now that PEAR is installed, we can get into installing OpenSSL and the necessary packages to make it work with PHP.

apt-get install openssl
apt-get install lsh-client
apt-get install libssh2-1
apt-get install libssh2-1-dev

With our libraries and packages installed, we can compile our ssh2 extension for PHP.

pecl install -f ssh2-beta

Finally, we need to add the extension to php.ini.

nano /etc/php5/apache/php.ini

Find the section titled “Extensions” and add this line:

extension=ssh2.so

And restart Apache:

apache2ctl -k graceful

In your WordPress admin interface, you should now see an “SSH” option when you go to add, remove, or update files on your server. WordPress provides text boxes to use your private and public SSH keys, but I found I only needed to use one of my user account’s credentials to authenticate to the server.

My friend Danny is a systems administrator and all-around IT guy at a manufacturing company in Indianapolis. He recently came up with a pretty useful little script, and wanted me to pass it on to the world.

Recently I needed to find out which folders a certain person was able to access on our Windows network. Apparently, this was extremely easy in Novell. Since it isn’t 1995 anymore, I tried to find a way to do this on the Internet. I couldn’t, so I set about making my own.

Microsoft has a utility called xcacls.vbs (if you’re using Vista, you’ll have to make sure WMI is installed, and modify the script. If you can’t do that comfortably, you probably don’t want to be messing with the rest of this anyway). It will allow you to change and view ACL’s from a command line. Since I’m not that interested in modifying the ACL’s in a script, the usage is fairly simple “xcacls c:\windows” will result in a listing of who has entries in the ACL and what the entry is (n.b. you’ll also have to have the default script host be cscript. Wscript won’t work).

In order for this to be useful, we really need to be able to have it run automatically on several, if not all, folders on a computer. The first step would be to get a list of the folders we want to run this on. I chose to limit it to one folder and all its subfolders only (c:\ will do everything, while c:\windows will only do the folders in c:\windows. If you want to do c:\windows and c:\program files only, you’ll have to run it twice).

What I was looking for was basically a text file that just had all the folders. This command will create exactly that:

dir "c:\program files" /s /b /o:gn /a:d > c:\batch\xcacls\dirlist.txt

Now that we’ve got a list of all the folders we need to search, we need to actually loop through it.

For /F "tokens=*" %%i in (dirlist.txt) do c:\batch\xcacls\aclSearch.bat administrator %%i

C:\batch\xcacls\aclSearch.bat is another batch file which takes two parameters (I’ll show you it in a minute). I call the other batch file so I don’t have to worry about how DOS handles variables (it doesn’t like to evaluate them during runtime, and will wait until the loop is done and use the final value for each iteration. It’s weird, I know).

A caveat about the for loop: when using for in an interactive CLI you use a single % sign in front of the i, when using it in a batch file, it’s a double %. Don’t ask me why.

aclSearch.bat contains the following

call c:\batch\xcacls\xcacls.vbs "%2" > c:\batch\xcacls\xcaclsResults.txt
 
find /i %1 c:\batch\xcacls\xcaclsResults.txt
 
if %errorlevel%==0 goto Found
 
goto End
 
:Found
 
echo %2 >;>c:\batch\xcacls\%1results.txt
 
:End

This calls xcacls.vbs (from Microsoft) passing it the folder name. The quotes are there to handle filenames with spaces. It then sends the results into a temporary file called xcaclsResults.txt

Next we do a find using the search string (the first item passed – administrator in this example) on that file. If Find finds a match, the errorlevel is 0; if not, it is 1. If the errorlevel is 0, then the folder name is put into a results file named whatever the search string is, with results.txt appended (in this example it’d be administratorresults.txt).

So, how do you actually use all this? FindPermission.bat contains:

dir %1 /s /b /o:gn /a:d>"c:\batch\xcacls\dirlist.txt"
 
for /F "tokens=*" %%i in (dirlist.txt) do c:\batch\xcacls\aclSearch.bat %2 %%i

To search the c:\program files directory for anything the administrators group has access to you’d type:

Findpermission.bat "c:\program files" administrators

The results will be in the same folder you ran findpermissons from and be called administratorsResults.txt. To search the C drive for anything Danny Parrott has access to, you’d need:

Findpermission.bat c:\ "Danny Parrott"

The results from this one will be in Danny Parrottresults.txt.

This does require that Findpermission.bat, aclSearch.bat, and xcacls.vbs be either in the same folder, or in a folder that’s in the path variable. It will work for either users or groups. This process is also not instantaneous. The xcacl.vbs script can take upwards of half a second to run, so on larger systems, this is something you’d want to start and come back to later. On the plus side, though, it hardly uses any system resources while running (5MB RAM and 2-4% CPU time on a four-year-old server at work) so you can run it during the day.

There’s a handy little query you can run in SQL to retrieve the identity (primary key) value of a record you just created. So, you can do something like this:

INSERT INTO
  People (
    Name
  ) VALUES (
    'Joe'
  );
  SELECT @@IDENTITY AS NewName;

This query will create a new person and also return the identity value of the newly created record. It can be useful for all kinds of things - I use it frequently.

We recently upgraded to ColdFusion 8 here at Purdue, and my code started breaking.

It turns out that CF8 attempts to “help” you by automatically running SELECT @@IDENTITY after any INSERT query. This is problematic in two ways - it cancels out your own @@IDENTITY query, and it arbitrarily names the result Generated_Keys.

So instead of being able to do something like this:

<cfset TheNewName = People.NewName>

You must use this:

<cfset TheNewName = People.Generated_Keys>

It’s really more annoying than anything else. It seems like a good idea to include the code automatically, but I think it would probably be a little better if there were a conditional in there that prevents CF8 from inserting its automatic query if a SELECT @@IDENTITY query is already present.

By Claire @ 2008.10.29 [Wed] | 09:08 AM

I tend to be the go-to person for tech support among my friends, family, and neighbors. A few nights ago, one of my neighbors asked me to help him with his custom-built machine. His USB ports had mysteriously quit working. I messed around, and the same thing kept happening. His Microsoft USB wireless mouse worked just fine, but his HP all-in-one inkjet printer and his SanDisk thumb drive didn’t work. Plugging them in resulted in a “one of the devices connected has malfunctioned” error from Windows. His thumb drive appeared to work just fine in Ubuntu Linux.

We removed all the USB host items from the Device Manager and reinstalled them, to no avail. Then I tried disabling the USB enhanced controller item (this is generally what lets Windows know that a USB controller is capable of USB 2.0). This worked, but kept his devices from working at USB 2.0 speeds. We even reinstalling Windows completely and still had the same problem.

I started Googling around and found this article regarding my exact problem - the SiS PCI to USB Enhanced Host Controller mysteriously quit working, and took all USB 2.0 devices down with it. This blogger’s solution was to shutdown and unplug the computer, wait for about half an hour, hold in the power button for a minute, and then restart the machine.

And, like magic…it worked.

I can only begin to guess why. Like this other blogger, my neighbor’s machine had a Gigabyte-brand motherboard. My theory is that something was getting corrupted or otherwise mistranslated by the motherboard regarding the USB 2.0 controller, and whatever was breaking things was being remembered across shutdowns and reboots.

By letting the machine sit for awhile, all the capacitors on the motherboard and power supply emptied out, thereby completely cutting power to the machine. This apparently reset whatever dark magic was causing the problem in the first place.

It’s likely that in Matt’s case, Linux was allowing the ports to work, but only at 1.1 speeds. Since we didn’t test how quickly file transfers took place in Linux, I can’t confirm this theory, but it would fit with my above assumptions.

At any rate, now we have our answer. The next time this happens (and I imagine it will), I’ll try the fixes listed on usbman.com first, so we can try to cure the problem once and for all.

By Claire @ 2008.10.27 [Mon] | 08:53 AM

Since OS X 10.4 (Tiger), Apple has provided a remote deskotp capability integrated into the operating system. However, unlike Windows (which uses a proprietary protocol called RDP), Apple chose to use the VNC protocol for their remote desktop server and client.

I wouldn’t recommend using Apple’s VNC server; it’s far more restrictive than alternatives. Vine server is much more robust and customizable, and it’s open-source.

However, if you find it necessary to use Apple’s built-in VNC for whatever reason, you may also find yourself needing to control the server from the command line (for instance, if the server application fails and you need to SSH into your remote Mac to restart the service).

I found out the hard way that the Perl script Apple uses to restart the server stores the VNC password in plaintext. This is wrong on a lot of levels, one being that it’s completely user-unfriendly. At any rate, after some Googling around, I found a Perl script that will encode the password with the necessary key. You can then input the encoded password in your VNC restart command.

The Perl script looks like this:

perl -nwe 'BEGIN { @k = unpack "C*", pack "H*", "1734516E8BA8C5E2FF1C39567390ADCA"}; \
chomp; s/^(.{8}).*/$1/; @p = unpack "C*", $_; foreach (@k) { printf "%02X", $_ ^ (shift @p || 0) }; print "\n"'

Paste this at your bash prompt and hit enter. You can then type your password, hit enter again, and have the encoded password ready to go. Once you have your encoded password, you can use the kickstart command to restart the VNC server. Apple has some documentation on using kickstart here.

Overall, Apple made a major blunder by not correctly encoding the password with the kickstart utility. I imagine it’s just part of Apple’s unwillingness to provide power users with real functionality. They’re far more focused on their GUI than on command-line utilities such as this one.

By Claire @ 2008.10.16 [Thu] | 04:15 PM

It’s been more than a month since I last posted.

Sorry about that.

I’m going to be working on a new project that involves Twitter (likely in PHP, so that I can run it from ABetterGeek.com), so I may post some insights into that in the near future.

I don’t intend for this to be a dead site; it’s just hard to keep up with regular writing. I need more to talk about. Politics, maybe. And religion. And some lawyer jokes for good measure.

Google Ads