<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	>

<channel>
	<title>A Better Geek</title>
	<atom:link href="http://blog.abettergeek.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.abettergeek.com</link>
	<description>Helping you be a better geek, one post at a time.</description>
	<pubDate>Wed, 03 Feb 2010 22:21:29 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Windows Server 2008 R2, SMTP, and Gmail for Domains (or How I learned to let go and love smart hosts)</title>
		<link>http://blog.abettergeek.com/server-management/windows-server-2008-r2-smtp-and-gmail-for-domains-or-how-i-learned-to-let-go-and-love-smart-hosts/</link>
		<comments>http://blog.abettergeek.com/server-management/windows-server-2008-r2-smtp-and-gmail-for-domains-or-how-i-learned-to-let-go-and-love-smart-hosts/#comments</comments>
		<pubDate>Wed, 13 Jan 2010 02:21:38 +0000</pubDate>
		<dc:creator>Claire</dc:creator>
		
		<category><![CDATA[Server Management]]></category>

		<category><![CDATA[Windows Server 2008]]></category>

		<guid isPermaLink="false">http://blog.abettergeek.com/?p=154</guid>
		<description><![CDATA[I&#8217;ve been gone for awhile. I mean, not really, just from A Better Geek. I met a special someone, so that took up a lot of my time. Then said Special Someone got a job with IBM in Virginia, and we packed up and moved 700 miles to Fairfax from Lafayette back in mid-September 2009. [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been gone for awhile. I mean, not really, just from A Better Geek. I met a special someone, so that took up a lot of my time. Then said Special Someone got a job with IBM in Virginia, and we packed up and moved 700 miles to Fairfax from Lafayette back in mid-September 2009. I&#8217;m looking for work and spending my time being a server administrator, because we decided to go for Verizon Business FiOS and are hosting everything (including our websites) from our home.</p>
<p>Let me tell you, this has been one huge educational experience that never seems to <strong>end</strong>. My server is now running my LAN&#8217;s internal DHCP and DNS. It&#8217;s also a game application server, an internal samba file server, and an internal and external web server.</p>
<p>One of the things apps like WordPress, PunBB, and other content systems use is email. I&#8217;ve already discussed in the past how to make sendmail in Linux play nicely with Apache and PHP, but I realized that things were changing as I started migrating our websites and projects to an entirely different environment - Windows Server 2008 R2 Enterprise and IIS 7.0. There are some growing pains, but at least it gives me a lot to write about!</p>
<p>Anyhow, I realized shortly after the migration of Dan&#8217;s game servers (and related websites) that the server wasn&#8217;t sending mail. Since, you know, I hadn&#8217;t set up an SMTP service in Windows. &#8220;So what?&#8221; I thought to myself, &#8220;I&#8217;ll just install it and everything will be hunky-dory, right?&#8221;</p>
<p>Wrong.</p>
<p>It turns out that in 2009, every large mail service provider on the Internet really hates relaying email that comes from suspicious locations, including IP addresses that are part of residential ISPs. Even though we have a static IP address through Verizon Business, it&#8217;s still part of Verizon&#8217;s greater IP pool - which includes all their dynamic IPs for residential FiOS and DSL services.</p>
<p>Google blacklisted me the second I tried to send a message to an @gmail.com address. It was just downhill from there. I found out from some people on IRC that I needed a reverse DNS entry if I wanted anyone to relay my email, so I called up Verizon and got that taken care of. Yahoo, MSN, and AOL started relaying my mail, but Google kept delaying delivery, claiming that an &#8220;unusual amount of unsolicited email&#8221; was coming from my IP address.</p>
<p>After many hours on IRC and doing additional research on Google, I decided it probably wasn&#8217;t worth it to keep wrestling to make the big mail servers of cyberspace deem my rinky-dink little server worthy of their approval. It was time to look for other solutions.</p>
<p>I decided right from the start that I did not want to deal with hosting mail. I have no interest in trying to mitigate mass quantities of spam. My friend Julie over <a title="The Gadgeteer" href="http://www.the-gadgeteer.com">The Gadgeteer</a> got on the Gmail Apps boat and moved her own email over to Google. It seemed appealing enough, so I decided to give it a shot. Google Apps offers a free version to cheapskates like me who can&#8217;t or don&#8217;t want to pay yet another monthly fee. The free version includes Google mail, calendar, sites, chat, and docs. Works for me!</p>
<p>Google was brilliant about the whole thing. I signed up, and when I clicked in the web-based control panel to set up email, it automagically discovered that my domain (polatrite.com, in this case) was registered with 1and1.com, so it directed me to a 1and1-specific how-to on setting up the MX records for my domain. About 18 hours later, 1and1 and Google had both updated their servers and records, and I was in business. Now it was time to figure out how to make my web server send email through Google&#8217;s SMTP servers.</p>
<p>Which is why we&#8217;re here today. If you&#8217;re still paying attention, that is. As always, this is a little screenshot-heavy, so hit the jump to carry onward.</p>
<p><span id="more-154"></span>First off, if you haven&#8217;t already, you need to install the SMTP service in Windows. Start by opening up your Server Manager. Click on Features in the lefthand pane, and then &#8220;Add Features&#8221;:</p>
<p><img class="size-full wp-image-157 alignnone" title="01" src="http://blog.abettergeek.com/wp-content/uploads/2010/01/01.png" alt="01" width="653" height="509" /></p>
<p>Make sure that both <strong>SMTP Server</strong> and <strong>SMTP Server Tools</strong> are checked. Windows, being the wizard-happy operating system that it is, will walk you through the steps to install SMTP, including installing any dependent services you may need. Once that&#8217;s done, we can continue to actually making your mail route through Google&#8217;s servers.</p>
<p>The SMTP standard allows for something called smart hosting. Essentially, an SMTP service set up with a smart host actually sends its mail to another SMTP server, which then relays the mail from there into the scary unknowns of cyberspace. This is exactly what I needed - by relaying my mail through Google&#8217;s servers, the outside world would see my mail as Google-sent, and nobody in their right mind is going to block Google mail (theoretically).</p>
<p>Before we can set up our server, we need enable IMAP in Gmail. Login to the Gmail web interface, and click <strong>Settings</strong> in the top right corner of your browser window. Select the <strong>Forwarding and POP/IMAP</strong> settings tab, and make sure <strong>Enable IMAP</strong> is selected. If it&#8217;s not, select it and save your changes.</p>
<p><img class="size-full wp-image-159 alignnone" title="02" src="http://blog.abettergeek.com/wp-content/uploads/2010/01/02.png" alt="02" width="646" height="464" /></p>
<p>Now that we have permission to access our mail outside of Google&#8217;s web interface, we can set up the server.</p>
<p>The SMTP service available in Windows Server 2008 is actually managed through IIS 6.0, not 7.0. Fire up the IIS 6.0 manager by going to <strong>Start &gt; Administrative Tools &gt; Internet Information Services (IIS) 6.0 Manager</strong>. Under your server, you&#8217;ll see a little hideous 16-color envelope icon. This is your SMTP virtual server, which IIS uses to send mail. Right-click on it and select <strong>Properties</strong>.</p>
<p>Click the <strong>Delivery</strong> tab, and then the <strong>Outbound Security&#8230;</strong> button. We want Basic Authentication. Enter your Google account credentials, and make sure <strong>TLS Encryption</strong> is enabled, since Google&#8217;s SMTP servers require SSL.</p>
<p><img class="size-full wp-image-160 alignnone" title="03" src="http://blog.abettergeek.com/wp-content/uploads/2010/01/03.png" alt="03" width="653" height="509" /></p>
<p style="text-align: left;">Click <strong>OK</strong>, then the <strong>Advanced&#8230;</strong> button on the same tab. Here&#8217;s where we set up our smart host that our own SMTP service will use to relay email. Enter the domain of your site under <strong>Fully-qualified domain name</strong>, and use smtp.gmail.com as the smart host.</p>
<p style="text-align: left;"><img class="size-full wp-image-161 alignnone" title="04" src="http://blog.abettergeek.com/wp-content/uploads/2010/01/04.png" alt="04" width="653" height="509" /></p>
<p style="text-align: left;">Click <strong>OK</strong>. Now we&#8217;re going to enable logging, which will be critically important to ensure that your email is being accepted by receiving SMTP servers. Click the <strong>General</strong> tab. Make sure the <strong>Enable logging</strong> box is selected, and choose your log format. I&#8217;m not all that well-versed on what the different formats are. &#8220;Microsoft IIS Log File Format&#8221; has been working fine for me. Click <strong>Properties&#8230;</strong> next the log format drop-down to choose where your logs are going to reside. Click <strong>OK</strong>.</p>
<p style="text-align: left;"><img class="size-full wp-image-162 alignnone" title="05" src="http://blog.abettergeek.com/wp-content/uploads/2010/01/05.png" alt="05" width="653" height="509" /></p>
<p style="text-align: left;">Double-check everything, and click <strong>OK</strong> to apply your new settings. I went ahead and restarted the SMTP service, just to make sure that everything was working correctly.</p>
<p style="text-align: left;">Now you can test your server and see if everything is working. I made a simple ColdFusion page that sent a test message to Gmail, AOL, Yahoo, and MSN (just to double-check!). It worked perfectly.</p>
<p style="text-align: left;">But&#8230;wait! Even though I had set the &#8220;from&#8221; parameter of the <span class="code">cfmail</span><strong> </strong>tag to come from my Gmail address, Google overrode this and used my polatrite.com email address as the &#8220;from&#8221; address in the message header. I don&#8217;t want all my websites sending mail from this one address! A Better Geek and Polatrite Gaming are two completely different entities, so I needed to remedy this right away.</p>
<p style="text-align: left;">Never fear, Google is here to save the day! Gmail has this neat feature, available in normal Gmail accounts and Google Apps accounts, that allows you to send mail from other mail accounts right from inside the Gmail web interface. It&#8217;s easy to set up, and it works well.</p>
<p style="text-align: left;">Log back in to your Gmail web interface, and go back to your settings. Navigate to the <strong>Accounts </strong>settings page. Select <strong>Add another email address you own</strong> in the <strong>Send mail as</strong> section, which will pop up a new window. Enter the name and email address you want to display on mail sent from this account.</p>
<p><img class="size-full wp-image-163 alignnone" title="06" src="http://blog.abettergeek.com/wp-content/uploads/2010/01/06.png" alt="06" width="461" height="406" /></p>
<p style="text-align: left;">On the next page, select to send the mail through the secondary address&#8217;s SMTP servers. It&#8217;s important to keep in mind that this will only work for email accounts that have given you permission to send mail externally (e.g. not through the webmail interface) - Yahoo and MSN/Live do not provide this functionality for free email accounts. However, all Gmail accounts and Google Apps accounts allow for external SMTP access. Enter <strong>smtp.gmail.com</strong> as the SMTP server, select port 465 or 587, and make sure <strong>Always use a secure connection (SSL)</strong> is enabled. Enter the username and password for this secondary email account, and click <strong>Add Account</strong>.</p>
<p><img class="size-full wp-image-164 alignnone" title="07" src="http://blog.abettergeek.com/wp-content/uploads/2010/01/07.png" alt="07" width="461" height="406" /></p>
<p style="text-align: left;">After you&#8217;ve added your account, Google will email that address with a confirmation message. Click the link in that email to validate that you are authorized to use it, and Google will enable that account in Gmail. Once your second account is activated, you can send mail from your websites with this second email address as the &#8220;from&#8221; address, and Google will send it accordingly.</p>
<p style="text-align: left;">Google does have some limitations on what is allowed with the free version of Google Apps, and it&#8217;s important to keep this in mind for your websites. A single message can have a maximum of 100 recipients. Additionally, you can send mail to a total of 500 recipients per day. If you have a very active server, you&#8217;re probably going to be better off running your own mail server or paying for a larger-scale male service (Google Apps Premier allows up to 2000 recipients daily), but for small-time stuff like I&#8217;m managing, this is going to work just fine. I&#8217;ll still try to get my server off Google&#8217;s mail blacklist so that I can eventually use my own SMTP server, but in the meantime, this is a fast and easy way to get Windows ready to go for sending mail through web applications.</p>
<p><img src="file:///D:/Users/SHIFUI%7E1/AppData/Local/Temp/moz-screenshot.png" alt="" /></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.abettergeek.com/server-management/windows-server-2008-r2-smtp-and-gmail-for-domains-or-how-i-learned-to-let-go-and-love-smart-hosts/feed/</wfw:commentRss>
		</item>
		<item>
		<title>I swear I&#8217;m not dead!</title>
		<link>http://blog.abettergeek.com/personal-stuff/i-swear-im-not-dead/</link>
		<comments>http://blog.abettergeek.com/personal-stuff/i-swear-im-not-dead/#comments</comments>
		<pubDate>Fri, 23 Jan 2009 03:08:00 +0000</pubDate>
		<dc:creator>Claire</dc:creator>
		
		<category><![CDATA[Personal Stuff]]></category>

		<guid isPermaLink="false">http://blog.abettergeek.com/?p=147</guid>
		<description><![CDATA[It&#8217;s a good thing I&#8217;m not trying to make a living off blog-writing, or else I&#8217;d be living in a cardboard box by now.
Life is busy, work is extra busy, things are moving at a fast pace&#8230;so ABetterGeek has gone by the wayside a bit. Don&#8217;t worry; I&#8217;ll post soon.
Before the end of 2009, at [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s a good thing I&#8217;m not trying to make a living off blog-writing, or else I&#8217;d be living in a cardboard box by now.</p>
<p>Life is busy, work is extra busy, things are moving at a fast pace&#8230;so ABetterGeek has gone by the wayside a bit. Don&#8217;t worry; I&#8217;ll post soon.</p>
<p>Before the end of 2009, at least.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.abettergeek.com/personal-stuff/i-swear-im-not-dead/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Make and upload your own iPhone ringtones for free</title>
		<link>http://blog.abettergeek.com/hardware/make-and-upload-your-own-iphone-ringtones-for-free/</link>
		<comments>http://blog.abettergeek.com/hardware/make-and-upload-your-own-iphone-ringtones-for-free/#comments</comments>
		<pubDate>Sun, 21 Dec 2008 22:40:32 +0000</pubDate>
		<dc:creator>Claire</dc:creator>
		
		<category><![CDATA[Gadgets]]></category>

		<category><![CDATA[Hardware]]></category>

		<category><![CDATA[iPhone]]></category>

		<guid isPermaLink="false">http://blog.abettergeek.com/?p=123</guid>
		<description><![CDATA[I just got an iPhone and switched to AT&#38;T after five years on Verizon Wireless. Don&#8217;t get me wrong - I really liked Verizon. It&#8217;s just that I left my previous employer several months ago, and I knew that resigning a contract meant they&#8217;d validate my employment status, realize I was no longer employed there, [...]]]></description>
			<content:encoded><![CDATA[<p>I just got an iPhone and switched to AT&amp;T after five years on Verizon Wireless. Don&#8217;t get me wrong - I really liked Verizon. It&#8217;s just that I left my previous employer several months ago, and I knew that resigning a contract meant they&#8217;d validate my employment status, realize I was no longer employed there, and cancel my 20% discount.</p>
<p>Fortunately, I discovered that Purdue has a deal with AT&amp;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.</p>
<p>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&#8230;things change.</p>
<p>Anyhow, I&#8217;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.</p>
<p>I&#8217;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&#8217;ve downloaded from the iTunes Store. I&#8217;m going to show you how to create ringtones from any audio file, whether it&#8217;s WAV, MP3, AAC, or anything else.</p>
<p>First off, you need <a href="http://audacity.sourceforge.net/">Audacity</a>. This is a free, open-source sound editor that&#8217;s been around for awhile. You want to make sure to get the latest <strong>beta</strong> 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 <a href="http://lame.buanzo.com.ar/">this</a> link is dead, try the version <a href="http://ffmpeg.arrozcru.com/builds/">here</a>.</p>
<p>You&#8217;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&#8217;t already have it, <a href="http://www.7-zip.org/">7-Zip</a> will allow you to extract the files. Once you have the files extracted, copy them into the <strong>Plugins</strong> directory of your Audacity program folder - it should be something like <span class="code">C:\Program Files\Audacity 1.3 Beta (Unicode)\Plug-Ins</span>.</p>
<p>If you want to make MP3 ringtones for phones other than the iPhone, you need the LAME libraries, available <a href="http://lame.buanzo.com.ar/">here</a>.</p>
<p>Now you can load up Audacity (it&#8217;s in your Start Menu once you&#8217;ve installed it). The first thing you need to do is tell it where the ffmpeg libraries reside. Click the <strong>Edit</strong> menu, and select <strong>Preferences</strong>. Go down to <strong>Import/Export</strong>, where you&#8217;ll see a box about ffmpeg in the top left corner:</p>
<p><img class="alignnone size-full wp-image-125" title="ffmpeg-prefs-1" src="http://blog.abettergeek.com/wp-content/uploads/2008/12/ffmpeg-prefs-1.png" alt="ffmpeg-prefs-1" width="296" height="98" /></p>
<p>Click <strong>Find Library</strong>, and browse to the Plugins folder where you extracted the files. You&#8217;ll see that a single dll appears - click it, and click Open. You&#8217;ll now see something like this:</p>
<p><img class="alignnone size-full wp-image-126" title="ffmpeg-prefs-2" src="http://blog.abettergeek.com/wp-content/uploads/2008/12/ffmpeg-prefs-2.png" alt="ffmpeg-prefs-2" width="308" height="98" /></p>
<p>Now that Audacity is set up for exporting to AAC, we can start making our ringtones. It&#8217;s pretty screenshot-heavy, so click the jump to see the rest.</p>
<p><span id="more-123"></span>First, find a song you want to use for your ringtone. For this example, we&#8217;ll be using &#8220;Never Let You Go&#8221; by Third Eye Blind.</p>
<p>Your ringtone should be no longer than 40 seconds, so we&#8217;ll use Audacity to select a portion of the song. To open a file, either drag it into the Audacity window, or use the File &gt; Open command. When you import an MP3, Audacity will automatically convert it so you can edit it:</p>
<p><img class="alignnone size-full wp-image-127" title="mp3-import" src="http://blog.abettergeek.com/wp-content/uploads/2008/12/mp3-import.png" alt="mp3-import" width="306" height="177" /></p>
<p>Once it&#8217;s done importing, click the play button to start playing your song. Watch the vertical progress line to see where you want to crop down the track. For instance, I wanted to only use a part near the end of the song, rather than just the first 40 seconds of the track. The progress bar is a vertical line with an arrow at the top:</p>
<p><img class="alignnone size-full wp-image-128" title="progress-line" src="http://blog.abettergeek.com/wp-content/uploads/2008/12/progress-line.png" alt="progress-line" width="315" height="350" /></p>
<p>Once you&#8217;ve figured out what part of the song you want to use, highlight it with your mouse. If you need to be more precise, use <strong>Ctrl+1</strong> to zoom in. You can see here the dark gray selection highlight from 0 to 25 seconds:</p>
<p><a href="http://blog.abettergeek.com/wp-content/uploads/2008/12/selection.png"><img class="alignnone size-medium wp-image-131" title="selection" src="http://blog.abettergeek.com/wp-content/uploads/2008/12/selection.png" alt="selection" width="673" height="313" /></a></p>
<p>Once you&#8217;ve selected the portion of the track you want to use, copy it (<strong>Ctrl+C</strong>), open a new file (<strong>Ctrl+N</strong>), and paste it in (<strong>Ctrl+V</strong>).</p>
<p>You probably don&#8217;t want your song to just abruptly cut off, so you can fade it out at the end. Select the last five or ten seconds or so of the clip, and go to <strong>Effect</strong> &gt; <strong>Utility</strong> &gt; <strong>Fade Out</strong>.</p>
<p><img class="alignnone size-full wp-image-136" title="fade-out" src="http://blog.abettergeek.com/wp-content/uploads/2008/12/fade-out.png" alt="fade-out" width="452" height="157" /></p>
<p>You&#8217;ll see the selection taper off as the volume decreases. You can reapply this filter if you want it to fade out even more. Once you have your song edited how you want, you can export it to AAC. Just go to <strong>File</strong> &gt; <strong>Export</strong> and select <strong>M4A (AAC) Files (FFmpeg)</strong> from the &#8220;Save As Type&#8221; drop-down:</p>
<p><img class="alignnone size-full wp-image-137" title="aac-export" src="http://blog.abettergeek.com/wp-content/uploads/2008/12/aac-export.png" alt="aac-export" width="373" height="274" /></p>
<p>Save your file. You&#8217;ll want to remember where you put it, so that you can import it into your iPhone.</p>
<p>iPhone ringtones are actually just M4A files with a different extension. Find your file in My Computer or Windows Explorer, right click on it, and click <strong>Rename</strong>. Change the file extension to <strong>.m4r</strong>. You&#8217;ll notice that the file type in Explorer&#8217;s detail view calls it a Ringtone:</p>
<p><img class="alignnone size-full wp-image-138" title="file-rename" src="http://blog.abettergeek.com/wp-content/uploads/2008/12/file-rename.png" alt="file-rename" width="376" height="30" /></p>
<p>Now, just drag the file into the Ringtones section of your iTunes library.</p>
<p><img class="alignnone size-full wp-image-139" title="itunes-library" src="http://blog.abettergeek.com/wp-content/uploads/2008/12/itunes-library.png" alt="itunes-library" width="487" height="174" /></p>
<p>Assuming you already have iTunes configured to sync with your iPhone, you can now just drag the newly imported file onto your iPhone, and it will sync and be available in the ringtone selection preferences pane.</p>
<p><img class="alignnone size-full wp-image-140" title="iphone-screen" src="http://blog.abettergeek.com/wp-content/uploads/2008/12/iphone-screen.jpg" alt="iphone-screen" width="320" height="480" /></p>
<p>If your song seems a little distorted when your ringer volume is at maximum, you can try dropping the overall volume by a few decibels, using the Normalize utility under <strong>Effect</strong> &gt; <strong>Utility</strong> &gt; <strong>Normalize</strong>:</p>
<p><img class="alignnone size-full wp-image-141" title="normalize" src="http://blog.abettergeek.com/wp-content/uploads/2008/12/normalize.png" alt="normalize" width="303" height="167" /></p>
<p>There&#8217;s no real magic number; it&#8217;s just a matter of trial and error to figure out what sounds best to you.</p>
<p>Getting MIDI files into the proper ringtone format takes a little more effort - I&#8217;ll show you how to do that next time!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.abettergeek.com/hardware/make-and-upload-your-own-iphone-ringtones-for-free/feed/</wfw:commentRss>
		</item>
		<item>
		<title>PHP: Dynamically generating images from text</title>
		<link>http://blog.abettergeek.com/web-development/php-dynamically-generating-images-from-text/</link>
		<comments>http://blog.abettergeek.com/web-development/php-dynamically-generating-images-from-text/#comments</comments>
		<pubDate>Mon, 15 Dec 2008 01:19:29 +0000</pubDate>
		<dc:creator>Claire</dc:creator>
		
		<category><![CDATA[PHP]]></category>

		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://blog.abettergeek.com/?p=66</guid>
		<description><![CDATA[If you&#8217;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 [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;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.</p>
<p>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.</p>
<p>Again, since my Linode didn&#8217;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.</p>
<p>I just had to download it from Ubuntu&#8217;s package manager&#8230;</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> php5-gd</pre></div></div>

<p>&#8230;and add it to the &#8220;extensions&#8221; section of php.ini&#8230;</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">nano</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>php5<span style="color: #000000; font-weight: bold;">/</span>apache2<span style="color: #000000; font-weight: bold;">/</span>php.ini
&nbsp;
<span style="color: #007800;">extension</span>=gd.so</pre></div></div>

<p>&#8230;and restart Apache.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">apache2ctl <span style="color: #660033;">-k</span> graceful</pre></div></div>

<p>Once that&#8217;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.</p>
<p>The code is pretty long, so hit the jump to see the rest.</p>
<p><span id="more-66"></span>Here&#8217;s the actual script,  broken down into sections:</p>
<p>First, we tell the browser that this page is a PNG image. This line needs to come before any other code, or else you might start seeing errors.</p>
<p>Next, we create a class with all the values we want to use for our image, except for the font and text.</p>
<p><span class="code">$transparent</span> tells GD to create a transparent image, so that it can be used against any background. The first set of RGB values indicate the color of the text, and the second set is for the background color, in order to antialias the text. I selected a shade of green in the same area of my header gradient where the text appears, and it blends in pretty smoothly.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?</span>
  <span style="color: #990000;">Header</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Content-type: image/png&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000000; font-weight: bold;">class</span> textPNG <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">var</span> <span style="color: #000088;">$size</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">20</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">var</span> <span style="color: #000088;">$rot</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// rotation in degrees</span>
    <span style="color: #000000; font-weight: bold;">var</span> <span style="color: #000088;">$pad</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// padding</span>
    <span style="color: #000000; font-weight: bold;">var</span> <span style="color: #000088;">$transparent</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// transparency set to on</span>
    <span style="color: #000000; font-weight: bold;">var</span> <span style="color: #000088;">$red</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">255</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// text colors</span>
    <span style="color: #000000; font-weight: bold;">var</span> <span style="color: #000088;">$grn</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">255</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">var</span> <span style="color: #000088;">$blu</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">255</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">var</span> <span style="color: #000088;">$bg_red</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">110</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// background colors</span>
    <span style="color: #000000; font-weight: bold;">var</span> <span style="color: #000088;">$bg_grn</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">218</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">var</span> <span style="color: #000088;">$bg_blu</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">110</span><span style="color: #339933;">;</span></pre></div></div>

<p>Next, we write the function that will actually create the image, starting out with some empty variables. The two variables that are passed to the function (<span class="code">$foo</span> and <span class="code">$font</span>) are going to give us the text to display, and the font file to use.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">    <span style="color: #000000; font-weight: bold;">function</span> draw<span style="color: #009900;">&#40;</span><span style="color: #000088;">$foo</span><span style="color: #339933;">,</span> <span style="color: #000088;">$font</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$width</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$height</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$offset_x</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$offset_y</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$bounds</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$image</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;&quot;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Now we need to figure out how big the image should be. First, we determine the height of the text based on a capital &#8220;W&#8221;. This will work for most fonts, but some of the handwriting ones I use in my tagline image have unusually tall characters, so I ended up manually specifying the height (e.g. <span class="code">$font-height = 55;</span>).</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">      <span style="color: #666666; font-style: italic;">// determine font height.</span>
      <span style="color: #000088;">$bounds</span> <span style="color: #339933;">=</span> <span style="color: #990000;">ImageTTFBBox</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>size<span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>rot<span style="color: #339933;">,</span> <span style="color: #000088;">$font</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;W&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>rot <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$font_height</span> <span style="color: #339933;">=</span> <span style="color: #990000;">abs</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$bounds</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">7</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">-</span><span style="color: #000088;">$bounds</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>rot <span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$font_height</span> <span style="color: #339933;">=</span> <span style="color: #990000;">abs</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$bounds</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">-</span><span style="color: #000088;">$bounds</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">7</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$font_height</span> <span style="color: #339933;">=</span> <span style="color: #990000;">abs</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$bounds</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">7</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">-</span><span style="color: #000088;">$bounds</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span></pre></div></div>

<p>Then we determine the width and the vertical and horiztonal coordinates for the bottom left corner of the text. I ended up setting the <span class="code">$height</span> variable to a specific value.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">      <span style="color: #666666; font-style: italic;">// determine bounding box.</span>
      <span style="color: #000088;">$bounds</span> <span style="color: #339933;">=</span> <span style="color: #990000;">ImageTTFBBox</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>size<span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>rot<span style="color: #339933;">,</span> <span style="color: #000088;">$font</span><span style="color: #339933;">,</span> <span style="color: #000088;">$foo</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>rot <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$width</span> <span style="color: #339933;">=</span> <span style="color: #990000;">abs</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$bounds</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">4</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">-</span><span style="color: #000088;">$bounds</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$height</span> <span style="color: #339933;">=</span> <span style="color: #990000;">abs</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$bounds</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">3</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">-</span><span style="color: #000088;">$bounds</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">7</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$offset_y</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$font_height</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$offset_x</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>rot <span style="color: #339933;">&amp;</span>gt<span style="color: #339933;">;</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$width</span> <span style="color: #339933;">=</span> <span style="color: #990000;">abs</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$bounds</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">-</span><span style="color: #000088;">$bounds</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">6</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$height</span> <span style="color: #339933;">=</span> <span style="color: #990000;">abs</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$bounds</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">-</span><span style="color: #000088;">$bounds</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">5</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$offset_y</span> <span style="color: #339933;">=</span> <span style="color: #990000;">abs</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$bounds</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">7</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">-</span><span style="color: #000088;">$bounds</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">5</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">+</span><span style="color: #000088;">$font_height</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$offset_x</span> <span style="color: #339933;">=</span> <span style="color: #990000;">abs</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$bounds</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">-</span><span style="color: #000088;">$bounds</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">6</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #000088;">$width</span> <span style="color: #339933;">=</span> <span style="color: #990000;">abs</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$bounds</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">4</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">-</span><span style="color: #000088;">$bounds</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">6</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$height</span> <span style="color: #339933;">=</span> <span style="color: #990000;">abs</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$bounds</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">7</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">-</span><span style="color: #000088;">$bounds</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$offset_y</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$font_height</span><span style="color: #339933;">;</span>
        <span style="color: #000088;">$offset_x</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span></pre></div></div>

<p>The last bit of our function generates the actual image, using the <span class="code">imagettftext</span> function of the GD library.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">      <span style="color: #000088;">$image</span> <span style="color: #339933;">=</span> <span style="color: #990000;">imagecreate</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$width</span><span style="color: #339933;">+</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>pad<span style="color: #339933;">*</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">+</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span><span style="color: #000088;">$height</span><span style="color: #339933;">+</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>pad<span style="color: #339933;">*</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">+</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #000088;">$background</span> <span style="color: #339933;">=</span> <span style="color: #990000;">ImageColorAllocate</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$image</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>bg_red<span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>bg_grn<span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>bg_blu<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$foreground</span> <span style="color: #339933;">=</span> <span style="color: #990000;">ImageColorAllocate</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$image</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>red<span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>grn<span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>blu<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>transparent<span style="color: #009900;">&#41;</span> <span style="color: #990000;">ImageColorTransparent</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$image</span><span style="color: #339933;">,</span> <span style="color: #000088;">$background</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #990000;">ImageInterlace</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$image</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #666666; font-style: italic;">// render it.</span>
      <span style="color: #990000;">ImageTTFText</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$image</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>size<span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>rot<span style="color: #339933;">,</span> <span style="color: #000088;">$offset_x</span><span style="color: #339933;">+</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>pad<span style="color: #339933;">,</span> <span style="color: #000088;">$offset_y</span><span style="color: #339933;">+</span><span style="color: #000088;">$this</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>pad<span style="color: #339933;">,</span> <span style="color: #000088;">$foreground</span><span style="color: #339933;">,</span> <span style="color: #000088;">$font</span><span style="color: #339933;">,</span> <span style="color: #000088;">$foo</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #666666; font-style: italic;">// output PNG object.</span>
      <span style="color: #990000;">imagePNG</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$image</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span></pre></div></div>

<p>Now we set variables based on the values specified in the original class we created.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">  <span style="color: #000088;">$text</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> textPNG<span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$msg</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000088;">$text</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>msg <span style="color: #339933;">=</span> <span style="color: #000088;">$msg</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// text to display</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$font</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000088;">$text</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>font <span style="color: #339933;">=</span> <span style="color: #000088;">$font</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// font to use (include directory if needed).</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$size</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000088;">$text</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>size <span style="color: #339933;">=</span> <span style="color: #000088;">$size</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// size in points</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$rot</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000088;">$text</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>rot <span style="color: #339933;">=</span> <span style="color: #000088;">$rot</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// rotation</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$pad</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000088;">$text</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>pad <span style="color: #339933;">=</span> <span style="color: #000088;">$pad</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// padding in pixels around text.</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$red</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000088;">$text</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>red <span style="color: #339933;">=</span> <span style="color: #000088;">$red</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// text color</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$grn</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000088;">$text</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>grn <span style="color: #339933;">=</span> <span style="color: #000088;">$grn</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// ..</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$blu</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000088;">$text</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>blu <span style="color: #339933;">=</span> <span style="color: #000088;">$blu</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// ..</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$bg_red</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000088;">$text</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>bg_red <span style="color: #339933;">=</span> <span style="color: #000088;">$bg_red</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// background color.</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$bg_grn</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000088;">$text</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>bg_grn <span style="color: #339933;">=</span> <span style="color: #000088;">$bg_grn</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// ..</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$bg_blu</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000088;">$text</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>bg_blu <span style="color: #339933;">=</span> <span style="color: #000088;">$bg_blu</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// ..</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$tr</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #000088;">$text</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>transparent <span style="color: #339933;">=</span> <span style="color: #000088;">$tr</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// transparency flag (boolean).</span></pre></div></div>

<p>These next two sections are specifically for my application, with a random tagline and font file. First, we read the text file and create an array, using each line as an array element. Then, we select a random element from the array and set it to a variable. The text file is stored in the same directory as the PHP page.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">  <span style="color: #666666; font-style: italic;">//get a random tagline from the text file</span>
  <span style="color: #000088;">$fname</span> <span style="color: #339933;">=</span> <span style="color: #990000;">file_get_contents</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'tags.txt'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$tagarray</span> <span style="color: #339933;">=</span> <span style="color: #990000;">explode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$fname</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$tagnum</span> <span style="color: #339933;">=</span> <span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$tagarray</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$line</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$tagarray</span><span style="color: #009900;">&#91;</span><span style="color: #990000;">rand</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span><span style="color: #000088;">$tagnum</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Second, the directory of fonts is read, and a random one is pulled from the list. You need to make sure to have the <span class="code">./</span> before the directory and filenames (assuming your font directory is a subdirectory of your PHP page).</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">  <span style="color: #666666; font-style: italic;">//get random font from ttf directory</span>
  <span style="color: #000088;">$dir</span> <span style="color: #339933;">=</span> <span style="color: #990000;">opendir</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;./ttf/&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$i</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">while</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$theFile</span> <span style="color: #339933;">=</span> <span style="color: #990000;">readdir</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$dir</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$theFile</span> <span style="color: #339933;">!=</span> <span style="color: #0000ff;">&quot;.&quot;</span> <span style="color: #339933;">&amp;</span>amp<span style="color: #339933;">;&amp;</span>amp<span style="color: #339933;">;</span> <span style="color: #000088;">$theFile</span> <span style="color: #339933;">!=</span> <span style="color: #0000ff;">&quot;..&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000088;">$array</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$i</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$theFile</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$i</span><span style="color: #339933;">++;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #990000;">closedir</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$dir</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$fontnum</span> <span style="color: #339933;">=</span> <span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$array</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000088;">$ttfLine</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$array</span><span style="color: #009900;">&#91;</span><span style="color: #990000;">rand</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span><span style="color: #000088;">$fontnum</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000088;">$ttf</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;./ttf/&quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$ttfLine</span><span style="color: #339933;">;</span></pre></div></div>

<p>Finally, we invoke the function to create the image, passing to it both the tagline and the font file.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">  <span style="color: #666666; font-style: italic;">//draw the image</span>
  <span style="color: #000088;">$text</span><span style="color: #339933;">-&amp;</span>gt<span style="color: #339933;">;</span>draw<span style="color: #009900;">&#40;</span><span style="color: #000088;">$line</span><span style="color: #339933;">,</span> <span style="color: #000088;">$ttf</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>Now, this is a little modified from the <a href="http://www.weberdev.com/get_example-1487.html">original code</a>. The code has the font and text variables set to static values. I wanted my code to randomly select both a font file and a tagline, so I stuck a bunch of fonts in a folder called <strong>ttf</strong>, and created a file named <strong>tags.txt</strong> with several taglines.</p>
<p>The <strong>ttf</strong> directory and <strong>tags.txt</strong> are both located in the same directory as the PHP file containing this code. Each tagline is on a separate line in the text file, so the loop looks for line breaks to indicate individual taglines.</p>
<p>You can call to the image just like you would any normal image file:</p>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;"><span style="color: #cc00cc;">#tagline</span> <span style="color: #00AA00;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">background</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">url</span><span style="color: #00AA00;">&#40;</span><span style="color: #ff0000; font-style: italic;">img/tagline.php</span><span style="color: #00AA00;">&#41;</span> <span style="color: #993333;">no-repeat</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span></pre></div></div>

<p>You&#8217;ll quickly discover that since IE 6 doesn&#8217;t support transparent PNGs, your image won&#8217;t look very good. This is easily solved with a <a href="http://www.twinhelix.com/css/iepngfix/">little hack that I discovered at twinhelix.com</a>. I couldn&#8217;t get the repeating background feature of the beta version to work properly, but it worked beautifully for this generated image.</p>
<p>IE 7 and up support transparent PNGs natively, so you only need to apply this for IE 6 and 5.5. If you&#8217;re already <a href="http://blog.abettergeek.com/?p=35">properly identifying the client browser and adding the appropriate stylesheet</a>, this is a breeze.</p>
<p>The possibilities for this script are pretty endless, and it can be tweaked to meet your specific needs. Happy coding!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.abettergeek.com/web-development/php-dynamically-generating-images-from-text/feed/</wfw:commentRss>
		</item>
		<item>
		<title>New site template!</title>
		<link>http://blog.abettergeek.com/personal-stuff/new-site-template/</link>
		<comments>http://blog.abettergeek.com/personal-stuff/new-site-template/#comments</comments>
		<pubDate>Sun, 14 Dec 2008 02:43:34 +0000</pubDate>
		<dc:creator>Claire</dc:creator>
		
		<category><![CDATA[Personal Stuff]]></category>

		<guid isPermaLink="false">http://blog.abettergeek.com/?p=62</guid>
		<description><![CDATA[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.
]]></description>
			<content:encoded><![CDATA[<p>I spent the better part of today redesigning the site. The new WP 2.7 interface kind of motivated me to revamp things.</p>
<p>Let me know what you think, if you find something broken, etc.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.abettergeek.com/personal-stuff/new-site-template/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Linux: Installing SSH2 for PHP5</title>
		<link>http://blog.abettergeek.com/software/linux-installing-ssh2-for-php5/</link>
		<comments>http://blog.abettergeek.com/software/linux-installing-ssh2-for-php5/#comments</comments>
		<pubDate>Fri, 12 Dec 2008 23:05:16 +0000</pubDate>
		<dc:creator>Claire</dc:creator>
		
		<category><![CDATA[Linux]]></category>

		<category><![CDATA[Open Source]]></category>

		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://blog.abettergeek.com/?p=51</guid>
		<description><![CDATA[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&#8217;t have [...]]]></description>
			<content:encoded><![CDATA[<p>I just installed WordPress 2.7 today. Boy, is it exciting! The entire interface is different, and things can be accomplished much more quickly.</p>
<p>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&#8217;t have an FTP server installed on my Linode, so I decided to see if I could use SSH instead.</p>
<p>Turns out it&#8217;s possible, but it sure was a beast to get up and running. I&#8217;ll go through what I did, in case anyone else had as much trouble with this as I did.</p>
<p>First off, you need to install <a href="http://pear.php.net/">PEAR</a>. This is a nifty little utility that can automatically compile PHP extensions.</p>
<p>Keep in mind that I&#8217;m working in Ubuntu 8.04.1 here, and my Linode installation is <strong>very</strong> stripped down.</p>
<p>First, you need to install the command-line interface for PHP, which allows you to run PHP scripts from a terminal.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> php5-cli</pre></div></div>

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

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> <span style="color: #c20cb9; font-weight: bold;">wget</span></pre></div></div>

<p>Once that&#8217;s done, we can install PEAR.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #000000; font-weight: bold;">/</span>
<span style="color: #c20cb9; font-weight: bold;">wget</span> http:<span style="color: #000000; font-weight: bold;">//</span>pear.php.net<span style="color: #000000; font-weight: bold;">/</span>go-pear <span style="color: #660033;">-O</span> go-pear.php
php go-pear.php</pre></div></div>

<p>Once the PEAR installation script is running, you need to configure the locations of each of the components. I chose to stick everything in <span class="code">/pear</span>, but you may want to put it somewhere else. I&#8217;d recommend keeping option 3 to my setting, though.</p>
<pre>1    /
2    /pear/temp
3    /bin
4    /pear
5    /pear/docs
6    /pear/data
7    /pear/tests</pre>
<p>Now that PEAR is installed, we can get into installing OpenSSL and the necessary packages to make it work with PHP.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> openssl
<span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> lsh-client
<span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> libssh2-<span style="color: #000000;">1</span>
<span style="color: #c20cb9; font-weight: bold;">apt-get</span> <span style="color: #c20cb9; font-weight: bold;">install</span> libssh2-<span style="color: #000000;">1</span>-dev</pre></div></div>

<p>With our libraries and packages installed, we can compile our ssh2 extension for PHP.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">pecl <span style="color: #c20cb9; font-weight: bold;">install</span> <span style="color: #660033;">-f</span> ssh2-beta</pre></div></div>

<p>Finally, we need to add the extension to php.ini.</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">nano</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>php5<span style="color: #000000; font-weight: bold;">/</span>apache<span style="color: #000000; font-weight: bold;">/</span>php.ini</pre></div></div>

<p>Find the section titled &#8220;Extensions&#8221; and add this line:</p>
<pre>extension=ssh2.so</pre>
<p>And restart Apache:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">apache2ctl <span style="color: #660033;">-k</span> graceful</pre></div></div>

<p>In your WordPress admin interface, you should now see an &#8220;SSH&#8221; 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&#8217;s credentials to authenticate to the server.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.abettergeek.com/software/linux-installing-ssh2-for-php5/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Guest post: Checking user permissions on a Windows network</title>
		<link>http://blog.abettergeek.com/maximizing-windows/guest-post-checking-user-permissions-on-a-windows-network/</link>
		<comments>http://blog.abettergeek.com/maximizing-windows/guest-post-checking-user-permissions-on-a-windows-network/#comments</comments>
		<pubDate>Wed, 19 Nov 2008 15:58:43 +0000</pubDate>
		<dc:creator>Claire</dc:creator>
		
		<category><![CDATA[Guest Posts]]></category>

		<category><![CDATA[Maximizing Windows]]></category>

		<category><![CDATA[Open Source]]></category>

		<category><![CDATA[Software]]></category>

		<category><![CDATA[Windows]]></category>

		<guid isPermaLink="false">http://blog.abettergeek.com/?p=45</guid>
		<description><![CDATA[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. [...]]]></description>
			<content:encoded><![CDATA[<p>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.</p>
<p>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.</p>
<p>Microsoft has a utility called <strong>xcacls.vbs</strong> (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 &#8220;<strong>xcacls c:\windows</strong>&#8221; 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).</p>
<p>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).</p>
<p>What I was looking for was basically a text file that just had all the folders. This command will create exactly that:</p>

<div class="wp_syntax"><div class="code"><pre class="winbatch" style="font-family:monospace;">dir <span style="color: #ff0000;">&quot;c:\program files&quot;</span> <span style="color: #66cc66;">/</span>s <span style="color: #66cc66;">/</span>b <span style="color: #66cc66;">/</span>o<span style="color: #FF1010; font-weight: bold;">:gn /a:d &amp;gt; c:\batch\xcacls\dirlist.txt</span></pre></div></div>

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

<div class="wp_syntax"><div class="code"><pre class="winbatch" style="font-family:monospace;"><span style="color: #800080;">For</span> <span style="color: #66cc66;">/</span>F <span style="color: #ff0000;">&quot;tokens=*&quot;</span> <span style="color: #66cc66;">%%</span>i <span style="color: #800080;">in</span> <span style="color: #66cc66;">&#40;</span>dirlist.txt<span style="color: #66cc66;">&#41;</span> do c<span style="color: #FF1010; font-weight: bold;">:\batch\xcacls\aclSearch.bat administrator %%i</span></pre></div></div>

<p><strong>C:\batch\xcacls\aclSearch.bat</strong> 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).</p>
<p>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.</p>
<p><strong>aclSearch.bat</strong> contains the following</p>

<div class="wp_syntax"><div class="code"><pre class="winbatch" style="font-family:monospace;"><span style="color: #800080;">call</span> c<span style="color: #FF1010; font-weight: bold;">:\batch\xcacls\xcacls.vbs &quot;%2&quot; &amp;gt; c:\batch\xcacls\xcaclsResults.txt</span>
&nbsp;
find <span style="color: #66cc66;">/</span>i <span style="color: #66cc66;">%</span>1 c<span style="color: #FF1010; font-weight: bold;">:\batch\xcacls\xcaclsResults.txt</span>
&nbsp;
<span style="color: #800080;">if</span> <span style="color: #66cc66;">%</span>errorlevel<span style="color: #66cc66;">%</span>==<span style="color: #cc66cc;">0</span> <span style="color: #800080;">goto</span> Found
&nbsp;
<span style="color: #800080;">goto</span> <span style="color: #800080;">End</span>
&nbsp;
<span style="color: #FF1010; font-weight: bold;">:Found</span>
&nbsp;
echo <span style="color: #66cc66;">%</span>2 <span style="color: #66cc66;">&amp;</span>gt<span style="color: #008000; font-style: italic;">;&amp;gt;c:\batch\xcacls\%1results.txt</span>
&nbsp;
<span style="color: #FF1010; font-weight: bold;">:End</span></pre></div></div>

<p>This calls <strong>xcacls.vbs</strong> (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 <strong>xcaclsResults.txt</strong></p>
<p>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 <strong>administratorresults.txt</strong>).</p>
<p>So, how do you actually use all this?  <strong>FindPermission.bat</strong> contains:</p>

<div class="wp_syntax"><div class="code"><pre class="winbatch" style="font-family:monospace;">dir <span style="color: #66cc66;">%</span>1 <span style="color: #66cc66;">/</span>s <span style="color: #66cc66;">/</span>b <span style="color: #66cc66;">/</span>o<span style="color: #FF1010; font-weight: bold;">:gn /a:d&amp;gt;&quot;c:\batch\xcacls\dirlist.txt&quot;</span>
&nbsp;
<span style="color: #800080;">for</span> <span style="color: #66cc66;">/</span>F <span style="color: #ff0000;">&quot;tokens=*&quot;</span> <span style="color: #66cc66;">%%</span>i <span style="color: #800080;">in</span> <span style="color: #66cc66;">&#40;</span>dirlist.txt<span style="color: #66cc66;">&#41;</span> do c<span style="color: #FF1010; font-weight: bold;">:\batch\xcacls\aclSearch.bat %2 %%i</span></pre></div></div>

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

<div class="wp_syntax"><div class="code"><pre class="winbatch" style="font-family:monospace;">Findpermission.bat <span style="color: #ff0000;">&quot;c:\program files&quot;</span> administrators</pre></div></div>

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

<div class="wp_syntax"><div class="code"><pre class="winbatch" style="font-family:monospace;">Findpermission.bat c<span style="color: #FF1010; font-weight: bold;">:\ &quot;Danny Parrott&quot;</span></pre></div></div>

<p>The results from this one will be in <strong>Danny Parrottresults.txt</strong>.</p>
<p>This does require that <strong>Findpermission.bat</strong>, <strong>aclSearch.bat</strong>, and <strong>xcacls.vbs</strong> 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.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.abettergeek.com/maximizing-windows/guest-post-checking-user-permissions-on-a-windows-network/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Coldfusion 8 and Microsoft SQL 2005 : @@IDENTITY</title>
		<link>http://blog.abettergeek.com/web-development/coldfusion-8-and-microsoft-sql-2005-identity/</link>
		<comments>http://blog.abettergeek.com/web-development/coldfusion-8-and-microsoft-sql-2005-identity/#comments</comments>
		<pubDate>Wed, 12 Nov 2008 16:51:52 +0000</pubDate>
		<dc:creator>Claire</dc:creator>
		
		<category><![CDATA[ColdFusion]]></category>

		<category><![CDATA[Microsoft SQL]]></category>

		<category><![CDATA[PHP]]></category>

		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://blog.abettergeek.com/?p=44</guid>
		<description><![CDATA[There&#8217;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 &#40;
    Name
  &#41; VALUES &#40;
    'Joe'
  &#41;;
  SELECT @@IDENTITY AS NewName;

This query will [...]]]></description>
			<content:encoded><![CDATA[<p>There&#8217;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:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span>
  People <span style="color: #66cc66;">&#40;</span>
    Name
  <span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span>
    <span style="color: #ff0000;">'Joe'</span>
  <span style="color: #66cc66;">&#41;</span>;
  <span style="color: #993333; font-weight: bold;">SELECT</span> @@IDENTITY <span style="color: #993333; font-weight: bold;">AS</span> NewName;</pre></div></div>

<p>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.</p>
<p>We recently upgraded to ColdFusion 8 here at Purdue, and my code started breaking.</p>
<p>It turns out that CF8 attempts to &#8220;help&#8221; you by automatically running <strong>SELECT @@IDENTITY</strong> after any <strong>INSERT</strong> query. This is problematic in two ways - it cancels out your own <strong>@@IDENTITY</strong> query, and it arbitrarily names the result <strong>Generated_Keys</strong>.</p>
<p>So instead of being able to do something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="cfm" style="font-family:monospace;"><span style="color: #333333;"><span style="color: #0000FF;">&lt;</span><span style="color: #990000; font-weight: bold;">cfset</span> TheNewName <span style="color: #0000FF;">=</span> People.NewName<span style="color: #0000FF;">&gt;</span></span></pre></div></div>

<p>You must use this:</p>

<div class="wp_syntax"><div class="code"><pre class="cfm" style="font-family:monospace;"><span style="color: #333333;"><span style="color: #0000FF;">&lt;</span><span style="color: #990000; font-weight: bold;">cfset</span> TheNewName <span style="color: #0000FF;">=</span> People.Generated_Keys<span style="color: #0000FF;">&gt;</span></span></pre></div></div>

<p>It&#8217;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 <strong>SELECT @@IDENTITY</strong> query is already present.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.abettergeek.com/web-development/coldfusion-8-and-microsoft-sql-2005-identity/feed/</wfw:commentRss>
		</item>
		<item>
		<title>When troubleshooting gets creative</title>
		<link>http://blog.abettergeek.com/hardware/when-troubleshooting-gets-creative/</link>
		<comments>http://blog.abettergeek.com/hardware/when-troubleshooting-gets-creative/#comments</comments>
		<pubDate>Wed, 29 Oct 2008 13:08:23 +0000</pubDate>
		<dc:creator>Claire</dc:creator>
		
		<category><![CDATA[Hardware]]></category>

		<guid isPermaLink="false">http://blog.abettergeek.com/?p=43</guid>
		<description><![CDATA[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 [...]]]></description>
			<content:encoded><![CDATA[<p>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&#8217;t work. Plugging them in resulted in a &#8220;one of the devices connected has malfunctioned&#8221; error from Windows. His thumb drive appeared to work just fine in Ubuntu Linux.</p>
<p>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.</p>
<p>I started Googling around and found <a href="http://skeptacles.blogspot.com/2006/10/xp-sis-pci-to-usb-enhanced-host.html">this article</a> regarding my exact problem - the <strong>SiS PCI to USB Enhanced Host Controller</strong> mysteriously quit working, and took all USB 2.0 devices down with it. This blogger&#8217;s solution was to shutdown <strong>and</strong> unplug the computer, wait for about half an hour, hold in the power button for a minute, and then restart the machine.</p>
<p>And, like magic&#8230;it worked.</p>
<p>I can only begin to guess why. Like this other blogger, my neighbor&#8217;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.</p>
<p>By letting the machine sit for awhile, all the capacitors on the motherboard and power supply emptied out, thereby <em>completely</em> cutting power to the machine. This apparently reset whatever dark magic was causing the problem in the first place.</p>
<p>It&#8217;s likely that in Matt&#8217;s case, Linux was allowing the ports to work, but only at 1.1 speeds. Since we didn&#8217;t test how quickly file transfers took place in Linux, I can&#8217;t confirm this theory, but it would fit with my above assumptions.</p>
<p>At any rate, now we have our answer. The next time this happens (and I imagine it will), <a href="http://www.usbman.com/Guides/SiS%20USB%20Tips%20and%20Tricks.htm">I&#8217;ll try the fixes listed on usbman.com</a> first, so we can try to cure the problem once and for all.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.abettergeek.com/hardware/when-troubleshooting-gets-creative/feed/</wfw:commentRss>
		</item>
		<item>
		<title>OS X : VNC from the command line</title>
		<link>http://blog.abettergeek.com/software/os-x-vnc-from-the-command-line/</link>
		<comments>http://blog.abettergeek.com/software/os-x-vnc-from-the-command-line/#comments</comments>
		<pubDate>Mon, 27 Oct 2008 12:53:51 +0000</pubDate>
		<dc:creator>Claire</dc:creator>
		
		<category><![CDATA[OS X]]></category>

		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://blog.abettergeek.com/?p=42</guid>
		<description><![CDATA[Since OS X 10.4 (Tiger), Apple has provided a remote desktop 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&#8217;t recommend using Apple&#8217;s VNC server; it&#8217;s far more restrictive than alternatives. Vine server [...]]]></description>
			<content:encoded><![CDATA[<p>Since OS X 10.4 (Tiger), Apple has provided a remote desktop 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.</p>
<p>I wouldn&#8217;t recommend using Apple&#8217;s VNC server; it&#8217;s far more restrictive than alternatives. <a title="Vine Server on SourceForge" href="http://sourceforge.net/projects/osxvnc/">Vine server</a> is much more robust and customizable, and it&#8217;s open-source.</p>
<p>However, if you find it necessary to use Apple&#8217;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).</p>
<p>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&#8217;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.</p>
<p>The Perl script looks like this:</p>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;">perl <span style="color: #339933;">-</span>nwe <span style="color: #ff0000;">'BEGIN { @k = unpack &quot;C*&quot;, pack &quot;H*&quot;, &quot;1734516E8BA8C5E2FF1C39567390ADCA&quot;}; \
chomp; s/^(.{8}).*/$1/; @p = unpack &quot;C*&quot;, $_; foreach (@k) { printf &quot;%02X&quot;, $_ ^ (shift @p || 0) }; print &quot;\n&quot;'</span></pre></div></div>

<p>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 <strong>kickstart</strong> command to restart the VNC server. Apple has some documentation on using kickstart <a href="http://support.apple.com/kb/HT2370">here</a>.</p>
<p>Overall, Apple made a major blunder by not correctly encoding the password with the kickstart utility. Hopefully this will be remedied in a future release of OS X.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.abettergeek.com/software/os-x-vnc-from-the-command-line/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
