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

<channel>
	<title>v-nessa.net &#187; linux</title>
	<atom:link href="http://www.v-nessa.net/tag/linux/feed" rel="self" type="application/rss+xml" />
	<link>http://www.v-nessa.net</link>
	<description>pink is the new black</description>
	<lastBuildDate>Tue, 20 Jul 2010 13:48:32 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Command Line PHP: Part 3</title>
		<link>http://www.v-nessa.net/2010/05/25/command-line-php-part-3</link>
		<comments>http://www.v-nessa.net/2010/05/25/command-line-php-part-3#comments</comments>
		<pubDate>Tue, 25 May 2010 14:38:49 +0000</pubDate>
		<dc:creator>Nessa</dc:creator>
				<category><![CDATA[uncategorized]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[tutorials]]></category>

		<guid isPermaLink="false">http://www.v-nessa.net/?p=331</guid>
		<description><![CDATA[This is part third and final part in my PHP command line tutorial series. If you didn&#8217;t see parts 1 and 2: Command Line PHP: Part 1 Command Line PHP: Part 2 More File and Disk Functions Getting Disk Space and Usage The disk_total_size and disk_free_space functions can tell you how much disk space you [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.v-nessa.net%2F2010%2F05%2F25%2Fcommand-line-php-part-3"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.v-nessa.net%2F2010%2F05%2F25%2Fcommand-line-php-part-3&amp;source=nessa421&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>This is part third and final part in my PHP command line tutorial series. If you didn&#8217;t see parts 1 and 2:</p>
<p><a href="http://www.v-nessa.net/2010/05/18/command-line-php-part-1" target="_blank">Command Line PHP: Part 1</a></p>
<p><a href="http://www.v-nessa.net/2010/05/21/command-line-php-part-2" target="_blank">Command Line PHP: Part 2</a></p>
<p><span id="more-331"></span></p>
<h2>More File and Disk Functions</h2>
<h3>Getting Disk Space and Usage</h3>
<p>The <a href="http://us2.php.net/manual/en/function.disk-total-space.php" target="_blank">disk_total_size</a> and <a href="http://us2.php.net/manual/en/function.disk-free-space.php" target="_blank">disk_free_space</a> functions can tell you how much disk space you have and how much is available, respectively:</p>
<p><code>$disksize = disk_total_space("/");<br />
$size = round(number_format($disksize / 1024 / 1024 / 1024, 2));</code></p>
<p><code>$diskfree = disk_free_space("/");<br />
$freesize = round(number_format($diskfree / 1024 / 1024 / 1024, 2));</code></p>
<p><code>echo "Total Disk Size: $size GB\n";<br />
echo "Free Disk Space: $freesize GB";</code></p>
<h3>Finding Files</h3>
<p>A little-known function called glob works sort of like the locate command, in that it will find files that match a certain string, but it only looks in the current folder and is not recursive. For example, the below code will search for all files in the current folder that end with .txt:</p>
<p><code>foreach (glob("*.txt") as $file) {<br />
echo "$file size " . filesize($file) . "\n";<br />
}</code></p>
<p>You can also use something like <a href="http://snippets.dzone.com/posts/show/4147" target="_blank">this example</a> to run as a loop and recursively search through folders.</p>
<h3>Getting File Path Information</h3>
<p>The famous <a href="http://php.net/pathinfo" target="_blank">pathinfo</a> function can give you information about a file on your system:</p>
<p><code>$file = "/etc/php5/cli/php.ini";<br />
if(file_exists($file)){<br />
$info = pathinfo($file);<br />
print_r($info);<br />
}</code></p>
<p>This will print out an array like below:</p>
<p><code>Array<br />
(<br />
[dirname] =&gt; /etc/php5/cli<br />
[basename] =&gt; php.ini<br />
[extension] =&gt; ini<br />
[filename] =&gt; php<br />
)</code></p>
<p>Which you can echo out values to and use in your scripts, for example:</p>
<p><code>$file = "/etc/php5/cli/php.ini";<br />
if(file_exists($file)){<br />
$info = pathinfo($file);<br />
$dir = $info[dirname];<br />
chdir($dir);<br />
echo "Changed directory to" . getcwd();<br />
}</code></p>
<p>There are also similar functions that will provide the same information, individually:</p>
<p><code>$file = "/etc/php5/cli/php.ini";</code><br />
<code><br />
echo "Absolute File Name: " . <strong>realpath</strong>($file) . "\n";<br />
echo "File Name: " . <strong>basename</strong>($file) . "\n";<br />
echo "File path: " . <strong>dirname</strong>($file) . "\n";</code></p>
<p>This will return:</p>
<p><code>Absolute File Name: /etc/php5/cli/php.ini<br />
File Name: php.ini<br />
File path: /etc/php5/cli</code></p>
<h2>Some Random Script Fragments and Functions</h2>
<p><strong>Prompt a user for input:</strong></p>
<p><code><strong>fwrite</strong>(<strong>STDOUT</strong>, "Hello...\nWhat is your name? ");<br />
$name = trim(<strong>fgets</strong>(<strong>STDIN</strong>));<br />
fwrite(STDOUT, "Hello, $name!\n");</code></p>
<p><strong>Print out your username and date:</strong></p>
<p><code>$me = exec('whoami');<br />
echo "Hello, " . $me . " The time is currently " .date("r") . "\n";</code></p>
<p><strong>Generate random strings and passwords:</strong></p>
<p><code>echo <strong>crypt</strong>("mypassword","randomsalt");<br />
echo <strong>md5</strong>("mypassword");</code></p>
<p><strong>Random password, variable length:</strong></p>
<p><code>function randomPass($length) {</code></p>
<p><code>$chars = "abcdefghijkmnopqrstuvwxyz023456789";<br />
srand((double)microtime()*1000000);<br />
$i = 0;<br />
$pass = '' ;</code></p>
<p><code>while ($i &lt;= $length) {<br />
$num = rand() % 33;<br />
$tmp = substr($chars, $num, 1);<br />
$pass = $pass . $tmp;<br />
$i++;<br />
}</code></p>
<p><code>return $pass;<br />
}</code></p>
<p><code>$password = randomPass(10);</code></p>
<p><code>echo "Your random password is: $password";</code></p>
<p><strong>List loaded PHP extensions, check is specific extension is loaded:</strong></p>
<p><code>$extensions = <strong>get_loaded_extensions</strong>();<br />
foreach ($extensions as &amp;$value) {<br />
echo $value . "\n";<br />
}</code></p>
<p><code>if (!<strong>extension_loaded</strong>('gd')) {<br />
echo "GD extension is not loaded";<br />
exit;<br />
}</code></p>
<p><strong>Get Server&#8217;s CPU Load:</strong></p>
<p><code>$load = <strong>sys_getloadavg</strong>();<br />
echo "Current: " . $load[0] . "\n";<br />
echo "5-min: " . $load[1] . "\n";<br />
echo "15-min: " . $load[2] . "\n";</code></p>
<p><strong>Get PHP memory limit and convert to human-readable format:</strong><br />
<code><br />
function convert($size)<br />
{<br />
$unit=array('b','kb','mb','gb','tb','pb');<br />
return @round($size/pow(1024,($i=floor(log($size,1024)))),2).' '.$unit[$i];<br />
}<br />
echo convert(memory_get_usage(true));</code></p>
<h2>Some Useful Links/Tutorials</h2>
<p><a href="http://articles.sitepoint.com/article/php-command-line-1" target="_blank">Command Line PHP Tutorial</a><br />
<a title="Simple System Maintenance with PHP-CLI" href="http://www.developertutorials.com/tutorials/php/simple-system-maintenance-with-php-cli-8-01-17/" target="_blank">Simple System Maintenance with PHP-CLI &#8211; Simple System Maintenance with PHP-CLI</a><br />
<a href="http://www.ibm.com/developerworks/opensource/library/os-php-command/index.html" target="_blank">Command Line PHP (IBM)</a><br />
<a href="http://kevin.vanzonneveld.net/techblog/article/create_daemons_in_php/" target="_blank">Running Daemons in PHP</a><br />
<a href="http://www.if-not-true-then-false.com/2010/php-class-for-coloring-php-command-line-cli-scripts-output-php-output-colorizing-using-bash-shell-colors/" target="_blank">PHP Class for Coloring Command Line Output</a><br />
<a href="http://brian.moonspot.net/php-progress-bar" target="_blank">PHP Command Line Progress Bar</a></p>
<p><map name='google_ad_map_331_7fa65e237551a74a'>
<area shape='rect' href='http://imageads.googleadservices.com/pagead/imgclick/331?pos=0' coords='1,2,367,28' />
<area shape='rect' href='http://services.google.com/feedback/abg' coords='384,10,453,23'/></map>
<img usemap='#google_ad_map_331_7fa65e237551a74a' border='0' src='http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=&amp;channel=&amp;output=png&amp;cuid=331&amp;url= http%3A%2F%2Fwww.v-nessa.net%2F2010%2F05%2F25%2Fcommand-line-php-part-3' /></p><img src="http://www.v-nessa.net/?ak_action=api_record_view&id=331&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.v-nessa.net/2010/05/25/command-line-php-part-3/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Command Line PHP: Part 2</title>
		<link>http://www.v-nessa.net/2010/05/21/command-line-php-part-2</link>
		<comments>http://www.v-nessa.net/2010/05/21/command-line-php-part-2#comments</comments>
		<pubDate>Fri, 21 May 2010 19:51:25 +0000</pubDate>
		<dc:creator>Nessa</dc:creator>
				<category><![CDATA[uncategorized]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[tutorials]]></category>

		<guid isPermaLink="false">http://www.v-nessa.net/?p=315</guid>
		<description><![CDATA[This post is continuing on my three-part series on command line PHP programming. Missed part one? It&#8217;s right behind you. This part will go over command execution and processes. Command Execution Let&#8217;s start with the basics &#8211; you need to execute an arbitrary command from your PHP script. The exec, shell_exec, passthru, and system functions [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.v-nessa.net%2F2010%2F05%2F21%2Fcommand-line-php-part-2"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.v-nessa.net%2F2010%2F05%2F21%2Fcommand-line-php-part-2&amp;source=nessa421&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>This post is continuing on my three-part series on command line PHP programming. Missed part one? <a href="http://www.v-nessa.net/2010/05/18/command-line-php-part-1" target="_blank">It&#8217;s right behind you</a>. This part will go over command execution and processes.</p>
<p><span id="more-315"></span></p>
<h2>Command Execution</h2>
<p>Let&#8217;s start with the basics &#8211; you need to execute an arbitrary command from your PHP script. The <a href="http://php.net/exec" target="_blank">exec</a>, <a href="http://php.net/shell_exec" target="_blank">shell_exec</a>, <a href="http://php.net/passthru" target="_blank">passthru</a>, and <a href="http://php.net/system" target="_blank">system</a> functions will take care of this for you:</p>
<p><code>exec("/usr/bin/perl /scripts/myscript.pl");</code></p>
<p>will do about the same thing as:</p>
<p><code>system("/usr/bin/perl /scripts/myscript.pl");</code></p>
<p>and</p>
<p><code>shell_exec("/usr/bin/perl /scripts/myscript.pl");</code></p>
<p>So what&#8217;s the difference between the three? A little, but not much. The <a href="http://php.net/system" target="_blank">system</a> function will place the output of the command in an output stream, and display the results whether you tell it to or not. However, it&#8217;s mostly useful to return a yes or no output (in the form of 1, 0, or -1) based on the exit code of the command it was executing. For example, the below script views the /proc/cpuinfo file and outputs a boolean value on whether the command executed:</p>
<p><code>$cpuinfo = system("cat /proc/cpuinfo",$exitcode);<br />
echo $exitcode;<br />
</code><br />
I could then use the boolean value to write an if statement, which is more accurate because I&#8217;m basing the condition on the output of the command itself rather than PHP returning output based on the fact that the command ran, ignoring errors the command may have posted:</p>
<p><code>if($exitcode == 1){<br />
echo "Command executed, but finished with errors";<br />
}</code></p>
<p>The annoying part with the system function though is that it doesn&#8217;t suppress the output of the command itself, but rather sends it directly to the output stream. What if you want to format the output of the command? Then you would use <a href="http://php.net/exec" target="_blank">exec</a>. Below is an example of using the exec command to list the contents of a folder and only output .tar files (using <a href="http://us3.php.net/substr" target="_blank">substr</a> to split the string)</p>
<p><code>$dir = exec("ls .",$output);<br />
foreach ($output as $file)<br />
{<br />
if (strtolower(substr($file, -4)) == '.tar')<br />
echo "$file\n";<br />
}</code></p>
<p>The <a href="http://php.net/shell_exec" target="_blank">shell_exec</a> function allows you to emulate a shell environment. For example, in Linux you have a choice of shells like sh, bash, and ksh that, allow you to do things such as while loops. Using shell_exec is about the same as using the backtick operator, which is generally how you&#8217;re run commands within a Perl script:</p>
<p><code> $output = shell_exec('ls nonexistentfile  2&gt;&amp;1 1&gt; /dev/null');</code></p>
<p>// Does the same as</p>
<p><code>$output = `ls nonexistent file 2&gt;&amp;1 1&gt; /dev/null`l</code></p>
<p>Finally, there&#8217;s the <a href="http://php.net/passthru" target="_blank">passthru</a> function which, when invoked, immediately displays raw ouput of the command being executed. This is intended for browsers, to display binary data such as images, and not necessarily something you&#8217;re use on the command line:</p>
<p><code>header('Content-Type: image/jpg');<br />
passthru('cat /home/user/public_html/images/image.png');<br />
</code></p>
<h3>A Word on Security</h3>
<p>A lot of hosts block command execution functions with the disable_functions setting in php.ini or by using safe mode, and for good reason. A lot of malicious scripts contain code with executable functions, and especially when the value of command or argument is passed as a variable, the results can be destructive. Here&#8217;s an example of a simple script that lists files, that accepts a folder name as a argument:</p>
<p><code>$folder = $argv[1];<br />
exec("ls $folder");</code></p>
<p>We&#8217;d have a security problem if someone passed this as the first argument for $folder:</p>
<p><code>myfolder &amp;&amp; cat /etc/shadow</code></p>
<p>To prevent this, PHP has built-in functions to escape shell arguments and commands, in order to prevent things that could be dangerous:</p>
<p><a href="http://us3.php.net/manual/en/function.escapeshellarg.php" target="_blank">escapeshellarg</a>: Encloses command arguments in single quotes so the argument is passed as one string:</p>
<p><code>exec('ls '.escapeshellarg($folder));</code></p>
<p><a href="http://us3.php.net/manual/en/function.escapeshellcmd.php" target="_blank">escapeshellcmd</a>: Escapes characters that can be used to trick a shell command (like the &amp;&amp; I used to execute cat)</p>
<h2>Process Management &amp; POSIX</h2>
<p>PHP has internal  functions that allow you to manage processes, such as proc_open, proc_close, etc. However, I admit that these tend to be difficult to learn an understand, while posix functions tend to do the job with less hassle.  <a href="http://theserverpages.com/php/manual/en/ref.posix.php" target="_blank">Posix</a> functions are basically system-level functions. In the below script, I&#8217;m going to change the user that the script runs as, view simple information about the process, then start a counter to 1 million but kill it when it reaches 50:</p>
<p><code>$user = posix_getpwnam($vnessa5);<br />
<strong>posix_setuid</strong>($user['uid']);<br />
<strong>posix_setgid</strong>($user['gid']);<br />
$pid = getmypid();</code></p>
<p><code>print_r(<strong>posix_times</strong>());<br />
echo "Script owner: ". <strong>get_current_user</strong>() . "(" . <strong>getmyuid</strong>() . ")\n";<br />
$i=0;<br />
while( $i &lt; 10000000 ){<br />
$i++;<br />
if($i == 50){<br />
echo "Reached 50 - killing!";<br />
<strong>posix_kill</strong>($pid,1);<br />
}<br />
}</code></p>
<p>Similarly, <a href="http://php.net/posix_getpid" target="_blank">posix_getpid</a> and <a href="http://php.net/getmypid" target="_blank">getmypid</a> do the same thing. If the script is a child of another process, you can get the parent process&#8217;s ID with <a href="http://php.net/posix_getppid" target="_blank">posix_getppid</a>. The <a href="http://www.php.net/manual/en/function.getrusage.php" target="_blank">getrusage</a> function can also be used to get more informative information than <a href="http://php.net/posix_times" target="_blank">posix_times</a>. To kill a process, you can see I used <a href="http://php.net/posix_kill" target="_blank">posix_kill</a>, with the process ID and exit code as arguments. This is what happened when I ran the script:</p>
<p><code>Array<br />
(<br />
[ticks] =&gt; 1279790432<br />
[utime] =&gt; 0<br />
[stime] =&gt; 0<br />
[cutime] =&gt; 0<br />
[cstime] =&gt; 0<br />
)<br />
Script owner: root(0)<br />
Reached 50 - killing!Hangup</code></p>
<p>Keep in mind that in most situations, using die() to bail out of a script is more appropriate that using kill. I could rewrite that part of the code to say this instead:</p>
<p><code>die("Reached 50 - Bailing out!);</code></p>
<p>I also found a nice post on running background processes, that you might want to check out <a href="http://nsaunders.wordpress.com/2007/01/12/running-a-background-process-in-php/" target="_blank">here</a>.</p>
<h2>Environmental Variables</h2>
<p>Environmental variables tend to be a major part of command line scripting, and is something that is part of PHP as well. Let&#8217;s start with defining an environmental variable with <a href="http://www.php.net/manual/en/function.putenv.php" target="_blank">putenv</a> and retrieving it with <a href="http://php.net/getenv" target="_blank">getenv</a>:</p>
<p><code>putenv("PATH=/fakebin");</code></p>
<p><code>if(!exec("test testdir")){<br />
echo "Could not execute test - path is " . getenv('PATH') ;<br />
}</code></p>
<p>In the above script, I set the $PATH environmental variable to /fakebin, so when I went to execute the &#8216;test&#8217; command (which is a valid Linux command located in /usr/bin/test), the scirpt could not find it since the command was not in /fakebin. This is about the same as setting the $PATH environment in a user&#8217;s .bashrc file. Keep in mind that the variable change lasts as long as the script does &#8211; after the script exits, the environmental variable is returned to its normal state. You can use getenv to pull any environmental variable, similar to the <a href="http://us.php.net/manual/en/reserved.variables.server.php" target="_blank">$_SERVER</a> superglobal.</p>
<p>A nice function for getting information about the current server is <a href="http://php.net/php_uname" target="_blank">php_uname</a>. You use it about the same way as the uname command in Linux:</p>
<p><code>echo php_uname();</code></p>
<p>Will return:</p>
<p><code>Linux server.v-nessa.net 2.6.18-028stab064.7 #1 SMP Wed Aug 26 13:11:07 MSD 2009 x86_64</code></p>
<p>You can further filter the output using the same arguments as uname, for instance, if I only need the server name:</p>
<p><code>echo php_uname(n);</code></p>
<p>PHP 5.3 also introduces a void function called <a href="http://php.net/gethostname" target="_blank">gethostname</a> which will get the hostname of your machine as well.</p>
<h3>The Server Superglobal</h3>
<p>The <a href="http://us.php.net/manual/en/reserved.variables.server.php" target="_blank">$_SERVER superglobal</a> is used to get environmental variables pursuant to the server and environment for the script you are running.  While it&#8217;s normally used in web applications, some of the values can be used for command line scripts as well:</p>
<p><code>echo "This file's name is " . $_SERVER['PHP_SELF'];</code></p>
<p>So you&#8217;ve made it part two of the series. Stay tuned for part three, which will go over specific system-level tasks and functions, with useful code snippets.</p>
<p>Next: <a href="http://www.v-nessa.net/2010/05/25/command-line-php-part-3" target="_blank">Command Line PHP: Part 3</a></p>
<p><map name='google_ad_map_315_7fa65e237551a74a'>
<area shape='rect' href='http://imageads.googleadservices.com/pagead/imgclick/315?pos=0' coords='1,2,367,28' />
<area shape='rect' href='http://services.google.com/feedback/abg' coords='384,10,453,23'/></map>
<img usemap='#google_ad_map_315_7fa65e237551a74a' border='0' src='http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=&amp;channel=&amp;output=png&amp;cuid=315&amp;url= http%3A%2F%2Fwww.v-nessa.net%2F2010%2F05%2F21%2Fcommand-line-php-part-2' /></p><img src="http://www.v-nessa.net/?ak_action=api_record_view&id=315&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.v-nessa.net/2010/05/21/command-line-php-part-2/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Command Line PHP &#8211; Part 1</title>
		<link>http://www.v-nessa.net/2010/05/18/command-line-php-part-1</link>
		<comments>http://www.v-nessa.net/2010/05/18/command-line-php-part-1#comments</comments>
		<pubDate>Tue, 18 May 2010 18:10:26 +0000</pubDate>
		<dc:creator>Nessa</dc:creator>
				<category><![CDATA[uncategorized]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[tutorials]]></category>

		<guid isPermaLink="false">http://www.v-nessa.net/?p=310</guid>
		<description><![CDATA[PHP isn&#8217;t just for websites anymore. In fact, almost every script I&#8217;ve written to perform server-side functions is either written in bash or PHP, rather than Perl or Python as preferred by my colleagues. It&#8217;s a common belief that PHP isn&#8217;t suited for CLI programming since it&#8217;s mainly used in web applications, but PHP has [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.v-nessa.net%2F2010%2F05%2F18%2Fcommand-line-php-part-1"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.v-nessa.net%2F2010%2F05%2F18%2Fcommand-line-php-part-1&amp;source=nessa421&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>PHP isn&#8217;t just for websites anymore. In fact, almost every script I&#8217;ve written to perform server-side functions is either written in bash or PHP, rather than Perl or Python as preferred by my colleagues. It&#8217;s a common belief that PHP isn&#8217;t suited for CLI programming since it&#8217;s mainly used in web applications, but PHP has over a hundred functions specifically intended for system management.</p>
<p>These kinds of posts can be rather lengthy, so I&#8217;m making this into a series with three parts.  Part 1 will go over the basic filesystem functions. You can find a complete listing <a href="http://us.php.net/manual/en/ref.filesystem.php" target="_blank">here</a>, but I&#8217;ll just go over a few of the more important and common ones.</p>
<p><span id="more-310"></span></p>
<h2><strong>The hashbang</strong></h2>
<p>As with any CLI script, the first line of your PHP script should contain the executable binary for PHP. You can usually find this by running:</p>
<blockquote><p>which php</p></blockquote>
<p>On my server the location is /usr/bin/php, so here&#8217;s the first line of my script:</p>
<p><code>#!/usr/bin/php</code></p>
<p>If you installed PHP in a custom location, you&#8217;ll need to specify that binary instead. You can also specify <a href="http://www.php-cli.com/" target="_blank">command line options</a> like -f, -c, etc.  Then set the permissions of your script to 755 to allow it to execute.</p>
<h2><strong>Accepting arguments with PHP<br />
</strong></h2>
<p>A major part of CLI scripting is the ability to accept arguments. For this, we&#8217;ll write a simple script called asl.php which will parse my name, sex, and location as arguments:</p>
<blockquote><p>[nessa@server] ./test.php 23 female virginia</p></blockquote>
<p>Here&#8217;s the script:</p>
<p><code>#!/usr/bin/php<br />
&lt;?php</code></p>
<p><code>print_r($argv);</code></p>
<p><code>?&gt;</code></p>
<p>The $argv variable is native, and parses as an array. So running this script will produce the following output:</p>
<p><code>Array<br />
(<br />
[0] =&gt; ./asl.php<br />
[1] =&gt; 23<br />
[2] =&gt; female<br />
[3] =&gt; virginia<br />
)</code></p>
<p>So if I only wanted to echo out my age, I can use the following code:</p>
<p><code>echo $argv[1];</code></p>
<p>If you notice, there are four values instead of the three that I passed. As with most scripting languages, PHP considers the filename as the first (0) variable. To remove the first variable, use the <a href="http://us.php.net/array_shift" target="_blank">array_shift</a> function:</p>
<p><code>array_shift($argv);</code></p>
<p>This means now that using value #1 as shown in the example above will output &#8220;female&#8221; instead of 23, making the command line order more correct, but this tends to be confusing for some people since it makes the first value 0 instead of 1. I usually prefer NOT to shift the array unless having the file name in there is going to adversely affect the intended functionality of the script.</p>
<p>From here ( keeping in mind that I&#8217;m not shifting the array anymore), I can assign the arguments to variables and access them from the script:</p>
<p><code>$age = $argv[1];</code><br />
<code>$gender = $argv[2];</code><br />
<code>$location = $argv[3];</code><br />
<code>// echo out the values</code><br />
<code>echo "Hello, I am $age-year-old $gender from $location";</code></p>
<p>In some cases you may want to validate the number of arguments passed, or what they contain. For instance, the below example is requiring that all three variables are passed (however, the code says four, since you have to include the script name as the first &#8220;argument&#8221;, as mentioned before):</p>
<p><code>if ($argc != 4) {<br />
die("Usage: asl.php &lt;age&gt; &lt;gender&gt; &lt;location&gt;\n");<br />
}</code></p>
<p>You can of course specify <em>less than</em> (&lt;) or <em>greater than</em> (&gt;) values operators.  In the next example, I want to make sure that the &#8220;age&#8221; argument is a number:</p>
<p><code>if (!is_numeric($age)){<br />
die("$age is not a number");<br />
}</code></p>
<p>I&#8217;m sure by now you get the idea =)</p>
<h2><strong>PHP File and Folder Management</strong></h2>
<h3>Creating files and folders, and checking their accessibility</h3>
<p>Continuing my above example, I want to end up with a file in /opt/app/users called &#8220;users.txt&#8221; that contains a list of all the output of asl.php. I first need to see if  /opt/app/users exists using the <a href="http://us3.php.net/manual/en/function.is-dir.php" target="_blank">is_dir </a>function, and if it doesn&#8217;t, create it with <a href="http://us3.php.net/manual/en/function.mkdir.php" target="_blank">mkdir</a>, then enter into that directory with <a href="http://us.php.net/manual/en/function.chdir.php" target="_blank">chdir</a>:</p>
<p><code>$dirname = "/opt/app/users;<br />
if(!<strong>is_dir</strong>($dirname)){<br />
<strong>mkdir</strong>($dirname, 0755);<br />
}<br />
<strong>chdir</strong>($dirname);</code></p>
<p>What if /opt/app doesn&#8217;t exist and I need to create the entire structure? The mkdir function has a recursive flag that is set to false by default, but can be enabled as so:</p>
<p><code>$dirstructure = "/opt/app/users";</code></p>
<p><code>if (!mkdir($dirstructure, <strong>0</strong>, true)) {<br />
die('Failed to create folders!');<br />
}</code></p>
<p>Now that the folders are created and verified, I use <a href="http://www.php.net/manual/en/function.file-exists.php" target="_blank">file_exists</a> and <a href="http://www.php.net/manual/en/function.is-readable.php" target="_blank">is_readable</a> to make sure that my users.txt file is there and can be seen. If not, we&#8217;ll use one of the file functions to create it:</p>
<p><code>$cwd = <strong>getcwd</strong>();<br />
$filename = $cwd . "/users.txt;<br />
if(<strong>file_exists</strong>($filename) &amp;&amp; <strong>is_readable</strong>($filename)){<br />
echo "File Exists and is readable";<br />
}else{<br />
<em>echo "File does not exist or is not readable";</em></code><br />
<code>touch($filename);<br />
}</code></p>
<p>If you notice, I added the <a href="http://us.php.net/manual/en/function.getcwd.php" target="_blank">getcwd</a> function to look for a file called users.txt in my current directory. If you need to see whether a file is executable instead of readable, you can simply use the <a href="http://us.php.net/manual/en/function.is-executable.php" target="_blank">is_executable</a> function, or to see if it&#8217;s writable, use <a href="http://us.php.net/manual/en/function.is-writable.php" target="_blank">is_writable</a>:</p>
<p><code>$filename = '/opt/app/users/users.txt';</code></p>
<p><code>if (!is_executable($filename)) {<br />
echo $filename.' is not executable';<br />
}<br />
</code><code>if (!is_writable($filename)) {<br />
echo $filename.' is not writable';<br />
} </code></p>
<p>Note that the result of these commands is based on the user running them. For instance, if the file is owned by the user root and is set to 600 permissions (root read/write only), but the user &#8216;user1&#8242; is running the script, the tests in the above lines of code will fail since that user does not have permissions to the file in question.</p>
<h3>Creating and deleting files</h3>
<p>There are a few functions you can use to create files with PHP. Here are the most commonly used: <a href="http://us2.php.net/manual/en/function.fopen.php" target="_blank">fopen</a>, <a href="http://www.php.net/manual/en/function.file-put-contents.php" target="_blank">file_put_contents</a>, <a href="http://us2.php.net/manual/en/function.touch.php" target="_blank">touch,</a> If you want to delete a file, simply use <a href="http://us2.php.net/unlink" target="_blank">unlink</a>.  In the below example</p>
<p><code>$filename = "/opt/app/users/users.txt";<br />
unlink($filename);<br />
</code></p>
<p>Unlink is not to be confused with the opposite of <a href="http://us2.php.net/manual/en/function.symlink.php" target="_blank">symlink</a>, which creates a symbolic link  (shortbut) between files:</p>
<p><code>symlimk("/opt/app/users/users.txt", "/home/nessa/Desktop/users.txt-shortcut");</code></p>
<p>And <a href="http://php.net/rmdir" target="_blank">rmdir</a> will remove a folder:</p>
<p><code>if (!is_dir('temp')) {<br />
mkdir('temp');<br />
}<br />
rmdir('temp');</code></p>
<h3>Writing to files</h3>
<p>The most common way to write to files is using the fopen function. Using my original example, asl.php is going to write the values of the arguments to a file called users.txt:</p>
<p><code>$filename = "/opt/app/users/users.txt";<br />
$fh = fopen($filename, 'w') or die("can't open file");<br />
$data = $age . $gender . $location;<br />
fwrite($fh, $date);<br />
fclose($fh);</code></p>
<h3>Reading contents of a file</h3>
<p>If you want the script to read the file, you can use a number of function such as <a href="http://us3.php.net/manual/en/function.readfile.php" target="_blank">readfile</a>, <a href="http://us3.php.net/manual/en/function.file-get-contents.php" target="_blank">file_get_contents</a>, <a href="http://us3.php.net/manual/en/function.fopen.php" target="_blank">fopen</a>, <a href="http://us3.php.net/manual/en/function.fread.php" target="_blank">fread</a>, and <a href="http://us3.php.net/manual/en/function.file.php" target="_blank">file</a>. The actual function you would use depends on what you&#8217;re planning on doing with the data. If you simply want to display the contents of the file as a string:</p>
<p><code>$filename = "/opt/app/users/users.txt";<br />
$data = file_get_contents($filename);<br />
echo $data;</code></p>
<p>Will display:</p>
<p><code>23 female virginia</code></p>
<p>If you need a more programmatic way of displaying the data, such as reading each column as a set of values (like if you&#8217;re inserting all this into a database), you&#8217;d use the file() function which will load the contents of the file into an array. Here&#8217;s a simple loop that echoes out each line in the file:</p>
<p><code>$filename = "/opt/app/users/users.txt";<br />
$lines = file($filename);</code></p>
<p><code>foreach ($lines as $line_num =&gt; $line)</code><br />
<code>{<br />
print "{$line_num} : " . $line . "\n";<br />
}</code></p>
<h3>Reading contents of a folder</h3>
<p>You can use the <a href="http://us3.php.net/opendir" target="_blank">opendir</a> function to run a loop and read the contents of a folder:</p>
<p><code>// open the current directory by opendir</code></p>
<p><code>$dirname = "/opt/app";<br />
$handle=opendir($dirname);</code></p>
<p><code>while (($file = readdir($handle))!==false) {<br />
echo "$file \n";<br />
}</code></p>
<p><code>closedir($handle);</code></p>
<h3>Changing permissions and ownership:</h3>
<p>In the above example where I was checking to see if the file was readable, I didn&#8217;t actually specify anything to address permissions &#8211; instead, I just created the file. To change the permissions or ownership of files, you can use the <a href="http://us2.php.net/chmod" target="_blank">chmod</a> and <a href="http://us2.php.net/chown" target="_blank">chown</a> functions.</p>
<p><code>$filename = "/opt/appf/users/users.txt";<br />
$username = posix_getpwuid(fileowner($filename));</code></p>
<p><code>// Get the octal value of permissions<br />
$perms = substr(sprintf('%o', fileperms($filename')), -4);</code></p>
<p><code>if($username[name] != "nessa" &amp;&amp; $perms != "0755" ){<br />
chmod($filename, 0755);<br />
chown($filename, "nessa");<br />
echo "Permissions fixed";<br />
}else{<br />
echo "Permissions are correct";</code></p>
<p>If you want to change the umask (that is, the default permissions of files created by the script), you can use the <a href="http://us.php.net/manual/en/function.umask.php" target="_blank">umask</a> function &#8211; which actually revokes permissions instead of setting them.</p>
<h3>Copying, moving, and renaming</h3>
<p>Say I want to rename the /opt/app folder to /etc/app. I&#8217;d use the <a href="http://us.php.net/manual/en/function.rename.php" target="_blank">rename</a> function as so, validating on whether of not it was renamed successfully:</p>
<p><code>if(!rename("/opt/app","/etc/app")){<br />
echo "Rename failed";<br />
}</code></p>
<p>You can also use the <a href="http://us.php.net/manual/en/function.copy.php" target="_blank">copy</a> function to copy files, noting that if the &#8220;new&#8221; file or folder already exists, it will be overwritten.</p>
<p><code>if(!copy("/opt/app","/etc/app")){<br />
echo "Copy failed";<br />
}</code></p>
<h2>User and File information</h2>
<h3>Getting user and group data</h3>
<p>The <a href="http://us3.php.net/fileowner" target="_blank">fileowner</a> function as shown above will return the UID of the file, but I specified the username. You can use <a href="http://us3.php.net/manual/en/function.posix-getpwuid.php" target="_blank">posix_getpwuid</a> to return an array with the user&#8217;s information in a more usable format:</p>
<div>
<p><code>$filename = "/opt/app/users/users.txt";</code><code><br />
$username = posix_getpwuid(fileowner($filename));<code>print_r($username);</code></code></p>
</div>
<div>Will return:</div>
<p><code>Array<br />
(<br />
[name] =&gt; nessa<br />
[passwd] =&gt; x<br />
[uid] =&gt; 1000<br />
[gid] =&gt; 1000<br />
[gecos] =&gt; Vanessa V.,,,<br />
[dir] =&gt; /home/nessa<br />
[shell] =&gt; /bin/bash<br />
)</code></p>
<p>So you can simply echo out the array values of $username based on the keys. For example, to get the shell of the user in the above example, simply echo to the &#8216;shell&#8217; key from the $username array:</p>
<p><code>echo $username[shell];</code></p>
<p>If you want to get group information for a file, you can use the same method, but with <a href="http://us.php.net/manual/en/function.filegroup.php" target="_blank">filegroup</a> and <a href="http://us.php.net/manual/en/function.posix-getgrgid.php" target="_blank">posix_getgrgid</a>:</p>
<p><code>$filename = "/opt/app/users/users.txt";</code><br />
<code>print_r(posix_getgrgid(filegroup($filename)));</code></p>
<h3>Getting file information</h3>
<p>You can also get information about a file using the <a href="http://us.php.net/manual/en/function.stat.php" target="_blank">stat</a> or <a href="http://us.php.net/manual/en/function.fstat.php" target="_blank">fstat</a> functions, which return the results to an array:</p>
<p><code>$filename = "/opt/app/users/users.txt";</code><br />
<code>$stat = stat($filename);</code><br />
<code>print_r($stat);</code></p>
<p>Will return a giant array of information for the file. If you only want to return one value, say, the size, echo it out like you would a normal array:</p>
<p><code>echo $stat[size];</code></p>
<p>So here we&#8217;ve finished the first part of PHP command line scripting, which covered the use of files, folder, and users. The next parts will go over command execution and process management.</p>
<p>See: <a href="http://www.v-nessa.net/2010/05/21/command-line-php-part-2" target="_self">Command Line PHP: Part 2,</a> <a href="http://www.v-nessa.net/2010/05/25/command-line-php-part-3" target="_blank">Command Line PHP: Part 3<br />
</a></p>
<p><map name='google_ad_map_310_7fa65e237551a74a'>
<area shape='rect' href='http://imageads.googleadservices.com/pagead/imgclick/310?pos=0' coords='1,2,367,28' />
<area shape='rect' href='http://services.google.com/feedback/abg' coords='384,10,453,23'/></map>
<img usemap='#google_ad_map_310_7fa65e237551a74a' border='0' src='http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=&amp;channel=&amp;output=png&amp;cuid=310&amp;url= http%3A%2F%2Fwww.v-nessa.net%2F2010%2F05%2F18%2Fcommand-line-php-part-1' /></p><img src="http://www.v-nessa.net/?ak_action=api_record_view&id=310&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.v-nessa.net/2010/05/18/command-line-php-part-1/feed</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>10 Excellent Open Source Alternatives</title>
		<link>http://www.v-nessa.net/2010/03/06/10-excellent-open-source-alternatives</link>
		<comments>http://www.v-nessa.net/2010/03/06/10-excellent-open-source-alternatives#comments</comments>
		<pubDate>Sat, 06 Mar 2010 19:41:58 +0000</pubDate>
		<dc:creator>Nessa</dc:creator>
				<category><![CDATA[uncategorized]]></category>
		<category><![CDATA[free stuff]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://www.v-nessa.net/?p=281</guid>
		<description><![CDATA[Those of you who are regular readers of my blog know that I&#8217;m a huge fan of open source software. I don&#8217;t think it&#8217;s smart for people to drop upwards to thousands of dollars on software unless they have that kind of money to waste, or have a need that isn&#8217;t being met by the [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.v-nessa.net%2F2010%2F03%2F06%2F10-excellent-open-source-alternatives"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.v-nessa.net%2F2010%2F03%2F06%2F10-excellent-open-source-alternatives&amp;source=nessa421&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>Those of you who are regular readers of my blog know that I&#8217;m a huge fan of <a href="http://www.opensource.org/" target="_blank">open source software</a>. I don&#8217;t think it&#8217;s smart for people to drop upwards to thousands of dollars on software unless they have that kind of money to waste, or have a need that isn&#8217;t being met by the open source community.  And then there are the <a href="http://limewire.com" target="_blank">less legal</a> alternatives, which I&#8217;m not against, but then again I can&#8217;t promote them here, either =)</p>
<p>So here&#8217;s a nice list of open source alternatives for people who want to save money by using open source software.</p>
<p><strong>1) Use Linux instead of Windows</strong></p>
<p>The transition from Windows to Linux is not as hard as you may think it is. When people think Linux, they think of an ugly black and white command prompt. This may be true if you&#8217;re thinking of running Linux as a server, but as a desktop you have a GUI similar to Windows and Mac, in the form of <a href="http://www.psychocats.net/ubuntu/kdegnome" target="_blank">KDE or Gnome</a>.  If you have applications that require Windows, you can usually run them by installing a program called <a href="http://www.winehq.org/" target="_blank">Wine</a>.  It can take a little getting used to, but for those buying a new PC or refurbishing an old one, Linux is the route to go if you want to save money and get better performance, security, and stability than you&#8217;ll ever get with Windows.  For newbies, I&#8217;d recommend <a href="http://ubuntu.com" target="_blank">Ubuntu</a> or <a href="http://fedoraproject.org" target="_blank">Fedora</a>.</p>
<p><strong>2) Use Gimp instead of Adobe Photoshop</strong></p>
<p><a href="http://www.v-nessa.net/wp-content/uploads/2010/03/gimp.png" rel="lightbox"><img class="alignright size-thumbnail wp-image-284" title="gimp" src="http://www.v-nessa.net/wp-content/uploads/2010/03/gimp-150x150.png" alt="" width="150" height="150" /></a>Adobe Photoshop will run you between $700 and $1000, maybe less if you purchase from an independent software distributor. If that&#8217;s a little steep for you, consider using <a href="http://gimp.org" target="_blank">Gimp</a> instead. It has a lot of the same functionality of Photoshop, and can read files created in Photoshop (.PSD) as well.  My sister is a photographer and just when she thought she was used to Photoshop, I introduced her to Gimp so she can do her photo editing outside of school, and she said it does as good of a job as Photoshop does. Similarly, I hear that <a href="http://www.inkscape.org/" target="_blank">Inkscape</a> makes an excellent alternative to Adobe Illustrator.</p>
<p><strong>3) Use OpenOffice instead of Microsoft Office</strong></p>
<p>My Dad, who has headed the IT department of his company for years, didn&#8217;t believe me when I told him that the thousands his company was spending on Microsoft Office licenses every couple years could be a waste of money, since <a href="http://openoffice.org" target="_blank">OpenOffice</a> has the same kind of functionality. The base package of OpenOffice contains alternatives to Word, Excel, PowerPoint, and Access, all of which have the same familiar interfaces and support for files created in their proprietary alternatives, but without the expensive licensing costs and resource requirements. The  software in OpenOffice also has a <a href="http://www.techsoup.org/learningcenter/software/page4765.cfm" target="_blank">number of features</a> that the other does not.</p>
<p><strong>4) Use Thunderbird or Evolution instead of Outlook<a href="http://www.v-nessa.net/wp-content/uploads/2010/03/thunderbird.jpg" rel="lightbox"><img class="alignright size-thumbnail wp-image-285" title="thunderbird" src="http://www.v-nessa.net/wp-content/uploads/2010/03/thunderbird-150x150.jpg" alt="" width="150" height="150" /></a></strong></p>
<p>Outlook sucks. I can&#8217;t tell you how many calls I got about it when I was in technical support, where email would suddenly stop working and the customer wouldn&#8217;t want to believe that their beloved Outlook was the problem. It usually comes bundled as part of the Microsoft Office suite, but you can buy it standalone. Why would you want to? <a href="http://www.mozillamessaging.com/en-US/thunderbird/" target="_blank">Thunderbird</a> is free, and a lot more efficient, feature-rich, stable, and secure than Outlook. Love the Outlook feel? Evolution is the Linux alternative to Outlook, only it doesn&#8217;t suck as much.</p>
<p><strong>5) Use ClamAV or AVG Instead of Norton, TrendMicro, or McAfee</strong></p>
<p>I&#8217;ve heard from many people that even though <a href="http://clamav.org" target="_blank">ClamAV</a> is free, it&#8217;s better than its leading enterprise alternatives. It also works on Windows (Via <a href="http://clamwin.com" target="_blank">ClamWIN</a>) and Linux. Need a firewall too, but don&#8217;t want the steep cost of Norton Personal Firewall? Consider <a href="http://www.rfxn.com/projects/advanced-policy-firewall/" target="_blank">APF</a> or <a href="http://smoothwall.org" target="_blank">Smoothwall</a>.</p>
<p><strong>6) Use Turbocash instead of Quickbooks or Microsoft Money</strong></p>
<p>I personally haven&#8217;t used Quickbooks before, but I heard it&#8217;s comparable to <a href="http://www.turbocash.net/" target="_blank">Turbocash</a>, which is perfect for smaller organizations or individuals needing software for finance management.</p>
<p><strong>7) Use VirtualBox  instead of Microsoft Virtual PC, VMWare, or Parallels Desktop<a href="http://www.v-nessa.net/wp-content/uploads/2010/03/virtualbox-logo.jpg" rel="lightbox"><img class="alignright size-thumbnail wp-image-286" title="virtualbox-logo" src="http://www.v-nessa.net/wp-content/uploads/2010/03/virtualbox-logo-150x150.jpg" alt="" width="150" height="150" /></a></strong></p>
<p>I generally used Virtual PC in the past to play with other operating systems, but you may find a use for it if you&#8217;re a software developer or you have applications that work on one OS but not another. Virtual PC usually ends up being free quite some time after its initial release, but it only runs on Windows. <a href="http://www.virtualbox.org/" target="_blank">VirtualBox</a> is open source and runs on Linux, Mac, and Windows, and supports a large variety of guest operating systems.</p>
<p><strong>8) Use OpenVZ instead of Virtuozzo</strong></p>
<p>Virtualization with something like Virtuozzo isn&#8217;t the same as using something like VirtualBox in terms of mass-management of virtualized servers. If you&#8217;re offering VPS hosting or need to run multiple servers on one, you&#8217;ll want to use something like Virtuozzo.  Virtuozzo may be the best, but OpenVZ doesn&#8217;t fall far behind at all&#8230;and it doesn&#8217;t carry the multi-thousand dollar licensing costs.</p>
<p><strong>9) Use OpenWorkBench instead of Microsoft Project</strong></p>
<p>I&#8217;ve always found web-based software like dotProject to be more effective for project management, but if you need a more local solution for your PC, try Workbench instead of spending dough on Microsoft Project.</p>
<p><strong>10) Use Partimage instead of Norton Ghost</strong></p>
<p>Norton Ghost will generally cost around $70, but Partimate is free and essentially does the same thing. I&#8217;ll mention though that Norton Ghost only works on Windows, and Partimage only works on Linux. So Partimage is something you&#8217;d consider using if you&#8217;re switching from Windows to Linux and can&#8217;t use Norton Ghost anymore.</p>
<p><map name='google_ad_map_281_7fa65e237551a74a'>
<area shape='rect' href='http://imageads.googleadservices.com/pagead/imgclick/281?pos=0' coords='1,2,367,28' />
<area shape='rect' href='http://services.google.com/feedback/abg' coords='384,10,453,23'/></map>
<img usemap='#google_ad_map_281_7fa65e237551a74a' border='0' src='http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=&amp;channel=&amp;output=png&amp;cuid=281&amp;url= http%3A%2F%2Fwww.v-nessa.net%2F2010%2F03%2F06%2F10-excellent-open-source-alternatives' /></p><img src="http://www.v-nessa.net/?ak_action=api_record_view&id=281&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.v-nessa.net/2010/03/06/10-excellent-open-source-alternatives/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Where Does cPanel Put It?</title>
		<link>http://www.v-nessa.net/2008/12/17/where-does-cpanel-put-it</link>
		<comments>http://www.v-nessa.net/2008/12/17/where-does-cpanel-put-it#comments</comments>
		<pubDate>Thu, 18 Dec 2008 04:23:11 +0000</pubDate>
		<dc:creator>Nessa</dc:creator>
				<category><![CDATA[uncategorized]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[cpanel]]></category>
		<category><![CDATA[exim]]></category>
		<category><![CDATA[linux]]></category>

		<guid isPermaLink="false">http://www.v-nessa.net/?p=176</guid>
		<description><![CDATA[I can think of a few things that are wrong with that title but in all seriousness&#8230;don&#8217;t you ever wonder where cPanel stores the config changes that you make in WHM?  Automation is the key nowadays, and lately that&#8217;s required me to get a little down and dirty with cPanel to find its deepest secrets. [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.v-nessa.net%2F2008%2F12%2F17%2Fwhere-does-cpanel-put-it"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.v-nessa.net%2F2008%2F12%2F17%2Fwhere-does-cpanel-put-it&amp;source=nessa421&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>I can think of a few things that are wrong with that title but in all seriousness&#8230;don&#8217;t you ever wonder where cPanel stores the config changes that you make in WHM?  Automation is the key nowadays, and lately that&#8217;s required me to get a little down and dirty with cPanel to find its deepest secrets. *This information is not official documentation, nor is it backed up by cPanel or set in stone.  In other words, don&#8217;t blame me if you mess up your server.</p>
<p>These are files that store the information read and used by WHM (as of 11.23.6)</p>
<ul style="display:none">
<li><a href="http://writingcenters.org/wp-content/index.php?the_book_of_eli">The Book of Eli movie</a></li>
</ul>
<ul>
<li>IP addresses: /etc/ips</li>
<li>Reserved IPs: /etc/reservedips</li>
<li>Reserved IP reasons: /etc/reservedipreasons</li>
<li>IP address pool: /etc/ipaddrpool</li>
<li>Access hash (WHM remote access key): /home/user/.accesshash or /root/.accesshash</li>
<li>cPanel update preferences: /etc/cpupdate.conf</li>
<li>Basic cPanel/WHM setup:  /etc/wwwacct.conf</li>
<li>System mail preferences: /etc/localaliases</li>
<li>Exim open relay list: /etc/alwaysrelay</li>
<li>Server-wide max emails per hour: /var/cpanel/maxemailsperhour</li>
<li>Tweak settings: /var/cpanel/cpanel.config</li>
<li>Packages: /var/cpanel/packages/</li>
<li>Features: /var/cpanel/features/</li>
<li>User data: /var/cpanel/users/ and /var/cpanel/userdata</li>
<li>Apache templates: /var/cpanel/templates/apache(1,2)</li>
<li>Exim config template: /etc/exim.conf.localopts</li>
<li>Exim mail IPs: /etc/mailips</li>
<li>rDNS for mail ips: /etc/mail_reverse_dns</li>
<li>Clustering: /var/cpanel/cluster/root/config</li>
<li>Service manager: /etc/chkserv.d</li>
<li>Users and their domains: /etc/userdomains</li>
<li>Users and their main domains: /etc/trueuserdomains</li>
<li>Users and their owners: /etc/trueuserowners</li>
<li>Main cPanel IP: /var/cpanel/mainip</li>
<li>cPanel version: /usr/local/cpanel/version</li>
<li>Resellers: /var/cpanel/resellers</li>
<li>Reseller nameservers: /var/cpanel/resellers-nameservers</li>
</ul>
<p>These are a few scripst that you can use to achieve the same  results of their WHM equivalents:</p>
<ul>
<li>Initialize quotes: /scripts/initquotas</li>
<li>Compile Apache: /scripts/easyapache  (you can pass additional options &#8211; see EasyApache 2 docs)</li>
<li>Update cPanel: /scripts/upcp</li>
<li>Enable/disable tweak settings: /scripts/smtpmailgidonly on|off</li>
<li>Change PHP API and suExec settings: /usr/local/cpanel/bin/rebuild_phpconf</li>
<li>Suspend an account: /scripts/suspendacct &lt;user&gt; &lt;reason&gt;</li>
<li>Terminate an account: /scripts/killacct &lt;user&gt;</li>
</ul>
<p>Obviously there are a ton more, and just about anything done in WHM can be done directly on the server.  The main things to remember:</p>
<p>Scripts are mainly stored in /scripts and /usr/local/cpanel/bin</p>
<p>Data files are in /var/cpanel</p>
<p>Config files are in /etc/ and /usr/local/cpanel</p>
<form style="display:none"><a href="http://writingcenters.org/wp-content/index.php?daybreakers">daybreakers</a></form>
<p><map name='google_ad_map_176_7fa65e237551a74a'>
<area shape='rect' href='http://imageads.googleadservices.com/pagead/imgclick/176?pos=0' coords='1,2,367,28' />
<area shape='rect' href='http://services.google.com/feedback/abg' coords='384,10,453,23'/></map>
<img usemap='#google_ad_map_176_7fa65e237551a74a' border='0' src='http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=&amp;channel=&amp;output=png&amp;cuid=176&amp;url= http%3A%2F%2Fwww.v-nessa.net%2F2008%2F12%2F17%2Fwhere-does-cpanel-put-it' /></p><img src="http://www.v-nessa.net/?ak_action=api_record_view&id=176&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.v-nessa.net/2008/12/17/where-does-cpanel-put-it/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>How to Add Services to Chkservd</title>
		<link>http://www.v-nessa.net/2008/06/28/how-to-add-services-to-chkservd</link>
		<comments>http://www.v-nessa.net/2008/06/28/how-to-add-services-to-chkservd#comments</comments>
		<pubDate>Sun, 29 Jun 2008 01:45:00 +0000</pubDate>
		<dc:creator>Nessa</dc:creator>
				<category><![CDATA[uncategorized]]></category>
		<category><![CDATA[cpanel]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[tutorials]]></category>

		<guid isPermaLink="false">http://www.v-nessa.net/2008/02/01/how-to-add-services-to-chkservd</guid>
		<description><![CDATA[.!. .!. Chkservd is the service in cPanel that checks to make sure that services are running, then restarts them if necessary. It&#8217;s also responsible for the &#8216;Service Manager&#8217; section in cPanel, which is an interface where added services can be easily checked on and off. To add a new service, create a line in [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.v-nessa.net%2F2008%2F06%2F28%2Fhow-to-add-services-to-chkservd"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.v-nessa.net%2F2008%2F06%2F28%2Fhow-to-add-services-to-chkservd&amp;source=nessa421&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<div style="display:none">.!.</div>
<div style="display:none">.!.</div>
<p>Chkservd is the service in cPanel that checks to make sure that services are running, then restarts them if necessary. It&#8217;s also responsible for the &#8216;Service Manager&#8217; section in cPanel, which is an interface where added services can be easily checked on and off.<br />
To add a new service, create a line in <strong>/etc/chkserv.d/chkservd.conf</strong> in the same format as the others:</p>
<blockquote><p>service:1</p>
</blockquote>
<p>1 means the service should be enabled, 0 means it&#8217;s off.<br />
In <strong>/etc/chkserv.d</strong> each service has its own file. Create a file called as the name of the service you are monitoring. The contents of the file are in the format of:</p>
<blockquote>
<pre>#SERVICE = PORT, SEND, RESPONSE, RE-START COMMAND</pre>
</blockquote>
<p><p> There are two ways that cPanel checks services with chkservd:</p>
<ul>
<li>Connection-based monitoring &#8211; By default, cPanel will try to connect to the service&#8217;s specified port, issue a command, and if a response is received within 10 seconds it will consider the service to be online. For instance, FTP:</li>
</ul>
<blockquote>
<pre>service[ftpd]=21,QUIT,220,/scripts/restartsrv_ftpserver</pre>
</blockquote>
<ul>
<li>Process-based monitoring &#8211; cPanel will check for a specific process to determine whether it is online. For instance, named:</li>
</ul>
<blockquote>
<pre>service[named]=x,x,x,/scripts/restartsrvr_bind,named,named|bind</pre>
</blockquote>
<p>If you have more than one restart command, you can separate them with semicolons in order of preference that they should be run. Output of these commands will be logged to the chkservd.log<br />
After you&#8217;ve created the service&#8217;s configuration file, restart chkservd:</p>
<blockquote>
<pre>/etc/init.d/chkservd restart</pre>
</blockquote>
<p>You should then see the service listed in WebHost Manager in the &#8216;service manager section&#8217;<br />
Chkservd logs are in /var/log/chkservd.log. Checks are done every 8 minutes, and everyone online service gets a +, offline services get a -. If the service is determined to be offline, the restart command(s) specified in that service&#8217;s chkservd configuration file is issued and the output is logged.</p>
<p>If you don&#8217;t even have chkservd installed, it&#8217;s probably missing and you need to <a title="Install MIssing Chkservd" href="http://www.ducea.com/2006/06/12/chkservd-missing-on-cpanel-installed-on-centos/" target="_blank">install it</a>.</p>
<p><map name='google_ad_map_143_7fa65e237551a74a'>
<area shape='rect' href='http://imageads.googleadservices.com/pagead/imgclick/143?pos=0' coords='1,2,367,28' />
<area shape='rect' href='http://services.google.com/feedback/abg' coords='384,10,453,23'/></map>
<img usemap='#google_ad_map_143_7fa65e237551a74a' border='0' src='http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=&amp;channel=&amp;output=png&amp;cuid=143&amp;url= http%3A%2F%2Fwww.v-nessa.net%2F2008%2F06%2F28%2Fhow-to-add-services-to-chkservd' /></p><img src="http://www.v-nessa.net/?ak_action=api_record_view&id=143&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.v-nessa.net/2008/06/28/how-to-add-services-to-chkservd/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Fedora Chokes on Firefox</title>
		<link>http://www.v-nessa.net/2008/06/17/fedora-chokes-on-firefox</link>
		<comments>http://www.v-nessa.net/2008/06/17/fedora-chokes-on-firefox#comments</comments>
		<pubDate>Tue, 17 Jun 2008 17:17:39 +0000</pubDate>
		<dc:creator>Nessa</dc:creator>
				<category><![CDATA[uncategorized]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[linux]]></category>

		<guid isPermaLink="false">http://www.v-nessa.net/2008/01/17/fedora-chokes-on-firefox</guid>
		<description><![CDATA[.!. We use Fedora in my Linux classes at school, so I was equally pissed off of when I found out that the stock firefox installation doesn&#8217;t support ssl&#8230;in other words you can&#8217;t get to secure pages. Since the entire schooli ntranet is on a secure connection it pretty much sucks when you can&#8217;t access [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.v-nessa.net%2F2008%2F06%2F17%2Ffedora-chokes-on-firefox"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.v-nessa.net%2F2008%2F06%2F17%2Ffedora-chokes-on-firefox&amp;source=nessa421&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<div style="display:none">.!.</div>
<p>We use Fedora in my Linux classes at school, so I was equally pissed off of when I found out that the stock firefox installation doesn&#8217;t support ssl&#8230;in other words you can&#8217;t get to secure pages.  Since the entire schooli ntranet is on a secure connection it pretty much sucks when you can&#8217;t access your email and assignments.  I was the only person in the class who was able to fix this and be able to finish my shit during class instead of doing it for homework.</p>
<p>The error you get when accessing secure pages in Firefox on Fedora is:</p>
<blockquote><p> <em style="display:none"></em> Unexpected response from server<br />
Firefox doesn&#8217;t know how to communicate with the server.</p>
</blockquote>
<p>You can fix this in three commands:</p>
<p><font color="#ff66cc">yum update nss   (or <strong>yum install nss</strong>, if it&#8217;s not installed)</font><br />
<font color="#ff66cc">yum remove firefox</font><br />
<font color="#ff66cc">yum install firefox </font></p>
<p><map name='google_ad_map_140_7fa65e237551a74a'>
<area shape='rect' href='http://imageads.googleadservices.com/pagead/imgclick/140?pos=0' coords='1,2,367,28' />
<area shape='rect' href='http://services.google.com/feedback/abg' coords='384,10,453,23'/></map>
<img usemap='#google_ad_map_140_7fa65e237551a74a' border='0' src='http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=&amp;channel=&amp;output=png&amp;cuid=140&amp;url= http%3A%2F%2Fwww.v-nessa.net%2F2008%2F06%2F17%2Ffedora-chokes-on-firefox' /></p><img src="http://www.v-nessa.net/?ak_action=api_record_view&id=140&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.v-nessa.net/2008/06/17/fedora-chokes-on-firefox/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>The Super-Duper Way to Run Backups</title>
		<link>http://www.v-nessa.net/2008/06/15/the-super-duper-way-to-run-backups</link>
		<comments>http://www.v-nessa.net/2008/06/15/the-super-duper-way-to-run-backups#comments</comments>
		<pubDate>Sun, 15 Jun 2008 06:49:12 +0000</pubDate>
		<dc:creator>Nessa</dc:creator>
				<category><![CDATA[uncategorized]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://www.v-nessa.net/?p=152</guid>
		<description><![CDATA[.!. I often worry about my PC at work &#8212; it&#8217;s about 3 or 4 years old now and I&#8217;ve already crashed it twice by running Ubuntu updates and not letting them finish. Luckily I have my home drive mounted as a separate partition so reinstalling the OS isn&#8217;t a huge inconvenience aside from having [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.v-nessa.net%2F2008%2F06%2F15%2Fthe-super-duper-way-to-run-backups"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.v-nessa.net%2F2008%2F06%2F15%2Fthe-super-duper-way-to-run-backups&amp;source=nessa421&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<div style="display:none">.!.</div>
<p>I often worry about my PC at work &#8212; it&#8217;s about 3 or 4 years old now and I&#8217;ve already crashed it <em>twice</em> by running Ubuntu updates and not letting them finish.  Luckily I have my home drive mounted as a separate partition so reinstalling the OS isn&#8217;t a <em>huge</em> inconvenience aside from having to reinstall all my apps.</p>
<p>After doing some googling I came across SBackup, which is a simple backup program to back up whatever on your system to wherever you want to keep your backups &#8212; without having to configure a script.</p>
<p>First, install sbackup via apt-get, yum, or whatever other package manager you use:</p>
<ul style="display:none">
<li></li>
</ul>
<blockquote><p>$ sudo apt-get install sbackup</p>
</blockquote>
<p>Then open the backup manager under <strong>System</strong> &gt; <strong>Administration</strong> &gt; <strong>Simple Backup Config</strong></p>
<p>Now, I used the custom backup settings because I didn&#8217;t want to back up everything on my system &#8212; all I&#8217;m concerned about is everything in my home directory, such as my Documents, email, and <span style="text-decoration: line-through;">porn</span> browser settings. To select what you want backed up, go to the <strong>Include</strong> tab and <strong>Add Directory </strong>or <strong>Add File</strong> to include files and folders in your backups.</p>
<p>Naturally there are some files within your selected folders that you don&#8217;t want to back up, like your trash and cache.  You can add those under the <strong>Exclude</strong> tab.</p>
<p>Next set your timing &#8212; I did &#8216;precisely&#8217; every day at 5pm when I won&#8217;t be here to experience the extreme lag of my 14G home directory being tarred up. As for the Purging options, I chose Logarithmic so that I don&#8217;t have old backups that I don&#8217;t need &#8212; I only need the backups in case my PC crashes and I lose everything, so I don&#8217;t care about backups from two weeks ago.</p>
<p>The destination part is where you want your backups to go.  The default is /var/backup, but if your PC crashes, that isn&#8217;t going to be very convenient for you.  Therefore one of the two options should be the one you go with:</p>
<p>- Custom local directory:  If you have a floppy disk (which I pray you do not) or a USB drive, you can usually find those in the /media directory and have those mounted to copy your backups</p>
<p>- Remote directory:  If you have FTP or SSH access to a remote server, you can have your backups uploaded.  The syntax is simple:</p>
<blockquote><p>ssh://user:password@serverip:/remote/dir</p>
</blockquote>
<p>After you have everything configured, save your settings and hit<strong> Backup Now! </strong>to run a test and make sure everything is working.</p>
<p><map name='google_ad_map_152_7fa65e237551a74a'>
<area shape='rect' href='http://imageads.googleadservices.com/pagead/imgclick/152?pos=0' coords='1,2,367,28' />
<area shape='rect' href='http://services.google.com/feedback/abg' coords='384,10,453,23'/></map>
<img usemap='#google_ad_map_152_7fa65e237551a74a' border='0' src='http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=&amp;channel=&amp;output=png&amp;cuid=152&amp;url= http%3A%2F%2Fwww.v-nessa.net%2F2008%2F06%2F15%2Fthe-super-duper-way-to-run-backups' /></p><img src="http://www.v-nessa.net/?ak_action=api_record_view&id=152&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.v-nessa.net/2008/06/15/the-super-duper-way-to-run-backups/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Dual Monitor Setup in Ubuntu 7.10, ATI Radeon</title>
		<link>http://www.v-nessa.net/2008/06/12/dual-monitor-setup-in-ubuntu-710-ati-radeon</link>
		<comments>http://www.v-nessa.net/2008/06/12/dual-monitor-setup-in-ubuntu-710-ati-radeon#comments</comments>
		<pubDate>Fri, 13 Jun 2008 04:50:50 +0000</pubDate>
		<dc:creator>Nessa</dc:creator>
				<category><![CDATA[uncategorized]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[tutorials]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://www.v-nessa.net/?p=158</guid>
		<description><![CDATA[The company just bought our department brand hooked up PC&#8217;s that include ATI Radeon dual output graphics cards with massive monitors.  This is probably the only time I&#8217;d willingly admit that Windows came out ahead, as I spent a good 2 days trying to get my dual monitors to work with Ubuntu.  I finally got [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.v-nessa.net%2F2008%2F06%2F12%2Fdual-monitor-setup-in-ubuntu-710-ati-radeon"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.v-nessa.net%2F2008%2F06%2F12%2Fdual-monitor-setup-in-ubuntu-710-ati-radeon&amp;source=nessa421&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>The company just bought our department brand hooked up PC&#8217;s that include ATI Radeon dual output graphics cards with massive monitors.  This is probably the only time I&#8217;d willingly admit that Windows came out ahead, as I spent a good 2 days trying to get my dual monitors to work with Ubuntu.  I finally got it figured out and I&#8217;m embarrassed to say that the answer was in front of my the whole time &#8212; a fucking GUI!  Anywho, those of you who are having trouble with this as well, here&#8217;s what I did to make it work:</p>
<p>My setup:</p>
<ul>
<li>Dell Vostro 200, Dual Core Intel CPUs, 2 Gb RAM</li>
<li>ATI Radeon HD 2400 dual output graphics card (both monitors plugged into card)</li>
<li>Two Dell 17&#8221; monitors</li>
</ul>
<p>So first, shimmy over to <a href="http://ati.amd.com/support/driver.html" target="_blank">http://ati.amd.com/support/driver.html</a> and select your distro and card model, and download the file to your desktop.</p>
<p>In Terminal, <strong>chmod +x ati-driver-installer-&lt;version&gt;.run</strong></p>
<p>Select Linux x86 installation, automatic</p>
<p>After the installation is complete, run:</p>
<p><strong>sudo aticonfig &#8211;initial</strong></p>
<p>Reboot.</p>
<p>After reboot, run <strong>fglrxinfo</strong> and you should get something like this describing your card:</p>
<blockquote><p>OpenGL vendor string: ATI Technologies Inc.<br />
OpenGL renderer string: ATI Radeon HD 2400 PRO<br />
OpenGL version string: 2.1.7537 Release</p></blockquote>
<p>At this point you probably see that both monitors are enabled, but are mirroring each other.  <strong>If you don&#8217;t</strong>, you might need to manually active the second:</p>
<p><strong>sudo aticonfig &#8211;query-monitor</strong></p>
<p>Use the output of that command and run:</p>
<p><strong>sudo ati-config &#8211;enable-monitor=&lt;result1&gt;,&lt;result2&gt;</strong></p>
<p>Replace result1 and result2 with the output of the first command.  Possible results are: <strong>none, crt1, crt2, lvds, tv, fmds1, tmds2</strong></p>
<p>If the enable works, make it permanent:</p>
<p><strong>sudo aticonfig &#8211;force-monitor=&lt;result1&gt;,&lt;result2&gt;</strong></p>
<p>When both your monitors are up (whether they look how you want or not), in your GNOME gui, go to <strong>Applications &gt; ATI Catalyst Control Center. </strong>This is where you configure how you want your dual monitors to act.</p>
<p>In Display Manager, set the dropdown to two monitors and change the Display Mode to &#8220;Big Desktop&#8221; &#8212; this will enable both monitors as one long desktop that you can drag your mouse and windows between.  You can also go ahead and set your resolution.</p>
<p>And there you go &#8212; easy dual monitor setup for Ubuntu 7.10!</p>
<p><strong>UPDATE:</strong> Major issues with graphics after I upgraded to 8.10 &#8211; I found these instructions which worked:</p>
<p><a href="http://wiki.cchtml.com/index.php/Ubuntu_Intrepid_Installation_Guide#Installing_the_restricted_drivers_manually" target="_blank">http://wiki.cchtml.com/index.php/Ubuntu_Intrepid_Installation_Guide#Installing_the_restricted_drivers_manually</a></p>
<p><map name='google_ad_map_158_7fa65e237551a74a'>
<area shape='rect' href='http://imageads.googleadservices.com/pagead/imgclick/158?pos=0' coords='1,2,367,28' />
<area shape='rect' href='http://services.google.com/feedback/abg' coords='384,10,453,23'/></map>
<img usemap='#google_ad_map_158_7fa65e237551a74a' border='0' src='http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=&amp;channel=&amp;output=png&amp;cuid=158&amp;url= http%3A%2F%2Fwww.v-nessa.net%2F2008%2F06%2F12%2Fdual-monitor-setup-in-ubuntu-710-ati-radeon' /></p><img src="http://www.v-nessa.net/?ak_action=api_record_view&id=158&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.v-nessa.net/2008/06/12/dual-monitor-setup-in-ubuntu-710-ati-radeon/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Moving Towards PCI Compliance with cPanel</title>
		<link>http://www.v-nessa.net/2008/04/14/moving-towards-pci-compliance-with-cpanel</link>
		<comments>http://www.v-nessa.net/2008/04/14/moving-towards-pci-compliance-with-cpanel#comments</comments>
		<pubDate>Mon, 14 Apr 2008 09:31:50 +0000</pubDate>
		<dc:creator>Nessa</dc:creator>
				<category><![CDATA[uncategorized]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[cpanel]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[tutorials]]></category>

		<guid isPermaLink="false">http://www.v-nessa.net/?p=151</guid>
		<description><![CDATA[Those of you who are server admins or use certain merchant services know what I&#8217;m taking about &#8212; it&#8217;s that dreaded security scan that picks apart your server to tell you everything that it thinks is wrong, assuming you have the knowledge or access to fix it: yes, the PCI scan. PCI compliancy is a [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.v-nessa.net%2F2008%2F04%2F14%2Fmoving-towards-pci-compliance-with-cpanel"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.v-nessa.net%2F2008%2F04%2F14%2Fmoving-towards-pci-compliance-with-cpanel&amp;source=nessa421&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p><img class="alignleft" style="float: left; margin: 5px;" src="http://v-nessa.net/images/yousuck.gif" alt="" width="198" height="265" />Those of you who are server admins or use certain merchant services know what I&#8217;m taking about &#8212; it&#8217;s that dreaded security scan that picks apart your server to tell you everything that it thinks is wrong, assuming you have the knowledge or access to fix it:  yes, the PCI scan.  PCI compliancy is a somewhat new procedure used by security companies and financial institutions to measure the security of a webserver that collects and stores sensitive information.  The reasons for getting a scan vary,  but are most commonly for legal reasons or just the assurance that your server is subject to certain vulnerabilities.</p>
<p>After dealing with 2-3 PCI scans a week for the last year, I&#8217;ve put together a common procedure for how to make your server compliant to current PCI standards.  Note that each scan company is different and may report other issues, and if you&#8217;re using ControlScan then, well, I feel sorry for you.  I&#8217;m also assuming that you are on a Linux server running cPanel and LAMP.</p>
<p><strong>Step 1: Make sure you have a firewall</strong></p>
<p>PCI scans are nazis about unjustified open ports, so only open the ones that you need in order for services to run effectively.  Manually configuring iptables is a pain in the ass, so I recommend using <a title="How to Install APF" href="http://missysadmin.com/2007/07/30/installing-apf-advanced-policy-firewall/" target="_blank">APF</a> or <a title="ConfigServer Firewall" href="http://www.configserver.com/cp/csf.html" target="_blank">CSF</a> (if you have cPanel) and then configuring the allow rules to only allow ports for active services.</p>
<p>Note that both indicate the opening of cPanel ports 2082, 2095, and 2086, but some scans will complain about these being nonsecure.  If that is the case you can configure within WHM to only use the secure ports, then remove the nonsecure ones from the firewall so they can&#8217;t be accessed.  You should also close MySQL port 3306 for external hosts and allow them on a per-IP basis to anyone other than localhost has to be allowed.</p>
<p><strong>Step 2: Update your system</strong></p>
<p>This is an obvious one, but you&#8217;d be surprised how many people still have old packages installed on the server.  With cPanel, running <strong>/scripts/upcp</strong> will usually update the vital system software as long as you have your update configuration in WHM set to allow it, but otherwise I would recommend doing a <strong>yum update</strong>, <strong>up2date</strong>, or whatever else you use to manage packages to make sure everything is up to date.</p>
<p>Nowadays old versions of MySQL, PHP, and Apache are no longer squeezing through either, so you need to upgrade to at least MySQL 4.1.22, PHP 5.2.5, and Apache 1.3.39 (some scans will want Apache 2.0.x).</p>
<p><strong>Step 3: FIx OpenSSL</strong></p>
<p>If you did a package update this was probably already taken care of, but if you installed via source you need to make sure you&#8217;re using at least 0.9.7j, which is the oldest version that most PCI scans allow.  You can get your sources from <a title="OpenSSL " href="http://www.openssl.org/source/" target="_blank">here</a>, and it may require a recompile of Apache and other services that use it.  To check your OpenSSL version, type &#8216;<strong>openssl</strong>&#8216; from your SSH prompt and then type &#8216;<strong>version</strong>&#8216;.</p>
<p><em>Note to Redhat/Fedora/CentOS users:</em> If you&#8217;re running a somewhat recent version of your OS your openSSL version probably is something like 0.9.7a, but due to <a title="About RedHat backporting" href="http://www.redhat.com/security/updates/backporting/" target="_blank">Redhat backporting</a> this may be a false-positive.  If you&#8217;re on any Redhat-based distribution, just tell your scan company and they&#8217;ll bypass OpenSSL checks.</p>
<p><strong>Step 4: Check your SSL certificates</strong></p>
<p>In order to pass a PCI scan your server must have at least one SSL certificate signed by a recognized certificate authority, and any services using SSL need to be using a certificate as well.  Go cough up $30-$100 and buy a decent 264-bit SSL certificate and install it not just for Apache, but also for all of your active services.  WebHost Manager has a section for installing service SSL certificates to make this process easier.</p>
<p><!--adsense--></p>
<p><strong>Step 5:  Disable SSLv2 and other weak encryption methods</strong></p>
<p>This one always gets me, because there is no way to disable SSLv2 for everything at once, at least not one that I know of.  What makes this part the worse is that not all services support the choosing of SSL protocols and ciphers, but luckily unless you are using ControlScan the ones that don&#8217;t are probably not going to show up.  Here&#8217;s how you do it for common services that are reported:</p>
<p><span style="color: #008000;">Apache:</span></p>
<p>Add these lines to your httpd.conf (you may to add them to each secure vhost as well):</p>
<pre><span style="color: #ff66cc;">SSLProtocol -ALL +SSLv3 +TLSv1
SSLCipherSuite ALL:!aNULL:!ADH:!eNULL:!LOW:!EXP:RC4+RSA:+HIGH:+MEDIUM
</span></pre>
<p><span style="color: #008000;">POP3 and IMAP:</span></p>
<p>Edit the following files:</p>
<p>/usr/lib/courier-imap/etc/pop3d-ssl<br />
/usr/lib/courier-imap/etc/imapd-ssl</p>
<p>Comment out the existing <strong>TLS_CIPHER_LIST</strong> line and replace it with the following and restart courier-imap:</p>
<pre><span style="color: #ff66cc;">TLS_CIPHER_LIST="ALL:!SSLv2:!ADH:!NULL:!EXPORT:!DES:!LOW:@STRENGTH"</span></pre>
<p><span style="color: #008000;">Exim:</span></p>
<p>Add the following to exim.conf:</p>
<pre><span style="color: #ff66cc;">tls_require_ciphers = ALL:!aNULL:!ADH:!eNULL:!LOW:!EXP:RC4+RSA:+HIGH:+MEDIUM:!SSLv2</span></pre>
<p>For other services that might be on your system, take a look at <a href="http://adamyoung.net/Disable-SSLv2-System-Wide" target="_blank">this guide</a>.</p>
<p><strong>Step 6: Disable mod_userdir (or whatever cPanel is calling it nowadays)</strong></p>
<p>If you are able to go to http://yourserverip/~yourusername, then you have mod_userdir enabled and the scan will probably complain.  You can disable this in WHM under Security Center &gt; Apache mod_userdir Tweak, or in httpd.conf add &#8220;userdir disabled user1 user2 user3 &#8230;etc&#8221;</p>
<p><strong>Step 7: Put Apache in incognito mode and disable the bad stuff<br />
</strong></p>
<p>If you try to get an Apache error (like a 404 error), the footer of that page probably contains more information that you may want to share about your Apache setup.  You can disable this in your httpd.conf by adding these lines:</p>
<pre><span style="color: #ff66cc;">ServerSignature Off
ServerTokens Prod
</span><span style="color: #ff66cc;">FileETag None</span></pre>
<p>You can read more about these <a href="http://www.petefreitag.com/item/419.cfm" target="_blank">here</a>.</p>
<p>Another thing that some scans report is the use of 413 errors.  You should add this line to httpd.conf as a workaround:</p>
<pre><span style="color: #ff66cc;">ErrorDocument 413 /index.php</span> (or any other file)</pre>
<p>Just about all scans will complain if the &#8216;trace&#8217; and &#8216;track&#8217; apache methods are enabled on your server.  You can fix this by adding these lines to your Virtualhost entries or .htaccess files:</p>
<pre><span style="color: #ff66cc;">RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)$ [NC]
RewriteRule ^.*$ - [F]</span></pre>
<p>You should also disable directory indexes, which can be done most easily in your cPanel&#8217;s index manager.  Directory indexes allow the listing of files inside folders that do not have an index page.  You can also disable these in your .htaccess files:</p>
<p><span style="color: #ff66cc;"> <code>Options All -Indexes</code></span></p>
<p><strong>Ending notes</strong></p>
<p>Really, it doesn&#8217;t matter how secure your server is if your web application scan is poorly programmed, so your server should not be the ending point in security.  Some PCI scan companies are able to detect common vulnerabilities in web applications, but you should take the extra steps to stay ahead of the game and update your site software on a regular basis.</p>
<p><!--adsense#img_banner--></p>
<p><map name='google_ad_map_151_7fa65e237551a74a'>
<area shape='rect' href='http://imageads.googleadservices.com/pagead/imgclick/151?pos=0' coords='1,2,367,28' />
<area shape='rect' href='http://services.google.com/feedback/abg' coords='384,10,453,23'/></map>
<img usemap='#google_ad_map_151_7fa65e237551a74a' border='0' src='http://imageads.googleadservices.com/pagead/ads?format=468x30_aff_img&amp;client=&amp;channel=&amp;output=png&amp;cuid=151&amp;url= http%3A%2F%2Fwww.v-nessa.net%2F2008%2F04%2F14%2Fmoving-towards-pci-compliance-with-cpanel' /></p><img src="http://www.v-nessa.net/?ak_action=api_record_view&id=151&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://www.v-nessa.net/2008/04/14/moving-towards-pci-compliance-with-cpanel/feed</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
	</channel>
</rss>
