<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss 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:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"  xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>SoftwareProjects - Internet Marketing and Web Development</title>
	<link>http://www.softwareprojects.com/images/logo.png</link>
	<description>Internet Marketing and Web Development</description>

	<generator>http://www.softwareprojects.com</generator>
	<language>en</language>

		<copyright>SoftwareProjects Inc</copyright>
		<managingEditor>support@softwareprojects.com (Adrian Singer)</managingEditor>
		<webMaster>support@softwareprojects.com</webMaster>
		<category>SoftwareProjects</category>
		<ttl>3000</ttl>

		<image>
			<url>http://www.softwareprojects.com/images/logo.png</url>
			<title>SoftwareProjects - Internet Marketing and Web Development</title>
			<link>http://www.softwareprojects.com/images/logo.png</link>
			<width>142</width>
			<height>55</height>

		</image>

<item>
<title><![CDATA[How to count unique visitors in an nginx access.log]]></title>
<link>http://www.softwareprojects.com/resources/programming/t-how-to-count-unique-visitors-in-an-nginx-1898.html</link>
<pubDate>Thu, 05 Nov 2009 01:25:06 GMT</pubDate>
<dc:creator><![CDATA[Mike Peters]]></dc:creator>
<category><![CDATA[Programming]]></category>
<guid isPermaLink="false">http://www.softwareprojects.com/resources/programming/t-how-to-count-unique-visitors-in-an-nginx-1898.html</guid>
<description><![CDATA[This nifty one-liner will count the number of unique visitors in an <a href="http://www.softwareprojects.com/resources/programming/t-installing-nginx-web-server-w-php-and-ssl-1474.html" target="_blank">NGinx</a> web-server access.log file, for a given day:<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">grep "\[04/Nov/2009" access.log | cut -d" " -f1 | sort | uniq | wc -l</code><hr />
</div>
<br />
Replace <b>04/Nov/2009</b> with the date you'd like to count the number of unique visitors for.]]></description>

		<wfw:commentRss>http://www.softwareprojects.com/resources/programming/t-how-to-count-unique-visitors-in-an-nginx-1898.html</wfw:commentRss>
		<feedburner:origLink>http://www.softwareprojects.com/resources/programming/t-how-to-count-unique-visitors-in-an-nginx-1898.html</feedburner:origLink>

</item>
<item>
<title><![CDATA[FreeBSD No Ports Fix]]></title>
<link>http://www.softwareprojects.com/resources/programming/t-freebsd-no-ports-fix-1895.html</link>
<pubDate>Wed, 04 Nov 2009 23:52:34 GMT</pubDate>
<dc:creator><![CDATA[Mike Peters]]></dc:creator>
<category><![CDATA[Programming]]></category>
<guid isPermaLink="false">http://www.softwareprojects.com/resources/programming/t-freebsd-no-ports-fix-1895.html</guid>
<description><![CDATA[When installing a FreeBSD system, you're asked if you would like to install the Ports Collection. If you chose no, you can follow these instructions to obtain the ports collection:<br />
<br />
<b>Option 1 - CVSup</b><br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">csup -L 2 -h cvsup.FreeBSD.org /usr/share/examples/cvsup/ports-supfile<BR>csup</code><hr />
</div>
<br />
<b>Option 2 - Portsnap</b><br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">portsnap fetch<BR>portsnap extract</code><hr />
</div>]]></description>

		<wfw:commentRss>http://www.softwareprojects.com/resources/programming/t-freebsd-no-ports-fix-1895.html</wfw:commentRss>
		<feedburner:origLink>http://www.softwareprojects.com/resources/programming/t-freebsd-no-ports-fix-1895.html</feedburner:origLink>

</item>
<item>
<title><![CDATA[How to: Add a Lead Opt-in Web Form]]></title>
<link>http://www.softwareprojects.com/resources/the-platform-all-in-one/t-how-to-add-a-lead-opt-in-web-form-1892.html</link>
<pubDate>Wed, 28 Oct 2009 09:21:38 GMT</pubDate>
<dc:creator><![CDATA[Adrian Singer]]></dc:creator>
<category><![CDATA[The Platform: All-In-One]]></category>
<guid isPermaLink="false">http://www.softwareprojects.com/resources/the-platform-all-in-one/t-how-to-add-a-lead-opt-in-web-form-1892.html</guid>
<description><![CDATA[A lead opt-in web form is a short form, asking the user to provide name, emailaddress, phone and/or other optional fields, for the purpose of signing up for a program, or receiving more information about your offering.<br />
<br />
<img src="http://www.softwareprojects.com/blogimages/76988008.png" border="0" alt="" /><br />
<br />
Unlike other shopping carts, the <a href="http://www.softwareprojects.com/shopping-cart" target="_blank">SPI cart</a> doesn't limit you to a single form style or any specific fields.<br />
<br />
You can create whatever html form you like, using any design and combination of fields (text, radio button, checkboxes, textareas) as needed.<br />
<br />
The only requirement is to have at least the emailaddress field, whenever saving a new lead to the database.<br />
<br />
<b>Step 1 - Design your opt-in form</b><br />
<br />
Use your favorite HTML editor to design your lead opt-in form.<br />
<br />
For simplicity, use 'name' as the fieldname for the user's name (or 'first_name' + 'last_name'), use 'emailaddress' as the fieldname for the user's email address and use 'phone' as the fieldname for the user's phone number.<br />
<br />
Here's a typical lead opt-in form with the basic name,emailaddress,phone fields as well as a few additional custom ones:<br />
<br />
<div style="margin:10px;  padding:4px; border:1px inset; background-color: #FDF8EB">

	<span style="margin:0px; width:550px; padding:4px;  overflow:auto; "><font face="courier new">  <br /></font><font color="#006600">&lt;</font><font color="#0000CC">form action</font><font color="#006600">=</font><font color="#CC0000">"#" </font><font color="#0000CC">method</font><font color="#006600">=</font><font color="#CC0000">"post"</font><font color="#006600">&gt;<br />&lt;</font><font color="#0000CC">p</font><font color="#006600">&gt;</font><font color="#0000CC">First Name</font><font color="#006600">: &lt;</font><font color="#0000CC">input type</font><font color="#006600">=</font><font color="#CC0000">"text" </font><font color="#0000CC">name</font><font color="#006600">=</font><font color="#CC0000">"first_name" </font><font color="#006600">/&gt;&lt;/</font><font color="#0000CC">p</font><font color="#006600">&gt;<br />&lt;</font><font color="#0000CC">p</font><font color="#006600">&gt;</font><font color="#0000CC">Last Name</font><font color="#006600">: &lt;</font><font color="#0000CC">input type</font><font color="#006600">=</font><font color="#CC0000">"text" </font><font color="#0000CC">name</font><font color="#006600">=</font><font color="#CC0000">"last_name" </font><font color="#006600">/&gt;&lt;/</font><font color="#0000CC">p</font><font color="#006600">&gt;<br />&lt;</font><font color="#0000CC">p</font><font color="#006600">&gt;</font><font color="#0000CC">Best Email</font><font color="#006600">: &lt;</font><font color="#0000CC">input type</font><font color="#006600">=</font><font color="#CC0000">"text" </font><font color="#0000CC">name</font><font color="#006600">=</font><font color="#CC0000">"email" </font><font color="#006600">/&gt;&lt;/</font><font color="#0000CC">p</font><font color="#006600">&gt;<br />&lt;</font><font color="#0000CC">p</font><font color="#006600">&gt;</font><font color="#0000CC">Best Phone Number</font><font color="#006600">: &lt;</font><font color="#0000CC">input type</font><font color="#006600">=</font><font color="#CC0000">"text" </font><font color="#0000CC">name</font><font color="#006600">=</font><font color="#CC0000">"phone" </font><font color="#006600">/&gt;&lt;/</font><font color="#0000CC">p</font><font color="#006600">&gt;<br />&lt;</font><font color="#0000CC">p</font><font color="#006600">&gt;</font><font color="#0000CC">Have you traded individual stocks</font><font color="#006600">?<br /></font><font color="#0000CC">Yes </font><font color="#006600">&lt;</font><font color="#0000CC">input name</font><font color="#006600">=</font><font color="#CC0000">"traded_indi_stock" </font><font color="#0000CC">type</font><font color="#006600">=</font><font color="#CC0000">"radio" </font><font color="#0000CC">value</font><font color="#006600">=</font><font color="#CC0000">"Yes" </font><font color="#006600">/&gt; </font><font color="#0000CC">No </font><font color="#006600">&lt;</font><font color="#0000CC">input name</font><font color="#006600">=</font><font color="#CC0000">"traded_indi_stock" </font><font color="#0000CC">type</font><font color="#006600">=</font><font color="#CC0000">"radio" </font><font color="#0000CC">value</font><font color="#006600">=</font><font color="#CC0000">"No" </font><font color="#006600">/&gt;<br />&lt;/</font><font color="#0000CC">p</font><font color="#006600">&gt;<br />&lt;</font><font color="#0000CC">p</font><font color="#006600">&gt;</font><font color="#0000CC">Have you traded options<br />Yes </font><font color="#006600">&lt;</font><font color="#0000CC">input name</font><font color="#006600">=</font><font color="#CC0000">"traded_option" </font><font color="#0000CC">type</font><font color="#006600">=</font><font color="#CC0000">"radio" </font><font color="#0000CC">value</font><font color="#006600">=</font><font color="#CC0000">"Yes" </font><font color="#006600">/&gt; </font><font color="#0000CC">No </font><font color="#006600">&lt;</font><font color="#0000CC">input name</font><font color="#006600">=</font><font color="#CC0000">"traded_option" </font><font color="#0000CC">type</font><font color="#006600">=</font><font color="#CC0000">"radio" </font><font color="#0000CC">value</font><font color="#006600">=</font><font color="#CC0000">"No" </font><font color="#006600">/&gt;<br />&lt;/</font><font color="#0000CC">p</font><font color="#006600">&gt;<br />&lt;</font><font color="#0000CC">input type</font><font color="#006600">=</font><font color="#CC0000">"submit" </font><font color="#0000CC">name</font><font color="#006600">=</font><font color="#CC0000">"submit" </font><font color="#0000CC">value</font><font color="#006600">=</font><font color="#CC0000">"Submit" </font><font color="#006600">/&gt;<br />&lt;/</font><font color="#0000CC">form</font><font color="#006600">&gt;  </font><font color="#0000CC"></font></span></div>
<br />
<b>Step 2 - Add custom fields to Leads table</b><br />
<br />
Since we're using a few custom fields in this example (traded_indi_stock, traded_option), we need to add those fields to the 'leads' table.<br />
<br />
Connect to your SPI database using <a href="https://softwareprojects.com/phpmyadmin" target="_blank">PHPMyAdmin</a>, locate the leads table and add the two new fields.  You only have to do this once every time you're adding a new custom field to a table.<br />
<br />
<img src="http://www.softwareprojects.com/blogimages/9dbc9f19.png" border="0" alt="" /><br />
<br />
Make sure you're adding the custom fields to the 'leads' table and pay close attention to the fieldnames.  The fieldnames you choose are going to have to match the fieldnames you pass to the do_addlead() function.  <br />
<br />
<b>Step 3 - Save the lead to the database</b><br />
<br />
Now that we have the custom leads in the 'leads' table, saving the lead to the database is the easy part.<br />
<br />
The code below renders the opt-in form, saves the lead to the database and redirects the user to a thankyou.html page.<br />
<br />
<div style="margin:10px;  padding:4px; border:1px inset; background-color: #FDF8EB">

	<span style="margin:0px; width:550px; padding:4px;  overflow:auto; "><font face="courier new"> <br /></font><font color="#006600">&lt;?</font><font color="#0000CC">php<br /></font><font color="#FF9900">// Include SPICart shopping cart API<br /></font><font color="#006600">require_once(</font><font color="#CC0000">"spicart.php"</font><font color="#006600">);<br /><br /></font><font color="#FF9900">// If this is a lead submit<br /></font><font color="#006600">if (!empty(</font><font color="#0000CC">$_POST</font><font color="#006600">&#91;</font><font color="#CC0000">'email'</font><font color="#006600">&#93;))<br />{<br /></font><font color="#FF9900">// Save lead to the database<br /></font><font color="#0000CC">$input </font><font color="#006600">= array();<br /></font><font color="#0000CC">$input</font><font color="#006600">&#91;</font><font color="#CC0000">'first_name'</font><font color="#006600">&#93; = </font><font color="#0000CC">$_POST</font><font color="#006600">&#91;</font><font color="#CC0000">'first_name'</font><font color="#006600">&#93;;<br /></font><font color="#0000CC">$input</font><font color="#006600">&#91;</font><font color="#CC0000">'last_name'</font><font color="#006600">&#93; = </font><font color="#0000CC">$_POST</font><font color="#006600">&#91;</font><font color="#CC0000">'last_name'</font><font color="#006600">&#93;;<br /></font><font color="#0000CC">$input</font><font color="#006600">&#91;</font><font color="#CC0000">'emailaddress'</font><font color="#006600">&#93; = </font><font color="#0000CC">$_POST</font><font color="#006600">&#91;</font><font color="#CC0000">'emailaddres'</font><font color="#006600">&#93;;<br /></font><font color="#0000CC">$input</font><font color="#006600">&#91;</font><font color="#CC0000">'phone'</font><font color="#006600">&#93; = </font><font color="#0000CC">$_POST</font><font color="#006600">&#91;</font><font color="#CC0000">'phone'</font><font color="#006600">&#93;;<br /></font><font color="#0000CC">$input</font><font color="#006600">&#91;</font><font color="#CC0000">'traded_indi_stock'</font><font color="#006600">&#93; = </font><font color="#0000CC">$_POST</font><font color="#006600">&#91;</font><font color="#CC0000">'traded_indi_stock'</font><font color="#006600">&#93;;<br /></font><font color="#0000CC">$input</font><font color="#006600">&#91;</font><font color="#CC0000">'traded_option'</font><font color="#006600">&#93; = </font><font color="#0000CC">$_POST</font><font color="#006600">&#91;</font><font color="#CC0000">'traded_option'</font><font color="#006600">&#93;;<br /></font><font color="#0000CC">do_addlead</font><font color="#006600">(</font><font color="#0000CC">$input</font><font color="#006600">, &amp;</font><font color="#0000CC">$output</font><font color="#006600">, &amp;</font><font color="#0000CC">$result_str</font><font color="#006600">);<br /></font><font color="#0000CC">Header</font><font color="#006600">(</font><font color="#CC0000">"Location: thankyou.html"</font><font color="#006600">);<br />die;<br />}<br /></font><font color="#0000CC">?&gt;<br /></font>&lt;form action="#" method="post"&gt;<br />&lt;p&gt;First Name: &lt;input type="text" name="first_name" /&gt;&lt;/p&gt;<br />&lt;p&gt;Last Name: &lt;input type="text" name="last_name" /&gt;&lt;/p&gt;<br />&lt;p&gt;Best Email: &lt;input type="text" name="emailaddress" /&gt;&lt;/p&gt;<br />&lt;p&gt;Best Phone Number: &lt;input type="text" name="phone" /&gt;&lt;/p&gt;<br />&lt;p&gt;Have you traded individual stocks?<br />Yes &lt;input name="traded_indi_stock" type="radio" value="Yes" /&gt; No &lt;input name="traded_indi_stock" type="radio" value="No" /&gt;<br />&lt;/p&gt;<br />&lt;p&gt;Have you traded options<br />Yes &lt;input name="traded_option" type="radio" value="Yes" /&gt; No &lt;input name="traded_option" type="radio" value="No" /&gt;<br />&lt;/p&gt;<br />&lt;input type="submit" name="submit" value="Submit" /&gt;<br />&lt;/form&gt; </font></span></div>
<br />
<b>Note about Affiliate Tracking</b><br />
<br />
Often times, affiliates will be sending their traffic to your lead opt-in forms.  You're going to want to know which affiliate generated which leads.<br />
<br />
Luckily the system takes care of this automatically.<br />
<br />
One of the fields in the 'leads' table is aff_id.  This is the ID of the referring affiliate and serves as the glue, associating leads with the affiliates who referred them.<br />
<br />
When a user clicks on an affiliate link to visit the opt-in form on your website, they typically follow a link that looks like this:<br />
<br />
<font color="Blue"><u><a href="http://www.YourDomain.com/?aff_id=1234" target="_blank">www.YourDomain.com/?aff_id=1234</a></u></font> <br />
<br />
Where 1234 is the affiliate ID.<br />
<br />
As soon as the user lands on the lead opt-in form, the spicart.php include at the top of your file, identifies the aff_id url-parameter and saves it in a cookie on the end-user's machine.<br />
<br />
Later when you call do_addlead(), this method picks up the aff_id from the end-user's cookie and passes it along, so that when the lead is added, the referring aff_id is saved as well.]]></description>

		<wfw:commentRss>http://www.softwareprojects.com/resources/the-platform-all-in-one/t-how-to-add-a-lead-opt-in-web-form-1892.html</wfw:commentRss>
		<feedburner:origLink>http://www.softwareprojects.com/resources/the-platform-all-in-one/t-how-to-add-a-lead-opt-in-web-form-1892.html</feedburner:origLink>

</item>
<item>
<title><![CDATA[Do It Yourself Web Server and Database monitoring]]></title>
<link>http://www.softwareprojects.com/resources/programming/t-do-it-yourself-web-server-and-database-m-1889.html</link>
<pubDate>Wed, 21 Oct 2009 06:44:12 GMT</pubDate>
<dc:creator><![CDATA[Mike Peters]]></dc:creator>
<category><![CDATA[Programming]]></category>
<guid isPermaLink="false">http://www.softwareprojects.com/resources/programming/t-do-it-yourself-web-server-and-database-m-1889.html</guid>
<description><![CDATA[When you have production web servers and databases, it is absolutely critical to have a monitoring system in-place that will alert you whenever service goes down.<br />
<br />
<b>Getting Started with website monitoring</b><br />
<br />
One of our favorite monitoring tools is <a href="http://www.pingdom.com" target="_blank">Pingdom</a>.  It's a $9.95/month easy-to-use service that will ping 5 of your servers, once every 60 seconds, alerting you via email &amp; SMS whenever any server goes down.<br />
<br />
In addition to downtime notifications, the service also provides response-time trends, raw data and uptime-over-time reports:<br />
<br />
<img src="http://www.softwareprojects.com/blogimages/24d940d6.png" border="0" alt="" /><br />
<br />
If you don't have any monitoring in-place right one, you should definitely try out Pingdom or a similar service.<br />
<br />
In about 5 minutes of setting it up, you'll have the peace of mind, knowing exactly when your merchant website, affiliate landing page or payment gateway goes down.<br />
<br />
<b>Beyond simple HTTP monitoring</b><br />
<br />
While Pingdom and other similar tools are great in letting you know once your website is -already- down, a lot of times the outage can be prevented in the first place, by detecting a decrease available memory, cpu, disk space etc.<br />
<br />
At the pinnacle of server monitoring are tools such as <a href="http://www.nagios.org/" target="_blank">Nagios</a> and <a href="http://munin.projects.linpro.no/" target="_blank">Munin</a>. <br />
<br />
Munin will monitor every single resource on your server, including: memory, cpu utilization, available handles, open connections, average load, running processes and more.<br />
<br />
Nagios sends alerts to groups of users based on predetermined rules.<br />
<br />
<img src="http://www.softwareprojects.com/blogimages/6fd56f32.png" border="0" alt="" /><br />
<br />
<b>Do It Yourself Server Monitoring</b><br />
<br />
In this post, I'd like to focus on how to create a simple monitoring script, that will survey remote servers for a few critical metrics, displaying the results on the screen.<br />
<br />
Unlike Nagios+Munin, such a setup doesn't require installing a monitoring component on each server.  Your monitoring script can run remotely, surveying all servers once every 60 seconds on a cronjob, sending an email/sms whenever detecting abnormal behavior.<br />
<br />
For the purpose of this example, our script will monitor the following metrics:<br />
<br />
= MySQL Database server<br />
* Number of running threads<br />
* Number of threads connected<br />
* Queries per second<br />
* Open tables<br />
* Sample query response<br />
* Number of tables in database<br />
<br />
= Any FreeBSD/Linux server<br />
* CPU load over the last 5 minutes<br />
* Available memory<br />
* Open sockets<br />
* Number of running processes<br />
<br />
<div style="margin:10px;  padding:4px; border:1px inset; background-color: #FDF8EB">

	<span style="margin:0px; width:550px; padding:4px;  overflow:auto; "><font face="courier new">  <br /></font><font color="#FF9900">// Set these for easier access<br /></font><font color="#0000CC">$USERNAME&nbsp;  </font><font color="#006600">= </font><font color="#CC0000">"root"</font><font color="#006600">;<br /></font><font color="#0000CC">$SERVER&nbsp;  </font><font color="#006600">= </font><font color="#CC0000">"www.mydomain.com"</font><font color="#006600">;<br /></font><font color="#0000CC">$DBHOST&nbsp; &nbsp; </font><font color="#006600">= </font><font color="#CC0000">"www.mydatabase.com"</font><font color="#006600">;<br /></font><font color="#0000CC">$DBUSER&nbsp; &nbsp; </font><font color="#006600">= </font><font color="#CC0000">"root"</font><font color="#006600">;<br /></font><font color="#0000CC">$DBPASS&nbsp; &nbsp; </font><font color="#006600">= </font><font color="#CC0000">"dbpassword"</font><font color="#006600">;<br /></font><font color="#0000CC">$DBNAME&nbsp; &nbsp; </font><font color="#006600">= </font><font color="#CC0000">"dbdatabasename"</font><font color="#006600">;<br /><br /></font><font color="#FF9900">// Get load average, available memory and number of running processes<br /></font><font color="#0000CC">$load_average </font><font color="#006600">= </font><font color="#CC0000">"N/A"</font><font color="#006600">;<br /></font><font color="#0000CC">$available_memory </font><font color="#006600">= </font><font color="#CC0000">"N/A"</font><font color="#006600">;<br /></font><font color="#0000CC">$running_processes </font><font color="#006600">= </font><font color="#CC0000">"N/A"</font><font color="#006600">;<br /></font><font color="#0000CC">$CRLF </font><font color="#006600">= </font><font color="#CC0000">"\\r\"\n"</font><font color="#006600">;<br /></font><font color="#0000CC">exec</font><font color="#006600">(</font><font color="#CC0000">"ssh -l$USERNAME $SERVER \"top -b -n 1\""</font><font color="#006600">,&amp;</font><font color="#0000CC">$buf</font><font color="#006600">);<br />for (</font><font color="#0000CC">$i</font><font color="#006600">=</font><font color="#0000CC">0</font><font color="#006600">,</font><font color="#0000CC">$str</font><font color="#006600">=</font><font color="#CC0000">""</font><font color="#006600">; </font><font color="#0000CC">$i</font><font color="#006600">&lt;</font><font color="#0000CC">count</font><font color="#006600">(</font><font color="#0000CC">$buf</font><font color="#006600">); </font><font color="#0000CC">$i</font><font color="#006600">++) </font><font color="#0000CC">$str </font><font color="#006600">.= </font><font color="#0000CC">$buf</font><font color="#006600">&#91;</font><font color="#0000CC">$i</font><font color="#006600">&#93;.</font><font color="#0000CC">$CRLF</font><font color="#006600">;<br />if ((</font><font color="#0000CC">$pos</font><font color="#006600">=</font><font color="#0000CC">strpos</font><font color="#006600">(</font><font color="#0000CC">$str</font><font color="#006600">,</font><font color="#CC0000">"load averages:"</font><font color="#006600">))!==</font><font color="#0000CC">false</font><font color="#006600">)<br />{<br />&nbsp; &nbsp; </font><font color="#0000CC">$str </font><font color="#006600">= </font><font color="#0000CC">trim</font><font color="#006600">(</font><font color="#0000CC">substr</font><font color="#006600">(</font><font color="#0000CC">$str</font><font color="#006600">, </font><font color="#0000CC">$pos</font><font color="#006600">+</font><font color="#0000CC">strlen</font><font color="#006600">(</font><font color="#CC0000">"load averages:"</font><font color="#006600">)));<br />&nbsp; &nbsp; if ((</font><font color="#0000CC">$pos</font><font color="#006600">=</font><font color="#0000CC">strpos</font><font color="#006600">(</font><font color="#0000CC">$str</font><font color="#006600">,</font><font color="#0000CC">$CRLF</font><font color="#006600">))!==</font><font color="#0000CC">false</font><font color="#006600">)<br />&nbsp; &nbsp; {<br />&nbsp; &nbsp; &nbsp; &nbsp; </font><font color="#0000CC">$load_average </font><font color="#006600">= </font><font color="#0000CC">substr</font><font color="#006600">(</font><font color="#0000CC">$str</font><font color="#006600">,</font><font color="#0000CC">0</font><font color="#006600">,</font><font color="#0000CC">$pos</font><font color="#006600">);<br />&nbsp; &nbsp; &nbsp; &nbsp; if ((</font><font color="#0000CC">$pos</font><font color="#006600">=</font><font color="#0000CC">strpos</font><font color="#006600">(</font><font color="#0000CC">$str</font><font color="#006600">,</font><font color="#CC0000">"up"</font><font color="#006600">))!==</font><font color="#0000CC">false</font><font color="#006600">) </font><font color="#0000CC">$load_average </font><font color="#006600">= </font><font color="#0000CC">substr</font><font color="#006600">(</font><font color="#0000CC">$load_average</font><font color="#006600">,</font><font color="#0000CC">0</font><font color="#006600">,</font><font color="#0000CC">$pos</font><font color="#006600">);<br />&nbsp; &nbsp; }<br />}<br />else<br />if ((</font><font color="#0000CC">$pos</font><font color="#006600">=</font><font color="#0000CC">strpos</font><font color="#006600">(</font><font color="#0000CC">$str</font><font color="#006600">,</font><font color="#CC0000">"load average:"</font><font color="#006600">))!==</font><font color="#0000CC">false</font><font color="#006600">)<br />{<br />&nbsp; &nbsp; </font><font color="#0000CC">$str </font><font color="#006600">= </font><font color="#0000CC">trim</font><font color="#006600">(</font><font color="#0000CC">substr</font><font color="#006600">(</font><font color="#0000CC">$str</font><font color="#006600">, </font><font color="#0000CC">$pos</font><font color="#006600">+</font><font color="#0000CC">strlen</font><font color="#006600">(</font><font color="#CC0000">"load average:"</font><font color="#006600">)));<br />&nbsp; &nbsp; if ((</font><font color="#0000CC">$pos</font><font color="#006600">=</font><font color="#0000CC">strpos</font><font color="#006600">(</font><font color="#0000CC">$str</font><font color="#006600">,</font><font color="#0000CC">$CRLF</font><font color="#006600">))!==</font><font color="#0000CC">false</font><font color="#006600">)<br />&nbsp; &nbsp; {<br />&nbsp; &nbsp; &nbsp; &nbsp; </font><font color="#0000CC">$load_average </font><font color="#006600">= </font><font color="#0000CC">substr</font><font color="#006600">(</font><font color="#0000CC">$str</font><font color="#006600">,</font><font color="#0000CC">0</font><font color="#006600">,</font><font color="#0000CC">$pos</font><font color="#006600">);<br />&nbsp; &nbsp; }<br />}<br />if ((</font><font color="#0000CC">$pos</font><font color="#006600">=</font><font color="#0000CC">strpos</font><font color="#006600">(</font><font color="#0000CC">$str</font><font color="#006600">,</font><font color="#CC0000">"processes:"</font><font color="#006600">))!==</font><font color="#0000CC">false</font><font color="#006600">)<br />{<br />&nbsp; </font><font color="#0000CC">$str </font><font color="#006600">= </font><font color="#0000CC">trim</font><font color="#006600">(</font><font color="#0000CC">substr</font><font color="#006600">(</font><font color="#0000CC">$str</font><font color="#006600">, </font><font color="#0000CC">$pos</font><font color="#006600">+</font><font color="#0000CC">strlen</font><font color="#006600">(</font><font color="#CC0000">"processes:"</font><font color="#006600">)));<br />&nbsp; if ((</font><font color="#0000CC">$pos</font><font color="#006600">=</font><font color="#0000CC">strpos</font><font color="#006600">(</font><font color="#0000CC">$str</font><font color="#006600">,</font><font color="#CC0000">","</font><font color="#006600">))!==</font><font color="#0000CC">false</font><font color="#006600">)<br />&nbsp; {<br />&nbsp; &nbsp; </font><font color="#0000CC">$running_processes </font><font color="#006600">= </font><font color="#0000CC">substr</font><font color="#006600">(</font><font color="#0000CC">$str</font><font color="#006600">,</font><font color="#0000CC">0</font><font color="#006600">,</font><font color="#0000CC">$pos</font><font color="#006600">);<br />&nbsp; }<br />}<br />else<br />if ((</font><font color="#0000CC">$pos</font><font color="#006600">=</font><font color="#0000CC">strpos</font><font color="#006600">(</font><font color="#0000CC">$str</font><font color="#006600">,</font><font color="#CC0000">"Tasks:"</font><font color="#006600">))!==</font><font color="#0000CC">false</font><font color="#006600">)<br />{<br />&nbsp; &nbsp; </font><font color="#0000CC">$str </font><font color="#006600">= </font><font color="#0000CC">trim</font><font color="#006600">(</font><font color="#0000CC">substr</font><font color="#006600">(</font><font color="#0000CC">$str</font><font color="#006600">, </font><font color="#0000CC">$pos</font><font color="#006600">+</font><font color="#0000CC">strlen</font><font color="#006600">(</font><font color="#CC0000">"Tasks:"</font><font color="#006600">)));<br />&nbsp; &nbsp; if ((</font><font color="#0000CC">$pos</font><font color="#006600">=</font><font color="#0000CC">strpos</font><font color="#006600">(</font><font color="#0000CC">$str</font><font color="#006600">,</font><font color="#CC0000">","</font><font color="#006600">))!==</font><font color="#0000CC">false</font><font color="#006600">)<br />&nbsp; &nbsp; </font><font color="#0000CC">$str </font><font color="#006600">= </font><font color="#0000CC">trim</font><font color="#006600">(</font><font color="#0000CC">substr</font><font color="#006600">(</font><font color="#0000CC">$str</font><font color="#006600">, </font><font color="#0000CC">$pos</font><font color="#006600">+</font><font color="#0000CC">1</font><font color="#006600">));<br />&nbsp; &nbsp; if ((</font><font color="#0000CC">$pos</font><font color="#006600">=</font><font color="#0000CC">strpos</font><font color="#006600">(</font><font color="#0000CC">$str</font><font color="#006600">,</font><font color="#CC0000">"run"</font><font color="#006600">))!==</font><font color="#0000CC">false</font><font color="#006600">)<br />&nbsp; &nbsp; {<br />&nbsp; &nbsp; &nbsp; &nbsp; </font><font color="#0000CC">$running_processes </font><font color="#006600">= </font><font color="#0000CC">substr</font><font color="#006600">(</font><font color="#0000CC">$str</font><font color="#006600">,</font><font color="#0000CC">0</font><font color="#006600">,</font><font color="#0000CC">$pos</font><font color="#006600">);<br />&nbsp; &nbsp; }<br />}<br />if ((</font><font color="#0000CC">$pos</font><font color="#006600">=</font><font color="#0000CC">strpos</font><font color="#006600">(</font><font color="#0000CC">$str</font><font color="#006600">,</font><font color="#CC0000">"Mem:"</font><font color="#006600">))!==</font><font color="#0000CC">false</font><font color="#006600">)<br />{<br />&nbsp; </font><font color="#0000CC">$str </font><font color="#006600">= </font><font color="#0000CC">trim</font><font color="#006600">(</font><font color="#0000CC">substr</font><font color="#006600">(</font><font color="#0000CC">$str</font><font color="#006600">, </font><font color="#0000CC">$pos</font><font color="#006600">+</font><font color="#0000CC">strlen</font><font color="#006600">(</font><font color="#CC0000">"Mem:"</font><font color="#006600">)));<br />&nbsp; if ((</font><font color="#0000CC">$pos</font><font color="#006600">=</font><font color="#0000CC">strpos</font><font color="#006600">(</font><font color="#0000CC">$str</font><font color="#006600">,</font><font color="#0000CC">$CRLF</font><font color="#006600">))!==</font><font color="#0000CC">false</font><font color="#006600">)<br />&nbsp; {<br />&nbsp; &nbsp; </font><font color="#0000CC">$available_memory </font><font color="#006600">= </font><font color="#0000CC">substr</font><font color="#006600">(</font><font color="#0000CC">$str</font><font color="#006600">, </font><font color="#0000CC">0</font><font color="#006600">, </font><font color="#0000CC">$pos</font><font color="#006600">);<br />&nbsp; }<br />}<br /><br /></font><font color="#FF9900">// Get open sockets<br /></font><font color="#0000CC">$open_sockets </font><font color="#006600">= </font><font color="#CC0000">"N/A"</font><font color="#006600">;<br /></font><font color="#0000CC">$buf </font><font color="#006600">= array();<br /></font><font color="#0000CC">exec</font><font color="#006600">(</font><font color="#CC0000">"ssh -l$USERNAME $SERVER "</font><font color="#0000CC">netstat </font><font color="#006600">-</font><font color="#0000CC">n </font><font color="#006600">| </font><font color="#0000CC">wc </font><font color="#006600">-</font><font color="#0000CC">l</font><font color="#CC0000">""</font><font color="#006600">,&amp;</font><font color="#0000CC">$buf</font><font color="#006600">);&nbsp;  <br /></font><font color="#0000CC">$open_sockets </font><font color="#006600">= </font><font color="#0000CC">trim</font><font color="#006600">(</font><font color="#0000CC">$buf</font><font color="#006600">&#91;</font><font color="#0000CC">0</font><font color="#006600">&#93;);&nbsp; &nbsp; &nbsp;  <br /><br /></font><font color="#FF9900">// Display server metrics<br /></font><font color="#006600">echo </font><font color="#CC0000">"== Server\r\n"</font><font color="#006600">;<br />echo </font><font color="#CC0000">"&nbsp; &nbsp; Load average: $load_average\r\n"</font><font color="#006600">;<br />echo </font><font color="#CC0000">"&nbsp; &nbsp; Open Sockets: $open_sockets\r\n"</font><font color="#006600">;<br />echo </font><font color="#CC0000">"   Running Processes: $running_processes\r\n"</font><font color="#006600">;<br />echo </font><font color="#CC0000">"&nbsp; Available memory: $available_memory\r\n"</font><font color="#006600">;<br />echo </font><font color="#CC0000">"\\r\"\n"</font><font color="#006600">;<br /><br /></font><font color="#FF9900">// Get running and connected threads<br /></font><font color="#0000CC">$db_threads_connected </font><font color="#006600">= </font><font color="#CC0000">"N/A"</font><font color="#006600">;<br /></font><font color="#0000CC">$db_running_threads </font><font color="#006600">= </font><font color="#CC0000">"N/A"</font><font color="#006600">;<br /></font><font color="#0000CC">mysql_connect</font><font color="#006600">(</font><font color="#0000CC">$DBHOST</font><font color="#006600">,</font><font color="#0000CC">$DBUSER</font><font color="#006600">,</font><font color="#0000CC">$DBPASS</font><font color="#006600">);<br /></font><font color="#0000CC">$Result </font><font color="#006600">= @</font><font color="#0000CC">mysql_query</font><font color="#006600">(</font><font color="#CC0000">"show status like '%thread%' "</font><font color="#006600">);<br /></font><font color="#0000CC">$cnt </font><font color="#006600">= @</font><font color="#0000CC">mysql_num_rows</font><font color="#006600">(</font><font color="#0000CC">$Result</font><font color="#006600">);<br />while (</font><font color="#0000CC">$cnt</font><font color="#006600">)<br />{&nbsp; <br />&nbsp; &nbsp; </font><font color="#0000CC">$cnt</font><font color="#006600">--;<br />&nbsp; &nbsp; if (!(</font><font color="#0000CC">$Row </font><font color="#006600">= @</font><font color="#0000CC">mysql_fetch_array</font><font color="#006600">(</font><font color="#0000CC">$Result</font><font color="#006600">))) continue;<br /><br />&nbsp; &nbsp; if (empty(</font><font color="#0000CC">$Row</font><font color="#006600">&#91;</font><font color="#CC0000">'Value'</font><font color="#006600">&#93;)) continue;<br /><br />&nbsp; &nbsp; if (</font><font color="#0000CC">Strcasecmp</font><font color="#006600">(</font><font color="#0000CC">$Row</font><font color="#006600">&#91;</font><font color="#CC0000">'Variable_name'</font><font color="#006600">&#93;,</font><font color="#CC0000">'Threads_connected'</font><font color="#006600">)==</font><font color="#0000CC">0</font><font color="#006600">)<br />&nbsp; &nbsp; </font><font color="#0000CC">$db_threads_connected </font><font color="#006600">= </font><font color="#0000CC">$Row</font><font color="#006600">&#91;</font><font color="#CC0000">'Value'</font><font color="#006600">&#93;;<br />&nbsp; &nbsp; else<br />&nbsp; &nbsp; if (</font><font color="#0000CC">Strcasecmp</font><font color="#006600">(</font><font color="#0000CC">$Row</font><font color="#006600">&#91;</font><font color="#CC0000">'Variable_name'</font><font color="#006600">&#93;,</font><font color="#CC0000">'Threads_running'</font><font color="#006600">)==</font><font color="#0000CC">0</font><font color="#006600">)<br />&nbsp; &nbsp; </font><font color="#0000CC">$db_running_threads </font><font color="#006600">= </font><font color="#0000CC">$Row</font><font color="#006600">&#91;</font><font color="#CC0000">'Value'</font><font color="#006600">&#93;;<br />}<br /><br /></font><font color="#FF9900">// Get queries per second<br /></font><font color="#0000CC">$Result </font><font color="#006600">= @</font><font color="#0000CC">mysql_query</font><font color="#006600">(</font><font color="#CC0000">"show status like 'questions' "</font><font color="#006600">);<br /></font><font color="#0000CC">$Row </font><font color="#006600">= @</font><font color="#0000CC">mysql_fetch_array</font><font color="#006600">(</font><font color="#0000CC">$Result</font><font color="#006600">);<br /></font><font color="#0000CC">$questions </font><font color="#006600">= </font><font color="#0000CC">$Row</font><font color="#006600">&#91;</font><font color="#CC0000">'Value'</font><font color="#006600">&#93;+</font><font color="#0000CC">0</font><font color="#006600">;<br /></font><font color="#0000CC">$Result </font><font color="#006600">= @</font><font color="#0000CC">mysql_query</font><font color="#006600">(</font><font color="#CC0000">"show status like 'uptime' "</font><font color="#006600">);<br /></font><font color="#0000CC">$Row </font><font color="#006600">= @</font><font color="#0000CC">mysql_fetch_array</font><font color="#006600">(</font><font color="#0000CC">$Result</font><font color="#006600">);<br /></font><font color="#0000CC">$uptime </font><font color="#006600">= </font><font color="#0000CC">$Row</font><font color="#006600">&#91;</font><font color="#CC0000">'Value'</font><font color="#006600">&#93;+</font><font color="#0000CC">0</font><font color="#006600">;<br /></font><font color="#0000CC">$db_queries_per_second </font><font color="#006600">= </font><font color="#0000CC">number_format</font><font color="#006600">(</font><font color="#0000CC">$questions</font><font color="#006600">/</font><font color="#0000CC">$uptime</font><font color="#006600">,</font><font color="#0000CC">0</font><font color="#006600">);<br /><br /></font><font color="#FF9900">// Get open tables<br /></font><font color="#0000CC">$db_open_tables </font><font color="#006600">= </font><font color="#CC0000">"N/A"</font><font color="#006600">;<br /></font><font color="#0000CC">$Result </font><font color="#006600">= @</font><font color="#0000CC">mysql_query</font><font color="#006600">(</font><font color="#CC0000">"show status like '%tables%' "</font><font color="#006600">);<br /></font><font color="#0000CC">$cnt </font><font color="#006600">= @</font><font color="#0000CC">mysql_num_rows</font><font color="#006600">(</font><font color="#0000CC">$Result</font><font color="#006600">);<br />while (</font><font color="#0000CC">$cnt</font><font color="#006600">)<br />{<br />&nbsp; &nbsp; </font><font color="#0000CC">$cnt</font><font color="#006600">--;<br />&nbsp; &nbsp; if (!(</font><font color="#0000CC">$Row </font><font color="#006600">= @</font><font color="#0000CC">mysql_fetch_array</font><font color="#006600">(</font><font color="#0000CC">$Result</font><font color="#006600">))) continue;<br /><br />&nbsp; &nbsp; if (empty(</font><font color="#0000CC">$Row</font><font color="#006600">&#91;</font><font color="#CC0000">'Value'</font><font color="#006600">&#93;)) continue;<br />&nbsp; &nbsp; if (</font><font color="#0000CC">Strcasecmp</font><font color="#006600">(</font><font color="#0000CC">$Row</font><font color="#006600">&#91;</font><font color="#CC0000">'Variable_name'</font><font color="#006600">&#93;,</font><font color="#CC0000">'Open_tables'</font><font color="#006600">)==</font><font color="#0000CC">0</font><font color="#006600">)<br />&nbsp; &nbsp; </font><font color="#0000CC">$db_open_tables </font><font color="#006600">= </font><font color="#0000CC">$Row</font><font color="#006600">&#91;</font><font color="#CC0000">'Value'</font><font color="#006600">&#93;;<br />}<br /><br /></font><font color="#FF9900">// Get query response<br /></font><font color="#0000CC">$Result </font><font color="#006600">= @</font><font color="#0000CC">mysql_query</font><font color="#006600">(</font><font color="#CC0000">"SELECT 1"</font><font color="#006600">);<br /></font><font color="#0000CC">$Row </font><font color="#006600">= @</font><font color="#0000CC">mysql_fetch_row</font><font color="#006600">(</font><font color="#0000CC">$Result</font><font color="#006600">);<br /></font><font color="#0000CC">$db_query_response </font><font color="#006600">= </font><font color="#0000CC">$Row</font><font color="#006600">&#91;</font><font color="#0000CC">0</font><font color="#006600">&#93;==</font><font color="#CC0000">'1' </font><font color="#006600">? </font><font color="#CC0000">"Good" </font><font color="#006600">: </font><font color="#CC0000">"BAD"</font><font color="#006600">;<br /><br /></font><font color="#FF9900">// Get total number of tables<br /></font><font color="#006600">@</font><font color="#0000CC">mysql_query</font><font color="#006600">(</font><font color="#CC0000">"use $DBNAME"</font><font color="#006600">);<br /></font><font color="#0000CC">$Result </font><font color="#006600">= @</font><font color="#0000CC">mysql_query</font><font color="#006600">(</font><font color="#CC0000">"show tables"</font><font color="#006600">);<br /></font><font color="#0000CC">$db_tables_in_database </font><font color="#006600">= @</font><font color="#0000CC">mysql_num_rows</font><font color="#006600">(</font><font color="#0000CC">$Result</font><font color="#006600">);<br /><br /></font><font color="#FF9900">// Display database metrics<br /></font><font color="#006600">echo </font><font color="#CC0000">"== Database\r\n"</font><font color="#006600">;<br />echo </font><font color="#CC0000">"&nbsp;  Running Threads: $db_running_threads\r\n"</font><font color="#006600">;<br />echo </font><font color="#CC0000">"   Threads Connected: $db_threads_connected\r\n"</font><font color="#006600">;<br />echo </font><font color="#CC0000">"  Queries Per Second: $db_queries_per_second\r\n"</font><font color="#006600">;<br />echo </font><font color="#CC0000">"&nbsp; &nbsp;  Open Tables: $db_open_tables\r\n"</font><font color="#006600">;<br />echo </font><font color="#CC0000">"&nbsp;   Query Response: $db_query_response\r\n"</font><font color="#006600">;<br />echo </font><font color="#CC0000">"&nbsp; Number of tables: $db_tables_in_database\r\n"</font><font color="#006600">;  </font><font color="#0000CC"></font></span></div>
<br />
The output of the script will look something like this:<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">== Server<BR>&nbsp; &nbsp; &nbsp; &nbsp; Load average: 0.09,&nbsp; 0.23,&nbsp; 0.23&nbsp; <BR>&nbsp; &nbsp; &nbsp; &nbsp; Open Sockets: 226<BR>&nbsp;  Running Processes: 1 running<BR>&nbsp; &nbsp; Available memory: 2203M Active, 112M Buf, 4668K Free<BR><BR>== Database<BR>&nbsp; &nbsp;  Running Threads: 3<BR>&nbsp;  Threads Connected: 16<BR>&nbsp; Queries Per Second: 320<BR>&nbsp; &nbsp; &nbsp; &nbsp;  Open Tables: 200<BR>&nbsp; &nbsp; &nbsp; Query Response: Good<BR>&nbsp; &nbsp; Number of tables: 1648</code><hr />
</div>
<br />
<b>Tip:</b> If you're looking to monitor dozens of servers, consider applying our <a href="http://www.softwareprojects.com/resources/programming/t-ssh-no-password-without-any-private-keys-its-magi-1880.html" target="_blank">ssh no password</a> approach, to save the hassle of having to exchange private keys with each server.]]></description>

		<wfw:commentRss>http://www.softwareprojects.com/resources/programming/t-do-it-yourself-web-server-and-database-m-1889.html</wfw:commentRss>
		<feedburner:origLink>http://www.softwareprojects.com/resources/programming/t-do-it-yourself-web-server-and-database-m-1889.html</feedburner:origLink>

</item>
<item>
<title><![CDATA[Product Launch Marketing: Quickest path to a 6 figure monthly cashflow]]></title>
<link>http://www.softwareprojects.com/resources/traffic-attract-customers/t-product-launch-marketing-quickest-path-1886.html</link>
<pubDate>Wed, 21 Oct 2009 04:49:28 GMT</pubDate>
<dc:creator><![CDATA[Kate Richards]]></dc:creator>
<category><![CDATA[Traffic - Attract Customers]]></category>
<guid isPermaLink="false">http://www.softwareprojects.com/resources/traffic-attract-customers/t-product-launch-marketing-quickest-path-1886.html</guid>
<description><![CDATA[A <b>Product Launch</b> is the process of building anticipation and emphasizing scarcity in a hungry market, towards the release of a new product / service, positioned to have the potential to make a significant  impact on the target customer's life. <br />
<br />
In the Internet Marketing world, Product Launches are powerful marketing vehicles used by Information-Marketers to drive a massive amount of traffic on a specific day ("Launch day"), with the goal of converting the wave of anonymous traffic into qualified leads and then paying customers.<br />
<br />
For the past 5 years, <a href="http://www.softwareprojects.com" target="_blank">SPI</a> has been instrumental in orchestrating some of the largest most-successful product launches online, working with leading information marketers on applying time-tested techniques to generate hundreds of millions of dollars in product revenues.<br />
<br />
Some of the recent product launches we handled include ListBuilding, GoogleCashDetective, 7FigurePPCSecrets, LaunchTree, AffiliateClassroom, PPCClassroom, DirectResponseMarketing. <br />
<br />
<b>Why does it work</b><br />
<br />
Product Launch Marketing works so well because they build on two fundamental human traits:<br />
<br />
#1. <a href="http://en.wikipedia.org/wiki/Herd_mentality" target="_blank">Herd Mentality</a> - Follow the leaders<br />
In the weeks building to the launch, opinion leaders and peers within your industry, will all glorify how great this product is going to be and why you absolutely must have it.<br />
<br />
#2. <a href="http://en.wikipedia.org/wiki/Scarcity" target="_blank">Scarcity</a> - Desire to want what we can't have<br />
Using a limited number of units, fixed close date, early-bird discounts, one-time-offers and other tactics, the company will build the impression you must act fast or lose the opportunity to own the product forever.<br />
<br />
Examples of great well-planned product launches: The iPhone, "The Secret" DVD, StomperNet 3.0, Gary Vaynerchuk's CrushIt book. <br />
<br />
<b>In Numbers</b><br />
<br />
A typical Internet Marketing Product Launch these days, yields $1m (One Million Dollars) on launch day, followed by $200k in monthly residual payments from a continuity program. <br />
<br />
It is far easier to convince 2,000 prospects to pay $99 a month, than it is to direct-sell a few large accounts in order to generate the equivalent of $200k in monthly revenues.<br />
<br />
1,000 users paying $99 a month = $100k a month<br />
2,000 users paying $50 a month = $100k a month<br />
4,000 users paying $25 a month = $100k a month<br />
<br />
50% of the revenues are often paid back to affiliates.  <br />
20% is the average three-months drop-out rate.<br />
<br />
<b>The SPI Product Launch Program</b><br />
<br />
With the "Product Launch Program", we are now helping dozens of companies in various industries, capitalize on this phenomenal marketing strategy.<br />
<br />
The SPI Product Launch Program, is not a how-to tutorial, or an online course.  <br />
<br />
This program is a joint-venture between you and SPI, whereby our company will work with you, hands-on, on every aspect of your product launch in a joint effort to make it a big success.<br />
<br />
What you can expect from SPI, during this process:<br />
<br />
* Hands-on consulting<br />
* Introduction to leading information-marketing affiliates<br />
* Access to case studies, analytics and proven tactics, used by leading information marketers<br />
* Access to live front-end and back-office systems, so that you can learn what works best <br />
* Professional services: Landing page design, Hosting, Affiliate system, Payment solutions<br />
* PLR: Videos and mp3 files to complement your member's-only content<br />
* Membership system integration (Wordpress+plugin / aMember / SPI)<br />
* Load testing, to ensure your setup can handle launch-day traffic<br />
* Affiliate emails autoresponder kit<br />
* Corporate address, Call center, Help desk<br />
* Ongoing Software development / website customizations / graphic design<br />
<br />
<b>Application Process</b><br />
<br />
Our success over the years has made this service very popular.  Committed to maintaining our strong reputation, SPI dedicates a lot of resources to every individual product launch we are involved with.<br />
<br />
Unfortunately we cannot blindly accept new clients into this program.<br />
<br />
Please contact your account manager (or <a href="http://www.softwareprojects.com/support_email.php" target="_blank">email us here</a>) for details on how to apply.]]></description>

		<wfw:commentRss>http://www.softwareprojects.com/resources/traffic-attract-customers/t-product-launch-marketing-quickest-path-1886.html</wfw:commentRss>
		<feedburner:origLink>http://www.softwareprojects.com/resources/traffic-attract-customers/t-product-launch-marketing-quickest-path-1886.html</feedburner:origLink>

</item>
<item>
<title><![CDATA[SSH no password without any private keys. It's magic!]]></title>
<link>http://www.softwareprojects.com/resources/programming/t-ssh-no-password-without-any-private-keys-1880.html</link>
<pubDate>Thu, 08 Oct 2009 14:18:17 GMT</pubDate>
<dc:creator><![CDATA[Michel Nadeau]]></dc:creator>
<category><![CDATA[Programming]]></category>
<guid isPermaLink="false">http://www.softwareprojects.com/resources/programming/t-ssh-no-password-without-any-private-keys-1880.html</guid>
<description><![CDATA[We all know that one can configure SSH to login automatically by adding the client's public key to the server's ~/.ssh/authorized_keys file. But what if you need to run commands on 200 machines and don't want to login to every single machine to add the key? Search no more, this tutorial has the answer!<br />
<br />
<font size="4">1. Installing sshpass</font><br />
<br />
sshpass is a tool for non-interactivly performing password authentication with SSH's so called "interactive keyboard password authentication".<br />
<br />
Here's a standard SSH connect command:<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">debian_I:~# ssh -l root localhost<BR>The authenticity of host 'localhost (127.0.0.1)' can't be established.<BR>RSA key fingerprint is b4:e9:e7:56:a2:b4:89:9b:d8:fd:7e:8e:f1:e4:1d:9f.<BR><b>Are you sure you want to continue connecting (yes/no)? yes</b><BR>Warning: Permanently added 'localhost' (RSA) to the list of known hosts.<BR><b>root@localhost's password:</b><BR>Last login: Thu Oct&nbsp; 8 09:35:41 2009 from localhost<BR>Linux debian_I 2.6.18-6-686 #1 SMP i686<BR>debian_I:~#</code><hr />
</div>
<br />
First you have to answer "yes" to accept the host key and then to enter the password.<br />
<br />
With sshpass, you are able to specify the password on the command line and skip this step. Here's how to install it:<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">mkdir -p /usr/local/src/<BR>cd /usr/local/src/<BR>wget http://downloads.sourceforge.net/project/sshpass/sshpass/1.04/sshpass-1.04.tar.gz?use_mirror=iweb<BR>tar xvfz sshpass-1.04.tar.gz<BR>cd sshpass-1.04<BR>./configure<BR>make<BR>make install</code><hr />
</div>
<br />
sshpass is now ready to be used!<br />
<br />
<font size="4">2. Using sshpass</font><br />
<br />
The sshpass' syntax is:<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">sshpass -p [password] [ssh command]</code><hr />
</div>
<br />
So instead of doing:<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">ssh -l root localhost</code><hr />
</div>
<br />
You can simply do:<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">sshpass -p myrootpass ssh -l root localhost</code><hr />
</div>
<br />
You will be automatically logged in, without any password prompt:<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">debian_I:~# sshpass -p myrootpass ssh -l root localhost<BR>Last login: Thu Oct&nbsp; 8 09:52:04 2009 from localhost<BR>Linux debian_I 2.6.18-6-686 #1 SMP i686<BR>debian_I:~#</code><hr />
</div>
<br />
<font size="4">3. Automatically accepting host keys</font><br />
<br />
The last problem is this prompt:<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">The authenticity of host 'localhost (127.0.0.1)' can't be established.<BR>RSA key fingerprint is b4:e9:e7:56:a2:b4:89:9b:d8:fd:7e:8e:f1:e4:1d:9f.<BR>Are you sure you want to continue connecting (yes/no)? yes</code><hr />
</div>
<br />
When you're using sshpass to connect on a single machine that you use often, it's not a big deal because you will get the prompt once and never again after. But if you want to connect to 200 machines, you definitely don't want to type "yes" 200 times.<br />
<br />
To fix this issue, simply add this line in /etc/ssh/ssh_config on the CLIENT machine:<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">StrictHostKeyChecking=no</code><hr />
</div>
<br />
With this setting enabled, SSH will automatically accept the host keys and will not prompt you about it.<br />
<br />
<font size="4">4. Automating the process</font><br />
<br />
This section will show you how to easily automate the process of running commands on any number of machines you want.<br />
<br />
First you will need a file containing the hostname, username and password for each of the servers you want to run commands on, in a CSV format. For example:<br />
<br />
<b>ssh_magic.csv:</b><br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">someserver.com,root,123456<BR>someotherserver.com,sshadmin,abcdef<BR>onelastserver.com,root,123456</code><hr />
</div>
<br />
Then you will create this bash script:<br />
<br />
<b>ssh_magic.sh:</b><br />
<div style="margin:10px;  padding:4px; border:1px inset; background-color: #FDF8EB">

	<span style="margin:0px; width:550px; padding:4px;  overflow:auto; "><font face="courier new">  </font><font color="#FF9900">#!/bin/sh<br /><br /># Loop ssh_magic.csv<br /></font><font color="#006600">for </font><font color="#0000CC">LINE in </font><font color="#006600">$(</font><font color="#0000CC">cat ssh_magic</font><font color="#006600">.</font><font color="#0000CC">csv</font><font color="#006600">)<br />do<br />&nbsp; &nbsp;   </font><font color="#FF9900"># Split line<br />&nbsp; &nbsp;   </font><font color="#0000CC">host</font><font color="#006600">=$(echo </font><font color="#0000CC">$LINE </font><font color="#006600">| </font><font color="#0000CC">cut </font><font color="#006600">-</font><font color="#0000CC">d </font><font color="#CC0000">"," </font><font color="#006600">-</font><font color="#0000CC">f1</font><font color="#006600">)<br />&nbsp; &nbsp;   </font><font color="#0000CC">user</font><font color="#006600">=$(echo </font><font color="#0000CC">$LINE </font><font color="#006600">| </font><font color="#0000CC">cut </font><font color="#006600">-</font><font color="#0000CC">d </font><font color="#CC0000">"," </font><font color="#006600">-</font><font color="#0000CC">f2</font><font color="#006600">)<br />&nbsp; &nbsp;   </font><font color="#0000CC">pass</font><font color="#006600">=$(echo </font><font color="#0000CC">$LINE </font><font color="#006600">| </font><font color="#0000CC">cut </font><font color="#006600">-</font><font color="#0000CC">d </font><font color="#CC0000">"," </font><font color="#006600">-</font><font color="#0000CC">f3</font><font color="#006600">)<br />&nbsp; &nbsp;   <br />&nbsp; &nbsp;   </font><font color="#FF9900"># Display server info<br />&nbsp; &nbsp;   </font><font color="#006600">echo </font><font color="#CC0000">""<br />&nbsp; &nbsp;   </font><font color="#006600">echo </font><font color="#CC0000">"HOSTNAME: $host"<br />&nbsp; &nbsp;   </font><font color="#006600">echo </font><font color="#CC0000">""<br />&nbsp; &nbsp;   <br />&nbsp; &nbsp;   </font><font color="#FF9900"># Run commands<br />&nbsp; &nbsp;   </font><font color="#0000CC">sshpass </font><font color="#006600">-</font><font color="#0000CC">p $pass ssh </font><font color="#006600">-</font><font color="#0000CC">l $user $host </font><font color="#CC0000">"uname -a"<br />&nbsp; &nbsp;   </font><font color="#0000CC">sshpass </font><font color="#006600">-</font><font color="#0000CC">p $pass ssh </font><font color="#006600">-</font><font color="#0000CC">l $user $host </font><font color="#CC0000">"df -h"<br />&nbsp; &nbsp;   <br />&nbsp; &nbsp;   </font><font color="#006600">echo </font><font color="#CC0000">""<br />&nbsp; &nbsp;   </font><font color="#006600">echo </font><font color="#CC0000">"===================================="<br /></font><font color="#0000CC">done<br /><br /></font><font color="#006600">echo </font><font color="#CC0000">""<br /></font><font color="#006600">echo </font><font color="#CC0000">"DONE"<br /></font><font color="#006600">echo </font><font color="#CC0000">""  </font><font color="#0000CC"></font></span></div>
<br />
Simply place ssh_magic.csv and ssh_magic.sh together and run the script.<br />
<br />
<font size="4">Conclusion</font><br />
<br />
You now know how to run commands on any number of SSH machines, without any prompt! Make sure you check the other ways to pass the password to sshpass - they offer more secure ways than directly on the command line with the -p option.]]></description>

		<wfw:commentRss>http://www.softwareprojects.com/resources/programming/t-ssh-no-password-without-any-private-keys-1880.html</wfw:commentRss>
		<feedburner:origLink>http://www.softwareprojects.com/resources/programming/t-ssh-no-password-without-any-private-keys-1880.html</feedburner:origLink>

</item>
<item>
<title><![CDATA[We're Hiring! Looking for Technical Account Managers, Team Leaders]]></title>
<link>http://www.softwareprojects.com/resources/the-basics/t-were-hiring-looking-for-technical-acco-1877.html</link>
<pubDate>Thu, 08 Oct 2009 02:30:13 GMT</pubDate>
<dc:creator><![CDATA[Mike Peters]]></dc:creator>
<category><![CDATA[The Basics]]></category>
<guid isPermaLink="false">http://www.softwareprojects.com/resources/the-basics/t-were-hiring-looking-for-technical-acco-1877.html</guid>
<description><![CDATA[<a href="http://www.softwareprojects.com" target="_blank">Software Projects</a>, a New York based full-service Internet Marketing firm, is seeking a bright, articulate, detail-oriented, and technical applicant interested in joining our group of software professionals. <br />
<br />
As a Technical Account Manager, you will work directly with clients, translating client vision into technical requirements, submit weekly plans, manage teams of engineers and oversee all software development work. <br />
<br />
You will brain-storm with engineers, think outside the box, provide direction and leadership, while directly interacting with some of the best minds in our industry. <br />
<br />
<b>== Requirements:</b> <br />
* Excellent problem solving skills <br />
* Leader, Motivator, Confidence, Energetic <br />
* Superb communication skills with the know-how to verbalize ideas into technical requirements <br />
* Minimum 2 years programming experience (PHP / C / Perl) <br />
* Experience with FreeBSD/Linux a great plus <br />
<br />
<b>== Responsibilities: </b><br />
* Translate client wants into requirements <br />
* Plan projects, oversee software development <br />
* Solve Problems<br />
* Update clients on progress <br />
* Maintain high client satisfaction <br />
<br />
<b>== Location:</b> <br />
You will be working from your home office for the first six months. After that time, you will have the option of relocating to one of our offices or continuing to work from home. <br />
<br />
<b>== Next steps:</b> <br />
Send an email to <a href="mailto:hr@softwareprojects.com" target="_blank">hr@softwareprojects.com</a> with your resume and let us know when is a good time to chat. <br />
<br />
Didn't update your resume in the last 2 years? That's fine. It's all about your experience and skills! Send us a quick cover-letter and we'll follow-up.]]></description>

		<wfw:commentRss>http://www.softwareprojects.com/resources/the-basics/t-were-hiring-looking-for-technical-acco-1877.html</wfw:commentRss>
		<feedburner:origLink>http://www.softwareprojects.com/resources/the-basics/t-were-hiring-looking-for-technical-acco-1877.html</feedburner:origLink>

</item>
<item>
<title><![CDATA[How to install basic Squid on FreeBSD]]></title>
<link>http://www.softwareprojects.com/resources/programming/t-how-to-install-basic-squid-on-freebsd-1874.html</link>
<pubDate>Fri, 02 Oct 2009 19:51:35 GMT</pubDate>
<dc:creator><![CDATA[Michel Nadeau]]></dc:creator>
<category><![CDATA[Programming]]></category>
<guid isPermaLink="false">http://www.softwareprojects.com/resources/programming/t-how-to-install-basic-squid-on-freebsd-1874.html</guid>
<description><![CDATA[Squid is a caching proxy for the Web supporting HTTP, HTTPS, FTP, and more. It reduces bandwidth and improves response times by caching and reusing frequently-requested web pages. Squid has extensive access controls and makes a great server accelerator. It runs on most available operating systems, including Windows and is licensed under the GNU GPL.<br />
<br />
This tutorial describes how to install a very simple implementation of Squid on your network.<br />
<br />
<font size="4">1. Getting started</font><br />
<br />
The first thing you want to do is to download Squid. In this tutorial, we're going to work in the /usr/local/src directory.<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">$ mkdir -p /usr/local/src<BR>$ cd /usr/local/src<BR>$ wget http://www.squid-cache.org/Versions/v3/3.0/squid-3.0.STABLE19.tar.gz</code><hr />
</div>
<br />
Then you want to extract Squid and change to its directory:<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">$ tar xvfz squid-3.0.STABLE19.tar.gz<BR>$ cd squid-3.0.STABLE19</code><hr />
</div>
<br />
We're now ready to compile and install Squid!<br />
<br />
<font size="4">2. Compiling/installing Squid</font><br />
<br />
Compiling and installing Squid is very easy:<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">$ ./configure --prefix=/usr/local/squid<BR>$ make all<BR>$ make install</code><hr />
</div>
<br />
If the configure command fails because you don't have Perl, you can simply install it like this:<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">$ pkg_add -r perl</code><hr />
</div>
<br />
Then re-run the configure command.<br />
<br />
<font size="4">3. Configuring Squid</font><br />
<br />
First of all, you need to add the "visible_hostname" setting in your Squid configuration file. The main configuration file is:<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">/usr/local/squid/etc/squid.conf</code><hr />
</div>
<br />
Open it with your favorite editor and find this block:<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">#&nbsp; TAG: visible_hostname</code><hr />
</div>
<br />
At the end of the block (before the next "TAG" block), insert a new line and put something like this:<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">visible_hostname freebsd</code><hr />
</div>
<br />
Replace "freebsd" with any hostname you want Squid to use - it can be a local hostname or a fully qualified domain name. Save the file.<br />
<br />
Now you need to adjust some permissions before Squid can be initialized...<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">$ mkdir -p /usr/local/squid/var/logs/<BR>$ chmod 777 /usr/local/squid/var/logs/<BR><BR>$ mkdir -p /usr/local/squid/var/cache/<BR>$ chmod 777 /usr/local/squid/var/cache/</code><hr />
</div>
<br />
Squid can now be initialized. Use this command:<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">/usr/local/squid/sbin/squid -z</code><hr />
</div>
<br />
Squid is now ready to run!<br />
<br />
<font size="4">4. Starting/stopping Squid</font><br />
<br />
<b>Starting Squid:</b><br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">/usr/local/squid/sbin/squid</code><hr />
</div>
<br />
<b>Stopping Squid:</b><br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">kill -9 `cat /usr/local/squid/var/logs/squid.pid`</code><hr />
</div>
<br />
You can start Squid automatically at boot time by creating the /usr/local/etc/rc.d/squid.sh file with this content:<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">#!/bin/sh<BR>/usr/local/squid/sbin/squid</code><hr />
</div>
<br />
You also need to allow execution of this file:<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">$ chmod 755 /usr/local/etc/rc.d/squid.sh</code><hr />
</div>
<br />
<font size="4">5. Using Squid with your browser</font><br />
<br />
To use Squid with your browser, you simply need to set it as a proxy in your browser's settings. Squid is listening on TCP port 3128. So if your FreeBSD machine's IP is 1.2.3.4, you will configure your proxy to be 1.2.3.4, port 3128.<br />
<br />
Once configured, all the traffic over the chosen protocols (usually your browser lets you choose for which protocols you want to use a proxy) will go through your Squid server.<br />
<br />
<font size="4">6. "Overriding" Web sites addresses</font><br />
<br />
The first place where Squid is looking when it comes to resolving URL's to IP addresses is in the /etc/hosts file. If you want to "override" Web sites addresses, simply add them in the /etc/hosts file along with the IP address where you want to redirect traffic.<br />
<br />
For example, let's say that you want your Squid's users to be sent to 1.2.3.4 when they request <a href="http://www.google.com" target="_blank">www.google.com</a> instead of to the real google.com. To do so, you will add this line in your /etc/hosts file:<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">1.2.3.4 google.com www.google.com</code><hr />
</div>
<br />
Replace "1.2.3.4" with the IP of the machine where you want to redirect traffic. This isn't really a "redirect" as the users will never see 1.2.3.4 in their browser. For them, it will look like just as if they were really on <a href="http://www.google.com" target="_blank">www.google.com</a>, not on 1.2.3.4.<br />
<br />
<b>NOTE</b>: you NEED to restart Squid when you make changes in /etc/hosts.<br />
<br />
<font size="4">Conclusion</font><br />
<br />
Squid is very simple to install and use. Though, it's also VERY powerful and flexible: it has literally thousands of options! This tutorial only covered the very basic use - refer to the Squid users guide if you want to customize squid.conf.<br />
<br />
<font size="4">Resources</font><br />
<br />
* <a href="http://www.squid-cache.org/" target="_blank">Squid</a><br />
* <a href="http://www.squid-cache.org/Doc/config/" target="_blank">Configuration guide</a><br />
* <a href="http://wiki.squid-cache.org/ConfigExamples/" target="_blank">Configuration examples</a><br />
* <a href="http://www.deckle.co.za/squid-users-guide/" target="_blank">Users guide</a>]]></description>

		<wfw:commentRss>http://www.softwareprojects.com/resources/programming/t-how-to-install-basic-squid-on-freebsd-1874.html</wfw:commentRss>
		<feedburner:origLink>http://www.softwareprojects.com/resources/programming/t-how-to-install-basic-squid-on-freebsd-1874.html</feedburner:origLink>

</item>
<item>
<title><![CDATA[How to convert mbox mailboxes to the maildir format]]></title>
<link>http://www.softwareprojects.com/resources/programming/t-how-to-convert-mbox-mailboxes-to-the-mai-1871.html</link>
<pubDate>Sun, 20 Sep 2009 07:35:13 GMT</pubDate>
<dc:creator><![CDATA[Adrian Singer]]></dc:creator>
<category><![CDATA[Programming]]></category>
<guid isPermaLink="false">http://www.softwareprojects.com/resources/programming/t-how-to-convert-mbox-mailboxes-to-the-mai-1871.html</guid>
<description><![CDATA[This weekend we converted all SPI <a href="http://www.softwareprojects.com/website/multihomed-webhosting" target="_blank">mutlihomed hosting</a> email mailboxes from the mbox format to maildir.<br />
<br />
<b>What is the difference between mbox and maildir?</b><br />
<br />
<b>Mbox</b> is the traditional way of storing mail messages in the Unix world. In this format, a regular text file which serves as the mail user's mailbox file is created.<br />
<br />
<u>Pros</u>: Format is universally supported, Appending a new mail into the mailbox file is fast, Searching text inside a single mailbox file is fast.<br />
<br />
<u>Cons</u>: Has file locking problems, Has problems when used with network file systems, Format is prone to corruption.<br />
<br />
<b>Maildir</b> is a new way of storing mail messages. In this format, a directory usually named Maildir is created for each mail user. Under this directory are three more directories named new, cur and tmp.<br />
 <br />
<u>Pros</u>: Locating, retrieving and deleting a specific mail is fast, Minimal to no file locking needed, Immune to mailbox corruption (assuming the hardware will not fail).<br />
<br />
<u>Cons</u>: Some filesystems may not efficiently handle a large number of small files, Searching text, which requires all mail files to be opened is slow.<br />
<br />
<b>Why we chose Maildir</b><br />
<br />
We've decided to upgrade to Maildir because its more reliable (entire mailbox never fully corrupts) and thanks to no locking it is noticeably much faster to access your mail over Maildir.<br />
<br />
Ongoing mbox file locking issues were driving us nuts.<br />
<br />
SPI is using the <a href="http://www.dovecot.org/" target="_blank">Dovecot mail server</a> on all machines.  Dovecot is one of the highest performing IMAP servers.  Luckily it supports both mbox and maildir, so all we had to do was: Convert old email messages from mbox to maildir. <br />
<br />
<b>Mb2md</b><br />
<br />
<a href="http://batleth.sapienti-sat.org/projects/mb2md/" target="_blank">Mb2md</a> is a Perl script that takes one or more Mbox format mailbox files in a directory and convert them to Maildir format mailboxes.<br />
<br />
Replace USERNAME below with the unix username whose mailbox you are converting<br />
<br />
<b>Step 1:</b> Set environment variables for Mb2md<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">setenv MAIL /var/mail/USERNAME</code><hr />
</div>
<br />
<b>Step 2:</b> Convert the inbox folder and create Maildir folder<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">sudo -u USERNAME mb2md -m</code><hr />
</div>
<br />
<b>Step 3:</b> Convert other folders the user created<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">sudo -u USERNAME mb2md -s /home/USERNAME/mail/ -R</code><hr />
</div>
<br />
<b>Step 4:</b> Copy IMAP subscriptions<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">cp /home/USERNAME/mail/.subscriptions /home/USERNAME/Maildir/subscriptions</code><hr />
</div>
<br />
<b>Step 5:</b> Tell sendmail to deliver new mail to the user's /Maildir<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">cd /home/USERNAME<BR>echo '"|IFS='"' '"' &amp;&amp; exec /usr/local/bin/procmail -f || exit 75 #YOUR EMAIL NAME"' >> .forward<BR>chmod 644 .forward<BR>echo "DEFAULT="'$'"HOME/Maildir/" >> .procmailrc<BR>chmod 644 .procmailrc<BR>chown USERNAME:USERNAME .forward<BR>chown USERNAME:USERNAME .procmailrc</code><hr />
</div>
<br />
<b>Step 6:</b> Delete old mbox files<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">rm /var/mail/USERNAME<BR>rm -fdr /home/USERNAME/mail</code><hr />
</div>
<br />
<b>Testing &amp; Troubleshooting</b><br />
<br />
To test, use sendmail to send a test message to your user:<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">sendmail USEREMAIL<BR>subject: Test, please ignore<BR><BR>This is a test<BR>.</code><hr />
</div>
<br />
If all works well, your email message will be delivered to the user's Maildir.<br />
<br />
If you see the mail appended to /var/mail/USERNAME (do a tail -f /var/mail/USERNAME), this means sendmail is failing to invoke .procmailrc and deliver the email message to Maildir.<br />
<br />
This is usually due to the /home or /home/USERNAME folders not having the correct file permissions.<br />
<br />
Run this command to troubleshoot:<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">sendmail -v -Am -d11 USERNAME < /dev/null</code><hr />
</div>]]></description>

		<wfw:commentRss>http://www.softwareprojects.com/resources/programming/t-how-to-convert-mbox-mailboxes-to-the-mai-1871.html</wfw:commentRss>
		<feedburner:origLink>http://www.softwareprojects.com/resources/programming/t-how-to-convert-mbox-mailboxes-to-the-mai-1871.html</feedburner:origLink>

</item>
<item>
<title><![CDATA[How to run FreeBSD on Windows using VMware Server]]></title>
<link>http://www.softwareprojects.com/resources/programming/t-how-to-run-freebsd-on-windows-using-vmwa-1868.html</link>
<pubDate>Tue, 15 Sep 2009 15:31:25 GMT</pubDate>
<dc:creator><![CDATA[Michel Nadeau]]></dc:creator>
<category><![CDATA[Programming]]></category>
<guid isPermaLink="false">http://www.softwareprojects.com/resources/programming/t-how-to-run-freebsd-on-windows-using-vmwa-1868.html</guid>
<description><![CDATA[<a href="http://www.softwareprojects.com/resources/programming/t-how-to-run-freebsd-on-windows-using-virtualbox-1865.html" target="_blank">In a recent post</a>, we explained how to run FreeBSD on Windows using VirtualBox. Today we will show you how to achieve the same thing but using VMware Server. VirtualBox is a very nice application: it's fast, simple and lightweight; but VMware Server has some very interesting features to offer:<br />
<br />
* It can run any number of virtual machines in the background. You don't need to keep any window opened and you can simply access your virtual machines using SSH if you wish.<br />
<br />
* It supports any guest operating system, including 64-bit versions.<br />
<br />
* All the administration is done via a great Web interface.<br />
<br />
As VirtualBox, VMware Server is also 100% free. Another product that is competing VMware Server, and that is also free, is Microsoft VirtualServer. It has the same features but is harder to install, harder to use and is a lot more fragile. After months of testing, VMware Server proved to be the best on performance, stability and usability.<br />
<br />
<font size="4">1. Download VMware Server</font><br />
<br />
The first step is obviously to download VMware Server. Go there: <a href="http://www.vmware.com/products/server/" target="_blank">http://www.vmware.com/products/server/</a> and click on the "Download" button on the left. You will need to register to download the software. Once you're registered and logged in, copy the "VMware Server 2 for Windows" serial number displayed in the "Licensing" section of the page and paste it somewhere - you will need it later. Then grab the "VMware Server 2" EXE image under the "Binaries" section. The file is around 500MB.<br />
<br />
<font size="4">2. Install VMware Server</font><br />
<br />
Installing VMware Server is very straightforward: basically, you simply run the setup file and hit next, next, next, next... without changing anything. There's no real options except which shortcuts you want to create.<br />
<br />
At the end of the setup, you will be asked to enter your serial number. Because of the virtual network adapters VMware Server installs, you will also be required to reboot: you need to do it immediately if you want to go further in this tutorial.<br />
<br />
<font size="4">3. Download FreeBSD</font><br />
<br />
In this tutorial, we'll be installing FreeBSD 7.2 minimal. If you have a 64-bit CPU, download this one (amd64 release):<br />
<br />
<a href="ftp://ftp.freebsd.org/pub/FreeBSD/releases/amd64/ISO-IMAGES/7.2/7.2-RELEASE-amd64-disc1.iso" target="_blank">ftp://ftp.freebsd.org/pub/FreeBSD/re...md64-disc1.iso</a><br />
<br />
If you have a 32-bit CPU, download this one (i386 release):<br />
<br />
<a href="ftp://ftp.freebsd.org/pub/FreeBSD/releases/i386/ISO-IMAGES/7.2/7.2-RELEASE-i386-disc1.iso" target="_blank">ftp://ftp.freebsd.org/pub/FreeBSD/re...i386-disc1.iso</a><br />
<br />
The ISO file is around 600MB.<br />
<br />
<font size="4">4. Create the FreeBSD Virtual Machine</font><br />
<br />
Start the VMware Server Web Access using the Start Menu shortcut (called "Web Access") or use your favorite browser and go to this URL: <a href="http://127.0.0.1:8308/ui/" target="_blank">http://127.0.0.1:8308/ui/</a><br />
<br />
Log into the VMware Server Web Access using your Windows account.<br />
<br />
The first thing to do is to add a Datastore to your VMware Server configuration. To do so, click on your machine name on the left panel and click on the "Add Datastore" link on the right panel. The Datastore is a folder where everything about virtual machines will get created and stored. Simply give it a name and specify the directory (example: name: VM, directory: d:\VM).<br />
<br />
Click on the "Create Virtual Machine" on the right panel:<br />
<br />
* Name the virtual machine "FreeBSD", select the Datastore you've just created and hit next.<br />
<br />
* Choose "Other operating systems", choose "FreeBSD" (32 or 64-bit, depending on your CPU) in the combo box and hit next.<br />
<br />
* Assign the amount of memory you want your virtual machine to have (usually the recommended amount is quite good, unless you need a high-performance virtual machine). If you have a multi-core CPU (or many CPU's), you can choose the number of CPU's you want your virtual machine to use. Hit next when you're satisfied with your settings.<br />
<br />
* Select "Create a New Virtual Disk" and hit next.<br />
<br />
* Choose the size you want your virtual disk to have and hit next.<br />
<br />
* Select "Add a Network Adapter" and hit next.<br />
<br />
* Leave the settings to "Bridged" and hit next.<br />
<br />
* In the CD/DVD section, select "Use an ISO Image" and hit next.<br />
<br />
* Move the FreeBSD 7.2 ISO image you've just downloaded somewhere under the directory you're using as your Datastore. Then select it and hit OK. Then hit next.<br />
<br />
* Select "Don't Add a Floppy Drive"<br />
<br />
* Select "Don't Add a USB Controller"<br />
<br />
* Check "Power on your new virtual machine now" and Hit "Finish"<br />
<br />
<font size="4">5. Installing FreeBSD</font><br />
<br />
Now that your FreeBSD virtual machine is created, it's time to install FreeBSD! First of all, in the VMware Server Web Access, click on the FreeBSD virtual machine on the left panel. Then click on the "Console" tab on the right, and click anywhere in the black screen. A small console window will popup: that's your FreeBSD machine, just like if you were sitting in front of a computer running FreeBSD.<br />
<br />
NOTE: the console window "steals the focus"; at any time, press CTRL+ALT to release focus from this window. And simply click into the console window to use it.<br />
<br />
It should boot from the ISO image you've specified in the setup: it's now time to install FreeBSD:<br />
<br />
* Choose "United States" and hit enter.<br />
<br />
* Choose "Standard" and hit enter.<br />
<br />
* In the Disk Geometry screen, hit "a", then "q".<br />
<br />
* Choose "BootMgr" and hit enter.<br />
<br />
* In the Partition screen, hit "a", then "q".<br />
<br />
* In the "Choose Distributions" screen, select "Minimal" and hit space to check it. Then hit tab, then enter on the OK button.<br />
<br />
* Choose CD/DVD and hit enter. The base system will install.<br />
<br />
* Network:<br />
<br />
Hit "yes" to configure network.<br />
Choose the "em0" network interface.<br />
Hit "yes" to configure using DHCP.<br />
Enter an hostname and hit enter many times.<br />
Choose "no" to use this machine as a gateway.<br />
Hit "no" to enable inetd.<br />
Hit "yes" to enable SSH.<br />
Hit "no" to anonymous FTP.<br />
Hit "no" to NFS server.<br />
Hit "no" to NFS client.<br />
<br />
* Last settings:<br />
<br />
Hit "no" to customize console.<br />
Hit "yes" to timezone and choose your timezone.<br />
Hit "no" to PS/2.<br />
Hit "no" to package collection.<br />
Hit "no" to create a user.<br />
Set the "root" password.<br />
Hit "no" to visit the options menu.<br />
<br />
At the main menu, hit tab to go to the "Exit Install" option, hit enter and then hit "yes". Close the console. In the VMware Server Web Access, select the FreeBSD Virtual Machine on the left panel and hit the red "stop" sign at the top. Then hit the green "play" sign and return in the console. Your FreeBSD system should boot normally.<br />
<br />
<font size="4">6. Mounting a shared folder using Samba</font><br />
<br />
It's very convenient to be able to easily and quickly share files between your Windows and FreeBSD machine.<br />
<br />
First of all, share a folder on your Windows machine (ex: share). It can be any folder, just share it normally. Then choose a mount point for that folder on your FreeBSD (ex: /mnt/share). We're now going to configure your FreeBSD machine so the shared folder will be automatically mounted at boot time.<br />
<br />
Here's the sample informations (replace with yours):<br />
<br />
Windows machine: win<br />
Windows IP addr: 192.168.0.100<br />
Windows share: share<br />
Windows user: administrator<br />
Windows password: mypass<br />
FreeBSD mount point: /mnt/share (do not forget to create the directory!)<br />
<br />
<b>In /etc/nsmb.conf, add:</b><br />
NOTE: the caps are important<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">[WIN]<BR>addr=192.168.0.100<BR><BR>[WIN:ADMINISTRATOR]<BR>password=mypass</code><hr />
</div>
<br />
<b>Then in /etc/fstab, add:</b><br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">//administrator@win/share&nbsp; &nbsp; /mnt/share&nbsp; &nbsp; &nbsp; smbfs&nbsp;  rw&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 0&nbsp; &nbsp; &nbsp;  0</code><hr />
</div>
<br />
NOTE: before rebooting FreeBSD to test, I recommend testing the mounting manually with a command like this:<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">mkdir -p /mnt/tmp<BR>mount_smbfs //administrator@win/share /mnt/tmp</code><hr />
</div>
<br />
Finally, reboot your FreeBSD machine and then go check in your mount point (like /mnt/share) if it works! Try creating folders from FreeBSD and from Windows and verify if it's working correctly. If it's not, the problem is probably on the authentication side.<br />
<br />
<font size="4">7. Starting the virtual machine automatically</font><br />
<br />
One other great VMware Server feature is the ability to start virtual machines automatically when you boot Windows.<br />
<br />
To configure this, in the VMware Server Web Access, click on your Windows machine name on the left panel, and then click on "Edit Virtual Machine Startup/Shutdown Settings". Select your FreeBSD virtual machine and click "Move Up" to put it in the "Any Order" category.<br />
<br />
<font size="4">Conclusion</font><br />
<br />
You now have a FreeBSD virtual machine, acting just like if it was a real server sitting somewhere in your house! Virtual machines are great for development and testing. Please let me know if you have any problems getting this tutorial working!]]></description>

		<wfw:commentRss>http://www.softwareprojects.com/resources/programming/t-how-to-run-freebsd-on-windows-using-vmwa-1868.html</wfw:commentRss>
		<feedburner:origLink>http://www.softwareprojects.com/resources/programming/t-how-to-run-freebsd-on-windows-using-vmwa-1868.html</feedburner:origLink>

</item>
<item>
<title><![CDATA[How to run FreeBSD on Windows using VirtualBox]]></title>
<link>http://www.softwareprojects.com/resources/programming/t-how-to-run-freebsd-on-windows-using-virt-1865.html</link>
<pubDate>Sat, 05 Sep 2009 01:15:58 GMT</pubDate>
<dc:creator><![CDATA[Mike Peters]]></dc:creator>
<category><![CDATA[Programming]]></category>
<guid isPermaLink="false">http://www.softwareprojects.com/resources/programming/t-how-to-run-freebsd-on-windows-using-virt-1865.html</guid>
<description><![CDATA[<b>Step 1 - Download and install VirtualBox</b><br />
<br />
VirtualBox is a general-purpose full virtualizer for x86 hardware.  It allows running any flavor Unix system on a Windows box.<br />
<br />
You can download the latest version of VirtualBox for Windows Hosts <a href="http://www.virtualbox.org/wiki/Downloads" target="_blank">here</a><br />
<br />
<b>Step 2 - Download FreeBSD 6</b><br />
<br />
Download the single-file dvd iso here <a href="ftp://ftp.freebsd.org/pub/FreeBSD/releases/i386/ISO-IMAGES/6.4/6.4-RELEASE-i386-dvd1.iso.gz" target="_blank">FreeBSD 6.4 download repository</a> <br />
<br />
Download <a href="http://www.7-zip.org/download.html" target="_blank">7-zip</a> and extract the 6.4-RELEASE-i386-dvd1.iso.gz file to a folder on your machine<br />
<br />
<b>Step 3 - Create a new FreeBSD VirtualBox machine</b><br />
<br />
Create a new VirtualBox machine, selecting BSD as the operating system and FreeBSD as the version.<br />
<br />
<img src="http://api4.softwareprojects.com/temp/222.gif" border="0" alt="" /><br />
<br />
Click Next to accept all defaults, but when you get to the 'Virtual Disk Location and Size' screen, change the disk size to 50GB.<br />
<br />
Double-click the new machine to start it. <br />
<br />
<b>Step 4 - Install FreeBSD on new Virtual Machine</b><br />
<br />
You will be greeted with a 'Welcome to the first run' wizard.<br />
<br />
A 'Select Installation Media' screen will then popup.  Pick the 'Image File' option, click the icon and locate the folder on your machine where you previously saved the FreeBSD iso file.<br />
<br />
<img src="http://www.softwareprojects.com/blogimages/1.png" border="0" alt="" /><br />
<br />
Click next a few times, keeping all default options.<br />
<br />
FreeBSD install will boot in the VirtualBox<br />
<br />
Select OK for United States<br />
Select Standard Installation<br />
Click A for 'Use Entire Disk', followed by Q<br />
Click Enter for BootMgr<br />
Click A for 'Auto Defaults', followed by Q<br />
Select option 4 (Developer) and Yes to install ports <br />
Select 1 for Install from CD<br />
<br />
You will see a message saying All file information saved successfully.  FreeBSD install will then begin running.<br />
<br />
<b>Step 5 - Configuration</b><br />
<br />
Select YES to configure Ethernet network devices and pick your Ethernet card on the next screen<br />
<br />
Select YES for DHCP <br />
<br />
Select NO for network gateway and NO for iNetD<br />
<br />
Select YES to enable SSH login<br />
<br />
Select NO for FTP and NFS server/client<br />
<br />
Select NO for all remaining questions<br />
<br />
Pick a password for your root user<br />
<br />
From the VirtualBox menu, select Devices - then Unmount CDRom<br />
<br />
Enter X to exit install and reboot the FreeBSD virtual machine]]></description>

		<wfw:commentRss>http://www.softwareprojects.com/resources/programming/t-how-to-run-freebsd-on-windows-using-virt-1865.html</wfw:commentRss>
		<feedburner:origLink>http://www.softwareprojects.com/resources/programming/t-how-to-run-freebsd-on-windows-using-virt-1865.html</feedburner:origLink>

</item>
<item>
<title><![CDATA[SoftLayer down for 2 hours due to a power outage]]></title>
<link>http://www.softwareprojects.com/resources/get-online-presence/t-softlayer-down-for-2-hours-due-to-a-powe-1862.html</link>
<pubDate>Fri, 04 Sep 2009 13:04:31 GMT</pubDate>
<dc:creator><![CDATA[Kate Richards]]></dc:creator>
<category><![CDATA[Get Online Presence]]></category>
<guid isPermaLink="false">http://www.softwareprojects.com/resources/get-online-presence/t-softlayer-down-for-2-hours-due-to-a-powe-1862.html</guid>
<description><![CDATA[Earlier tonight, at 1:30am EST, <a href="http://www.softlayer.com" target="_blank">SoftLayer</a> - one of the tier 1 data centers we use, experienced a power outage in their primary facility, rendering thousands of sites dead.<br />
<br />
<img src="http://www.softwareprojects.com/blogimages/outage.jpg" border="0" alt="" /><br />
<br />
SPI engineers were alerted to the outage within seconds (we take monitoring very seriously). After establishing that the core problem was a total data-center failure, we verified load balancers are properly redirecting traffic to other locations.  <br />
<br />
The Power Outage lasted a total of <b>2 hours and 3 minutes</b> according to our friends at <a href="http://www.pingdom.com" target="_blank">Pingdom</a>:<br />
<br />
<img src="http://www.softwareprojects.com/blogimages/downtime.jpg" border="0" alt="" /><br />
<br />
All SPI client sites are <a href="http://www.softwareprojects.com/hosting" target="_blank">multi-homed</a>, which means we host everything in two independent data centers: Rackspace, Softlayer, NTT Verio and iWeb.  <br />
<br />
SPI utilizes redundant global load balancing, to immediately redirect end users from west coast to east coast, when such global outages happen.<br />
<br />
<b>How it works</b><br />
<br />
New end users hitting your mydomain.com are diverted to active servers.<br />
<br />
Old users / scripts (which keep a cached version of your website ip address) continue getting routed to the old server until their local DNS cache is cleared.<br />
<br />
<b>What's Next</b><br />
<br />
While the DNS ttl (time to live) is setup as 60 seconds, some browsers and ISPs don't honor that and can take up to 2 hours until the DNS entry is refreshed.<br />
<br />
As a workaround for these type of catastrophes where active users have cached  a malfunctioning server's ip address, we'll be configuring the load balancers to reply back with all available server ip addresses, letting an end-user's machine rotate ips internally.<br />
<br />
We understand the importance of keeping your sites up at all times and although our current setup ensures 100% uptime for new users, we are determined to come up with a solution for users with a cached version of a malfunctioning server ip address.<br />
<br />
Your SPI account manager will contact you with any specific steps you have to take, in order to enable this setup for your domains.]]></description>

		<wfw:commentRss>http://www.softwareprojects.com/resources/get-online-presence/t-softlayer-down-for-2-hours-due-to-a-powe-1862.html</wfw:commentRss>
		<feedburner:origLink>http://www.softwareprojects.com/resources/get-online-presence/t-softlayer-down-for-2-hours-due-to-a-powe-1862.html</feedburner:origLink>

</item>
<item>
<title><![CDATA[How to recover from MySQL replication Event too small corruption]]></title>
<link>http://www.softwareprojects.com/resources/programming/t-how-to-recover-from-mysql-replication-ev-1859.html</link>
<pubDate>Fri, 04 Sep 2009 10:37:39 GMT</pubDate>
<dc:creator><![CDATA[Dawn Rossi]]></dc:creator>
<category><![CDATA[Programming]]></category>
<guid isPermaLink="false">http://www.softwareprojects.com/resources/programming/t-how-to-recover-from-mysql-replication-ev-1859.html</guid>
<description><![CDATA[If you're using MySQL <a href="http://www.softwareprojects.com/resources/programming/t-mysql-storage-engines-1470.html" target="_blank">InnoDB tables</a> with these two lines in your /etc/my.cnf, for the most part, your database should gracefully handle unexpected shutdowns without data corruption:<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">innodb_flush_log_at_trx_commit=1<BR>sync_binlog=1</code><hr />
</div> <br />
I was working on such a database today, that experienced a power outage.<br />
<br />
While all InnoDB data remained intact (I <a href="http://www.softwareprojects.com/resources/programming/t-how-to-check-mysql-replication-databases-are-in-syn-1832.html" target="_blank">verified the checksum to ensure database is in sync</a>), replication relay logs got corrupted.<br />
<br />
Trying to SLAVE START failed with this nasty error message:<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">Relay log read failure: Could not parse relay log event entry. The possible reasons are: the master's binary log is corrupted (you can check this by running 'mysqlbinlog' on the binary log), the slave's relay log is corrupted (you can check this by running 'mysqlbinlog' on the relay log), a network problem, or a bug in the master's or slave's MySQL code. If you want to check the master's binary log or slave's relay log, you will be able to know their names by issuing 'SHOW SLAVE STATUS' on this slave. </code><hr />
</div> <br />
Here's how to recover from such an error -<br />
<br />
<b>Step 1: Identify the corrupted file</b><br />
<br />
Issue a SHOW SLAVE STATUS followed by a SHOW MASTER STATUS and record the relay log filenames and positions.<br />
<br />
In my case those were: mysql-bin.000313 position 1037717439 and mysql-bin.000249 position 326501604<br />
<br />
Running mysqlbinlog to read the first block in each of these files, starting at the last position, immediately reveals the problematic file:<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left"><b>/usr/local/mysql/bin/mysqlbinlog -Hvv mysql-bin.000313 --start-position=1037717439 | more</b><BR><BR>ERROR: Error in Log_event::read_log_event(): 'Event too small', data_len: 0, event_type: 0<BR>ERROR: Could not read entry at offset 326501604: Error in log format or read error.<BR>/*!40019 SET @@session.max_insert_delayed_threads=0*/;<BR>/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;<BR>DELIMITER /*!*/;</code><hr />
</div> <br />
Notice the ERROR on the first line.  This tells us we've found the corrupted replication file<br />
<br />
<b>Step 2 - Skip the bad block</b><br />
<br />
This involves some trial and error, but what we want to do is use mysqlbinlog to <a href="http://www.softwareprojects.com/resources/programming/t-how-to-manually-process-mysql-replication-log-files-1826.html" target="_blank">manually parse MySQL replication log file</a> to the end, bypassing the 'Event too small' bad block.<br />
<br />
Once done, we have to update relay-log.info, so that MySQL doesn't try to process this file again.<br />
<br />
Replaced this:<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left"><b>cat relay-log.info</b><BR><BR>./mysql-bin.000313 <BR>1037717439 <BR>mysql-bin.000249<BR>113612</code><hr />
</div> <br />
With:<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">./mysql-bin.000314 <BR>0<BR>mysql-bin.000249<BR>113612</code><hr />
</div> <br />
(Telling MySQL to advance to the next file mysql-bin.000314)<br />
<br />
<b>Step 3 - Restart</b> <b>database</b><br />
<br />
While this may be a bit of an overkill, I prefer restarting the entire database, before issuing a SLAVE START<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">mysqladmin shutdown<BR>mysqld_safe &amp;</code><hr />
</div>]]></description>

		<wfw:commentRss>http://www.softwareprojects.com/resources/programming/t-how-to-recover-from-mysql-replication-ev-1859.html</wfw:commentRss>
		<feedburner:origLink>http://www.softwareprojects.com/resources/programming/t-how-to-recover-from-mysql-replication-ev-1859.html</feedburner:origLink>

</item>
<item>
<title><![CDATA[How to serve Mercurial HG repository over NGinx]]></title>
<link>http://www.softwareprojects.com/resources/programming/t-how-to-serve-mercurial-hg-repository-ove-1856.html</link>
<pubDate>Thu, 03 Sep 2009 14:31:08 GMT</pubDate>
<dc:creator><![CDATA[Adrian Singer]]></dc:creator>
<category><![CDATA[Programming]]></category>
<guid isPermaLink="false">http://www.softwareprojects.com/resources/programming/t-how-to-serve-mercurial-hg-repository-ove-1856.html</guid>
<description><![CDATA[<a href="http://www.softwareprojects.com/resources/programming/t-mercurial-version-control-1853.html" target="_blank">Mercurial</a> server can be setup in two modes:<br />
<br />
* <b>hg serve</b> - a built in lightweight web server that is provided as part of the Mercurial package.  hg serve can be used to quickly serve a single repository, but it's not a good choice for production systems.  <br />
<br />
hg serve doesn't support user authentication, multiple repositories and is limited to handling a single connection at a time.<br />
<br />
* <b>hgweb.cgi </b>- a Python script that is faster, supports user authentication, multiple repositories, styles and web console.<br />
<br />
As part of this post I'll walk you through setting up hgweb.cgi on an NGinx web server.<br />
<br />
<b>Step 1 - Install Python</b><br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">cd /usr/ports/lang/python25<BR>make all install</code><hr />
</div>
<br />
<b>Step 2 - Install hgweb.cgi </b><br />
<br />
Save this file under your web server main direcory.  <br />
<br />
hgweb.cgi:<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">#!/usr/bin/env python<BR><BR>import cgitb<BR>from mercurial.hgweb.hgwebdir_mod import hgwebdir<BR>from mercurial.hgweb.request import wsgiapplication<BR>from flup.server.fcgi import WSGIServer<BR><BR>cgitb.enable()<BR><BR>def make_web_app():<BR> return hgwebdir("/home/admin/htdocs/hgweb.config")<BR><BR>WSGIServer(wsgiapplication(make_web_app)).run()</code><hr />
</div>
<br />
Replace /home/admin/htdocs/ with your web server folder<br />
<br />
<b>Step 3 - Configure hgweb</b><br />
<br />
Save this config file under your web server main directory.  <br />
<br />
hgweb.config:<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">[ui]<BR>username = root<BR>editor = vim<BR><BR>[hooks]<BR>changegroup = hg update >&amp;2<BR><BR>[web]<BR>baseurl =/.<BR>style= gitweb<BR>push_ssl = false<BR>allow_push = *<BR><BR>[paths]<BR>Clients = /home/<BR>SPI = /home/admin/htdocs/</code><hr />
</div>
<br />
Replace mydomain with your web server url<br />
<br />
Create this global settings file under /etc/mercurial/hgrc:<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">[web]<BR>style= gitweb</code><hr />
</div>
<br />
<b>Step 4 - Install Spawn-fcgi</b><br />
<br />
Before we can tell NGinx to handle the hgweb.cgi Python script, we have to install spawn-fcgi<br />
<br />
Follow these steps:<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">wget "http://www.lighttpd.net/download/spawn-fcgi-1.6.2.tar.gz"<BR>tar -xvf spawn-fcgi-1.6.2.tar.gz<BR>cd spawn-fcgi-1.6.2<BR>./configure<BR>make all<BR>make install</code><hr />
</div>
<br />
Start spawn-fcgi:<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">/usr/local/bin/spawn-fcgi -f /home/code/hgweb.cgi -a 127.0.0.1 -p 8081</code><hr />
</div>
<br />
Try running hgweb.cgi by issuing: python hgweb.cgi<br />
If you get a message about missing flup, you'll have to download flup and install it:<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">wget "http://www.saddi.com/software/flup/dist/flup-1.0.1.tar.gz"<BR>tar -xvf flup-1.0.1.tar.gz<BR>cd flup-1.0.1<BR>python setup.py install</code><hr />
</div>
<br />
--<br />
<br />
Now create a new file under /usr/local/etc/rc.d/start-spawnfcgi.sh to start spawn-fcgi automatically after a reboot.<br />
<br />
Save the same line above under /usr/local/etc/rc.d/start-spawnfcgi.sh<br />
<br />
<b>Step 5 - Configure NGinx<br />
<br />
</b>Add this to your nginx.conf, replacing mydomain.com with your web server domain name and 1.2.3.4 with the dedicated ip address:<br />
<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">&nbsp; &nbsp; server {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  <BR>&nbsp; &nbsp; &nbsp; &nbsp; listen&nbsp; &nbsp; &nbsp;  1.2.3.4:80;<BR>&nbsp; &nbsp; &nbsp; &nbsp; server_name&nbsp; mydomain.com;<BR>&nbsp; &nbsp; <BR>&nbsp; &nbsp; server_name_in_redirect off;<BR><BR>&nbsp; auth_basic&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "Restricted";<BR>&nbsp; auth_basic_user_file&nbsp; /home/hg/.htpasswd;<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; gzip on;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  <BR><BR>&nbsp; &nbsp; location / {<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; root&nbsp;  /home/hg/; <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; index&nbsp; index.php index.html index.htm;<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fastcgi_pass&nbsp;  127.0.0.1:8081;&nbsp; &nbsp;  <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fastcgi_param&nbsp; SCRIPT_FILENAME&nbsp; /home/hg/$fastcgi_script_name;<BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; include&nbsp; &nbsp; &nbsp; &nbsp; /etc/nginx/fastcgi_top.conf;<BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fastcgi_param&nbsp; DOCUMENT_ROOT&nbsp; &nbsp; /home/hg/;<BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; include&nbsp; &nbsp; &nbsp; &nbsp; /etc/nginx/fastcgi_bottom.conf;<BR><BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fastcgi_param&nbsp; QUERY_STRING&nbsp; &nbsp;  $query_string;<BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fastcgi_param&nbsp; REQUEST_METHOD&nbsp;  $request_method;<BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fastcgi_param&nbsp; CONTENT_TYPE&nbsp; &nbsp;  $content_type;<BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fastcgi_param&nbsp; CONTENT_LENGTH&nbsp;  $content_length;<BR>&nbsp; &nbsp; &nbsp; &nbsp; }<BR><BR><BR>&nbsp; &nbsp; }</code><hr />
</div>
<br />
Note that we are password protecting the repository by using an .htpasswd file.  You can generate one using publicly available htpasswd generators like <a href="http://home.flash.net/cgi-bin/pw.pl" target="_blank">this one</a>.<br />
<br />
Tell NGinx to reload its configuration file:<br />
<div style="margin:20px; margin-top:5px">
	<div class="smallfont" style="margin-bottom:2px">Code:</div>
	<hr /><code style="margin:0px" dir="ltr" style="text-align:left">kill -HUP `cat /usr/local/nginx/logs/nginx.pid`</code><hr />
</div>
<br />
If all goes well, you should be able to point your browser to mydomain.com and see a list of Mercurial repositories.]]></description>

		<wfw:commentRss>http://www.softwareprojects.com/resources/programming/t-how-to-serve-mercurial-hg-repository-ove-1856.html</wfw:commentRss>
		<feedburner:origLink>http://www.softwareprojects.com/resources/programming/t-how-to-serve-mercurial-hg-repository-ove-1856.html</feedburner:origLink>

</item>
<item>
<title><![CDATA[Mercurial Version Control]]></title>
<link>http://www.softwareprojects.com/resources/programming/t-mercurial-version-control-1853.html</link>
<pubDate>Wed, 02 Sep 2009 19:13:37 GMT</pubDate>
<dc:creator><![CDATA[Adrian Singer]]></dc:creator>
<category><![CDATA[Programming]]></category>
<guid isPermaLink="false">http://www.softwareprojects.com/resources/programming/t-mercurial-version-control-1853.html</guid>
<description><![CDATA[<a href="http://www.selenic.com/mercurial" target="_blank">Mercurial</a> (also called HG) is a cross-platform, super-fast, distributed revision control system for software developers.<br />
<br />
Unlike other version control tools such as CVS, SVN, Preforce etc., Mercurial is a distributed system, where every node can act as both a client and server.<br />
<br />
We've tested <b>a lot </b>of competing revision control systems, before Mercurial won us over.<br />
<br />
<b>The advantages Mercurial brings to the table include:</b><br />
<br />
* Allows users to work on a local copy of the files, even when not connected to a network<br />
<br />
* Most operation are faster since no network is involved<br />
<br />
* Allows private work, so you can use your revision control system even for early drafts you don't want to publish<br />
<br />
* Avoids relying on a single physical machine. A server disk crash is a non-event with distributed revision control<br />
<br />
* Allows participation in projects without requiring permissions from project authorities, instead of requiring "committer" status<br />
<br />
<b>Graphical User Interface</b><br />
<br />
Mercurial comes with great desktop integration for Windows and Mac, using a tool called Tortoise.  Once installed, it adds a right-click context-menu, allowing one-click commit, file diff, sync, directly from the file explorer.<br />
<br />
Tortoise includes a green icon next to all files that are up-to-date and an orange icon next to files that have been updated and need to be uploaded.<br />
<br />
<img src="http://www.softwareprojects.com/blogimages/image001.png" border="0" alt="" /><br />
<br />
<b>How to install Mercurial</b><br />
<br />
An all-in-one Mercurial+Tortoise installer is available <a href="http://bitbucket.org/tortoisehg/" target="_blank">here </a><br />
<br />
Once installed, Mercurial will add a right-click context-menu, as shown in the image above.<br />
<br />
Before you move forward, it is important that you setup a Username, so that all Commits you upload, include your name.<br />
<br />
Right click and select '<b>Global Options</b>' from HG menu.  Then enter your full name under Username<br />
<br />
<img src="http://www.softwareprojects.com/blogimages/adrian.jpg" border="0" alt="" /><br />
<br />
Next - click on the '<b>Sync</b>' tab and select Update as the 'after pull operation'<br />
<br />
<img src="http://api4.softwareprojects.com/temp/sync2.jpg" border="0" alt="" /><br />
<br />
<b>Connecting to a live repository</b><br />
<br />
Create a new folder on your machine where you'd like to save all source files, right click and select 'Create Repository Here' from Mercurial's menu<br />
<br />
<img src="http://www.softwareprojects.com/blogimages/menu.jpg" border="0" alt="" /><br />
<br />
This will create two files under the current directory:<br />
<b>.hg </b>subfolder<br />
<b>.hgignore </b>text file<br />
<br />
To avoid any conflicts, go ahead and delete the .hgignore text file.<br />
<br />
Now that the repository is created, we can download all files from the server.  Right click again and select '<b>Synchronize</b>' from the menu.  <br />
<br />
This popup window will open:<br />
<br />
<img src="http://www.softwareprojects.com/blogimages/sync.jpg" border="0" alt="" /><br />
<br />
Enter the live repository url and click the '<b>Pull</b>' button to download all source files from the live repository.<br />
<br />
 Note: You can repeat this process of synchronizing with the live server, whenever you'd like to download updates from the server.<br />
<br />
The first time you synchornize, it's going to take a while.  But subsequent pulls will be very quick.<br />
<br />
<b>Updating Files</b><br />
<br />
<b>Step 1: </b>Open the local copy of the file in your favorite editor, make changes and hit Save.<br />
<br />
Mercurial detects the change and automatically updates the file icon to orange.<br />
<br />
<b>Step 2: </b>Once you're done making changes, right-click and select HG Commit.<br />
<br />
Enter a comment describing the changes you've just implemented.  For example:<br />
<i>"Project 384283 - Added opt-in form on instant pay increase"</i><br />
<br />
Good comments are the basis of a solid version control system.  Your comments help other developers understand the nature of your changes, as they download them to their local repositories.<br />
<br />
<b>Step 3: </b>Unlike a centralized cvs, the 'Commit' operation is a local one.  Once changes are committed to your local repository, Right click and select '<b>Synchronize</b>'.  Enter the live repository url and click the 'Push' button.  This takes care of uploading your changes to the server.<br />
<br />
<b>Adding new files to the project</b><br />
<br />
In order to add a new file, you have to take one additional step - <br />
<br />
Highlight the new files, right click and select 'Add Files'<br />
<br />
<img src="http://www.softwareprojects.com/blogimages/add.jpg" border="0" alt="" /><br />
<br />
Then, follow the steps listed under "Updating Files", committing changes and synchronizing with the server.]]></description>

		<wfw:commentRss>http://www.softwareprojects.com/resources/programming/t-mercurial-version-control-1853.html</wfw:commentRss>
		<feedburner:origLink>http://www.softwareprojects.com/resources/programming/t-mercurial-version-control-1853.html</feedburner:origLink>

</item>

</channel></rss>