<?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/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Southern Bread &#187; programming</title>
	<atom:link href="http://www.southernbread.org/tag/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.southernbread.org</link>
	<description>Southern History, American Freedom, Christian Liberty</description>
	<lastBuildDate>Sat, 04 Feb 2012 21:12:04 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>MIDI Programming in Windows</title>
		<link>http://www.southernbread.org/midi-programming-in-windows/</link>
		<comments>http://www.southernbread.org/midi-programming-in-windows/#comments</comments>
		<pubDate>Sun, 07 Jan 2007 22:13:00 +0000</pubDate>
		<dc:creator>Dave</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.southernbread.org/programming/windows_midi_functions.html</guid>
		<description><![CDATA[I recently wrote a guitar tuner app called FrequentZ that uses the short MIDI functions of Windows to generate it&#8217;s tones. I thought I would show everyone how it&#8217;s done in case you would like to incorporate some MIDI functionality into your own software. The best resource for Windows MIDI programming on the web is [...]]]></description>
			<content:encoded><![CDATA[<p>I recently wrote a guitar tuner app called <a href="/cgi-bin/pl.cgi/software/frequentz.html">FrequentZ</a> that uses the short MIDI functions of Windows to generate it&#8217;s tones.  I thought I would show everyone how it&#8217;s done in case you would like to incorporate some MIDI functionality into your own software.  The best resource for Windows MIDI programming on the web is found <a href="http://www.borg.com/~jglatt/tech/winapi.htm">here</a>, so if you want to do something more complex, see that reference first.  But, if your goals are more modest like mine were then you can probably get by with just a few of the MIDI functions that Windows has to offer.  All of the code will be in masm32.</p>
<p>Here is the basic code you&#8217;ll need to generate some tones:</p>
<div class="code"><pre><pre>
...
;## Include the multimedia libraries
include&nbsp;&nbsp; winmm.inc
includelib&nbsp;&nbsp; winmm.lib

.data
AGUITAR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dd&nbsp;&nbsp;0000018C0h&nbsp;&nbsp;;## Acoustic Guitar
dwMidiMessage&nbsp;&nbsp; dd&nbsp;&nbsp;0007F2890h&nbsp;&nbsp;;## E Note

.data?
hMidi&nbsp;&nbsp; HANDLE&nbsp;&nbsp;?

.code
...
;## Open a handle to the MIDI device
invoke&nbsp;&nbsp;MIDIOutOpen, ADDR hMidi, MIDI_MAPPER, 0, 0, 0
mov&nbsp;&nbsp;&nbsp;&nbsp; hMidi, eax

;## Change patch number
invoke&nbsp;&nbsp;MIDIOutShortMsg, hMidi, AGUITAR

;## Create a note-off MIDI message
mov&nbsp;&nbsp;&nbsp;&nbsp; eax, dwMidiMessage
mov&nbsp;&nbsp;&nbsp;&nbsp; edx, 0FFFFFF80h
and&nbsp;&nbsp;&nbsp;&nbsp; edx, eax
mov&nbsp;&nbsp;&nbsp;&nbsp; dwMidiOffMessage, edx 

;## Send a message to play the note
invoke&nbsp;&nbsp;MIDIOutShortMsg, hMidi, dwMidiMessage
invoke&nbsp;&nbsp;Sleep, 2000&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
invoke&nbsp;&nbsp;MIDIOutShortMsg, hMidi, dwMidiOffMessage

;## Close the handle
invoke&nbsp;&nbsp;MIDIOutClose, hMidi
...
</pre></pre></div>
<p>So here&#8217;s what&#8217;s happening.  We declare two 32-bit values to hold the MIDI patch number we want to use (AGUITAR) and the note we want to play (E).  In the main code we first open a handle to the Windows MIDI mapper device by calling <b>MIDIOutOpen</b> and then change the patch number to 24 wich is supposed to sound like an acoustic guitar.  Next, we create a MIDI message to turn the note off.  We do this by ANDing the 32-bit MIDI note-on message with a bitmask that will leave everything the same except change the last byte to 128 (80h).  The bitwise AND operator compares bits and returns a 1 if both the source AND destination bits are 1.  Otherwise it returns 0.  It works like this for us:</p>
<table style="background-color:white; border:solid black 1px;">
<tr>
<td><b>90h</b></td>
<td>1</td>
<td>0</td>
<td>0</td>
<td>1</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
</tr>
<tr>
<td><b>80h</b></td>
<td>1</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
</tr>
<tr>
<td><b> = </b></td>
<td>1</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
</tr>
</table>
<p>And because the remaining 24 bits of the destination value are all 1&#8217;s (FFFFFF), the rest of the MIDI message is preserved.</p>
<p>Finally, we send the message to play the note using <b>MIDIOutShortMsg</b>, sleep for a couple of seconds to make sure the note has time to play and then turn the note back off with another call.  Last thing to do is to close the handle when you&#8217;re finished.  It&#8217;s a good idea to look all of these functions up in the <a href="http://msdn2.microsoft.com/en-us/library/ms711640.aspx">Windows multimedia API</a> because they have a description in there about how the MIDI message byte order should be arranged.  The other thing to note is that if you are triggering these notes from a GUI element like a button, then you should really fire off a second thread to handle playing the note.  Otherwise, your GUI interface will hang because of the <b>Sleep</b> call.  That&#8217;s very annoying.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.southernbread.org/midi-programming-in-windows/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SQL Injection Defense &#8211; Part I (Authentication)</title>
		<link>http://www.southernbread.org/sql-injection-defense-part-i-authentication/</link>
		<comments>http://www.southernbread.org/sql-injection-defense-part-i-authentication/#comments</comments>
		<pubDate>Wed, 27 Sep 2006 11:31:00 +0000</pubDate>
		<dc:creator>Dave</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[sql injection]]></category>

		<guid isPermaLink="false">http://www.southernbread.org/programming/1149998399.html</guid>
		<description><![CDATA[I want to do a couple of posts on SQL injection attack prevention. I am going to show some of the techniques I use to ward them off. For example, we use a three pronged approach at the authentication point: variable binding, row counting, and syntax detection. When a username and password are entered on [...]]]></description>
			<content:encoded><![CDATA[<p>I want to do a couple of posts on SQL injection attack prevention.  I<br />
am going to show some of the techniques I use to ward them off.  For example,<br />
we use a three pronged approach at<br />
the authentication point:  variable binding, row counting, and syntax<br />
detection.  When a username and password are entered on the login form<br />
we check to make sure that there is nothing obviously wrong with the<br />
input, like password being of acceptable length and such.  The next<br />
thing we do is check to make sure there is no known SQL syntax within<br />
the username or password.  For example, if someone inputs a password<br />
like this:</p>
<p><pre><code>
&amp;#8217; OR 1=1
</code></pre></p>
<p>it will get rejected at this step.  All of the SQL keywords are<br />
stored in big lookup table and checked against.  The next step then is<br />
to bind the variables instead of passing them in as plain strings.  This<br />
is a crucial step to avoid SQL injection.  So instead of:</p>
<p><pre><code>
$sql=&quot;SELECT * FROM users WHERE username=&quot;$username&quot; AND 
password=&quot;$password&quot; LIMIT 1
</code></pre></p>
<p>we use:</p>
<p><pre><code>
$sql=&quot;SELECT * FROM users WHERE username=? AND password=? LIMIT 1
$sth=$dbh-&gt;prepare($sql);
$sth-&gt;execute($username,$password);
</code></pre></p>
<p>The final thing we do is check the row count of the result set.  Even<br />
though we used &#8220;LIMIT 1&#8243;, if there is an injection going on then we must<br />
assume that it has been changed.  Be sure and check that you have a row<br />
count that is sane for the operation you are performing.  If you are<br />
logging someone in then you should return an error if the result count<br />
is 0 or greater than 1, like this:</p>
<p><pre><code>
die unless($sth-&gt;rows() eq 1);
</code></pre></p>
<p>Next time I&#8217;ll focus on SQL injection that happens beyond the front<br />
gate.  Sometimes you can&#8217;t be so strict on row counts and syntax checks<br />
once a user is inside.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.southernbread.org/sql-injection-defense-part-i-authentication/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>NumPad &#8211; Pad Numbers in Filenames</title>
		<link>http://www.southernbread.org/numpad-pad-numbers-in-filenames/</link>
		<comments>http://www.southernbread.org/numpad-pad-numbers-in-filenames/#comments</comments>
		<pubDate>Fri, 22 Sep 2006 20:33:00 +0000</pubDate>
		<dc:creator>Dave</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[mp3]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://www.southernbread.org/software/numpad.html</guid>
		<description><![CDATA[One of the most annoying things with mp3&#8217;s (other than DRM of course) is consecutive numbering. The sort algorithm on Windows and most mp3 players sorts as it goes through the filename one character at a time. So if you have 12 files named &#8220;file-1.mp3 &#8230; file-12.mp3&#8243;, they will sort like this: file-1.mp3 file-10.mp3 file-11.mp3 [...]]]></description>
			<content:encoded><![CDATA[<p>One of the most annoying things with mp3&#8217;s (other than DRM of course) is consecutive numbering.  The sort algorithm on Windows and most mp3 players sorts as it goes through the filename one character at a time.  So if you have 12 files named &#8220;file-1.mp3 &#8230; file-12.mp3&#8243;, they will sort like this:</p>
<div class="code"><pre><pre>
file-1.mp3
file-10.mp3
file-11.mp3
file-12.mp3
file-2.mp3
file-3.mp3
file-4.mp3
file-5.mp3
file-6.mp3
file-7.mp3
file-8.mp3
file-9.mp3
</pre></pre></div>
<p>That is obviously not what anybody wants.  To correct this, consecutively numbered files must be zero-padded in order to sort correctly.  So the previous list would need to look like this:</p>
<div class="code"><pre><pre>
file-01.mp3
file-02.mp3
file-03.mp3
file-04.mp3
file-05.mp3
file-06.mp3
file-07.mp3
file-08.mp3
file-09.mp3
file-10.mp3
file-11.mp3
file-12.mp3
</pre></pre></div>
<p>I run into this problem often enough that I started looking around for software that would pad the numbers in filenames automatically for me.  I couldn&#8217;t find anything out there that would do it in an automated fashion so I wrote a perl script to do it.  I wrote it in Perl so that I could run it under Linux as well.  I frequently need to have jpeg&#8217;s consecutively numbered as well so that was important.  Here is the script:</p>
<div class="code"><pre><pre>
#!/usr/bin/perl

use strict;
use warnings;

my $dirname = $ARGV[0] || &quot;&quot;;
my $change&nbsp;&nbsp;= $ARGV[1] || &quot;no&quot;;
my $ext&nbsp;&nbsp;&nbsp;&nbsp; = $ARGV[2] || &quot;.mp3&quot;;
my $padsize = $ARGV[3] || 4;

##: Give usage if no arguments are defined
if ($dirname eq &quot;&quot;) {
&nbsp;&nbsp;print STDOUT &quot;Usage: numpad.pl \&quot;directory\&quot; [change?] [.ext] [padsize]\n&quot;;
&nbsp;&nbsp;print STDOUT &quot;&nbsp;&nbsp;[change?] - default is \&quot;no\&quot; - should I actually rename the file\n&quot;;&nbsp;&nbsp;
&nbsp;&nbsp;print STDOUT &quot;&nbsp;&nbsp;[.ext] - default is \&quot;.mp3\&quot; - what files should be acted upon\n&quot;;
&nbsp;&nbsp;print STDOUT &quot;&nbsp;&nbsp;[padsize] - default is \&quot;4\&quot; - how many digits should I pad to\n&quot;;
&nbsp;&nbsp;print STDOUT &quot;\n&quot;;
&nbsp;&nbsp;print STDOUT &quot;Example:\n&quot;;
&nbsp;&nbsp;print STDOUT &quot;&nbsp;&nbsp;numpad.pl \&quot;c:\\mp3\\album\&quot; yes .wav 5\n&quot;;
&nbsp;&nbsp;exit(1);
}

##: Change to the directory asked for
chdir($dirname) or die &quot;Couldn&amp;#8217;t change to directory &amp;#8217;$dirname&amp;#8217;: $!&quot;;

##: Open and read in the directory based on the fileglob given
opendir(DIR, &quot;$dirname&quot;) or die &quot;Couldn&amp;#8217;t open directory &amp;#8217;$dirname&amp;#8217;: $!&quot;;
my @files = grep { /.*$ext/ } readdir(DIR);
closedir DIR;

##: Loop through the file entries and mod them
foreach my $file (@files) {
&nbsp;&nbsp;my $newfilename=&quot;&quot;;

&nbsp;&nbsp;##: Cut off the extension, to be put back on later
&nbsp;&nbsp;$file =~ s/$ext//g;

&nbsp;&nbsp;##: Split the filename into an array using any number as a separator
&nbsp;&nbsp;my @fnparts = split(/([0-9]*)/, $file);

&nbsp;&nbsp;##: Loop through the array and pad any numerical elements
&nbsp;&nbsp;foreach (@fnparts) {
&nbsp;&nbsp;&nbsp;&nbsp;my $result = $_;
&nbsp;&nbsp;&nbsp;&nbsp;my $number = 0;
&nbsp;&nbsp;&nbsp;&nbsp;if($result =~ m/[0-9]+/) {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$number = sprintf(&quot;%0&quot;.$padsize.&quot;d&quot;, $result);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$newfilename.=$number;
&nbsp;&nbsp;&nbsp;&nbsp;} else {
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$newfilename.=$result;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;}
&nbsp;&nbsp;$newfilename.=$ext;
&nbsp;&nbsp;$file.=$ext;
&nbsp;&nbsp;print STDOUT &quot;$file\n&nbsp;&nbsp;-&gt; $newfilename\n&quot;;
&nbsp;&nbsp;if($change eq &quot;yes&quot;) {
&nbsp;&nbsp;&nbsp;&nbsp;rename($file, $newfilename);
&nbsp;&nbsp;}
}
</pre></pre></div>
<p>Just save this code as a file named <b>numpad.pl</b>.  If you run it on Windows, you will have to either install a perl interpereter first(get the <a href="http://www.activestate.com/store/activeperl/download/">MSI package from ActiveState</a>) or download the native executable version below that was compiled with <a href="http://www.indigostar.com">Perl2Exe</a>.  If you use the interpreter method you would need to execute perl and pass the script name to it as the first argument.  Like this:</p>
<div class="code"><pre><pre>
c:\&gt; perl numpad.pl &quot;c:\mp3\album&quot; yes .wav 5
</pre></pre></div>
<p>That example would zero-pad all the files in the <i>c:\mp3\album</i> directory that end with <i>.wav</i>, making any number it finds in a filename at least <i>5</i> digits long.  This script should handle any files you give it; not just mp3&#8217;s.  You can also re-run it with a different padding amount and it will redo the padding if you put too many on the first time.  If you tell it &#8220;no&#8221; as the second argument, it will just show you what it would do instead of actually doing it.  As always, <b>USE AT YOUR OWN RISK!</b></p>
<ul>
<li>Native Exe Version: <a href="/downloads/numpad.exe">numpad.exe</a></li>
<li>Perl Source Version: <a href="/downloads/numpad">numpad</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.southernbread.org/numpad-pad-numbers-in-filenames/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fixing HTML Markup Problems</title>
		<link>http://www.southernbread.org/fixing-html-markup-problems/</link>
		<comments>http://www.southernbread.org/fixing-html-markup-problems/#comments</comments>
		<pubDate>Sat, 23 Sep 2006 09:22:00 +0000</pubDate>
		<dc:creator>Dave</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[xhtml]]></category>

		<guid isPermaLink="false">http://www.southernbread.org/programming/fixing_markup_problems.html</guid>
		<description><![CDATA[Every webmaster that is concerned with standards compliance has to constantly keep their site validated. I strive to keep this site compliant with the XHTML 1.0 Strict specification and that means a trip to the W3C validator every time I make a change to the site. One of the constant annoyances with the XHTML Strict [...]]]></description>
			<content:encoded><![CDATA[<p>Every webmaster that is concerned with standards compliance has to constantly keep their site validated.  I strive to keep this site compliant with the XHTML 1.0 Strict specification and that means a trip to the W3C validator every time I make a change to the site.  One of the constant annoyances with the XHTML Strict specs are character set issues and closing unary tags.  I have eased my burden a little by putting in a plugin to my blog software to fix those problems right before the page is rendered.  That means even if I mis-type something in a blog post it won&#8217;t keep the site from validating, because it gets fixed at display-time.</p>
<p>Here is what the meat of the plugin looks like:</p>
<p><pre><code>
&nbsp;&nbsp;##: Tag fixes
&nbsp;&nbsp;$$body_ref =~ s/\&lt;br([^\/]*?)\&gt;/\&lt;br$1\/\&gt;/gi;
&nbsp;&nbsp;$$body_ref =~ s/\&lt;hr([^\/]*?)\&gt;/\&lt;hr$1\/\&gt;/gi;
&nbsp;&nbsp;
&nbsp;&nbsp;##: Character code fixes
&nbsp;&nbsp;$$body_ref =~ s/\&amp;#8217;/\&amp;\#8217\;/gi;
&nbsp;&nbsp;$$body_ref =~ s/\x93/\&amp;\#8220\;/gi;
&nbsp;&nbsp;$$body_ref =~ s/\x94/\&amp;\#8221\;/gi;&nbsp;&nbsp;
&nbsp;&nbsp;$$body_ref =~ s/\x92/\&amp;\#8217\;/gi;
&nbsp;&nbsp;$$body_ref =~ s/\x91/\&amp;\#8217\;/gi;
&nbsp;&nbsp;$$body_ref =~ s/\x85/\.\.\./gi;
&nbsp;&nbsp;$$body_ref =~ s/\x96/-/gi;
</code></pre></p>
<p>You can get the gist of it I hope.  The <b>$$body_ref</b> variable just contains the contents of the current blog post that is being assembled.  Each line performs a regex search/replace operation and corrects a potential markup problem.  The top 2 lines fix the 2 most common problems I run into with unary tag closing.  They add closing forward-slash&#8217;s to the <b>br</b> and <b>hr</b> html tags.  Those are the ones I forget most often.  You might need to include the <b>img</b> tag also if it&#8217;s a problem for you.</p>
<p>The character code fixes are needed to fix those &#8220;non SGML character number&#8221; messages that annoy the crap out of everybody.  They usually sneak in when you do a copy/paste operation off of a webpage and stick it in your blog post.  If you&#8217;re not familiar with regex syntax, the <b>x00</b> in the search string is an octal notation.  It means to replace every occurence of that character code with the appropriate html entity name that makes it compliant with XHTML.  In my opinion, HTML entity names are the easiest and most readable route to take in this situation.  The ones I listed above are the most common for me, but you can find a more complete list <a href="http://www.ascii.cl/htmlcodes.htm">here</a>.</p>
<p>This is not all just to make you feel better about being an open standards fanboy.  It has a real purpose.  For instance, if your site is listed on one of the standards compliance list sites like <a href="http://www.w3csites.com">W3CSites</a>, you don&#8217;t want to get delisted just because you forgot to close a <b>br</b> tag on one of your blog posts.  This just adds another layer of protection against that happening.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.southernbread.org/fixing-html-markup-problems/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Config::Tiny</title>
		<link>http://www.southernbread.org/configtiny/</link>
		<comments>http://www.southernbread.org/configtiny/#comments</comments>
		<pubDate>Fri, 25 Aug 2006 09:22:00 +0000</pubDate>
		<dc:creator>Dave</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.southernbread.org/linux/config_tiny.html</guid>
		<description><![CDATA[I have a few mod_perl web apps that I maintain for my employer. One of the problems that you run into with any web app is the proper placement of global configuration parameters within the application. I&#8217;m talking about things such as database hostname, database login credentials, query timeout parameters, etc. Since a web application [...]]]></description>
			<content:encoded><![CDATA[<p>I have a few <a href="http://perl.apache.org">mod_perl</a> web apps that I maintain for my employer.  One of the problems that you run into with any web app is the proper placement of global configuration parameters within the application.  I&#8217;m talking about things such as database hostname, database login credentials, query timeout parameters, etc.  Since a web application is stateless(each reply/request cycle is atomic) you have to make these global variables available from within each of your modules independently, but in a way that still let&#8217;s you have only a single point of administration for changing them.  Here is the method I use for handling this situation.</p>
<p>I use the cpan module <a href="http://search.cpan.org/dist/Config-Tiny/lib/Config/Tiny.pm">Config::Tiny</a> and create a new module that handles returning the current global configuration data whenever it&#8217;s functions are called.  Config::Tiny reads an INI style configuration file, and since it reads this file each time it&#8217;s called, you don&#8217;t have to bounce your apache process just to make a configuration change.  Here is a mock example of a file that Config::Tiny might read:</p>
<div class="code"><pre><pre>
##: Config file

[database]
type=mysql
server=mysql.domain.com
user=username
pass=password
database=mywebapp

[global]
expires=86400
maxusers=5
</pre></pre></div>
<p>You could save this file as /etc/mywebapp.conf and that would become the administrative point for any configuration changes to your app.  Now here is a look at the module(I&#8217;m assuming you are familiar with module creation, if not look <a href="http://mathforum.org/~ken/perl_modules.html">here</a>) you would use to retrieve that data from the config file and hand it to your application:</p>
<div class="code"><pre><pre>
package mywebapp::Conf;

#use 5.008;
use strict;
use warnings;

require Exporter;

our @ISA = qw(Exporter);
our %EXPORT_TAGS = ( &amp;#8217;all&amp;#8217; =&gt; [ qw() ] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{&amp;#8217;all&amp;#8217;} } );
our @EXPORT = qw(
&nbsp;&nbsp;get_db_config
);

our $VERSION = &amp;#8217;0.01&amp;#8217;;

sub get_db_config {
&nbsp;&nbsp;use Config::Tiny;

&nbsp;&nbsp;##: Hash ref to return
&nbsp;&nbsp;my $dbase;

&nbsp;&nbsp;##: Open the config file
&nbsp;&nbsp;my $config=Config::Tiny-&gt;read(&amp;#8217;/etc/mywebapp.conf&amp;#8217;);

&nbsp;&nbsp;##: Get values
&nbsp;&nbsp;$dbase-&gt;{&amp;#8217;type&amp;#8217;}=$config-&gt;{database}-&gt;{type};
&nbsp;&nbsp;$dbase-&gt;{&amp;#8217;server&amp;#8217;}=$config-&gt;{database}-&gt;{server};
&nbsp;&nbsp;$dbase-&gt;{&amp;#8217;user&amp;#8217;}=$config-&gt;{database}-&gt;{user};
&nbsp;&nbsp;$dbase-&gt;{&amp;#8217;pass&amp;#8217;}=$config-&gt;{database}-&gt;{pass};
&nbsp;&nbsp;$dbase-&gt;{&amp;#8217;database&amp;#8217;}=$config-&gt;{database}-&gt;{database};

&nbsp;&nbsp;return($dbase);
}

1;
__END__
</pre></pre></div>
<p>So now we have a module who&#8217;s subroutines we can call from within our mod_perl modules.  But this method is not restricted to only mod_perl.  Since we created a generic perl module, we can call it from any perl script.  For example sometimes you might have to get access to this same config information if you have a perl script that runs from a cronjob to do cleanup on your database.</p>
<p>If you were going to call it from a mod_perl module you might do something like this:</p>
<div class="code"><pre><pre>
package mywebapp::UpdateUserInfo;
...
use mywebapp::Conf;

sub handler {
...
my $dbase=get_db_config();
...
}

1;
</pre></pre></div>
<p>Now you have a hashref full of all the pertinent info needed to login to your database backend.  You could go one step further and add a <b>connect_to_db</b> function to your config module and then you wouldn&#8217;t even have to mess with the database info at all.  With this setup in place, tasks like changing the database server&#8217;s hostname or login credentials are now a trivial task that doesn&#8217;t require taking your webapp offline.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.southernbread.org/configtiny/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>LDAP From a CGI</title>
		<link>http://www.southernbread.org/ldap-from-a-cgi/</link>
		<comments>http://www.southernbread.org/ldap-from-a-cgi/#comments</comments>
		<pubDate>Tue, 15 Aug 2006 14:28:00 +0000</pubDate>
		<dc:creator>Dave</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.southernbread.org/linux/ldap_from_a_cgi_skeleton.html</guid>
		<description><![CDATA[When I&#8217;m writing web code these days, I find myself using LDAP in some form almost every time. It&#8217;s become the &#8220;glue&#8221; that ties a lot of our web/intranet apps together. If you have never worked with LDAP from within a CGI, here is a kind of skeleton example to get you started. It uses [...]]]></description>
			<content:encoded><![CDATA[<p>When I&#8217;m writing web code these days, I find myself using LDAP in some form almost every time.  It&#8217;s become the &#8220;glue&#8221; that ties a lot of our web/intranet apps together.  If you have never worked with LDAP from within a CGI, here is a kind of skeleton example to get you started.  It uses perl&#8217;s Net::LDAP module to grab a list of users from the &#8220;Domain Users&#8221; OU of our Active Directory and show them in an HTML table.  The returned results are sorted alphabetically by first name (&#8220;givenName&#8221; in directory speak).  Net::LDAP is feature rich and has all the bells and whistles you are likely to need for an intranet app.  Check out the <a href="http://search.cpan.org/~gbarr/perl-ldap/lib/Net/LDAP.pod">API documentation</a> for more details.</p>
<div class="code"><pre><pre>
#!/usr/bin/perl -w
use Net::LDAP;
use strict;

##: Bind anonymously to the ldap database
my $basedn=&quot;ou=Domain Users,dc=domain,dc=com&quot;;
my $ldap=Net::LDAP-&gt;new(&amp;#8217;ldap.domain.com&amp;#8217;) 
&nbsp;&nbsp;or die &quot;Couldn&amp;#8217;t connect to directory server.\n&quot;;
my $mesg=$ldap-&gt;bind(&amp;#8217;user@domain.com&amp;#8217;,password=&gt;&amp;#8217;********&amp;#8217;) 
&nbsp;&nbsp;or die &quot;Couldn&amp;#8217;t bind to directory server.\n&quot;;

##: Query LDAP to get a list of users and their info
$mesg=$ldap-&gt;search( 
&nbsp;&nbsp;base=&gt; $basedn,
&nbsp;&nbsp;filter=&gt; &quot;(objectClass=user)&quot;,
&nbsp;&nbsp;attrs=&gt; [&amp;#8217;displayName&amp;#8217;,&amp;#8217;givenName&amp;#8217;,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;#8217;sn&amp;#8217;,&amp;#8217;mail&amp;#8217;,&amp;#8217;telephoneNumber&amp;#8217;,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;#8217;streetAddress&amp;#8217;,&amp;#8217;l&amp;#8217;,&amp;#8217;st&amp;#8217;,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;#8217;postalCode&amp;#8217;,&amp;#8217;homePhone&amp;#8217; ] );

##: Display the directory
my $count=0;
my $results=&quot;&quot;;
foreach my $entry ($mesg-&gt;sorted(&amp;#8217;givenName&amp;#8217;)) {
&nbsp;&nbsp;$results.=&quot;&lt;tr&gt;&quot;;
&nbsp;&nbsp;$results.=&quot;&lt;td&gt;&quot;.$entry-&gt;get_value(&amp;#8217;displayName&amp;#8217;).&quot;&lt;/td&gt;&quot;;
&nbsp;&nbsp;$results.=&quot;&lt;td&gt;&quot;.$entry-&gt;get_value(&amp;#8217;streetAddress&amp;#8217;).&quot;&lt;/td&gt;&quot;;
&nbsp;&nbsp;$results.=&quot;&lt;td&gt;&quot;.$entry-&gt;get_value(&amp;#8217;l&amp;#8217;).&quot;&lt;/td&gt;&quot;;
&nbsp;&nbsp;$results.=&quot;&lt;td&gt;&quot;.$entry-&gt;get_value(&amp;#8217;st&amp;#8217;).&quot;&lt;/td&gt;&quot;;
&nbsp;&nbsp;$results.=&quot;&lt;td&gt;&quot;.$entry-&gt;get_value(&amp;#8217;postalCode&amp;#8217;).&quot;&lt;/td&gt;&quot;;
&nbsp;&nbsp;$results.=&quot;&lt;td&gt;&quot;.$entry-&gt;get_value(&amp;#8217;homePhone&amp;#8217;).&quot;&lt;/td&gt;&quot;;
&nbsp;&nbsp;$results.=&quot;&lt;td&gt;&quot;.$entry-&gt;get_value(&amp;#8217;mail&amp;#8217;).&quot;&lt;/td&gt;&quot;;
&nbsp;&nbsp;$results.=&quot;&lt;/tr&gt;&quot;;
&nbsp;&nbsp;$count++;
}
$mesg=$ldap-&gt;unbind;

print STDOUT &quot;Content-Type: text/html\n\n&quot;;
print STDOUT &quot;&lt;html&gt;\n\n&lt;head&gt;\n&quot;;
print STDOUT &quot;&lt;title&gt;User Listing - Full&lt;/title&gt;\n&quot;;
print STDOUT &quot;&lt;/head&gt;\n\n&lt;body&gt;\n&quot;;
print STDOUT &quot;Records Returned: &lt;b&gt;$count&lt;/b&gt;&lt;br /&gt;\n&quot;;
print STDOUT &quot;&lt;table border=&amp;#8217;1&amp;#8217; rules=&amp;#8217;1&amp;#8217;&gt;&lt;tr&gt;&quot;;
print STDOUT &quot;&lt;th&gt;Name&lt;/th&gt;&quot;;
print STDOUT &quot;&lt;th&gt;Address&lt;/th&gt;&quot;;
print STDOUT &quot;&lt;th&gt;City&lt;/th&gt;&quot;;
print STDOUT &quot;&lt;th&gt;State&lt;/th&gt;&quot;;
print STDOUT &quot;&lt;th&gt;Zip&lt;/th&gt;&quot;;
print STDOUT &quot;&lt;th&gt;Phone&lt;/th&gt;&quot;;
print STDOUT &quot;&lt;th&gt;Email&lt;/th&gt;&quot;;
print STDOUT &quot;&lt;/tr&gt;\n&quot;;
print STDOUT $results;
print STDOUT &quot;&lt;/table&gt;\n&quot;;
print STDOUT &quot;&lt;/body&gt;\n&lt;/html&gt;&quot;;
</pre></pre></div>
]]></content:encoded>
			<wfw:commentRss>http://www.southernbread.org/ldap-from-a-cgi/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Groupwise Address Book Converter</title>
		<link>http://www.southernbread.org/groupwise-address-book-converter/</link>
		<comments>http://www.southernbread.org/groupwise-address-book-converter/#comments</comments>
		<pubDate>Wed, 09 Aug 2006 10:38:00 +0000</pubDate>
		<dc:creator>Dave</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://www.southernbread.org/software/gwabconvert.html</guid>
		<description><![CDATA[Here is a little script I cooked up to help us with the migration from Groupwise to Exchange a couple of months ago. It will take a .nab file exported from Groupwise and convert the field names into Outlook compatible names so the Outook import wizard will map them properly into the contacts list. It [...]]]></description>
			<content:encoded><![CDATA[<p>Here is a little script I cooked up to help us with the migration from Groupwise to Exchange a couple of months ago.  It will take a <b>.nab</b> file exported from Groupwise and convert the field names into Outlook compatible names so the Outook import wizard will map them properly into the contacts list.  It will replace the contents of the input file.  It also strips out any of the old &#8220;internet:&#8221; prefixed addresses left over from older versions of Groupwise if you have any.  This was a real lifesaver for me when doing the conversion.</p>
<div class="code"><pre><pre>
Const ForReading = 1
Const ForWriting = 2

Set objArgs = WScript.Arguments

Dim arrFieldSearch
Dim arrFieldReplace
arrFieldSearch = Array(&quot;@DOMAIN.GWIA&quot;,&quot;.DOMAIN.GWIA&quot;,
&nbsp;&nbsp;&quot;.GWIA.DOMAIN&quot;,&quot;internet:&quot;,&quot;Internet:&quot;,
&nbsp;&nbsp;&quot;INTERNET:&quot;,&quot;:::TAGMAP:::0FFE0003:***&quot;,
&nbsp;&nbsp;&quot;3001001E:Name&quot;,&quot;3A08001E:Office Phone Number&quot;,
&nbsp;&nbsp;&quot;3A18001E:Department&quot;,&quot;3A23001E:Fax Number&quot;,
&nbsp;&nbsp;&quot;3003001E:E-Mail Address&quot;,&quot;3A06001E:FirstName&quot;,
&nbsp;&nbsp;&quot;3A11001E:LastName&quot;,&quot;3A17001E:Title&quot;,
&nbsp;&nbsp;&quot;3A29001E:Address&quot;,&quot;3A27001E:City&quot;,&quot;3A28001E:State&quot;,
&nbsp;&nbsp;&quot;3A26001E:Country&quot;,&quot;3A2A001E:ZIP Code&quot;,&quot;3002001E:E-Mail Type&quot;,
&nbsp;&nbsp;&quot;3A19001E:Mailstop&quot;,&quot;3A09001E:Home Phone Number&quot;,
&nbsp;&nbsp;&quot;3A1C001E:Cellular Phone Number&quot;,&quot;3A21001E:Pager Number&quot;,
&nbsp;&nbsp;&quot;3A1A001E:Phone Number&quot;,&quot;600B001E:Greeting&quot;,
&nbsp;&nbsp;&quot;600F001E:Owner&quot;,&quot;3A16001E:Organization&quot;,&quot;3004001E:Comments&quot;,
&nbsp;&nbsp;&quot;3A00001E:User ID&quot;,&quot;6604001E:Domain&quot;,&quot;6609001E:Additional Routing&quot;,
&nbsp;&nbsp;&quot;6605001E:Post Office&quot;,&quot;6603001E:GUID&quot;,&quot;6607001E:NDS Distinguished Name&quot;,
&nbsp;&nbsp;&quot;6608001E:Network ID&quot;,&quot;660D001E:Internet Domain&quot;,&quot;8000001E:Pumatech_ID&quot;
)

arrFieldReplace = Array(&quot;&quot;,&quot;&quot;,&quot;&quot;,&quot;&quot;,&quot;&quot;,&quot;&quot;,&quot;Category&quot;,&quot;Name&quot;,
&nbsp;&nbsp;&quot;Company Main Phone&quot;,&quot;Department&quot;,&quot;Business Fax&quot;,
&nbsp;&nbsp;&quot;E-Mail Address&quot;,&quot;First Name&quot;,&quot;Last Name&quot;,&quot;Job Title&quot;,
&nbsp;&nbsp;&quot;Business Street&quot;,&quot;Business City&quot;,&quot;Business State&quot;,&quot;Business Country&quot;,
&nbsp;&nbsp;&quot;Business Postal Code&quot;,&quot;E-Mail Type&quot;,&quot;Office Location&quot;,&quot;Home Phone&quot;,
&nbsp;&nbsp;&quot;Mobile Phone&quot;,&quot;Pager&quot;,&quot;Business Phone&quot;,&quot;Title&quot;,&quot;User 1&quot;,&quot;Company&quot;,
&nbsp;&nbsp;&quot;Notes&quot;,&quot;User 2&quot;,&quot;User 3&quot;,&quot;Office Location&quot;,&quot;Post Office&quot;,
&nbsp;&nbsp;&quot;6603001E:GUID&quot;,&quot;6607001E:NDS Distinguished Name&quot;,
&nbsp;&nbsp;&quot;6608001E:Network ID&quot;,&quot;660D001E:Internet Domain&quot;,&quot;8000001E:Pumatech_ID&quot;
)

For F = 0 to objArgs.Count - 1
&nbsp;&nbsp;strFileName = objArgs(F)
&nbsp;&nbsp;WScript.echo F &amp; &quot;. &quot; &amp; strFileName
&nbsp;&nbsp;
&nbsp;&nbsp;Set objFSO = CreateObject(&quot;Scripting.FileSystemObject&quot;)
&nbsp;&nbsp;Set objFile = objFSO.OpenTextFile(strFileName, ForReading)
&nbsp;&nbsp;
&nbsp;&nbsp;strText = objFile.ReadAll
&nbsp;&nbsp;objFile.Close
&nbsp;&nbsp;
&nbsp;&nbsp;i = 0
&nbsp;&nbsp;For Each strSearchFor in arrFieldSearch
&nbsp;&nbsp;&nbsp;&nbsp;strReplaceWith = arrFieldReplace(i)
&nbsp;&nbsp;&nbsp;&nbsp;strNewText = Replace(strText, strSearchFor, strReplaceWith, 1, -1, 1)
&nbsp;&nbsp;&nbsp;&nbsp;strText = strNewText
&nbsp;&nbsp;&nbsp;&nbsp;i = i + 1
&nbsp;&nbsp;Next
&nbsp;&nbsp;
&nbsp;&nbsp;Set objFile = objFSO.OpenTextFile(strFileName, ForWriting)
&nbsp;&nbsp;objFile.WriteLine strNewText
&nbsp;&nbsp;objFile.Close
Next

WScript.echo &quot;Finished Conversion!&quot;
</pre></pre></div>
<p>Just copy the code into a file called &#8220;abconvert.vbs&#8221; and put it into your &#8220;Send To&#8221; folder.  Then just right-click on an exported .nab file and send it to the script.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.southernbread.org/groupwise-address-book-converter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SoftScan and SSReader</title>
		<link>http://www.southernbread.org/softscan-and-ssreader/</link>
		<comments>http://www.southernbread.org/softscan-and-ssreader/#comments</comments>
		<pubDate>Fri, 04 Aug 2006 11:29:00 +0000</pubDate>
		<dc:creator>Dave</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Hobbies]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://www.southernbread.org/software/softscan.html</guid>
		<description><![CDATA[Here is a simple pair of programs that make administering licensing a little easier for sysadmins. SoftScan will simply enumerate the Uninstall key in the registry and dump it all to a file. This is the same key that Add/Remove Programs draws it&#8217;s info from. It also dumps the version of Windows being run as [...]]]></description>
			<content:encoded><![CDATA[<p>Here is a simple pair of programs that make administering licensing a little easier for sysadmins.  SoftScan will simply enumerate the Uninstall key in the registry and dump it all to a file.  This is the same key that Add/Remove Programs draws it&#8217;s info from.  It also dumps the version of Windows being run as well as all the installed PCI devices it can find.</p>
<p>The other program called SSReader will then take all the dump files produced by SoftScan in a directory and aggregate them to produce a count of how many installations of each piece of software there are.  I use it here at the office by putting SoftScan in the global login script.  Then any time I want to know how many installs of a certain piece of software I have, I just fire up SSReader and check.  I then know how many licenses I need to buy if I&#8217;m over.</p>
<p>
SoftScan Usage:</p>
<div class="code"><pre><pre>
softscan.exe /p-c:\path\to\store\report
</pre></pre></div>
<p>There is also a /q switch that will make SoftScan not display a progress bar, and a /? switch to get usage info.
</p>
<p>
SSReader Usage:</p>
<div class="code"><pre><pre>
ssreader.exe
</pre></pre></div>
<p>Just double-click it and go.  When you first start SSReader it will ask you to choose a directory.  Just choose the same directory that you use in the /p- switch of SoftScan.  There is a filter box at the top of the SSReader window.  When you type in the box, it narrows the displayed programs down in realtime.
</p>
<p>This isn&#8217;t exactly Beta software but I wouldn&#8217;t call it stable either.  If you find any glaring problems with it please shoot me an e-mail.  I&#8217;ll release the masm32 source at a later date after I clean it up.</p>
<ul>
<li>Download current SoftScan <a href="/downloads/softscan.exe">Binary</a>
<li>Download current SSReader <a href="/downloads/ssreader.exe">Binary</a>
</ul></p>
]]></content:encoded>
			<wfw:commentRss>http://www.southernbread.org/softscan-and-ssreader/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PodWrangler &#8211; New Version (v0.1.4.1)</title>
		<link>http://www.southernbread.org/podwrangler-new-version-v0-1-4-1/</link>
		<comments>http://www.southernbread.org/podwrangler-new-version-v0-1-4-1/#comments</comments>
		<pubDate>Fri, 28 Jul 2006 01:23:00 +0000</pubDate>
		<dc:creator>Dave</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[podcast]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.southernbread.org/software/podwrangler_141.html</guid>
		<description><![CDATA[I prettified the buttons to make it look a little spiffier and squashed a big bug in the code that allows you to change the download directory for a certain feed. It&#8217;s getting insanely big though. 96KB is just total bloat-ware. The next release will fix some of those glaring holes in the UI like [...]]]></description>
			<content:encoded><![CDATA[<p>I prettified the buttons to make it look a little spiffier and squashed a big bug in the code that allows you to change the download directory for a certain feed.  It&#8217;s getting insanely big though.  96KB is just total bloat-ware.  The next release will fix some of those glaring holes in the UI like being able to cancel an in-progress download.  Use the &#8220;Check for updates&#8221; as always to update automatically.</p>
<ul>
<li>Get the source and binary <a href="/cgi-bin/pl.cgi/software/podwrangler.html">here</a>
</ul></p>
]]></content:encoded>
			<wfw:commentRss>http://www.southernbread.org/podwrangler-new-version-v0-1-4-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Automatic Power Profile Configuration</title>
		<link>http://www.southernbread.org/automatic-power-profile-configuration/</link>
		<comments>http://www.southernbread.org/automatic-power-profile-configuration/#comments</comments>
		<pubDate>Sat, 22 Jul 2006 21:52:00 +0000</pubDate>
		<dc:creator>Dave</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[sysadmin]]></category>

		<guid isPermaLink="false">http://www.southernbread.org/software/powercfg.html</guid>
		<description><![CDATA[Show me a sysadmin that likes to do the same thing 10 times in a row by hand and I&#8217;ll show you the sweater I got from Tony Blair. So in that vain, here is a batch file you can run from your login scripts that will automatically configure desktop and laptop power profiles in [...]]]></description>
			<content:encoded><![CDATA[<p>Show me a sysadmin that likes to do the same thing 10 times in a row by hand and I&#8217;ll show you the sweater I got from Tony Blair.  So in that vain, here is a batch file you can run from your login scripts that will automatically configure desktop and laptop power profiles in windows.  Why this isn&#8217;t included in Group Policy Management I do not know, but since every copy of Windows XP sp2 has the powercfg.exe program this should be close enough to a sure thing.  If you need to tweak the settings just look <a href="http://www.jsifaq.com/SUBQ/TIP8300/rh8369.htm">here</a> for an explanation of the switches.</p>
<p><b>Desktops</b></p>
<div class="code"><pre><pre>
@echo off
cls
:Creates a desktop power profile

:QUERY
powercfg.exe /Q cust_desktop
IF NOT ERRORLEVEL 1 GOTO QUIT
IF ERRORLEVEL 1 GOTO DELETE

:DELETE
powercfg.exe /D OLDPROFILE

:CREATE
powercfg.exe /C cust_desktop

:ADJUST
powercfg.exe /X cust_desktop /monitor-timeout-ac 0
powercfg.exe /X cust_desktop /monitor-timeout-dc 0
powercfg.exe /X cust_desktop /disk-timeout-ac 0
powercfg.exe /X cust_desktop /disk-timeout-dc 0
powercfg.exe /X cust_desktop /standby-timeout-ac 0
powercfg.exe /X cust_desktop /standby-timeout-dc 0
powercfg.exe /X cust_desktop /hibernate-timeout-ac 0
powercfg.exe /X cust_desktop /hibernate-timeout-dc 0
powercfg.exe /X cust_desktop /processor-throttle-ac NONE
powercfg.exe /X cust_desktop /processor-throttle-dc NONE

:GLOBAL
powercfg.exe /G off /OPTION BATTERYICON
powercfg.exe /G off /OPTION RESUMEPASSWORD

:ACTIVATE
powercfg.exe /S cust_desktop

:QUIT
@cls
exit
</pre></pre></div>
<p><b>Laptops</b></p>
<div class="code"><pre><pre>
@echo off
cls
:Creates a laptop power profile

:QUERY
powercfg.exe /Q cust_laptop
IF NOT ERRORLEVEL 1 GOTO QUIT
IF ERRORLEVEL 1 GOTO DELETE

:DELETE
powercfg.exe /D OLDPROFILE

:CREATE
powercfg.exe /C cust_laptop

:ADJUST
powercfg.exe /X cust_laptop /monitor-timeout-ac 0
powercfg.exe /X cust_laptop /monitor-timeout-dc 15
powercfg.exe /X cust_laptop /disk-timeout-ac 0
powercfg.exe /X cust_laptop /disk-timeout-dc 30
powercfg.exe /X cust_laptop /standby-timeout-ac 0
powercfg.exe /X cust_laptop /standby-timeout-dc 0
powercfg.exe /X cust_laptop /hibernate-timeout-ac 0
powercfg.exe /X cust_laptop /hibernate-timeout-dc 0
powercfg.exe /X cust_laptop /processor-throttle-ac NONE
powercfg.exe /X cust_laptop /processor-throttle-dc NONE

:GLOBAL
powercfg.exe /G on /OPTION BATTERYICON
powercfg.exe /G off /OPTION RESUMEPASSWORD

:ACTIVATE
powercfg.exe /S cust_laptop

:QUIT
@cls
exit
</pre></pre></div>
]]></content:encoded>
			<wfw:commentRss>http://www.southernbread.org/automatic-power-profile-configuration/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

