<?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>Tony Bhimani&#039;s Blog &#187; HOWTOs</title>
	<atom:link href="http://www.tonybhimani.com/category/howtos/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.tonybhimani.com</link>
	<description>Where I Share my Linux + Mac + Programming Experiences</description>
	<lastBuildDate>Mon, 24 Oct 2011 05:00:28 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>AJAX: Learn The Basics Without Using Toolkit Libraries</title>
		<link>http://www.tonybhimani.com/2011/10/23/ajax-learn-the-basics-without-using-toolkit-libraries/</link>
		<comments>http://www.tonybhimani.com/2011/10/23/ajax-learn-the-basics-without-using-toolkit-libraries/#comments</comments>
		<pubDate>Mon, 24 Oct 2011 05:00:28 +0000</pubDate>
		<dc:creator>Tony Bhimani</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[HOWTOs]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[XML]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[XMLHttpRequest]]></category>

		<guid isPermaLink="false">http://www.tonybhimani.com/?p=408</guid>
		<description><![CDATA[AJAX is one of the popular acronym buzzwords in the world of web development technologies. It stands for Asynchronous JavaScript and XML. What it does is allow you to make your website far more dynamic by updating portions in realtime &#8230; <a href="http://www.tonybhimani.com/2011/10/23/ajax-learn-the-basics-without-using-toolkit-libraries/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>AJAX is one of the popular acronym buzzwords in the world of web development technologies. It stands for Asynchronous JavaScript and XML. What it does is allow you to make your website far more dynamic by updating portions in realtime without page reloads (refreshes). This beginners AJAX tutorial will teach you how to write JavaScript code to do some simple screen updates. It&#8217;ll focus on a low-level AJAX implementation meaning JavaScript toolkits like jQuery and script.aculo.us will not be used (future tutorials will make use of these high-level time-saving tools). In my opinion, learning AJAX in this manner is far better because you&#8217;ll grasp the concept and it will help you move in the direction of using toolkits to simplify your coding (<em>you must crawl before you can walk&#8230;</em>). Also, this AJAX tutorial will be the first post in a series I plan on publishing regarding this subject.</p>
<p><strong>Phase 1: Writing the AJAX JavaScript Code &#8211; Making the Call</strong></p>
<p>I first learned AJAX from the <a href="http://www.w3schools.com/" rel="nofollow" target="_blank">W3Schools</a> website and will be using their code base as the foundation for this AJAX tutorial. The first step in working with AJAX is to create an object of <code>XMLHttpRequest</code>. The Firefox, Opera, Safari, and Internet Explorer browsers all handle this differently, however code wise the first three are the same. Internet Explorer (yes, Microsoft) has to take a unique approach (putting it nicely) which is different than the other mainstream web browsers. Getting back on point now, the code below is a modified version of what you can find from the W3Schools AJAX Guide for creating a object for <code>XMLHttpRequest</code> (the interface to make AJAX music).</p>
<pre class="code">function GetXmlHttpObject() {
  var xmlHttp = null;
  try {
    // Firefox, Opera 8.0+, Safari
    xmlHttp = new XMLHttpRequest();
  } catch (e) {
    // Internet Explorer
    try {
      xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
    } catch (e) {
      xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
  }
  return xmlHttp;
}</pre>
<p>The code starts with creating a variable handle for the <code>XMLHttpRequest</code> object and making it null. Within a <code>try</code> and <code>catch</code> block the <code>XMLHttpRequest()</code> method is called. If an object is created then exit the function and return the object. If the object can&#8217;t be created then the ActiveX (Microsoft) route is taken by using <code>Msxml2.XMLHTTP</code> and <code>Microsoft.XMLHTTP</code>. If this part fails as well, AJAX isn&#8217;t possible with the browser for whatever reason, otherwise after having called this <code>GetXmlHttpObject()</code> function we&#8217;ll have an AJAX object to work with. Next we&#8217;ll build an AJAX request.</p>
<pre class="code">// create xml http object
var objXmlHttp = GetXmlHttpObject();
// open a connection and send the ajax request
objXmlHttp.open("GET", "http://www.domain.com/ajaxresponder.php", true);
objXmlHttp.send();</pre>
<p>The AJAX request is composed of a call to the <code>open</code> and <code>send</code> methods of the <code>XmlHttpRequest</code> object. The <code>open</code> method takes three parameters (type of request [GET or POST], URL of the file on the server, and boolean true [asynchronous] or false [synchronous]).</p>
<ul>
<li>
<p><strong>Type of Request:</strong> GET or POST? Well, it depends on your requirements but most of the time you will be using GET for your AJAX calls. AJAX is information dependent meaning that what you give it will determine what it gives back to you. For example, say you&#8217;re providing a weather service and want to get the temperature for a specific zip code. That zip code would be passed as part of the URL in the query string. The file on the server would accept that input and give the temperature as output.</p>
</li>
<li>
<p><strong>URL of file on the server:</strong> This URL is where the processing of your data happens. The type of file will be a dynamic server-side scripting language such as PHP that can take your input (via GET or POST), process it, and send back formatted output that you will present to the user&#8217;s browser. Using the weather example from above, this script would take the zip code and possibly do a database lookup to get the temperature and pass it back to the AJAX caller.</p>
</li>
<li>
<p><strong>Asynchronous or Synchronous:</strong> Once again, depending on your requirements you may choose one option over the other. A high percentage of the time your calls will be asynchronous, which means that once the AJAX call is issued your browser won&#8217;t be held up waiting on the response; it can continue doing other tasks and once the response does come in it can be processed. One instance when a synchronous call would be necessary is when the response of a first AJAX call is required by a second call. If you keep it asynchronous then once the first AJAX call is done the second would run right away. There is no guarantee that the first call would be fast enough to get the result to pass to the second call, hence keeping it synchronous forces the order of operations to follow through. Be careful though! If the synchronous call takes a long time processing it can appear that your browser window has locked up!</p>
</li>
</ul>
<p><strong>Phase 2: Crafting a Server-Side PHP Script to Process AJAX Requests</strong></p>
<p>With the JavaScript code in place for invoking the AJAX call the server-side script to handle that call needs to be written. The sole purpose of this script will be to listen for the AJAX call, process the request, and send back output. Because this is AJAX tutorial is being written in a manner with beginners in mind, the server-side script is going to be extremely basic. What it will do is send back a random quote from a famous author. In the next tutorial I&#8217;ll take it up a notch by showing you how to integrate a database and fetching data.</p>
<p>I&#8217;ll be using PHP to write this server-side script because that is my preferred language, however you can use Perl CGI, Cold Fusion, Microsoft&#8217;s Active Server Pages, ASP.NET or another language as long as the server that will be hosting the script can support it. If you don&#8217;t know PHP then try and follow along and I&#8217;ll explain the code as I go.</p>
<pre class="code">&lt;?php

/************************************************
      AJAX FAMOUS AUTHOR QUOTE SCRIPT
  Quotes Source: www.famousquotesandauthors.com
*************************************************/

// we use an array for the famous author quotes
$quotes_arr = array(
&quot;I know only that what is moral is what you feel good after and what is immoral is what you feel bad after. - Ernest Hemingway&quot;,
&quot;Eve left Adam, to meet the Devil in private. - Alexander Pope&quot;,
&quot;Democracy is based on the conviction that man has the moral and intellectual capacity, as well as the inalienable right, to govern himself with reason and justice. - Harry S. Truman&quot;,
&quot;Crime is a logical extension of the sort of behaviour that is often considered perfectly respectable in legitimate business. - Robert Rice&quot;,
&quot;By time and toil we sever What strength and rage could never. - Jean de la Fontaine&quot;,
&quot;Human history is in essence a history of ideas. - H. G. Wells&quot;
);

// the quotes are chosen randomly
$quote_choice = rand(0, sizeof($quotes_arr) - 1);

// echo the random quote
echo $quotes_arr[$quote_choice];

?&gt;
</pre>
<p>This is a very simple PHP script. All it does is define a six string array with the variable name of <code>$quotes_arr</code>. One of those six quotes is chosen at random using the PHP <code>rand()</code> function. What <code>rand()</code> will do is pick a random number between 0 and the size of the array less one (6 &#8211; 1 = 5) to serve as an index for choosing a string from the array. Note: PHP arrays are zero-based indexing meaning the first element begins at zero, not one. Finally, using PHP&#8217;s <code>echo</code> the chosen quote string is printed out to the browser.</p>
<p><strong>Phase 3: Putting All This AJAX &amp; PHP Coding Stuff Together</strong></p>
<p>The pieces to this AJAX puzzle are on the table, it&#8217;s time to fit them together. We&#8217;ve learned how to build an AJAX request and what an AJAX processing script can look like, the last step is to build the HTML page that makes use of them. The mechanics will be once the page loads the AJAX request will be made, the famous quote will be received from the server-side script, and the quote will be written to the HTML page. I&#8217;ve also included a button that can be clicked to load a new quote when clicked.</p>
<pre class="code">&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;  dir=&quot;ltr&quot; lang=&quot;en-US&quot;&gt;
&lt;head&gt;
&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot; /&gt;
&lt;title&gt;AJAX Tutorial: Random Famous Quotes&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;script type=&quot;text/javascript&quot; language=&quot;JavaScript&quot;&gt;
&lt;!--
function GetXmlHttpObject() {
  var xmlHttp = null;
  try {
    // Firefox, Opera 8.0+, Safari
    xmlHttp = new XMLHttpRequest();
  } catch (e) {
    // Internet Explorer
    try {
      xmlHttp = new ActiveXObject(&quot;Msxml2.XMLHTTP&quot;);
    } catch (e) {
      xmlHttp = new ActiveXObject(&quot;Microsoft.XMLHTTP&quot;);
    }
  }
  return xmlHttp;
}
// create xml http object
var objXmlHttp = GetXmlHttpObject();
// open a connection and send the ajax request
objXmlHttp.open(&quot;GET&quot;, &quot;http://www.tonybhimani.com/files/2011/10/ajax-quotes.php&quot;, true);
objXmlHttp.send();
objXmlHttp.onreadystatechange=function() {
  if (objXmlHttp.readyState == 4 &#038;&#038; objXmlHttp.status == 200) {
    document.getElementById(&quot;quotes&quot;).innerHTML = objXmlHttp.responseText;
  }
}
// --&gt;
&lt;/script&gt;
&lt;p&gt;&lt;strong&gt;Random Quote of the Day&lt;/strong&gt;&lt;/p&gt;
&lt;p id=&quot;quotes&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;&lt;input type=&quot;button&quot; name=&quot;reload&quot; value=&quot;Reload Page&quot; onclick=&quot;javascript:window.location.reload(true);&quot; /&gt;&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>You may notice I&#8217;ve added some extra code to the AJAX JavaScript section. Because this is an asynchronous call we have to declare an event handler. An event handler is a code block that sits around and waits for an event to occur before it executes its code. Our event handler (JavaScript function) is attached to the <code>onreadystatechange</code> event of the <code>XMLHttpRequest</code> object. It will get executed when the ready state changes. We check two <code>XMLHttpRequest</code> properties <code>readyState</code> and <code>status</code> for specific values. Once these values are attained (<code>readyState</code> of 4 meaning all data has been received and HTTP status of 200) we then use <code>getElementById</code> and change the HTML code between the start and end tags of the P with the id of quotes using this <code>innerHTML</code> property.</p>
<p>Okay, we&#8217;ve reached the end of this beginner&#8217;s AJAX tutorial. I&#8217;ve been talking about AJAX this whole time and I&#8217;m sure you&#8217;re eager to finally see the AJAX code in action. Below is a link to the sample page where you will see a randomly pulled quote from the PHP AJAX script. Click the Reload Page button to see another quote from the PHP array.</p>
<p><a href="http://www.tonybhimani.com/files/2011/10/famous-quotes.html" title="AJAX Tutorial for Beginners: Random Famous Author Quotes" target="_blank"><strong>AJAX Tutorial for Beginners: Random Famous Author Quotes</strong></a></p>
<p>Source Code Download: <a href="http://www.tonybhimani.com/files/2011/10/ajax-tutorial-1-no-toolkits1.zip" title="AJAX Tutorial for Beginners 1 [ No Toolkits ]">AJAX Tutorial for Beginners 1 [ No Toolkits ] (Zip)</a></p>
<div class="gpo_leftcontainer"><div class="gpo_buttons"><g:plusone size="tall" count="true"></g:plusone></div></div> <a href='http://twitter.com/share?url=http%3A%2F%2Fwww.tonybhimani.com%2F%3Fp%3D408&count=vertical&related=&text=AJAX%3A%20Learn%20The%20Basics%20Without%20Using%20Toolkit%20Libraries' class='twitter-share-button' data-text='AJAX: Learn The Basics Without Using Toolkit Libraries' data-url='http://www.tonybhimani.com/?p=408' data-counturl='http://www.tonybhimani.com/2011/10/23/ajax-learn-the-basics-without-using-toolkit-libraries/' data-count='vertical' data-via='TonyBhimani'></a> <script type='text/javascript'>
<!--
tweetmeme_source = 'TonyBhimani';
tweetmeme_url = 'http://www.tonybhimani.com/2011/10/23/ajax-learn-the-basics-without-using-toolkit-libraries/';
//-->
</script><script type="text/javascript" src="http://tweetmeme.com/i/scripts/button.js"></script>
]]></content:encoded>
			<wfw:commentRss>http://www.tonybhimani.com/2011/10/23/ajax-learn-the-basics-without-using-toolkit-libraries/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>JavaScript: Controlling a Popup Window&#8217;s Parent Window</title>
		<link>http://www.tonybhimani.com/2011/10/16/javascript-controlling-a-popup-windows-parent-window/</link>
		<comments>http://www.tonybhimani.com/2011/10/16/javascript-controlling-a-popup-windows-parent-window/#comments</comments>
		<pubDate>Mon, 17 Oct 2011 06:47:33 +0000</pubDate>
		<dc:creator>Tony Bhimani</dc:creator>
				<category><![CDATA[HOWTOs]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Control Windows]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[Popup Parent]]></category>
		<category><![CDATA[Popup Window]]></category>

		<guid isPermaLink="false">http://www.tonybhimani.com/?p=363</guid>
		<description><![CDATA[You may find it useful to control a parent window from a generated popup window, such as being able to manipulate its look, content, etc. One example being a web application I wrote for work. In the portion for entering &#8230; <a href="http://www.tonybhimani.com/2011/10/16/javascript-controlling-a-popup-windows-parent-window/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>You may find it useful to control a parent window from a generated popup window, such as being able to manipulate its look, content, etc. One example being a web application I wrote for work. In the portion for entering a new sales order, products are added from a popup search window. When the product being added is selected, a button is clicked and the parent window&#8217;s line item table is modified to include the selected product. This is only one example as many others exist. This tutorial will discuss how to launch a popup window and change properties of the parent (colors, fonts, sizes, and styles).</p>
<p><a href="http://www.tonybhimani.com/files/2011/10/Parent_Window.png"><img class="alignleft size-medium wp-image-370" title="Parent Window Screenshot for JavaScript Manipulation" src="http://www.tonybhimani.com/files/2011/10/Parent_Window-300x215.png" alt="Parent Window Screenshot for JavaScript Manipulation" width="300" height="215" /></a> We begin with creating the parent window. There won&#8217;t anything fancy with it, just a H1 title, a couple paragraphs of text, and a link to launch the popup window controller. To the left is a screenshot of what our parent window will look like when the HTML has been added. In the code some elements have been added to allow us to use JavaScript to control (manipulate) the contents of the parent window. Namely id attributes for the H1 and P tags for use the the Document Object Method <code>getElementById</code>.</p>
<p>Parent Window HTML + JavaScript Code ( parent-window.html ):</p>
<pre class="code">&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"  dir="ltr" lang="en-US"&gt;
&lt;head&gt;
&lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /&gt;
&lt;title&gt;The Parent Window [ JavaScript: Controlling a Popup Window's Parent Window ]&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;h1 id="page_title"&gt;The Parent Window&lt;/h1&gt;
&lt;p id="paragraph1"&gt;This is the window that will be controlled by the popup window.&lt;/p&gt;
&lt;p id="paragraph2"&gt;Click the link below to open the popup window controller.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;a href="#" onclick="javascript:window.open('popup-window.html','popupwindow','width=450,height=250,menu=0,status=0');"&gt;Launch Popup Window&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;small&gt;Note: Please disable any popup blocker software if you don't see the popup window.&lt;/small&gt;&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>
<p>You&#8217;ll see that the code for opening the popup window is located in the href onclick. The JavaScript <code>window.open</code> is called and the popup window filename is passed as the first parameter, followed by a name for the window, and lastly the specs for the window appearance (width, height, hide the menu and status bars).</p>
<p><a href="http://www.tonybhimani.com/files/2011/10/Popup_Window.png"><img class="alignleft size-medium wp-image-380" title="Popup Window Screenshot for JavaScript Parent Window Manipulation" src="http://www.tonybhimani.com/files/2011/10/Popup_Window-300x222.png" alt="Popup Window Screenshot for JavaScript Parent Window Manipulation" width="300" height="222" /></a> With the parent window created the next step is to create the popup window. The purpose of the popup window is to control its parent window. For this demonstration it&#8217;s accomplished through a series of buttons that call JavaScript functions that alter the parent window&#8217;s properties (as seen on the left). I have created buttons that change the window&#8217;s background color, the font family for the H1 title, the font size for the first paragraph, the font style for the second paragraph, and to reload the parent window page. Obviously I&#8217;m only scratching the surface here as much more can be done with JavaScript to alter the parent window.</p>
<p>Popup Window HTML + JavaScript Code ( popup-window.html ):</p>
<pre class="code">&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;  dir=&quot;ltr&quot; lang=&quot;en-US&quot;&gt;
&lt;head&gt;
&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot; /&gt;
&lt;title&gt;The Popup Window [ JavaScript: Controlling a Popup Window's Parent Window ]&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;script type=&quot;text/javascript&quot; language=&quot;JavaScript&quot;&gt;
&lt;!--
var parent_window = window.opener;
var bgcolor_index = 0;
var h1font_index = 0;
var para1_index = 0;
var para2_index = 0;

function backgroundColor() {
  var colors = ['#ff0000', '#00ff00', '#0000ff', '#ffff00', '#00ffff', '#cccccc', '#ffffff'];
  if (parent_window &#038;&#038; !parent_window.closed) {
    parent_window.document.body.style.backgroundColor = colors[bgcolor_index];
    if (++bgcolor_index &gt; colors.length - 1) { bgcolor_index = 0; }
  }
}

function h1TitleFontFamily() {
  var fonts = ['Arial', 'Helvectica', 'Sans Serif', 'Verdana', 'Times New Roman'];
  if (parent_window &#038;&#038; !parent_window.closed) {
    var page_title = parent_window.document.getElementById('page_title');
    page_title.style.fontFamily = fonts[h1font_index];
    if (++h1font_index &gt; fonts.length - 1) { h1font_index = 0; }
  }
}

function paragraph1FontSize() {
  var sizes = ['8pt', '12pt', '16pt', '20pt', '32pt', '64pt'];
  if (parent_window &#038;&#038; !parent_window.closed) {
    var paragraph1 = parent_window.document.getElementById('paragraph1');
    paragraph1.style.fontSize = sizes[para1_index];
    if (++para1_index &gt; sizes.length - 1) { para1_index = 0; }
  }
}

function paragraph2FontStyle() {
  var styles = ['oblique', 'italic', 'normal'];
  if (parent_window &#038;&#038; !parent_window.closed) {
    var paragraph2 = parent_window.document.getElementById('paragraph2');
    paragraph2.style.fontStyle = styles[para2_index];
    paragraph2.style.fontWeight = 'bold';
    if (++para2_index &gt; styles.length - 1) {
      para2_index = 0;
      paragraph2.style.fontWeight = '';
    }
  }
}

function reloadParent() {
  if (parent_window &#038;&#038; !parent_window.closed) {
    parent_window.location.reload(true);
  }
}
// --&gt;
&lt;/script&gt;
&lt;h1 align=&quot;center&quot;&gt;The Popup Window&lt;/h1&gt;
&lt;table width=&quot;100%&quot; border=&quot;0&quot; cellpadding=&quot;10&quot; cellspacing=&quot;0&quot;&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot; valign=&quot;middle&quot;&gt;&lt;input type=&quot;button&quot; name=&quot;button1&quot; id=&quot;button1&quot; value=&quot;Background Color&quot; onclick=&quot;backgroundColor();&quot; /&gt;&lt;/td&gt;
&lt;td align=&quot;center&quot; valign=&quot;middle&quot;&gt;&lt;input type=&quot;button&quot; name=&quot;button2&quot; id=&quot;button2&quot; value=&quot;H1 Title Font Family&quot; onclick=&quot;h1TitleFontFamily();&quot; /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot; valign=&quot;middle&quot;&gt;&lt;input type=&quot;button&quot; name=&quot;button3&quot; id=&quot;button3&quot; value=&quot;Paragraph 1 Font Size&quot; onclick=&quot;paragraph1FontSize();&quot; /&gt;&lt;/td&gt;
&lt;td align=&quot;center&quot; valign=&quot;middle&quot;&gt;&lt;input type=&quot;button&quot; name=&quot;button4&quot; id=&quot;button4&quot; value=&quot;Paragraph 2 Font Style&quot; onclick=&quot;paragraph2FontStyle();&quot; /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;center&quot; valign=&quot;middle&quot; colspan=&quot;2&quot;&gt;&lt;input type=&quot;button&quot; name=&quot;button5&quot; id=&quot;button5&quot; value=&quot;Reload Parent Window&quot; onclick=&quot;reloadParent();&quot; /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>I&#8217;m not going to go over all the code. The key to making the popup control the parent is the <code>Window</code> object&#8217;s <code>opener</code> property ala <code>window.opener</code>. In my code I assign it to a variable called <code>parent_window</code> which I use throughout my functions. By referencing it in front of the <code>document</code> object you can hook into the window properties of the parent much like you would for any foreground window. Having done so you now have access to <code>getElementById</code> and other Document Object Methods to get a handle to the object. Add some creative JavaScript and you can build some pretty interesting web applications with popup windows.</p>
<p>That&#8217;s it in a nutshell so enough talk. I&#8217;m sure you want see it in action, so try out the <a href="http://www.tonybhimani.com/files/2011/10/parent-window.html" title="Controlling a Popup Window's Parent Window Demonstration" target="_blank"><strong>Controlling a Popup Window&#8217;s Parent Window Demonstration</strong></a>.</p>
<p>Source Code Download: <a href="http://www.tonybhimani.com/files/2011/10/parent-window-controller.zip" title="Control a Parent Window by Popup using JavaScript Source Code (Zip)">Control a Parent Window by Popup using JavaScript (Zip)</a></p>
<div class="gpo_leftcontainer"><div class="gpo_buttons"><g:plusone size="tall" count="true"></g:plusone></div></div> <a href='http://twitter.com/share?url=http%3A%2F%2Fwww.tonybhimani.com%2F%3Fp%3D363&count=vertical&related=&text=JavaScript%3A%20Controlling%20a%20Popup%20Window%26%23039%3Bs%20Parent%20Window' class='twitter-share-button' data-text='JavaScript: Controlling a Popup Window&#039;s Parent Window' data-url='http://www.tonybhimani.com/?p=363' data-counturl='http://www.tonybhimani.com/2011/10/16/javascript-controlling-a-popup-windows-parent-window/' data-count='vertical' data-via='TonyBhimani'></a> <script type='text/javascript'>
<!--
tweetmeme_source = 'TonyBhimani';
tweetmeme_url = 'http://www.tonybhimani.com/2011/10/16/javascript-controlling-a-popup-windows-parent-window/';
//-->
</script><script type="text/javascript" src="http://tweetmeme.com/i/scripts/button.js"></script>
]]></content:encoded>
			<wfw:commentRss>http://www.tonybhimani.com/2011/10/16/javascript-controlling-a-popup-windows-parent-window/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP: Checkbox Arrays with Javascript Usage</title>
		<link>http://www.tonybhimani.com/2011/10/15/php-checkbox-arrays-with-javascript-usage/</link>
		<comments>http://www.tonybhimani.com/2011/10/15/php-checkbox-arrays-with-javascript-usage/#comments</comments>
		<pubDate>Sat, 15 Oct 2011 10:12:22 +0000</pubDate>
		<dc:creator>Tony Bhimani</dc:creator>
				<category><![CDATA[HOWTOs]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Arrays]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[HTML Forms]]></category>

		<guid isPermaLink="false">http://www.tonybhimani.com/?p=314</guid>
		<description><![CDATA[If you&#8217;ve created HTML forms then you&#8217;ll have used checkboxes and radio buttons for gathering user input. Taking it a step further you would link your form with a server-side scripting language such as PHP to capture the user input &#8230; <a href="http://www.tonybhimani.com/2011/10/15/php-checkbox-arrays-with-javascript-usage/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;ve created HTML forms then you&#8217;ll have used checkboxes and radio buttons for gathering user input. Taking it a step further you would link your form with a server-side scripting language such as PHP to capture the user input and process it. Things get a little tricky when you have groups of checkboxes or radio buttons in your form. Once you create a group of these same control types you form what is known as an array. An array is simply an integer-indexed collection of objects. When defining a checkbox or radio button you need to give it a name. This naming convention allows you to access the value of the control object and use it for whatever purpose you need (store it, email it, etc).</p>
<pre class="code">&lt;form action=&quot;#&quot;&gt;
&lt;input type=&quot;checkbox&quot; name=&quot;language&quot; value=&quot;English&quot; /&gt; I speak English&lt;br /&gt;
&lt;input type=&quot;checkbox&quot; name=&quot;language&quot; value=&quot;French&quot; /&gt; I speak French
&lt;/form&gt;
</pre>
<p>Above is an example of two checkboxes for choosing a spoken language. Notice how they both share the same name <em>language</em> to create an array (more precisely a nodelist of elements).</p>
<pre class="code">&lt;script type=&quot;text/javascript&quot; language=&quot;JavaScript&quot;&gt;
&lt;!--
function showMyChoices1() {
  var strChoices = &quot;&quot;
  var objCBarray = document.getElementsByName('language');
  for (i = 0; i &lt; objCBarray.length; i++) {
    if (objCBarray[i].checked) {
      strChoices += &quot;* &quot; + objCBarray[i].value + &quot;\n&quot;;
    }
  }
  if (strChoices.length &gt; 0) {
    var strMessage = &quot;You speak\n&quot; + strChoices;
    alert(strMessage);
  } else {
    alert(&quot;Please choose your spoken language(s).&quot;);
  }}
// --&gt;
&lt;/script&gt;
</pre>
<p>Next I have created a simple function called <em>showMyChoices1</em> that loops through the checkboxes, creates a message, and displays it using an alert. The variable <em>objCBarray</em> is a handle for the checkbox nodelist acquired by using <code>getElementsByName</code> Document Object Method. Using a for loop to iterate through each checkbox (the loop count is determined by the length property), the checked ones get added to a string called <em>strChoices</em>. After the for loop is finished the length of the string is tested for a value greater than zero. If it tests positive then an alert is shown with the checked values, otherwise a message prompting the user to select a language is shown.</p>
<p>Let&#8217;s put it all together (including a button) and see it in action. Try it below.<script type="text/javascript" language="JavaScript"><!--
function showMyChoices1() {
  var strChoices = "";
  var objCBarray = document.getElementsByName('language');
  for (i = 0; i < objCBarray.length; i++) {
    if (objCBarray[i].checked) {
      strChoices += "* " + objCBarray[i].value + "\n";
    }
  }
  if (strChoices.length > 0) {
    var strMessage = "You speak\n" + strChoices;
    alert(strMessage);
  } else {
    alert("Please choose your spoken language(s).");
  }
}
// --></script><br />
<form action="#">
<input type="checkbox" name="language" value="English" /> I speak English<br />
<input type="checkbox" name="language" value="French" /> I speak French<br />
<input type="button" value="Show My Choices" onclick="showMyChoices1();" /></form>
<p>Here is the code for the JavaScript only version.</p>
<pre class="code">&lt;script type=&quot;text/javascript&quot; language=&quot;JavaScript&quot;&gt;
&lt;!--
function showMyChoices1() {
  var strChoices = &quot;&quot;;
  var objCBarray = document.getElementsByName('language');
  for (i = 0; i &lt; objCBarray.length; i++) {
    if (objCBarray[i].checked) {
      strChoices += &quot;* &quot; + objCBarray[i].value + &quot;\n&quot;;
    }
  }
  if (strChoices.length &gt; 0) {
    var strMessage = &quot;You speak\n&quot; + strChoices;
    alert(strMessage);
  } else {
    alert(&quot;Please choose your spoken language(s).&quot;);
  }
}
// --&gt;
&lt;/script&gt;
&lt;form action=&quot;#&quot;&gt;
&lt;input type=&quot;checkbox&quot; name=&quot;language&quot; value=&quot;English&quot; /&gt; I speak English&lt;br /&gt;
&lt;input type=&quot;checkbox&quot; name=&quot;language&quot; value=&quot;French&quot; /&gt; I speak French&lt;br /&gt;
&lt;input type=&quot;button&quot; value=&quot;Show My Choices&quot; onclick=&quot;showMyChoices1();&quot; /&gt;
&lt;/form&gt;
</pre>
<p>If you plan on using PHP to process your form data then the way the checkboxes were named isn&#8217;t going to work. PHP requires you to name the variable in an array manner. It&#8217;s basically the same as before but you have to add trailing square brackets []. For example, I used <em>language</em> for the name of my checkboxes. To make this work with PHP I&#8217;ll need to use <em>language[]</em>. Having made this change the JavaScript function I&#8217;ve created won&#8217;t work because of the variable name in <code>getElementsByName</code> (be it with or without the brackets, no bueno). Square brackets in JavaScript have a special meaning so two changes need to be made to my code.</p>
<p>The first change is to add an id to the &lt;form&gt; tag so it can be accessed via <code>getElementById</code> (now I&#8217;ll be using this HTML DOM method in place of <code>getElementsByName</code>). The second change is in how I call the <code>getElementById</code>. Notice the notation of how I reference the id of my form and then my checkboxes (BTW, this second function version uses <em>food[]</em> checkboxes). The rest of the function remains the same.</p>
<pre class="code">&lt;script type=&quot;text/javascript&quot; language=&quot;JavaScript&quot;&gt;
&lt;!--
function showMyChoices2() {
  var strChoices = &quot;&quot;;
  var objCBarray = document.getElementById('myform')['food[]'];
</pre>
<p>Try out the PHP + JavaScript version below.<script type="text/javascript" language="JavaScript"><!--
function showMyChoices2() {
  var strChoices = "";
  var objCBarray = document.getElementById('myform')['food[]'];
  for (i = 0; i < objCBarray.length; i++) {
    if (objCBarray[i].checked) {
      strChoices += "* " + objCBarray[i].value + "\n";
    }
  }
  if (strChoices.length > 0) {
    var strMessage = "Your favorite food(s)\n" + strChoices;
    alert(strMessage);
  } else {
    alert("Please choose your favorite foods.");
  }
}
// --></script><br />
<form id="myform" action="#">
<p>My favorite food is?</p>
<input type="checkbox" name="food[]" value="Burgers" /> Burgers<br />
<input type="checkbox" name="food[]" value="Pizza" /> Pizza<br />
<input type="checkbox" name="food[]" value="Spaghetti" /> Spaghetti<br />
<input type="checkbox" name="food[]" value="Tamales" /> Tamales<br />
<input type="button" value="Show My Choices" onclick="showMyChoices2();" /></form>
<p>Here is the code for the PHP + JavaScript version.</p>
<pre class="code">&lt;script type=&quot;text/javascript&quot; language=&quot;JavaScript&quot;&gt;
&lt;!--
function showMyChoices2() {
  var strChoices = &quot;&quot;;
  var objCBarray = document.getElementById('myform')['food[]'];
  for (i = 0; i &lt; objCBarray.length; i++) {
    if (objCBarray[i].checked) {
      strChoices += &quot;* &quot; + objCBarray[i].value + &quot;\n&quot;;
    }
  }
  if (strChoices.length &gt; 0) {
    var strMessage = &quot;Your favorite food(s)\n&quot; + strChoices;
    alert(strMessage);
  } else {
    alert(&quot;Please choose your favorite foods.&quot;);
  }
}
// --&gt;
&lt;/script&gt;
&lt;form id=&quot;myform&quot; action=&quot;#&quot;&gt;
&lt;p&gt;My favorite food is?&lt;/p&gt;
&lt;input type=&quot;checkbox&quot; name=&quot;food[]&quot; value=&quot;Burgers&quot; /&gt; Burgers&lt;br /&gt;
&lt;input type=&quot;checkbox&quot; name=&quot;food[]&quot; value=&quot;Pizza&quot; /&gt; Pizza&lt;br /&gt;
&lt;input type=&quot;checkbox&quot; name=&quot;food[]&quot; value=&quot;Spaghetti&quot; /&gt; Spaghetti&lt;br /&gt;
&lt;input type=&quot;checkbox&quot; name=&quot;food[]&quot; value=&quot;Tamales&quot; /&gt; Tamales&lt;br /&gt;
&lt;input type=&quot;button&quot; value=&quot;Show My Choices&quot; onclick=&quot;showMyChoices2();&quot; /&gt;
&lt;/form&gt;
</pre>
<p>All that would be left to do is build a PHP script to process the form submission data and set the script&#8217;s file name as the action in the &lt;form&gt; tag. That&#8217;s beyond the scope of this post, however if you need help doing it, post a comment. Using this code you should now be able to use client-side JavaScript to preprocess form data before it hits the server using standard variable names and PHP array type ones.</p>
<p>Source Code Download: <a href='http://www.tonybhimani.com/files/2011/10/js-php-checkboxes.zip'>JavaScript PHP Checkbox Array Source Code (Zip)</a></p>
<div class="gpo_leftcontainer"><div class="gpo_buttons"><g:plusone size="tall" count="true"></g:plusone></div></div> <a href='http://twitter.com/share?url=http%3A%2F%2Fwww.tonybhimani.com%2F%3Fp%3D314&count=vertical&related=&text=PHP%3A%20Checkbox%20Arrays%20with%20Javascript%20Usage' class='twitter-share-button' data-text='PHP: Checkbox Arrays with Javascript Usage' data-url='http://www.tonybhimani.com/?p=314' data-counturl='http://www.tonybhimani.com/2011/10/15/php-checkbox-arrays-with-javascript-usage/' data-count='vertical' data-via='TonyBhimani'></a> <script type='text/javascript'>
<!--
tweetmeme_source = 'TonyBhimani';
tweetmeme_url = 'http://www.tonybhimani.com/2011/10/15/php-checkbox-arrays-with-javascript-usage/';
//-->
</script><script type="text/javascript" src="http://tweetmeme.com/i/scripts/button.js"></script>
]]></content:encoded>
			<wfw:commentRss>http://www.tonybhimani.com/2011/10/15/php-checkbox-arrays-with-javascript-usage/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ogre3D SDK 1.7.3 for Apple iPhone iOS HOWTO</title>
		<link>http://www.tonybhimani.com/2011/07/09/ogre3d-sdk-1-7-3-for-apple-iphone-ios-howto/</link>
		<comments>http://www.tonybhimani.com/2011/07/09/ogre3d-sdk-1-7-3-for-apple-iphone-ios-howto/#comments</comments>
		<pubDate>Sun, 10 Jul 2011 06:12:02 +0000</pubDate>
		<dc:creator>Tony Bhimani</dc:creator>
				<category><![CDATA[3D Graphics]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[HOWTOs]]></category>
		<category><![CDATA[MacOSX]]></category>
		<category><![CDATA[Ogre3D]]></category>
		<category><![CDATA[CMake]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Mac OSX]]></category>
		<category><![CDATA[Ogre Samples]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://www.tonybhimani.com/?p=179</guid>
		<description><![CDATA[Welcome to my third installment for Ogre3D on the Mac platform. This tutorial will describe the steps to installing the Ogre3D SDK version 1.7.3 Apple iPhone iOS release on Mac OS X. I&#8217;ll also go over installing the Ogre Xcode &#8230; <a href="http://www.tonybhimani.com/2011/07/09/ogre3d-sdk-1-7-3-for-apple-iphone-ios-howto/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Welcome to my third installment for Ogre3D on the Mac platform. This tutorial will describe the steps to installing the Ogre3D SDK version 1.7.3 Apple iPhone iOS release on Mac OS X. I&#8217;ll also go over installing the Ogre Xcode iPhone Template for generating a default iOS project and building the Ogre Samples Browser project. Although this sounds like a lot of information to cover, much of the groundwork was explained in my first guide for Mac OS X Ogre SDK and my second one outlining how to build the Ogre Samples Browser. I highly recommend reading those before continuing any further with these instructions because I won&#8217;t discuss installing Xcode, the NVIDIA Cg Toolkit, or CMake. My two prior Ogre tutorials can be found below.</p>
<ul>
<li><a title="Click to visit Guide to Installing Ogre3D on Mac OS X (Xcode + Ogre SDK 1.7.3)" href="http://www.tonybhimani.com/2011/06/25/guide-to-installing-ogre3d-on-macosx-xcode-ogre-sdk-1-7-3/">Guide to Installing Ogre3D on Mac OS X (Xcode + Ogre SDK 1.7.3)</a></li>
<li><a title="Click to vist Building the Ogre3D SDK Samples on Mac OS X" href="http://www.tonybhimani.com/2011/07/05/building-the-ogre3d-sdk-samples-on-macosx/">Building the Ogre3D SDK Samples on Mac OS X</a></li>
</ul>
<p><strong>Step 1 &#8211; Download &amp; Install Ogre SDK 1.7.3 for iPhone &amp; iOS Dependencies</strong></p>
<p>Much like my OSX Ogre tutorial, I&#8217;m sticking to the prebuilt release of the Ogre SDK for iPhone. Perhaps in the future I&#8217;ll write up a doc on building the Ogre SDK from source, but now is not the time. First thing is we&#8217;ll do is download the Ogre SDK for iPhone. This guide is written for the version 1.7.3 of Ogre3D which is the current release at this time. Visit the Ogre website to download the <a title="Ogre 1.7.3 SDK for iPhone" href="http://www.ogre3d.org/download/sdk" target="_blank">Ogre 1.7.3 SDK for iPhone</a>. Follow the link for the Ogre iPhone SDK. Download the iPhone SDK to your computer (it&#8217;ll be a DMG disk image called OgreSDK_iOS_v1-7-3.dmg) and mount it (double-click it).<a href="http://www.tonybhimani.com/files/2011/07/MacOSX_Ogre_SDK_iPhone_DMG_File_Window.png"><img class="alignleft size-medium wp-image-186" title="MacOSX Ogre SDK iPhone DMG File Window" src="http://www.tonybhimani.com/files/2011/07/MacOSX_Ogre_SDK_iPhone_DMG_File_Window-169x300.png" alt="MacOSX Ogre SDK iPhone DMG File Window" width="169" height="300" /></a></p>
<p>After the disk image mounts, a mock iPhone window appears. There is a folder called OgreSDK that you&#8217;ll need to copy to your hard drive. This contains [almost] everything you need to build iPhone Ogre apps. In this tutorial we&#8217;ll drop the Ogre SDK into the hard drive root. Now if you followed my Ogre Mac OSX tutorial then we&#8217;ll have a name conflict because there is already a /OgreSDK, so copy the OgreSDK folder from the iPhone window to somewhere like your Desktop. Rename it to OgreSDK_iOS and move it to /OgreSDK_iOS (i.e. open a Finder window and drag it over to the hard drive root). So now we have the Ogre iOS SDK installed, the next step is to install the Ogre SDK iPhone iOS Dependencies.</p>
<p><img class="alignright size-medium wp-image-189" title="MacOSX Ogre iPhone SDK Dependencies Window" src="http://www.tonybhimani.com/files/2011/07/MacOSX_Ogre_iPhone_SDK_Dependencies_Window-300x204.png" alt="MacOSX Ogre iPhone SDK Dependencies Window" width="178" height="121" /></p>
<p>The <a title="Click to visit Ogre iOS dependencies at SourceForge" href="http://sourceforge.net/projects/ogre/files/" target="_blank">Ogre iOS dependencies</a> DMG file can be found at SourceForge. Follow the <em>ogre-dependencies-mac -&gt; 1.7</em> path to get to the Ogre iOS precompiled dependencies DMG file. Download <a title="Click to download Ogre_iOS_4.3_Dependencies_20110411.dmg" href="http://sourceforge.net/projects/ogre/files/ogre-dependencies-mac/1.7/Ogre_iOS_4.3_Dependencies_20110411.dmg/download">Ogre_iOS_4.3_Dependencies_20110411.dmg</a> and mount the disk image. You&#8217;ll see a iPhoneDependencies folder. Copy it and paste it inside of the iPhone SDK folder /OgreSDK_iOS.</p>
<p>That&#8217;s all there is to getting the Ogre SDK for iPhone set up on Mac OS X. The next task we&#8217;ll move on to is building the Ogre iPhone Samples Browser and running it in the iPhone iOS Simulator.</p>
<p><strong>Step 2 &#8211; Generate a Xcode Project for the iPhone Samples Browser</strong></p>
<p>Building the Ogre Samples Browser for the iPhone is very similar to how it&#8217;s built for OSX. Both procedures utilize CMake to create a new [working] copy of a Xcode project. However, in regards to making a new Xcode iPhone project, we do have to add one extra step to the CMake process, and that&#8217;s adding a new boolean name/value property called OGRE_BUILD_PLATFORM_IPHONE.</p>
<p><a href="http://www.tonybhimani.com/files/2011/07/MacOSX_CMake_OgreSDK_iOS_Add_Property.png"><img class="alignleft size-medium wp-image-194" title="MacOSX CMake OgreSDK iOS Add Property" src="http://www.tonybhimani.com/files/2011/07/MacOSX_CMake_OgreSDK_iOS_Add_Property-300x276.png" alt="MacOSX CMake OgreSDK iOS Add Property" width="270" height="248" /></a><a href="http://www.tonybhimani.com/files/2011/07/MacOSX_CMake_OgreSDK_iOS_Generate_Xcode.png"><img class="alignleft size-medium wp-image-195" title="MacOSX CMake OgreSDK iOS Generate Xcode Project" src="http://www.tonybhimani.com/files/2011/07/MacOSX_CMake_OgreSDK_iOS_Generate_Xcode-300x276.png" alt="MacOSX CMake OgreSDK iOS Generate Xcode Project" width="270" height="248" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>Fire up CMake. Set the location of the Ogre iOS SDK with the <em>Browse Source</em> button (/OgreSDK_iOS) and set the location of where to build the binaries with the <em>Browse Build</em> button (/OgreSDK_iOS). Click the <em>Configure</em> button, set the project generator as <em>Xcode</em>, and choose <em>Use default native compilers</em>. Once the process has finished you&#8217;ll see a lot of red. Click the <em>Add Entry</em> button up top. In the <em>Add Cache Entry</em> dialog box, for the Name field enter <em>OGRE_BUILD_PLATFORM_IPHONE</em>, set the Type to <em>BOOL</em>, and make sure Value is <em>checked</em>, then click <em>OK</em>. Finally, click <em>Configure</em> twice (once after each configuration process completes) and then the <em>Generate</em> button. The new Xcode project OGRE.xcodeproj for building the Ogre iOS SDK Samples Browser is ready to use.</p>
<p><strong>Step 3 &#8211; Build the Ogre SDK iPhone Samples Browser Project in Xcode</strong></p>
<p><a href="http://www.tonybhimani.com/files/2011/07/MacOSX_Xcode_Project_Build_Ogre_iPhone_App.png"><img class="alignleft size-medium wp-image-204" title="MacOSX Xcode Project Build Ogre iPhone App" src="http://www.tonybhimani.com/files/2011/07/MacOSX_Xcode_Project_Build_Ogre_iPhone_App-300x220.png" alt="MacOSX Xcode Project Build Ogre iPhone App" width="300" height="220" /></a>With our Ogre iOS project in hand we&#8217;re ready to build the Samples Browser. The Ogre Xcode project for iPhone is located in the root of your OgreSDK iOS install directory (/OgreSDK_iOS). It&#8217;s called OGRE.xcodeproj (same as the OSX version of the project). Launch Xcode and open the project or just double-click the .xcodeproj file. Unlike the OSX project where we had to make some changes to compile without error, the Ogre iPhone project works out of the box without modification. Click the <em>Build and Run</em> icon in the toolbar (or click the <em>Build</em> menu and select <em>Build and Run</em>). It&#8217;ll take some time for the Ogre iPhone Project to compile. Once it&#8217;s done compiling the iOS Simulator will open and the Ogre iPhone Samples Browser demo will launch.</p>
<p><a href="http://www.tonybhimani.com/files/2011/07/MacOSX_iPhone_iOS_Simulator_Ogre_Samples_Browser.png"><img class="alignright size-medium wp-image-205" title="MacOSX iPhone iOS Simulator Ogre Samples Browser" src="http://www.tonybhimani.com/files/2011/07/MacOSX_iPhone_iOS_Simulator_Ogre_Samples_Browser-300x159.png" alt="MacOSX iPhone iOS Simulator Ogre Samples Browser" width="300" height="159" /></a>To the right is a screenshot of one the demo samples from the project. Using the demo from the simulator is somewhat difficult. To return back to the main screen, click on the <em>Hardware</em> menu and select <em>Shake Gesture</em>. Pat yourself on the back, you&#8217;ve made your first Ogre iPhone application. Our last task for this tutorial will be to modify the Xcode iPhone project template so we can have a basic framework available for when we want to start new Ogre SDK projects for the iPhone iOS platform.</p>
<p>Note: What we have done is build the iPhone project so it works on the iOS Simulator. If you try to deploy to an actual iPhone device, you&#8217;ll receive an error message <em>[Code Sign error: The identity 'iPhone Developer' doesn't match any valid certificate/private key pair in the default keychain]</em>. Deploying your app(s) to an iPhone requires signing up for the <a title="Click to visit Apple iOS Developer Program" href="http://developer.apple.com/programs/ios/" target="_blank">Apple iOS Developer Program</a> which costs $99/yr. The alternative would be to jail-break our iPhone, but I wouldn&#8217;t recommend that. I don&#8217;t have an iPhone so I won&#8217;t be able to go into the details of deploying to a physical device, however there are plenty of resources on the Internet that explain the steps. If I do get an iPhone in the future, I&#8217;ll revisit this topic and post a follow-up tutorial.</p>
<p><strong>Step 4 &#8211; Install &amp; Edit the Ogre Xcode Project Template for iPhone iOS</strong></p>
<p>If you followed my tutorial for the Ogre SDK on Mac OS X then you&#8217;ll already have the Ogre Xcode Templates installed and can skip the next two paragraphs. To install the Xcode templates, you&#8217;ll need to download and install a package found on SourceForge.</p>
<p>Download the <a href="http://sourceforge.net/projects/ogre/files/ogre-dependencies-mac/1.7/Ogre_Xcode_Templates_20101211.pkg.zip/download">Ogre_Xcode_Templates_20101211.pkg.zip</a> file to your Desktop or some other location on your Mac, extract the Ogre Xcode Templates Package from the zip file, and launch the installer by <em>double-clicking</em> on the package.</p>
<p>On Step 5 of the installer you’ll be asked for the paths to the OSX and iOS Ogre SDK locations. Ignore the OS X portion of the screen and choose the <em>Find Ogre</em> button for the iPhone option. Point to the /OgreSDK_iOS path (or to the location where you decided to install the Ogre SDK for iPhone). Finish the installation by clicking <em>Continue</em> and finally <em>Close</em>.</p>
<p>To edit the Ogre iPhone Xcode template, we need to modify the file project.pbxproj. We&#8217;ll need root privileges to do this so we&#8217;ll need sudo and it&#8217;ll be easier to do it through the Terminal using nano rather than the Text Editor. Open a Terminal window (commonly found under Applications -&gt; Utilities). Issue the following commands.</p>
<pre class="code">computer:~ tony$ cd /Library/Application\ Support/Developer/Shared/Xcode/Project\ Templates/Ogre/iPhone\ OS/
computer:~ tony$ cd ___PROJECTNAME___.xcodeproj/
computer:~ tony$ sudo nano project.pbxproj</pre>
<p><a href="http://www.tonybhimani.com/files/2011/07/MacOSX_Ogre_Xcode_Template_iPhone_project.pbxproj_nano.png"><img class="alignleft size-medium wp-image-216" title="MacOSX Ogre Xcode Template iPhone project.pbxproj nano" src="http://www.tonybhimani.com/files/2011/07/MacOSX_Ogre_Xcode_Template_iPhone_project.pbxproj_nano-300x180.png" alt="MacOSX Ogre Xcode Template iPhone project.pbxproj nano" width="300" height="180" /></a>There are two changes we&#8217;ll be making to the to the project.pbxproj settings file, just in many different locations. It&#8217;s a good thing nano has search &amp; replace otherwise this could because extremely tedious. To use the search &amp; replace feature,<br />
press ctrl-\ [ Control-Backslash ]</p>
<p>We&#8217;re going to search for the string _OGRESDK_ROOT_ and replace it with the location of where our Ogre iOS SDK is installed (/OgreSDK_iOS). So after pressing <em>ctrl-\</em> [ Control-Backslash ], in the first prompt enter <em>_OGRESDK_ROOT_</em> and press enter, then enter <em>/OgreSDK_iOS</em> (or wherever you put your Ogre iOS SDK) for the second prompt. You can press the &#8216;y&#8217; key (Yes) to replace each instance one at a time or press the &#8216;a&#8217; key (All) to do them all at once. Here are the line numbers that the changes occur on.<br />
[ Lines 43-50, 52-54, 263-272, 276-279, 295-304, 308-311 ]</p>
<p><a href="http://www.tonybhimani.com/files/2011/07/MacOSX_Xcode_Template_iPhone_OTHER_LDFLAGS_nano.png"><img class="alignright size-medium wp-image-221" title="MacOSX Xcode Template iPhone OTHER_LDFLAGS nano" src="http://www.tonybhimani.com/files/2011/07/MacOSX_Xcode_Template_iPhone_OTHER_LDFLAGS_nano-300x193.png" alt="MacOSX Xcode Template iPhone OTHER_LDFLAGS nano" width="300" height="193" /></a>Next we need to add a linker flag to both our Debug &amp; Release configurations so after compilation our Ogre iPhone program gets linked against a specific dynamic library (otherwise you&#8217;ll get linker errors for undefined symbols such as &#8220;_inflateInit_&#8221; &#8220;_inflateEnd&#8221; &#8220;_inflate&#8221; and others). Scroll down to line number 323 (you can press ctrl-c [ Control-C ] to determine what line number you&#8217;re on in nano).</p>
<p>Add a new line and enter the text <em>OTHER_LDFLAGS = /usr/lib/libz.dylib;</em> then scroll to line number 335 and a new line and enter that same text again. You can see how the changes look in the screenshot to the right. Save the Ogre Xcode Template project.pbxproj settings file by pressing ctrl-o [ Control-O ]. Exit with ctrl-x [ Control-X ].</p>
<p><strong>Step 5 &#8211; Build &amp; Run a Demo Project from the Ogre Xcode iPhone Template</strong></p>
<p><a href="http://www.tonybhimani.com/files/2011/07/MacOSX_Xcode_iPhone_Template_Project_Demo.png"><img class="alignleft size-medium wp-image-225" title="MacOSX Xcode Ogre iPhone Template Project Demo" src="http://www.tonybhimani.com/files/2011/07/MacOSX_Xcode_iPhone_Template_Project_Demo-300x217.png" alt="MacOSX Xcode Ogre iPhone Template Project Demo" width="240" height="174" /></a>The end of this Ogre iPhone SDK tutorial is here. There&#8217;s just one last thing to do &#8211; build and run a demo from our Xcode iPhone template. Open Xcode and create a new project, choose <em>Ogre</em> under User Templates, and click on the <em>iPhone OS</em> option. Click the <em>Choose</em> button and give your project a name (e.g. OgreDemo_iPhone). Click the <em>Build and Run</em> button from the toolbar or use the <em>Build</em> menu if you prefer.</p>
<p><a href="http://www.tonybhimani.com/files/2011/07/MacOSX_Ogre_Xcode_iPhone_Demo_iOS_Simulator.png"><img class="alignright size-medium wp-image-226" title="MacOSX Ogre Xcode iPhone Demo iOS Simulator" src="http://www.tonybhimani.com/files/2011/07/MacOSX_Ogre_Xcode_iPhone_Demo_iOS_Simulator-300x159.png" alt="MacOSX Ogre Xcode iPhone Demo iOS Simulator" width="300" height="159" /></a>If all goes well (which it should) your demo project from the Xcode iPhone template will be running in the iOS iPhone Simulator (as can be seen to the right). It&#8217;ll look exactly like the demo project as found in the Mac OS X version (a Green Ogre Head enclosed by the Space Skybox). You can rotate the camera view by click-holding down your mouse on the screen and moving it around. Good job! You&#8217;ve built an Ogre iPhone application and viewed it in the iOS Simulator.</p>
<p>In conclusion, you&#8217;ve learned how to install the Ogre 1.7.3 SDK for iPhone on Mac OSX and built the Samples Browser that comes with the SDK by using CMake. Expanding upon that you also learned how to install the Ogre Xcode Templates, tweaked the iPhone settings file for your development machine, and built a demo project from that iPhone OS version. Now that you&#8217;re familiar with setting up Ogre on a Mac the next thing would be to learn how to make some custom Ogre apps. I recommend checking out the <a title="Click to visit Ogre3D Tutorials Website" href="http://www.ogre3d.org/tikiwiki/Tutorials" target="_blank">tutorials on the Ogre3D website</a> since you now have a working Ogre development environment.</p>
<div class="gpo_leftcontainer"><div class="gpo_buttons"><g:plusone size="tall" count="true"></g:plusone></div></div> <a href='http://twitter.com/share?url=http%3A%2F%2Fwww.tonybhimani.com%2F%3Fp%3D179&count=vertical&related=&text=Ogre3D%20SDK%201.7.3%20for%20Apple%20iPhone%20iOS%20HOWTO' class='twitter-share-button' data-text='Ogre3D SDK 1.7.3 for Apple iPhone iOS HOWTO' data-url='http://www.tonybhimani.com/?p=179' data-counturl='http://www.tonybhimani.com/2011/07/09/ogre3d-sdk-1-7-3-for-apple-iphone-ios-howto/' data-count='vertical' data-via='TonyBhimani'></a> <script type='text/javascript'>
<!--
tweetmeme_source = 'TonyBhimani';
tweetmeme_url = 'http://www.tonybhimani.com/2011/07/09/ogre3d-sdk-1-7-3-for-apple-iphone-ios-howto/';
//-->
</script><script type="text/javascript" src="http://tweetmeme.com/i/scripts/button.js"></script>
]]></content:encoded>
			<wfw:commentRss>http://www.tonybhimani.com/2011/07/09/ogre3d-sdk-1-7-3-for-apple-iphone-ios-howto/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Building the Ogre3D SDK Samples on Mac OS X</title>
		<link>http://www.tonybhimani.com/2011/07/05/building-the-ogre3d-sdk-samples-on-macosx/</link>
		<comments>http://www.tonybhimani.com/2011/07/05/building-the-ogre3d-sdk-samples-on-macosx/#comments</comments>
		<pubDate>Wed, 06 Jul 2011 06:37:22 +0000</pubDate>
		<dc:creator>Tony Bhimani</dc:creator>
				<category><![CDATA[3D Graphics]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[HOWTOs]]></category>
		<category><![CDATA[MacOSX]]></category>
		<category><![CDATA[Ogre3D]]></category>
		<category><![CDATA[CMake]]></category>
		<category><![CDATA[Mac OSX]]></category>
		<category><![CDATA[Ogre Samples]]></category>
		<category><![CDATA[Samples Browser]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://www.tonybhimani.com/?p=148</guid>
		<description><![CDATA[In my previous Ogre3D tutorial for the Mac I showed you how to set up your Mac OSX development environment with the Ogre SDK 1.7.3, install the Xcode templates, and create a sample Ogre project. That&#8217;s a great start but &#8230; <a href="http://www.tonybhimani.com/2011/07/05/building-the-ogre3d-sdk-samples-on-macosx/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In my previous Ogre3D tutorial for the Mac I showed you how to set up your Mac OSX development environment with the Ogre SDK 1.7.3, install the Xcode templates, and create a sample Ogre project. That&#8217;s a great start but what if you wanted to build the samples that came with the Ogre SDK? If you try and use the default Xcode project you&#8217;ll receive build errors. To remedy this we have to install a new application called CMake.</p>
<p><strong>Step 1 &#8211; Install CMake 2.8.3</strong></p>
<p>The Ogre SDK framework makes use of CMake for creating build scripts (or projects) for the chosen target platform. If you were to build the Ogre3D render engine from source, you&#8217;d use CMake to generate a project for Xcode or a Unix Makefile. For building the SDK samples that come with Ogre, it&#8217;s the same process in using CMake to generate a working Xcode project to build those samples. To sum it up, we need CMake.</p>
<p><a href="http://www.tonybhimani.com/files/2011/06/MacOSX_CMake_2.8.3_Window.png"><img class="alignleft size-medium wp-image-150" title="MacOSX CMake 2.8.3 Window" src="http://www.tonybhimani.com/files/2011/06/MacOSX_CMake_2.8.3_Window-300x278.png" alt="MacOSX CMake 2.8.3 Window" width="300" height="278" /></a>To <a title="Click to download CMake 2.8.3" href="http://www.cmake.org/files/v2.8/cmake-2.8.3-Darwin-universal.dmg" target="_blank">download CMake 2.8.3</a> you can click that link you just read over. It&#8217;s a Mac DMG disk image. Save it to your Desktop or another location of your choice. Launch the DMG by double-clicking it. Follow the instructions and install CMake to your Mac computer. Check your Applications folder. You should now have CMake 2.8-3 icon. Launch CMake. The User Interface (UI) is to the point (set the source code location, where to build the binaries, and configure the name/value pairs, then build). Next we generate a new Xcode project for the Ogre SDK Samples.</p>
<p><strong>Step 2 &#8211; Generate a New Ogre SDK Samples Xcode Project</strong></p>
<p>You&#8217;ll need to know where you installed your copy of the Ogre SDK to. Mine is located in the root /OgreSDK. Follow the steps below to generate a new Xcode Project for the Ogre SDK Samples.</p>
<p><a href="http://www.tonybhimani.com/files/2011/06/MacOSX_CMake_OgreSDK_Samples_Project.png"><img class="alignleft size-medium wp-image-161" title="MacOSX CMake OgreSDK Samples Project" src="http://www.tonybhimani.com/files/2011/06/MacOSX_CMake_OgreSDK_Samples_Project-300x278.png" alt="MacOSX CMake OgreSDK Samples Project" width="300" height="278" /></a></p>
<ol>
<li>Click the <em>Browse Source</em> button and browse to the location of your Ogre SDK installation (/OgreSDK).</li>
<li>Click the <em>Browse Build</em> button and choose a location where you&#8217;d like the build binaries to be saved to. I use the same location as my SDK install (/OgreSDK).</li>
<li>Click on the Configure button. Another window will popup asking for what type of project generator (Xcode) and compilers (Use default native compilers) to use.</li>
<li>CMake will run through the motions and show some Ogre SDK build variables in red. Click the <em>Configure</em> button one more time. After another set of motions you&#8217;ll see more concrete CMake variables.</li>
<li>Click the CMake <em>Generate</em> button to create the Xcode project for building the Ogre SDK Samples. That&#8217;s it for CMake. You can close it now.</li>
</ol>
<p><strong>Step 3 &#8211; Modify Settings in the Ogre3D SDK Samples Project</strong></p>
<p>Before we can build the Ogre Samples we need to make a few modifications to our Xcode Ogre Project. Inside /OgreSDK there is a Xcode project called OGRE.xcodeproj. Double-click the Ogre project to launch Xcode. Go ahead and start the build process. You&#8217;ll encounter hundreds (if not thousands) of errors. To correct this issue we need to change the build architecture to i386. The Ogre.framework SDK we&#8217;re using is prebuilt for i386 so building for any other architecture will fail (unless you build from the source code). Okay, so let&#8217;s make the needed changes so we can compile the Ogre Samples.</p>
<p><a href="http://www.tonybhimani.com/files/2011/07/MacOSX_Xcode_Edit_Active_Target_Archs.png"><img class="alignleft size-medium wp-image-168" title="MacOSX Xcode Edit Active Target Archs" src="http://www.tonybhimani.com/files/2011/07/MacOSX_Xcode_Edit_Active_Target_Archs-300x225.png" alt="MacOSX Xcode Edit Active Target Archs" width="300" height="225" /></a>In Xcode, click on the <em>Project</em> menu, select <em>Edit Active Target &#8220;ALL_BUILD&#8221;</em>, a dialog window will appear. Make sure you&#8217;re on the <em>Build</em> tab and that the Configuration is <em>All Configurations</em> and Show is <em>All Settings</em>. Under the <em>User-Defined</em> Settings, the first property is <em>ARCHS</em>. Double-click and edit the value <em>$(ARCHS_STANDARD_32_BIT)</em>. i.e. Take the _64 out of the property value. Save the change and exit the Info window.</p>
<p><a href="http://www.tonybhimani.com/files/2011/07/MacOSX_Xcode_Edit_Project_Settings.png"><img class="alignright size-medium wp-image-170" title="MacOSX Xcode Edit Project Settings" src="http://www.tonybhimani.com/files/2011/07/MacOSX_Xcode_Edit_Project_Settings-300x226.png" alt="MacOSX Xcode Edit Project Settings" width="300" height="226" /></a>Next, click on the <em>Project</em> menu and select <em>Edit Project Settings</em>, the Project Info window appears. Make sure you&#8217;re on the <em>Build</em> tab and that the Configuration is <em>All Configurations</em> and Show is <em>All Settings</em>. Under <em>Architecture</em> Settings, the second option Architecture, set the property value to <em>32-bit Universal</em>. Remove all the other architectures except <em>i386</em> for the <em>Valid Architectures</em> property. You can now close the Project Info window.</p>
<p><strong>Step 4 &#8211; Compile the Ogre3D SDK Samples Project in Xcode</strong></p>
<p><img class="alignleft size-medium wp-image-172" title="MacOSX Xcode OGRE Samples Browser Project" src="http://www.tonybhimani.com/files/2011/07/MacOSX_Xcode_OGRE_Samples_Browser_Project-300x237.png" alt="MacOSX Xcode OGRE Samples Browser Project" width="300" height="237" /></p>
<p>At last, the final step, which is the easiest. Build the Ogre project! Click the <em>Build and Run</em> toolbar button or select it from the <em>Build</em> menu. There are 34 samples to compile so the Ogre Samples Xcode Project will take some time to build. If all goes well (which it should) you&#8217;ll have the Ogre Samples running. Explore the Ogre samples. If you encountered compile errors, double-check your project settings.<a href="http://www.tonybhimani.com/files/2011/07/MacOSX_OGRE_Samples_Browser_Penguin.png"><img class="alignright size-medium wp-image-173" title="MacOSX OGRE Samples Browser Penguin" src="http://www.tonybhimani.com/files/2011/07/MacOSX_OGRE_Samples_Browser_Penguin-300x239.png" alt="MacOSX OGRE Samples Browser Penguin" width="300" height="239" /></a></p>
<p>Say Hello to the Penguin from one of the Ogre Samples Browser. There are 33 more to check out, everything from BSP Scenes, to Shadows, to Skydomes, and more.</p>
<p>More Ogre3D guides to read:</p>
<p><a title="Click to visit Guide to Installing Ogre3D on Mac OS X (Xcode + Ogre SDK 1.7.3)" href="http://www.tonybhimani.com/2011/06/25/guide-to-installing-ogre3d-on-macosx-xcode-ogre-sdk-1-7-3/">Guide to Installing Ogre3D on Mac OS X (Xcode + Ogre SDK 1.7.3)</a></p>
<div class="gpo_leftcontainer"><div class="gpo_buttons"><g:plusone size="tall" count="true"></g:plusone></div></div> <a href='http://twitter.com/share?url=http%3A%2F%2Fwww.tonybhimani.com%2F%3Fp%3D148&count=vertical&related=&text=Building%20the%20Ogre3D%20SDK%20Samples%20on%20Mac%20OS%20X' class='twitter-share-button' data-text='Building the Ogre3D SDK Samples on Mac OS X' data-url='http://www.tonybhimani.com/?p=148' data-counturl='http://www.tonybhimani.com/2011/07/05/building-the-ogre3d-sdk-samples-on-macosx/' data-count='vertical' data-via='TonyBhimani'></a> <script type='text/javascript'>
<!--
tweetmeme_source = 'TonyBhimani';
tweetmeme_url = 'http://www.tonybhimani.com/2011/07/05/building-the-ogre3d-sdk-samples-on-macosx/';
//-->
</script><script type="text/javascript" src="http://tweetmeme.com/i/scripts/button.js"></script>
]]></content:encoded>
			<wfw:commentRss>http://www.tonybhimani.com/2011/07/05/building-the-ogre3d-sdk-samples-on-macosx/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Guide to Installing Ogre3D on Mac OS X (Xcode + Ogre SDK 1.7.3)</title>
		<link>http://www.tonybhimani.com/2011/06/25/guide-to-installing-ogre3d-on-macosx-xcode-ogre-sdk-1-7-3/</link>
		<comments>http://www.tonybhimani.com/2011/06/25/guide-to-installing-ogre3d-on-macosx-xcode-ogre-sdk-1-7-3/#comments</comments>
		<pubDate>Sun, 26 Jun 2011 01:20:12 +0000</pubDate>
		<dc:creator>Tony Bhimani</dc:creator>
				<category><![CDATA[3D Graphics]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[HOWTOs]]></category>
		<category><![CDATA[MacOSX]]></category>
		<category><![CDATA[Ogre3D]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[Mac OSX]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://www.tonybhimani.com/?p=45</guid>
		<description><![CDATA[This guide serves as an introduction to getting started with Ogre3D on Mac OS X, namely setting up the development environment and building a basic application. It&#8217;ll serve as the first in several series of blog posts I intend to &#8230; <a href="http://www.tonybhimani.com/2011/06/25/guide-to-installing-ogre3d-on-macosx-xcode-ogre-sdk-1-7-3/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This guide serves as an introduction to getting started with Ogre3D on Mac OS X, namely setting up the development environment and building a basic application. It&#8217;ll serve as the first in several series of blog posts I intend to write on the subject. Let me say this first. I am not an expert on Ogre, 3D graphics development or theory, or Macs. I may get the jargon wrong and my instructions may not work for very system, so contacting me for help may not the best thing to do, however I&#8217;ll do what I can to assist if you do.</p>
<p>There is a lot of information on Ogre in general on the Internet, but not too much on configuring it on Mac or Linux. I will write a document for installing Ogre on Linux at a later date, but for now it&#8217;s OSX time. Also, you should definitely visit the <a title="Ogre3D Wiki Site" href="http://www.ogre3d.org/tikiwiki/" target="_blank">Ogre Wiki</a> after reading this tutorial for even more information.</p>
<p><strong>Step 1 &#8211; Download &amp; Install Apple Xcode IDE</strong></p>
<p>To get started, you should first get the Xcode IDE if you don&#8217;t already have it. Apple makes it available as a free download after you create an account on their website (the 3.x version is free at the time of this writing). Visit the <a title="Apple Developer - Technologies" href="http://developer.apple.com/technologies/" target="_blank">Apple Developer Website</a> to download a copy of the Xcode 3 IDE. After you download Xcode, then install it. I&#8217;m not going into detail for this step as it&#8217;s very straightforward to install the Xcode IDE.</p>
<p><strong>Step 2 &#8211; Download &amp; Install NVIDIA Cg Toolkit</strong></p>
<p>The NVIDIA CG Toolkit isn&#8217;t required but is needed for the Ogre Cg Program Manager. To install the toolkit, you&#8217;ll need to go to the NVIDIA developer website, create a login if you don&#8217;t already have one, then download the Mac OS X DMG image. To do this, visit the <a title="NVIDIA Developer Cg Toolkit Page" href="http://developer.nvidia.com/cg-toolkit" target="_blank">NVIDIA Developer Cg Toolkit Page</a> and scroll to the bottom of the page. Click on the <em><a title="Click to download NVIDIA Cg Toolkit Download" href="http://developer.nvidia.com/cg-toolkit-download" target="_blank">download</a></em> link. On the Access Denied page, click on the <em>Login</em> link. Proceed to create an account by clicking on the <em>Create new account</em> tab. Go back to the download page and fetch the Mac OS X file image. Install the NVIDIA Cg Toolkit it like you would any other Mac setup package.</p>
<p><strong>Step 3 &#8211; Download &amp; Install Ogre SDK 1.7.3 &amp; OSX Dependencies</strong></p>
<p>At the time of this article the current version of Ogre3D is 1.7.3. To keep things simple we&#8217;ll be installing the prebuilt release of Ogre SDK for OS X instead of compiling from source. To get started, we have to visit the Ogre3D website and download the <a title="Ogre 1.7.3 SDK for Mac OS X" href="http://www.ogre3d.org/download/sdk" target="_blank">Ogre 1.7.3 SDK for Mac OS X</a>. On that page there is a link to the latest Mac OS X Ogre3D release. Download the Ogre SDK to your computer (it&#8217;ll be a .DMG Apple Disk Image File). Double-click the Ogre SDK DMG to mount the disk image.<a href="http://www.tonybhimani.com/files/2011/06/Ogre3D_1.7.3_SDK_for_Mac_OS_X.png"><img class="alignleft size-medium wp-image-62" title="Ogre3D 1.7.3 SDK for Mac OS X window" src="http://www.tonybhimani.com/files/2011/06/Ogre3D_1.7.3_SDK_for_Mac_OS_X-300x258.png" alt="Ogre3D 1.7.3 SDK for Mac OS X window" width="300" height="258" /></a></p>
<p>You&#8217;ll be greeted with an Ogre SDK window (as shown on the left). There is a blue folder called OgreSDK in that window, <em>ctrl-click</em> (aka right-click) on that folder and select the <em>Copy &#8220;OgreSDK&#8221;</em> menu option. Paste the folder to your hard drive (I recommend the root, that being /OgreSDK). Open a Finder window, select your hard drive under Devices, <em>ctrl-click</em> and Paste the OgreSDK folder.</p>
<p><a href="http://www.tonybhimani.com/files/2011/06/Copy_OgreSDK_folder_to_hard_drive.png"><img class="alignright size-medium wp-image-66" title="Copy OgreSDK folder to hard drive" src="http://www.tonybhimani.com/files/2011/06/Copy_OgreSDK_folder_to_hard_drive-300x170.png" alt="Copy OgreSDK folder to hard drive" width="300" height="170" /></a>As you can see from the image to the right, the OgreSDK folder is quite large so the copy process may take a moment. When it&#8217;s done we move on to the next step, that being installing the Ogre dependency files. There is a zip file containing dependencies we&#8217;ll need to be able to build our own Ogre Mac OSX applications, and these dependencies are boost, FreeImage, freetype, OIS, and zzip.</p>
<p>The <a title="Ogre Mac OSX Dependencies on SourceForge" href="http://sourceforge.net/projects/ogre/files/" target="_blank">Ogre Mac OSX dependencies</a> zip file is located on SourceForge. When you get there, follow the <em>ogre-dependencies-mac -&gt; 1.7</em> folder path. Download the file <a title="Click to download OgreDependencies_OSX_20110208.zip" href="http://sourceforge.net/projects/ogre/files/ogre-dependencies-mac/1.7/OgreDependencies_OSX_20110208.zip/download" target="_blank">OgreDependencies_OSX_20110208.zip</a> and extract its contents. You&#8217;ll get a folder called Dependencies. Move that folder into the /OgreSDK folder (or wherever you put yours).</p>
<p><strong>Step 4 &#8211; Download &amp; Install Ogre Xcode Templates</strong></p>
<p>Xcode templates are available for creating minimal Ogre3D Mac Projects. The <a href="https://sourceforge.net/projects/ogre/files/ogre-dependencies-mac/1.7/OgreDependencies_OSX_20110208.zip/download">Mac OS X Universal Precompiled Dependencies </a>for OSX and iOS can be found of the SourceForge website. There are two installer versions available: the one that has Ogre templates for Xcode 3 and the other for Xcode 4. My directions are made for Xcode 3 so that is the Ogre template installer I&#8217;ll be using. I can&#8217;t tell you if my directions will work for Xcode 4 since I don&#8217;t have it to test against.<br />
<a href="http://www.tonybhimani.com/files/2011/06/Ogre_Xcode_Templates_Installer.png"><img class="alignright size-medium wp-image-87" title="Ogre Xcode Templates Installer" src="http://www.tonybhimani.com/files/2011/06/Ogre_Xcode_Templates_Installer-300x222.png" alt="Ogre Xcode Templates Installer" width="270" height="200" /></a></p>
<p>Okay, so first thing is to download the Ogre Xcode template installer package. Visit the <a title="Ogre SourceForge Files Site" href="https://sourceforge.net/projects/ogre/files/ogre-dependencies-mac/1.7/" target="_blank">Ogre SourceForge Files</a> website. Download the <a title="Click to download Ogre_Xcode_Templates_20101211.pkg.zip" href="http://sourceforge.net/projects/ogre/files/ogre-dependencies-mac/1.7/Ogre_Xcode_Templates_20101211.pkg.zip/download" target="_blank">Ogre_Xcode_Templates_20101211.pkg.zip</a> file to your Desktop or some other location on your Mac, extract the Ogre Xcode Templates Package from the zip file, and launch the installer by <em>double-clicking</em> on the package.</p>
<p><a href="http://www.tonybhimani.com/files/2011/06/Select_Ogre_Install_Location.png"><img class="size-medium wp-image-94 alignleft" title="Select Ogre Install Location" src="http://www.tonybhimani.com/files/2011/06/Select_Ogre_Install_Location-300x222.png" alt="Select Ogre Install Location" width="270" height="200" /></a>On Step 5 of the installer you&#8217;ll be asked for the paths to the OSX and iOS Ogre SDK locations. I haven&#8217;t discussed the iOS iPhone SDK release of Ogre and we&#8217;ve only installed the OSX version, so for now choose the <em>Find Ogre</em> button for the OSX option. Point to the /OgreSDK path (or to the location where you decided to install the Ogre SDK). Wrap up the rest of the installation by clicking <em>Continue</em> and finally <em>Close</em>.</p>
<p><strong>Step 5 &#8211; Create a Mac OSX Ogre Project From The Xcode Template</strong></p>
<p>Fire up Xcode and create a new Ogre3D project. You&#8217;ll notice on the left side there is now an Ogre section under User Templates. Click on Ogre and there are two template to choose from: iPhone OS and Mac OS X. I&#8217;m going to save the iPhone stuff for my next Ogre tutorial, so for now pick Mac OS X and click the <em>Choose</em> button. When the Xcode popup dialog appears point it to the location where you&#8217;d like to save your Ogre project and give it a name (e.g. <em>OgreDemo</em>).<br />
<a href="http://www.tonybhimani.com/files/2011/06/Ogre_Demo_Xcode_Project.png"><img class="alignleft size-medium wp-image-101" title="Ogre Demo Xcode Project" src="http://www.tonybhimani.com/files/2011/06/Ogre_Demo_Xcode_Project-300x220.png" alt="Ogre Demo Xcode Project" width="300" height="220" /></a></p>
<p>You should now be looking at your Ogre Xcode Project. You may notice that there is some text in red (it indicates a problem). Basically, these files are broken, the paths don&#8217;t resolve. This is caused by a bug in the Ogre Xcode Templates. Step 6 below will resolve this issue. If you attempt to build the project, you&#8217;ll receive over 200 errors.</p>
<p>I recommend you familiarize with Xcode if you&#8217;ve never used it before. You can find documentation on the Apple Developer Website.  Follow this link for the User Guide &#8211; <a title="Xcode 4 User Guide: About Xcode 4" href="http://developer.apple.com/library/ios/#documentation/ToolsLanguages/Conceptual/Xcode4UserGuide/Introduction/Introduction.html" target="_blank">Xcode 4 User Guide: About Xcode 4</a>.</p>
<p><strong>Step 6 &#8211; Resolving the Ogre Xcode Template Bugs</strong></p>
<p>This next phase deals with fixing some bugs that exist within the Ogre Xcode Templates. What we need to do is correct some Framework and .dylib paths, change the Mac Base SDK, Xcode project format, GCC compiler version, alter the header and library search paths, and make these changes permanent for future projects. Let&#8217;s get started.</p>
<p>1) Correct the Framework and .dylib paths &#8211; We&#8217;ll start with Cg.framework. <em>Ctrl-click</em> it and select <em>Get Info</em>. When the info box displays you&#8217;ll see the path is red. There is a <em>Choose</em> button to the far right of the window, click that and navigate to this file system path /<em>Library/Frameworks</em> and select <em>Cg.framework</em> then click the <em>Choose</em> button. On the info screen the path is now black. Hit the close button in the upper left of the window.</p>
<p><a href="http://www.tonybhimani.com/files/2011/06/Cg.framework_Info_Window.png"><img class="alignnone size-medium wp-image-109" title="Cg.framework Info Window" src="http://www.tonybhimani.com/files/2011/06/Cg.framework_Info_Window-300x212.png" alt="Cg.framework Info Window" width="300" height="212" /></a> <a href="http://www.tonybhimani.com/files/2011/06/Cg.framework_Info_Window_Details.png"><img class="size-medium wp-image-110 alignnone" title="Cg.framework Info Window Details" src="http://www.tonybhimani.com/files/2011/06/Cg.framework_Info_Window_Details-300x252.png" alt="Cg.framework Info Window Details" width="240" height="202" /></a></p>
<p>Follow this same procedure for the following files:</p>
<ul>
<li><span style="font-size: 10pt;"><em>Ogre.framework &#8211; /OgreSDK/lib/release/Ogre.framework</em></span></li>
<li><span style="font-size: 10pt;"><em>libOIS.a &#8211;  /OgreSDK/lib/release/libOIS.a</em></span></li>
<li><span style="font-size: 10pt;"><em>Plugin_CgProgramManager.dylib &#8211; /OgreSDK/lib/Plugin_CgProgramManager.dylib</em></span></li>
<li><span style="font-size: 10pt;"><em>Plugin_OctreeSceneManager.dylib &#8211; /OgreSDK/lib/Plugin_OctreeSceneManager.dylib</em></span></li>
<li><span style="font-size: 10pt;"><em>RenderSystem_GL.dylib &#8211; /OgreSDK/lib/RenderSystem_GL.dylib</em></span></li>
</ul>
<p>2) Change the Mac Base SDK, Xcode project format, and GCC compiler version &#8211; Go to the <em>Project</em> menu and select <em>Edit Project Settings</em> option. On the info screen&#8217;s General tab, change the Xcode Project Format to <em>Xcode 3.1-compatible</em> and Base SDK for All Configurations to <em>Mac OS X 10.6</em>. Click on the <em>Build</em> tab, <em>All Configurations</em>, scroll down to the <em>Compiler Version</em> section, and for <em>C/C++ Compiler Version</em> change the value to <em>System default (GCC 4.2)</em>. Close the info window.</p>
<p><a href="http://www.tonybhimani.com/files/2011/06/Project_OgreDemo_Info_General.png"><img class="alignnone size-medium wp-image-117" title="Project OgreDemo Info General" src="http://www.tonybhimani.com/files/2011/06/Project_OgreDemo_Info_General-300x256.png" alt="Project OgreDemo Info General" width="300" height="256" /></a><a href="http://www.tonybhimani.com/files/2011/06/Project_OgreDemo_Info_Build.png"><img class="alignnone size-medium wp-image-118" title="Project OgreDemo Info Build" src="http://www.tonybhimani.com/files/2011/06/Project_OgreDemo_Info_Build-300x256.png" alt="Project OgreDemo Info Build" width="300" height="256" /></a></p>
<p>3) Alter the Header and Library Search Paths &#8211; Go back to the <em>Project</em> menu and select the <em>Edit Active Target &#8220;Project Name&#8221;</em> option (Project Name will be what you chose to name your project when you created it). Click on the <em>Build</em> tab, <em>All Configurations</em>, and scroll down to the <em>Search Paths</em> section. There are three lines we&#8217;re interested in: Framework Search Paths, Header Search Paths, and Library Search Paths. You&#8217;ll see that the paths prefix with _OGRESDK_ROOT_. This was supposed to be replaced with the Ogre SDK install location (aka /OgreSDK) you selected during the Xcode Template installation. To correct this we&#8217;ll edit each entry and replace _OGRESDK_ROOT_ with /OgreSDK. Close the window when you&#8217;re done.</p>
<p>Amendment &#8211; July 4, 2011</p>
<p>Change the boost headers directory from <em>boost_1_42</em> to <em>boost_1_46_1 </em>in the header Search Paths. Thanks to Guido for pointing this out.</p>
<p><a href="http://www.tonybhimani.com/files/2011/06/Target_OgreDemo_Info_Build_Before.png"><img class="alignnone size-medium wp-image-122" title="Target OgreDemo Info Build Before" src="http://www.tonybhimani.com/files/2011/06/Target_OgreDemo_Info_Build_Before-300x256.png" alt="Target OgreDemo Info Build Before" width="300" height="256" /></a><a href="http://www.tonybhimani.com/files/2011/06/Target_OgreDemo_Info_Build_After.png"><img class="alignnone size-medium wp-image-123" title="Target OgreDemo Info Build After" src="http://www.tonybhimani.com/files/2011/06/Target_OgreDemo_Info_Build_After-300x256.png" alt="Target OgreDemo Info Build After" width="300" height="256" /></a></p>
<p>That&#8217;s it for the changes. Build your project (<em>Build</em> menu -&gt; <em>Build and Run</em> option). You shouldn&#8217;t receive any build errors (if you did, check all the setting changes from above and make sure you didn&#8217;t miss something). When the demo launches there will be a settings window, accept the defaults and click the OK button. Tada! It&#8217;s an Ogre!</p>
<p><a href="http://www.tonybhimani.com/files/2011/06/Ogre_MacOSX_Demo_Project_Window.png"><img class="alignnone size-medium wp-image-124" title="Ogre MacOSX Demo Project Window" src="http://www.tonybhimani.com/files/2011/06/Ogre_MacOSX_Demo_Project_Window-300x233.png" alt="Ogre MacOSX Demo Project Window" width="300" height="233" /></a></p>
<p>Press the Escape key to exit the Ogre3D program. There is still one last thing to do.</p>
<p>4) Make the Changes Permanent for Future Projects &#8211; The changes we&#8217;ve made are for this project only, so how do we apply them to any future projects created from the Ogre Xcode template? Luckily the solution is rather simple. Our modified project contains a settings file called project.pbxproj that holds the paths of all the frameworks, headers, libraries, and etc we applied as well as more information that isn&#8217;t relevant to our topic. <del>All we have to do is copy the project.pbxproj file and overwrite the version that came with the Ogre Xcode Templates.</del></p>
<p><del>Open your Ogre project folder. Inside there is an item called <em>PROJECT.xcodeproj</em> (where PROJECT is the name of the project you created). <em>Ctrl-click</em> the xcodeproj and select <em>Show Package Contents</em>. Next copy the project.pbxproj file (ctrl-click, copy) and open a new Finder window. Navigate to the Ogre Xcode Templates file system path shown below.</del></p>
<p><del><span style="font-size: 10pt;"><em>/Library/Application Support/Developer/Shared/Xcode/Project Templates/Ogre/Mac OS X</em></span></del></p>
<p><em><a href="http://www.tonybhimani.com/files/2011/06/MacOSX_Finder_Window_Ogre_Xcode_Template_File_System_Path.png"><img class="alignleft size-medium wp-image-132" title="MacOSX Finder Window Ogre Xcode Template File System Path" src="http://www.tonybhimani.com/files/2011/06/MacOSX_Finder_Window_Ogre_Xcode_Template_File_System_Path-300x204.png" alt="MacOSX Finder Window Ogre Xcode Template File System Path" width="300" height="204" /></a></em><br />
<del>Here you&#8217;ll find the project template files that Xcode uses to create your Ogre3D projects. Move into the xcodeproj folder (ctrl-click, Show Package Contents) and paste the project.pbxproj you copied earlier. Replace the existing version. Technically we are done but we should change the file&#8217;s permissions to match.</del></p>
<p><a href="http://www.tonybhimani.com/files/2011/06/MacOSX_Terminal_project.pbxproj_Chown_Permissions.png"><img class="alignright size-medium wp-image-133" title="MacOSX Terminal project.pbxproj Chown Permissions" src="http://www.tonybhimani.com/files/2011/06/MacOSX_Terminal_project.pbxproj_Chown_Permissions-300x188.png" alt="MacOSX Terminal project.pbxproj Chown Permissions" width="300" height="188" /></a><br />
<del>Open a Terminal window (Applications -&gt; Utilities -&gt; Terminal). Navigate to the same Ogre Xcode Templates path from above. Change ownership of the project.pbxproj using the chown command. The full list of commands are show in the image.</del></p>
<pre class="code"><del>computer:~ tony$ cd /Library/Application\ Support/Developer/Shared/Xcode/Project\ Templates/Ogre/Mac\ OS\ X/
computer:~ tony$ cd ___PROJECTNAME___.xcodeproj/
computer:~ tony$ sudo chown root:admin project.pbxproj</del></pre>
<p>Amendment &#8211; July 4, 2011</p>
<p>In my haste of making this tutorial I didn&#8217;t completely test every aspect. The stricken out text above was for copying the OgreDemo project&#8217;s project.pbxproj settings file on top of the Ogre Xcode Project template&#8217;s version. The problem is that some settings then become hard-coded to use a file name of OgreDemo and the project won&#8217;t build unless it has the same exact name. Obviously that won&#8217;t work. You could rename but that defeats the purpose of a template. So we&#8217;ll be making modifications to the Ogre Xcode project template project.pbxproj directly this time around. We&#8217;re also going to bypass the copy, paste, ownership stuff, and use nano for editing to make the changes. Open a Terminal and issue the commands below.</p>
<pre class="code">computer:~ tony$ cd /Library/Application\ Support/Developer/Shared/Xcode/Project\ Templates/Ogre/Mac\ OS\ X/
computer:~ tony$ cd ___PROJECTNAME___.xcodeproj/
computer:~ tony$ sudo nano project.pbxproj</pre>
<p>Make the following changes to the Ogre Xcode Template project.pbxproj settings file. I&#8217;ve included the line numbers for your information. To see what line number you&#8217;re on in nano, press ctrl-c. [ Control-C ]</p>
<p><a href="http://www.tonybhimani.com/files/2011/06/MacOSX_Ogre_Xcode_Template_project.pbxproj_nano.png"><img class="alignleft size-medium wp-image-164" title="MacOSX Ogre Xcode Template project.pbxproj nano" src="http://www.tonybhimani.com/files/2011/06/MacOSX_Ogre_Xcode_Template_project.pbxproj_nano-300x183.png" alt="MacOSX Ogre Xcode Template project.pbxproj nano" width="210" height="128" /></a></p>
<p><span style="font-family: Georgia, 'Bitstream Charter', serif; line-height: 24px; font-size: 16px;">Replace <em>libois.a</em> with <em>libOIS.a<br />
<span style="font-style: normal;">[ Lines 16, 73, 98, 126 ]</span></em></span></p>
<p><span style="font-family: Georgia, 'Bitstream Charter', serif; line-height: 24px; font-size: 16px;">Replace <em>boost_1_42</em> with <em>boost_1_46_1<br />
</em>[ Lines 311, 342 ] </span></p>
<p><span style="font-family: Georgia, 'Bitstream Charter', serif; line-height: 24px; font-size: 16px;">Replace the path to Cg.framework <em>_OGRESDK_ROOT_/Dependencies</em> with <em>/Library/Frameworks<br />
</em></span>[ Line 71 ]</p>
<p>Replace all <em>_OGRESDK_ROOT_</em> with your Ogre SDK path <em>/OgreSDK<br />
</em>[ Lines 72-73, 76-78, 299-300, 309-312, 318-320, 333-334, 340-343, 349-351 ]</p>
<p>Fix the Build Configurations (Debug &amp; Release)<br />
Change <em>ARCHS = &#8220;$(ONLY_ACTIVE_ARCH_PRE_XCODE_3_1)&#8221;;</em> to <em>ARCHS = &#8220;$(ARCHS_STANDARD_32_BIT)&#8221;;<br />
</em>Change <em>GCC_VERSION = 4.0;</em> to <em>GCC_VERSION = &#8220;&#8221;;<br />
</em>Change <em>ONLY_ACTIVE_ARCH_PRE_XCODE_3_1 = &#8220;$(NATIVE_ARCH)&#8221;;</em> to <em>ONLY_ACTIVE_ARCH = YES;<br />
</em>Change <em>SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;</em> to <em>SDKROOT = /Developer/SDKs/MacOSX10.6.sdk;<br />
</em>[ Lines 360, 363, 366, 368 ] and [ Lines 375, 377, 380, 382 ]</p>
<p>Once you&#8217;ve made all the changes to the Ogre Xcode Template project.pbxproj, save the file by pressing ctrl-o. [ Control-O ] and ctrl-x [ Control-X ] to exit nano. Now any project created from the Ogre Xcode Templates will compile and from any name you save your project as.</p>
<p>That concludes this tutorial on installing the Ogre SDK 1.7.3 on a Mac OS X system. Any future Xcode projects you create using the Ogre Xcode Template won&#8217;t need changes to compile out the door. Stay tuned for more Ogre3D Mac articles from me.</p>
<div class="gpo_leftcontainer"><div class="gpo_buttons"><g:plusone size="tall" count="true"></g:plusone></div></div> <a href='http://twitter.com/share?url=http%3A%2F%2Fwww.tonybhimani.com%2F%3Fp%3D45&count=vertical&related=&text=Guide%20to%20Installing%20Ogre3D%20on%20Mac%20OS%20X%20%28Xcode%20%2B%20Ogre%20SDK%201.7.3%29' class='twitter-share-button' data-text='Guide to Installing Ogre3D on Mac OS X (Xcode + Ogre SDK 1.7.3)' data-url='http://www.tonybhimani.com/?p=45' data-counturl='http://www.tonybhimani.com/2011/06/25/guide-to-installing-ogre3d-on-macosx-xcode-ogre-sdk-1-7-3/' data-count='vertical' data-via='TonyBhimani'></a> <script type='text/javascript'>
<!--
tweetmeme_source = 'TonyBhimani';
tweetmeme_url = 'http://www.tonybhimani.com/2011/06/25/guide-to-installing-ogre3d-on-macosx-xcode-ogre-sdk-1-7-3/';
//-->
</script><script type="text/javascript" src="http://tweetmeme.com/i/scripts/button.js"></script>
]]></content:encoded>
			<wfw:commentRss>http://www.tonybhimani.com/2011/06/25/guide-to-installing-ogre3d-on-macosx-xcode-ogre-sdk-1-7-3/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Creating Multi-Volume Archives and Checksums</title>
		<link>http://www.tonybhimani.com/2008/04/30/creating-multi-volume-archives-and-checksums/</link>
		<comments>http://www.tonybhimani.com/2008/04/30/creating-multi-volume-archives-and-checksums/#comments</comments>
		<pubDate>Thu, 01 May 2008 03:59:08 +0000</pubDate>
		<dc:creator>Tony Bhimani</dc:creator>
				<category><![CDATA[HOWTOs]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[cat]]></category>
		<category><![CDATA[Checksum]]></category>
		<category><![CDATA[gzip]]></category>
		<category><![CDATA[md5sum]]></category>
		<category><![CDATA[Multi-Volume]]></category>
		<category><![CDATA[sha1sum]]></category>
		<category><![CDATA[split]]></category>
		<category><![CDATA[tar]]></category>
		<category><![CDATA[Volume Archive]]></category>

		<guid isPermaLink="false">http://www.tonybhimani.com/?p=27</guid>
		<description><![CDATA[The goal of this article is to help you create multi-volume archives and generate checksums to validate integrity. Why? You have data larger than any single CD-R disc or DVD and you need to split it into pieces, or you &#8230; <a href="http://www.tonybhimani.com/2008/04/30/creating-multi-volume-archives-and-checksums/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>The goal of this article is to help you create multi-volume archives and generate checksums to validate integrity. Why? You have data larger than any single CD-R disc or DVD and you need to split it into pieces, or you have to transfer gigabytes of data over the net and would rather send smaller segments instead of a giant glob. As an example, I&#8217;ll create a multi-volume gzip archive of /home with a MD5 checksum using tar, gzip, split, and md5sum.</p>
<h3>Creating Volumes from your Data</h3>
<p>1. Create a single TAR archive of all your data using tar to preserve permissions, directory structures, etc.</p>
<pre class="code">[root@linux archive]# tar -cf home.tar /home
tar: Removing leading `/' from member names
[root@linux archive]# ls -la home.tar
-rw-r--r-- 1 root root 304220160 Apr 30 13:34 home.tar</pre>
<p>2. Compress your TAR archive using gzip (or any other compressing program of your choice).</p>
<pre class="code">[root@linux archive]# gzip home.tar
[root@linux archive]# ls -la home.tar.gz
-rw-r--r-- 1 root root 284859091 Apr 30 13:34 home.tar.gz</pre>
<p>3. Use the split command to chop the compressed archive into smaller segments (I&#8217;ll be using 100MB pieces).</p>
<pre class="code">[root@linux archive]# split -d -b100m home.tar.gz home.tar.gz.
[root@linux archive]# ls -la
total 556940
drwxr-xr-x 2 root root      4096 Apr 30 13:56 .
drwxr-x--- 6 root root      4096 Apr 30 13:31 ..
-rw-r--r-- 1 root root 284859091 Apr 30 13:34 home.tar.gz
-rw-r--r-- 1 root root 104857600 Apr 30 13:56 home.tar.gz.00
-rw-r--r-- 1 root root 104857600 Apr 30 13:56 home.tar.gz.01
-rw-r--r-- 1 root root  75143891 Apr 30 13:57 home.tar.gz.02</pre>
<p>4. Create a MD5 checksum (or a SHA1 checksum).</p>
<pre class="code">[root@linux archive]# md5sum home.tar.gz* > MD5SUM
[root@linux archive]# cat MD5SUM
cb16175f4acad02f977f74d5c142879b  home.tar.gz
33c745ca49ab6e63b727658ec148cf67  home.tar.gz.00
14e6952b632fbb7f4c0731067afdb46c  home.tar.gz.01
386655357f8553c7730fd792c22fde2a  home.tar.gz.02</pre>
<p>Same thing but creating a SHA1 checksum instead (you don&#8217;t need two checksums, I just illustrate to use both types &#8212; pick one).</p>
<pre class="code">[root@linux archive]# sha1sum home.tar.gz* > SHA1SUM
[root@linux archive]# cat SHA1SUM
3858b51622dc9135c192a7c98dec24ccd35c63d6  home.tar.gz
6bc12b26dc1388d70d1a7cc0290dc6c9e8e0f97e  home.tar.gz.00
0683a44538ac65330fe103440e4f2a4a3a652be5  home.tar.gz.01
eb0f65fd0f4b3d98221e3ae8600f1691b536ad1d  home.tar.gz.02</pre>
<h3>Restoring your Data from the Volumes</h3>
<p>You&#8217;ve burned or transferred your volumes and now want to restore them to the original. Here are the steps.</p>
<p>1. Verify the checksum against the volumes (ignore the error on the original file).</p>
<pre class="code">[root@linux resurrection]# md5sum --check MD5SUM
md5sum: home.tar.gz: No such file or directory
home.tar.gz: FAILED open or read
home.tar.gz.00: OK
home.tar.gz.01: OK
home.tar.gz.02: OK
md5sum: WARNING: 1 of 4 listed files could not be read</pre>
<p>Once again, same deal but with the SHA1SUM file.</p>
<pre class="code">[root@linux resurrection]# sha1sum --check SHA1SUM
sha1sum: home.tar.gz: No such file or directory
home.tar.gz: FAILED open or read
home.tar.gz.00: OK
home.tar.gz.01: OK
home.tar.gz.02: OK
sha1sum: WARNING: 1 of 4 listed files could not be read</pre>
<p>2. Join the volume pieces together using cat (after you finish you can validate the checksum *again* to see if the original file passes an integrity check).</p>
<pre class="code">[root@node2 resurrection]# cat home.tar.gz.* > home.tar.gz
[root@node2 resurrection]# ls -la home.tar.gz
-rw-r--r-- 1 root root 284859091 Apr 30 15:23 home.tar.gz</pre>
<p>3. Decompress and extract the tar.gz file contents and you&#8217;re done.</p>
<pre class="code">[root@linux resurrection]# tar zxvf home.tar.gz
<em>... verbose file list ...</em>
[root@linux resurrection]# ls -la
total 556952
drwxr-xr-x 3 root root      4096 Apr 30 15:33 .
drwxr-x--- 7 root root      4096 Apr 30 15:02 ..
drwxr-xr-x 4 root root      4096 Apr 30 13:06 home
-rw-r--r-- 1 root root 284859091 Apr 30 15:23 home.tar.gz
-rw-r--r-- 1 root root 104857600 Apr 30 15:04 home.tar.gz.00
-rw-r--r-- 1 root root 104857600 Apr 30 15:04 home.tar.gz.01
-rw-r--r-- 1 root root  75143891 Apr 30 15:04 home.tar.gz.02
-rw-r--r-- 1 root root       193 Apr 30 15:05 MD5SUM
-rw-r--r-- 1 root root       225 Apr 30 15:05 SHA1SUM</pre>
<p>Contents extracted and there is the <em>home</em> directory. The End.</p>
<p>I got the idea of using the split command from this post on the <a href="http://ubuntuforums.org/showthread.php?t=455033" title="Ubuntu Forum (how to create multi zip files)">Ubuntu Forum (how to create multi zip files)</a> because I couldn&#8217;t get tar or gzip to create multi-volume archives.</p>
<div class="gpo_leftcontainer"><div class="gpo_buttons"><g:plusone size="tall" count="true"></g:plusone></div></div> <a href='http://twitter.com/share?url=http%3A%2F%2Fwww.tonybhimani.com%2F%3Fp%3D27&count=vertical&related=&text=Creating%20Multi-Volume%20Archives%20and%20Checksums' class='twitter-share-button' data-text='Creating Multi-Volume Archives and Checksums' data-url='http://www.tonybhimani.com/?p=27' data-counturl='http://www.tonybhimani.com/2008/04/30/creating-multi-volume-archives-and-checksums/' data-count='vertical' data-via='TonyBhimani'></a> <script type='text/javascript'>
<!--
tweetmeme_source = 'TonyBhimani';
tweetmeme_url = 'http://www.tonybhimani.com/2008/04/30/creating-multi-volume-archives-and-checksums/';
//-->
</script><script type="text/javascript" src="http://tweetmeme.com/i/scripts/button.js"></script>
]]></content:encoded>
			<wfw:commentRss>http://www.tonybhimani.com/2008/04/30/creating-multi-volume-archives-and-checksums/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating Captcha Images with PHP and the GD Library</title>
		<link>http://www.tonybhimani.com/2008/02/01/creating-captcha-images-with-php-and-the-gd-library/</link>
		<comments>http://www.tonybhimani.com/2008/02/01/creating-captcha-images-with-php-and-the-gd-library/#comments</comments>
		<pubDate>Sat, 02 Feb 2008 06:34:01 +0000</pubDate>
		<dc:creator>Tony Bhimani</dc:creator>
				<category><![CDATA[HOWTOs]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[captcha]]></category>
		<category><![CDATA[gd]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[security images]]></category>

		<guid isPermaLink="false">http://www.tonybhimani.com/2008/02/01/creating-captcha-images-with-php-and-the-gd-library/</guid>
		<description><![CDATA[A long time ago I wrote some code to create captcha images using PHP. The goal was to create similar or exact representations of the captcha&#8217;s used on Yahoo&#8217;s Overture. I really don&#8217;t have an answer why I chose their &#8230; <a href="http://www.tonybhimani.com/2008/02/01/creating-captcha-images-with-php-and-the-gd-library/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>A long time ago I wrote some code to create <a href="http://en.wikipedia.org/wiki/Captcha" title="Captcha definition on Wikipedia" target="_blank">captcha</a> images using PHP. The goal was to create similar or exact representations of the captcha&#8217;s used on Yahoo&#8217;s Overture. I really don&#8217;t have an answer why I chose their style except that it&#8217;s possible I liked the way they looked. I am sharing this code for creating the images but it&#8217;s up to you to create some logic in applying their use with HTML forms (I&#8217;ll give some hints at the end of this post).</p>
<p>This is the code to create the image. It returns an image resource identifier.  Note the use of a custom TrueType font &#8212;  you&#8217;ll need to change that line to the path of a font on your system.</p>
<pre class="code">&lt;?php
// generate captcha image - returns image handle
function captcha_image($code_string, $img_width=150, $img_height=40) {
  // seed srand
  srand((double)microtime()*1000000);

  // create image
  $im = @imagecreate($img_width, $img_height) or die("Cannot Initialize new GD image stream");

  // security code
  $security_code = $code_string;

  // define font
  $font = "/usr/fonts/ttf/Georgia.ttf";

  // create some colors
  $black = imagecolorallocate($im, 0, 0, 0);
  $white = imagecolorallocate($im, 255, 255, 255);
  $grey = imagecolorallocate($im, 128, 128, 128);

  // randomness, we need lots of randomness <img src='http://www.tonybhimani.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />
  // background color -&gt; 1=black, 2=white, 3=grey (more colors can be added)
  // lines -&gt; black bg (1=white or 2=grey), white bg (1=black or 2=grey), grey bg (black only)
  $randval = rand(1, 3);
  if ($randval == 1) {
    $bgcolor = $black;
    $fontcolor = $white;
    $linecolor = ((rand(0, 1) == 0) ? $black : $white);
  } elseif ($randval == 2) {
    $bgcolor = $white;
    $fontcolor = $black;
    $linecolor = ((rand(0, 1) == 0) ? $black : $white);
  } else {
    $bgcolor = $grey;
    $fontcolor = $black;
    $linecolor = ((rand(0, 1) == 0) ? $black : $grey);
  }

  // line positioning and increment
  $x_start = rand(0, 10);
  $x_size = rand(5, 10);
  $y_start = rand(0, 10);
  $y_size = rand(5, 10);

  // fill with background color
  imagefill($im, 0, 0, $bgcolor);

  // initial x position
  $font_x = 10;

  // write text
  for ($i = 0; $i &lt; strlen($security_code); $i++) {
    // font size -&gt; 20 to 35
    $font_size = rand(25, 35);
    // font angle -&gt; -20 to +20
    $font_angle = rand(0, 20);
    if ($font_angle != 0) { if (rand(0, 1) == 0) { $font_angle = -$fone_angle; } }
    // font y position -&gt; if font_size &lt;= 27 then 30 to 35, if font_size &gt; 27 then 30 to 35
    if ($font_size &lt;= 27) { $font_y = rand(25, 30); } else { $font_y = rand(30, 35); }
    // write the text
    imagettftext($im, $font_size, $font_angle, $font_x, $font_y, $fontcolor, $font, $security_code{$i});
    // one more time to make it bolder
    imagettftext($im, $font_size, $font_angle, $font_x+1, $font_y+1, $fontcolor, $font, $security_code{$i});
    // next font x position
    $font_x += ($font_size + 5);
  }

  // draw horizontal lines
  for ($y = $y_start; $y &lt; $img_height; $y += $y_size) {
    imageline($im, 0, $y, $img_width, $y, $linecolor);
  }
  // draw vertical lines
  for ($x = $x_start; $x &lt; $img_width; $x += $x_size) {
    imageline($im, $x, 0, $x, $img_height, $linecolor);
  }

  // return captcha image handle
  return $im;
}
?&gt;</pre>
<p>We need a method for generating random four character strings when the captcha is created and displayed to the user. This function will do the trick.</p>
<pre class="code">&lt;?php
function secret_key($length=4) {
  $salt = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
  srand((double)microtime()*1000000);
  $i = 0;
  $skey = "";
  while ($i &lt; $length) {
    $num = rand() % strlen($salt);
    $tmp = substr($salt, $num, 1);
    $skey .= $tmp;
    $i++;
  }
  return $skey;
}
?&gt;</pre>
<p>With everything in place, we can generate the secret key, create the captcha, and finally display it to the user using this code.</p>
<pre class="code">&lt;?php
// set headers
header("Content-type: image/png");
header("Cache-Control: no-cache");
header("Pragma: no-cache");

// generate secret
$skey = secret_key();

// create captcha and output to browser as PNG image
$im = captcha_image($skey);
@imagepng($im);
@imagedestroy($im);
?&gt;</pre>
<p>Here is an example of the code in action. The style looks very similar to the images used on <a href="https://secure.overture.com/login.do" title="Yahoo's Overture" target="_blank">Yahoo&#8217;s Overture</a>.</p>
<p><strong><font size="+1">Captcha Demo »</font></strong>   <img src="http://www.tonybhimani.com/files/captcha/captcha.php" alt="Captcha" /></p>
<p>Now you know how to create a captcha, so what about verifying the input against the captcha value? This can be accomplished a variety of ways and everyone tends to have their preference.</p>
<ul>
<li>One method is to save the secret key in a session variable. As the image is created, store the key in a session variable and once the form is submitted, check the user&#8217;s value against the one stored in the session. If they match, proceed but if they fail, return an error and don&#8217;t process the form data.</li>
<li>If you don&#8217;t want to use sessions, you could try using temp files. Store the key in a temp file and pass some value as a query string identifying to the script that the key is in that file. Read in the key and <a href="http://www.php.net/manual/en/function.md5.php" title="PHP: md5 function reference" target="_blank">MD5</a> or <a href="http://www.php.net/manual/en/function.sha1.php" title="PHP: sha1 function reference" target="_blank">SHA1</a> crypt the key and save it in a hidden form field. When the form is submitted, compare the hashed key against the user input (which you will also hash). Process the form data if the keys match.</li>
</ul>
<p>You can download the provided source file. Use the PHP file as an image source in your HTML IMG tag.</p>
<pre class="code">&lt;img src="<span style="background-color: #ffff00">http://www.yourdomain.com/captcha.php</span>"&gt;</pre>
<p>Don&#8217;t forget to edit the path to the TrueType font you want to use in the <em>captcha_image</em> function. Failure to do so will lead to missing image characters.</p>
<p><strong>Source Files:</strong> <a href="http://www.tonybhimani.com/files/2008/02/captcha.zip" title="Captcha PHP Source Code">captcha.zip</a></p>
<div class="gpo_leftcontainer"><div class="gpo_buttons"><g:plusone size="tall" count="true"></g:plusone></div></div> <a href='http://twitter.com/share?url=http%3A%2F%2Fwww.tonybhimani.com%2F%3Fp%3D17&count=vertical&related=&text=Creating%20Captcha%20Images%20with%20PHP%20and%20the%20GD%20Library' class='twitter-share-button' data-text='Creating Captcha Images with PHP and the GD Library' data-url='http://www.tonybhimani.com/?p=17' data-counturl='http://www.tonybhimani.com/2008/02/01/creating-captcha-images-with-php-and-the-gd-library/' data-count='vertical' data-via='TonyBhimani'></a> <script type='text/javascript'>
<!--
tweetmeme_source = 'TonyBhimani';
tweetmeme_url = 'http://www.tonybhimani.com/2008/02/01/creating-captcha-images-with-php-and-the-gd-library/';
//-->
</script><script type="text/javascript" src="http://tweetmeme.com/i/scripts/button.js"></script>
]]></content:encoded>
			<wfw:commentRss>http://www.tonybhimani.com/2008/02/01/creating-captcha-images-with-php-and-the-gd-library/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Domain Redirection using Apache mod_rewrite and .htaccess</title>
		<link>http://www.tonybhimani.com/2008/01/26/domain-redirection-using-apache-mod_rewrite-and-htaccess/</link>
		<comments>http://www.tonybhimani.com/2008/01/26/domain-redirection-using-apache-mod_rewrite-and-htaccess/#comments</comments>
		<pubDate>Sun, 27 Jan 2008 04:21:49 +0000</pubDate>
		<dc:creator>Tony Bhimani</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[BIND]]></category>
		<category><![CDATA[HOWTOs]]></category>
		<category><![CDATA[domain redirection]]></category>
		<category><![CDATA[htaccess]]></category>
		<category><![CDATA[mod_rewrite]]></category>
		<category><![CDATA[URL rewrite]]></category>

		<guid isPermaLink="false">http://www.tonybhimani.com/2008/01/26/domain-redirection-using-apache-mod_rewrite-and-htaccess/</guid>
		<description><![CDATA[I recently acquired more XenoCafe domains (xenocafe.info, xenocafe.net, and xenocafe.org) and finally got around to adding them to my server. Instead of them being their own sites (well, point to my primary site, but the URL in the browser address &#8230; <a href="http://www.tonybhimani.com/2008/01/26/domain-redirection-using-apache-mod_rewrite-and-htaccess/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I recently acquired more XenoCafe domains (<a href="http://xenocafe.info/" title="XenoCafe Linux Tutorials for Beginners" target="_blank">xenocafe.info</a>, <a href="http://xenocafe.net/" title="XenoCafe Linux Tutorials for Beginners" target="_blank">xenocafe.net</a>, and <a href="http://xenocafe.org/" title="XenoCafe Linux Tutorials for Beginners" target="_blank">xenocafe.org</a>) and finally got around to adding them to my server. Instead of them being their own sites (well, point to my primary site,  but the URL in the browser address bar is taken over by the new domain name), I wanted them to redirect to my primary domain (<a href="http://xenocafe.com/" title="XenoCafe Linux Tutorials for Beginners" target="_blank">xenocafe.com</a>).</p>
<p>If you want to achieve the same effect, here is how I did it (to see it in action, click on the first three XenoCafe links above). All you need is Apache, mod_rewrite, and htaccess. I&#8217;m going to skip the step-by-step configuration stuff to cut down the length of this article. If you need help, you can register for an account and post a question to the comments section for this post.</p>
<p>In this mock setup, I&#8217;ll use 10.10.100.34 as the IP address of my web server, example.com as the primary domain I want to redirect to, and ourexamples.com as the domain I want to redirect from (to example.com). This is a three step process that involves creating the zone file(s), adding the redirect domains to your Apache httpd.conf VirtualHost configuration, and finally creating the htaccess mod_rewrite rules to redirect all requests for the new domains to your desired domain.</p>
<p><strong>Create a New Zone File for each Domain you Acquired</strong></p>
<p>The primary domain example.com already has a zone file and is a functioning web site, but for ourexamples.com to work we need to create a zone file for it. Here is an example (we only need the minimum &#8211; SOA, NS, and the host for web).</p>
<pre class="code">$TTL   21600
$ORIGIN ourexamples.com.
@       IN      SOA     ns1.example.com. hostmaster.example.com. (
                        2008012601      ; serial
                        3600            ; refresh
                        600             ; retry
                        86400           ; expiry
                        21600 )         ; minimum

        IN      NS      ns1.example.com.
        IN      NS      ns2.example.com.

        IN      A       10.10.100.34
www     IN      A       10.10.100.34</pre>
<p>Now reload the zone(s) for changes to take effect.</p>
<p><strong>Add the Redirect Domains to the Primary Domain&#8217;s VirtualHost Definition (using the ServerAlias directive)</strong></p>
<p>Edit your primary domain&#8217;s virtual host entry and add the new domain(s) using the <a href="http://httpd.apache.org/docs/2.0/mod/core.html#serveralias" title="Apache ServerAlias Directive" target="_blank">ServerAlias</a> directive. Below is an example of editing the example.com virtual host and adding the new redirection domain ourexamples.com (highlighted line).</p>
<pre class="code">&lt;VirtualHost *:80&gt;
    ServerAdmin hostmaster@example.com
    ServerName example.com
    ServerAlias www.example.com
    <span style="background-color: #ffff00">ServerAlias ourexamples.com www.ourexamples.com</span>
    DocumentRoot /web/example/html
    ScriptAlias /cgi-bin/ /web/example/html/cgi-bin/
    ErrorLog /web/example/logs/error_log
    CustomLog /web/example/logs/access_log combined
    &lt;Directory "/web/example/html"&gt;
        AllowOverride All
    &lt;/Directory&gt;
&lt;/VirtualHost&gt;</pre>
<p>Restart Apache to reload the virtual host changes. Next we&#8217;ll need to create the htaccess file to configure domain redirection.</p>
<p><strong>Using mod_rewrite to Redirect the Domain Requests</strong></p>
<p>If we were to stop here, the new domain would work, however there is no redirection to your primary domain name. It will simply use the same document root and serve the files without any changes to the URL in the browser address bar. If this is what you desire, then stop here, otherwise continue on to bounce all requests from ourexamples.com to example.com.</p>
<p>In the document root of where your HTML files are stored (where DocumentRoot points to in your Apache VirtualHost definition), create a .htaccess with a text editor. Here is the example.</p>
<pre class="code">&lt;IfModule mod_rewrite.c&gt;
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\.example\.com [NC]
RewriteCond %{HTTP_HOST} !^$
RewriteRule (.*) http://www.example.com/$1 [L,R=301]
&lt;/IfModule&gt;</pre>
<p>In short, what this code does is turn on mod_rewrite&#8217;s engine, check the HTTP host to see if it matches www.example.com and also checks for empty references; if either case is a yes it rewrites the URL to http://www.example.com using a permanent redirect (HTTP 301 Redirection header). The $1 appends any portion trailing the domain name from the original (directories and/or pages being accessed). This code also forces the &#8216;www&#8217; prefix on all requests &#8212; <em>http://example.com </em>=&gt;<em> http://www.example.com</em> and <em>http://ourexamples.com </em>=&gt;<em> http://www.example.com</em> and so on.</p>
<div class="gpo_leftcontainer"><div class="gpo_buttons"><g:plusone size="tall" count="true"></g:plusone></div></div> <a href='http://twitter.com/share?url=http%3A%2F%2Fwww.tonybhimani.com%2F%3Fp%3D21&count=vertical&related=&text=Domain%20Redirection%20using%20Apache%20mod_rewrite%20and%20.htaccess' class='twitter-share-button' data-text='Domain Redirection using Apache mod_rewrite and .htaccess' data-url='http://www.tonybhimani.com/?p=21' data-counturl='http://www.tonybhimani.com/2008/01/26/domain-redirection-using-apache-mod_rewrite-and-htaccess/' data-count='vertical' data-via='TonyBhimani'></a> <script type='text/javascript'>
<!--
tweetmeme_source = 'TonyBhimani';
tweetmeme_url = 'http://www.tonybhimani.com/2008/01/26/domain-redirection-using-apache-mod_rewrite-and-htaccess/';
//-->
</script><script type="text/javascript" src="http://tweetmeme.com/i/scripts/button.js"></script>
]]></content:encoded>
			<wfw:commentRss>http://www.tonybhimani.com/2008/01/26/domain-redirection-using-apache-mod_rewrite-and-htaccess/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Openfire Jabber/XMPP Server on CentOS mini-Howto</title>
		<link>http://www.tonybhimani.com/2007/12/31/openfire-jabberxmpp-server-on-centos-mini-howto/</link>
		<comments>http://www.tonybhimani.com/2007/12/31/openfire-jabberxmpp-server-on-centos-mini-howto/#comments</comments>
		<pubDate>Tue, 01 Jan 2008 06:13:38 +0000</pubDate>
		<dc:creator>Tony Bhimani</dc:creator>
				<category><![CDATA[CentOS]]></category>
		<category><![CDATA[HOWTOs]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[jabber]]></category>
		<category><![CDATA[openfire]]></category>
		<category><![CDATA[xmpp]]></category>

		<guid isPermaLink="false">http://www.tonybhimani.com/2007/12/31/openfire-jabberxmpp-server-on-centos-mini-howto/</guid>
		<description><![CDATA[So you want to set up your own private chat network for friends or family, or maybe your company uses the major chat providers like AIM, Yahoo, MSN, or Google for interoffice communication, but you want more control and to &#8230; <a href="http://www.tonybhimani.com/2007/12/31/openfire-jabberxmpp-server-on-centos-mini-howto/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>So you want to set up your own private chat network for friends or family, or maybe your company uses the major chat providers like AIM, Yahoo, MSN, or Google for interoffice communication, but you want more control and to keep the network traffic inside your LAN. Whatever your case may be, this guide will show you how to do it with Ignite Realtime&#8217;s Openfire Jabber Server for Linux.</p>
<p><strong>Before we get started&#8230;</strong></p>
<p>There are two preliminary steps to complete before we install Openfire. They aren&#8217;t essential to its functionality (you can skip them if you&#8217;d like), but they&#8217;ll make things easier when it comes to managing the administration for you and your users. Those two steps are setting up a DNS alias for the server host name and creating a MySQL database for the backend instead of using the included embedded database.</p>
<p><strong>» Create a DNS Host Name for your Jabber Server</strong></p>
<p>For this guide I&#8217;ll use the host name &#8216;jabber&#8217; for my Openfire server. I run my own DNS server so I&#8217;ll be editing my zone file to add the new alias. If you use a third party service for DNS on your domain then you should know how to add new aliases. If you don&#8217;t then you should consult their Support documentation for more information.</p>
<p>Open your zone file in a text editor and add your new alias. Yours may look something like this example when you&#8217;re done. The highlighted line is what I added.</p>
<pre class="code">$TTL    21600
$ORIGIN mydomain.com.

@       IN      SOA     ns1.my-name-server.com. admin.my-name-server.com. (
                        2007122301      ; serial
                        3600            ; refresh
                        600             ; retry
                        86400           ; expiry
                        21600 )         ; minimum

                IN      NS      ns1.my-name-server.com.
                IN      NS      ns2.my-name-server.com.

                IN      MX      10      mx1.my-mail-server.com.
                IN      MX      20      mx2.my-mail-server.com.

                IN      A       10.0.0.100

www             IN      A       10.0.0.100
ftp             IN      A       10.0.0.100
<span style="background-color: #ffff00">jabber          IN      A       10.0.0.100</span></pre>
<p>Save your changes, flush the cache and reload the zone.</p>
<pre class="code">[root@node1 ~]# rndc flush
[root@node1 ~]# rndc reload</pre>
<p><strong>» Create the MySQL Database for Openfire Data</strong></p>
<p>Sometimes a tool like <a href="http://www.phpmyadmin.net/">phpMyAdmin</a> comes in handy for managing MySQL databases, however I don&#8217;t have it installed on this server. Instead I&#8217;ll be adding my Openfire database from the MySQL console. All we need to do is create the database, add an user account that has full control over that database, and reload (flush) the privileges.</p>
<pre class="code">[root@node1 ~]# mysql -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or g.
Your MySQL connection id is 3 to server version: 5.0.22

Type 'help;' or 'h' for help. Type 'c' to clear the buffer.

mysql&gt; CREATE DATABASE `openfire`;
Query OK, 1 row affected (0.00 sec)

mysql&gt; CREATE USER 'openfire'@'localhost' IDENTIFIED BY 'password';
Query OK, 0 rows affected (0.01 sec)

mysql&gt; GRANT USAGE ON *.* TO 'openfire'@'localhost' IDENTIFIED BY 'password' WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0;
Query OK, 0 rows affected (0.00 sec)

mysql&gt; GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, CREATE TEMPORARY TABLES ON `openfire`.* TO 'openfire'@'localhost';
Query OK, 0 rows affected (0.01 sec)

mysql&gt; FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.02 sec)

mysql&gt; quit
Bye
[root@node1 ~]#</pre>
<p>Now that all the preliminaries are out of the way, we can move onto installing Openfire.</p>
<p><strong>Download and Install the Openfire Software</strong></p>
<p>Openfire can be downloaded from the <a href="http://www.igniterealtime.org/">Ignite Realtime</a> web site. As of this writing, the latest version available for download is <a href="http://www.igniterealtime.org/downloadServlet?filename=openfire/openfire-3.4.2-1.i386.rpm">Openfire 3.4.2 for Linux</a>.</p>
<p>We&#8217;ll start by downloading the Openfire RPM via wget.</p>
<pre class="code">[root@node1 ~]# wget -O openfire-3.4.2-1.i386.rpm http://www.igniterealtime.org/downloadServlet?filename=openfire/openfire-3.4.2-1.i386.rpm
--12:18:13-- http://www.igniterealtime.org/downloadServlet?filename=openfire/openfire-3.4.2-1.i386.rpm
Resolving www.igniterealtime.org... 63.246.20.125
Connecting to www.igniterealtime.org|63.246.20.125|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 40451331 (39M) [application/x-rpm]
Saving to: `openfire-3.4.2-1.i386.rpm'

100%[=====================================================================&gt;] 40,451,331   368K/s   in 1m 52s

12:20:05 (354 KB/s) - `openfire-3.4.2-1.i386.rpm' saved [40451331/40451331]

[root@node1 ~]#</pre>
<p>Now install the RPM, start the Openfire service, verify it is actively running, and set it to auto-start whenever your server is rebooted.</p>
<pre class="code">[root@node1 ~]# rpm -ivh openfire-3.4.2-1.i386.rpm
Preparing...                ########################################### [100%]
   1:openfire               ########################################### [100%]
[root@node1 ~]# /etc/init.d/openfire start
Starting openfire:
[root@node1 ~]# ps -ef | grep -i openfire
root      2508     1  0 07:35 pts/0    00:00:00 su -s /bin/sh -c /opt/openfire/jre/bin/java -server  -DopenfireHome=/opt/openfire -Dopenfire.lib.dir=/opt/openfire/lib -classpath "/opt/openfire/lib/startup.jar" -jar "/opt/openfire/lib/startup.jar" daemon
daemon    2511  2508 37 07:35 ?        00:00:07 /opt/openfire/jre/bin/java -server -DopenfireHome=/opt/openfire -Dopenfire.lib.dir=/opt/openfire/lib -classpath /opt/openfire/lib/startup.jar -jar /opt/openfire/lib/startup.jar
root      2526  2414  1 07:35 pts/0    00:00:00 grep -i openfire
[root@node1 ~]# chkconfig --level 235 openfire on
[root@node1 ~]#</pre>
<p><strong>Open Ports in your Firewall</strong></p>
<p>If you have a firewall in place you&#8217;ll need to open some ports before we can start configuring Openfire through its web interface. Openfire uses ports 5222, 7777, 9090, 9091 for client connections, file transfer proxy, http web administration and the secured administration respectively. If you use iptables tables like I do, add these lines to your <em>/etc/sysconfig/iptables</em> rules file and reload. See my <a href="http://www.xenocafe.com/tutorials/linux/redhat/iptables/iptables_linux_redhat-part1.php" title="RedHat IPTables Tutorial on XenoCafe" target="_blank">RedHat IPTables Tutorial on XenoCafe</a> for more information on configuring iptables from the ground up.</p>
<pre class="code">-A INPUT -p tcp -i eth0 --dport 5222 -j ACCEPT
-A INPUT -p udp -i eth0 --dport 5222 -j ACCEPT
-A INPUT -p tcp -i eth0 --dport 7777 -j ACCEPT
-A INPUT -p udp -i eth0 --dport 7777 -j ACCEPT
-A INPUT -p tcp -i eth0 --dport 9090 -j ACCEPT
-A INPUT -p udp -i eth0 --dport 9090 -j ACCEPT
-A INPUT -p tcp -i eth0 --dport 9091 -j ACCEPT
-A INPUT -p udp -i eth0 --dport 9091 -j ACCEPT</pre>
<p>Then reload iptables to accept the new directives.</p>
<pre class="code">[root@node1 ~]# iptables-restore &lt; /etc/sysconfig/iptables</pre>
<p><strong>Configure Openfire through its Web Interface</strong></p>
<p>1. Launch your favorite browser and go to <em>http://your_jabber_server_ip_address:9090</em> or if you set up a DNS alias <em>http://jabber.mydomain.com:9090</em> to go to the Openfire web interface. You&#8217;ll be greeted by Openfire&#8217;s setup tool. In the first step, select your language. Here we choose English.</p>
<p><a href="http://www.tonybhimani.com/files/openfire_server/language.jpg" title="Openfire Setup: Language Selection Screen" target="_blank"><img src="http://www.tonybhimani.com/files/openfire_server/small_language.jpg" alt="Openfire Setup: Language Selection Screen" border="0" height="261" width="425" /></a></p>
<p>2. The next step is to set the server domain. If you opted for an IP address name, enter your server&#8217;s IP. If you opted to create a DNS alias, enter the DNS server domain. Here we created jabber.mydomain.com so we&#8217;ll enter that. By default the Openfire web interface console ports are 9090 and 9091 for standard and secure respectively. You can use other ports if you wish (NOTE: you&#8217;ll have to change your firewall settings if you use different ports), but for this guide we&#8217;re sticking with the default values.</p>
<p><a href="http://www.tonybhimani.com/files/openfire_server/server.jpg" title="Openfire Setup: Server Settings Screen" target="_blank"><img src="http://www.tonybhimani.com/files/openfire_server/small_server.jpg" alt="Openfire Setup: Server Settings Screen" border="0" height="187" width="425" /></a></p>
<p>3. You have two choices regarding which database to use for Openfire to store its data: an external database like MySQL, MSSQL, PostgreSQL, etc&#8230; or to use the bundled embedded database. If you setup a MySQL database like we did in this guide then select the Standard Database Connection option. If you didn&#8217;t, the only choice is to use the Embedded Database.</p>
<p><a href="http://www.tonybhimani.com/files/openfire_server/database.jpg" title="Openfire Setup: Language Selection Screen" target="_blank"><img src="http://www.tonybhimani.com/files/openfire_server/small_database.jpg" alt="Openfire Setup: Database Settings Screen" border="0" height="200" width="425" /></a></p>
<p>4. To set up your database connection, select the appropriate driver from the Database Driver Presets list (we set up a MySQL database so we&#8217;ll select MySQL). The page will refresh and you need to fill in the necessary information (the database host, name, username, and password). You should have this information from when you setup your MySQL database. Per this guide, MySQL is on the same server as my Openfire installation (localhost) and I created a database called &#8216;openfire&#8217; with a username of &#8216;openfire&#8217; and set a password.</p>
<p><a href="http://www.tonybhimani.com/files/openfire_server/dbsettings.jpg" title="Openfire Setup: Database Settings Configuration Screen" target="_blank"><img src="http://www.tonybhimani.com/files/openfire_server/small_dbsettings.jpg" alt="Openfire Setup: Database Settings Configuration Screen" border="0" height="319" width="425" /></a></p>
<p>5. The profile step has to do with the users and groups of chat members and where Openfire will store that information (new users, user groups, etc&#8230;). We won&#8217;t opt for LDAP to store this information. It is much more convenient to save it in our in our database.</p>
<p><a href="http://www.tonybhimani.com/files/openfire_server/profile.jpg" title="Openfire Setup: Profile Settings Screen" target="_blank"><img src="http://www.tonybhimani.com/files/openfire_server/small_profile.jpg" alt="Openfire Setup: Profile Settings Configuration Screen" border="0" height="187" width="425" /></a></p>
<p>6. We&#8217;re almost done. Enter the administrator email address (your email address) and set a password for your Openfire server.</p>
<p><a href="http://www.tonybhimani.com/files/openfire_server/admin.jpg" title="Openfire Setup: Admin Account Screen" target="_blank"><img src="http://www.tonybhimani.com/files/openfire_server/small_admin.jpg" alt="Openfire Setup: Admin Account Screen" border="0" height="204" width="425" /></a></p>
<p>7. Now you&#8217;re done! Pat yourself on the back. Click the <strong>Login to admin console</strong> button.</p>
<p><a href="http://www.tonybhimani.com/files/openfire_server/setupcomplete.jpg" title="Openfire Setup: Setup Complete Screen" target="_blank"><img src="http://www.tonybhimani.com/files/openfire_server/small_setupcomplete.jpg" alt="Openfire Setup: Setup Complete Screen" border="0" height="276" width="425" /></a></p>
<p>8. Type in the Openfire admin password you entered in Step 6 and click the <strong>Login</strong> button.</p>
<p><a href="http://www.tonybhimani.com/files/openfire_server/login.jpg" title="Openfire Setup: Admin Login Screen" target="_blank"><img src="http://www.tonybhimani.com/files/openfire_server/small_login.jpg" alt="Openfire Setup: Admin Login Screen" border="0" height="274" width="425" /></a></p>
<p>Welcome to the Openfire Administration Console. Take a look around and get familiar with the layout.</p>
<p><a href="http://www.tonybhimani.com/files/openfire_server/console.jpg" title="Openfire: Administration Console Screen" target="_blank"><img src="http://www.tonybhimani.com/files/openfire_server/small_console.jpg" alt="Openfire: Administration Console Screen" border="0" height="309" width="425" /></a></p>
<p><strong>Time to Make Some Openfire Configuration Changes</strong></p>
<p>Your Openfire installation will work out of the box and you can skip this section if you want, but for this tutorial I wanted to make some changes. Namely, I want my server to follow some rules so there is no chaos.</p>
<ol>
<li>I don&#8217;t want any other servers to be able to communicate with mine (it&#8217;s private and self sufficient)</li>
<li>I define the member base so anonymous users cannot create accounts (ideal for an office environment)</li>
<li>Finally, all communication between clients and the server is encrypted (force jabber clients to use SSL)</li>
</ol>
<p>Follow along if you want to use any of these features or jump ahead to the <a href="#cugjc" title="Creating Users and Groups for Jabber Clients">Creating Users and Groups for Jabber Clients</a> section.</p>
<p>1. On the left under <strong>Server Settings</strong>, click the <strong>Server to Server</strong> link. In the top panel <strong>Service Enabled</strong>, choose the <strong>Disabled</strong> option and click <strong>Save Settings</strong>.</p>
<p><a href="http://www.tonybhimani.com/files/openfire_server/srv2srv.jpg" title="Openfire: Administration Console 'Server to Server' Screen" target="_blank"><img src="http://www.tonybhimani.com/files/openfire_server/small_srv2srv.jpg" alt="Openfire: Administration Console 'Server to Server' Screen" border="0" height="191" width="425" /></a></p>
<p>2. Click the <strong>Registration &amp; Login</strong> link in the left side menu. Disable both options under <strong>Inband Account Registration</strong> and <strong>Anonymous Login</strong>. We&#8217;ll leave the <strong>Change Password</strong> option alone to let users update their passwords as they see fit. Click the <strong>Save Settings</strong> button at the bottom of the page.</p>
<p><a href="http://www.tonybhimani.com/files/openfire_server/reglogin.jpg" title="Openfire: Administration Console 'Registration &amp; Login' Screen" target="_blank"><img src="http://www.tonybhimani.com/files/openfire_server/small_reglogin.jpg" alt="Openfire: Administration Console 'Registration &amp; Login' Screen" border="0" height="309" width="425" /></a></p>
<p>3. Click the <strong>Security Settings</strong> link on the left. Under <strong>Client Connection Security</strong>, choose the <strong>Required</strong> option to force jabber clients to use SSL (NOTE: If the client doesn&#8217;t support SSL and this option is enabled, the client will not be able to connect to the server). Click the <strong>Save Settings</strong> button.</p>
<p><a href="http://www.tonybhimani.com/files/openfire_server/security.jpg" title="Openfire: Administration Console 'Security Settings' Screen" target="_blank"><img src="http://www.tonybhimani.com/files/openfire_server/small_security.jpg" alt="Openfire: Administration Console 'Security Settings' Screen" border="0" height="277" width="425" /></a></p>
<p><strong>Openfire SSL Certificates</strong></p>
<p>Openfire creates self-signed SSL Certificates by default. Remember the port 9091 from before? If you ever want to access this administration console from a Secure Connection, then you&#8217;ll need to restart the Openfire HTTP Server.</p>
<p>Click the <strong>Server Certificates</strong> link on the left menu.</p>
<p><a href="http://www.tonybhimani.com/files/openfire_server/sslcerts.jpg" title="Openfire: Administration Console 'Server Certificates' Screen" target="_blank"><img src="http://www.tonybhimani.com/files/openfire_server/small_sslcerts.jpg" alt="Openfire: Administration Console 'Server Certificates' Screen" border="0" height="291" width="425" /></a></p>
<p>Click the link in the highlight section.</p>
<p><img src="http://www.tonybhimani.com/files/openfire_server/httprestart.jpg" alt="Openfire: HTTP Restart Link" border="0" height="20" width="425" /></p>
<p>Openfire will restart the HTTP Web Server and kick you back to the login screen. Log back in and the SSL Certificate should now be in use and you can access the console from SSL.</p>
<p><a title="cugjc" name="cugjc"></a><strong>Creating Users and Groups for Jabber Clients</strong></p>
<p>Since we&#8217;re creating a jabber server for a mock office environment, we prohibit anonymous users from creating accounts. Because of this, we will manage all users and groups on a global scale through our Openfire server. This means, all groups and users will be pushed to the clients that log in so they don&#8217;t have to add every single user account or group to their client. Also, any changes happen in real-time on the client (new users or groups added, removed, etc&#8230;). Kind of cool, huh? This is accomplished through Contact Group List Sharing.</p>
<p>We&#8217;ll be creating a mock Developer &#8220;Devel&#8221; group and add some users to it. Click on the <strong>Users/Groups</strong> tab on the top.</p>
<p>1. Go to <strong>Create New User</strong> under the <strong>Users</strong> section on the left. Fill in the <strong>Username</strong>, <strong>Password</strong>, and <strong>Confirm Password</strong>  fields and click the <strong>Create User</strong> button.</p>
<p><a href="http://www.tonybhimani.com/files/openfire_server/newuser.jpg" title="Openfire: Administration Console 'Create New User' Screen" target="_blank"><img src="http://www.tonybhimani.com/files/openfire_server/small_newuser.jpg" alt="Openfire: Administration Console 'Create New User' Screen" border="0" height="292" width="425" /></a></p>
<p>Repeat this process to add all the users you want on your server.</p>
<p><a href="http://www.tonybhimani.com/files/openfire_server/userprops.jpg" title="Openfire: Administration Console 'User Properties' Screen" target="_blank"><img src="http://www.tonybhimani.com/files/openfire_server/small_userprops.jpg" alt="Openfire: Administration Console 'User Properties' Screen" border="0" height="344" width="425" /></a></p>
<p>2. Go to <strong>Create New Group</strong> under the <strong>Groups</strong> section on the left. Fill in the <strong>Group Name</strong> and an optional <strong>Description</strong>. Click the <strong>Create Group</strong> button.</p>
<p><a href="http://www.tonybhimani.com/files/openfire_server/newgroup.jpg" title="Openfire: Administration Console 'Create Group' Screen" target="_blank"><img src="http://www.tonybhimani.com/files/openfire_server/small_newgroup.jpg" alt="Openfire: Administration Console 'Create Group' Screen" border="0" height="283" width="425" /></a></p>
<p>3. The group has been added. Now we&#8217;ll share the contact list so it&#8217;s global to all jabber clients that connect to our server. Under the <strong>Contact List (Roster) Sharing</strong> section, click the <strong>Enable contact list group sharing</strong> option. In the name field, type in the same name as set for the group. Click the <strong>Save Contact List Settings</strong> button.</p>
<p><a href="http://www.tonybhimani.com/files/openfire_server/editgroup.jpg" title="Openfire: Administration Console 'Edit Group' Screen" target="_blank"><img src="http://www.tonybhimani.com/files/openfire_server/small_editgroup.jpg" alt="Openfire: Administration Console 'Edit Group' Screen" border="0" height="261" width="425" /></a></p>
<p>4. Scroll down the page and type in an user name to the <strong>Add User</strong> field and click the <strong>Add</strong> button.</p>
<p><a href="http://www.tonybhimani.com/files/openfire_server/addmembers.jpg" title="Openfire: Administration Console 'Members of This Group' Screen" target="_blank"><img src="http://www.tonybhimani.com/files/openfire_server/small_addmembers.jpg" alt="Openfire: Administration Console 'Members of This Group' Screen" border="0" height="110" width="425" /></a></p>
<p>Now we have one member in our group. Repeat this for each user you want assigned to this group.</p>
<p><a href="http://www.tonybhimani.com/files/openfire_server/groupmembers.jpg" title="Openfire: Administration Console 'Members of This Group' Screen" target="_blank"><img src="http://www.tonybhimani.com/files/openfire_server/small_groupmembers.jpg" alt="Openfire: Administration Console 'Members of This Group' Screen" border="0" height="107" width="425" /></a></p>
<p><strong>Setting up a Jabber Client (Spark 2.5.8 for Windows)</strong></p>
<p>Our Openfire Jabber Server is useless unless we have clients connect to it and communicate through it. We&#8217;ll use <a href="http://www.igniterealtime.org/downloads/index.jsp" title="Spark Jabber Client" target="_blank">Spark </a>from Ignite Realtime. If that doesn&#8217;t suit you then you are open to use another jabber client since there are many of them out there (<a href="http://www.jabber.org/software/clients.shtml" title="Jabber Clients" target="_blank">see the client from jabber.org</a>).</p>
<p>1. Download <a href="http://www.igniterealtime.org/downloadServlet?filename=spark/spark_2_5_8.exe" title="Download Spark 2.5.8 for Windows">Spark</a>, install it, and launch it.</p>
<p>2. Type in your Openfire user credentials (<strong>Username</strong> and <strong>Password</strong>). In the <strong>Server</strong> field, type in the Openfire Servers IP address or DNS alias. Click the <strong>Login</strong> button.</p>
<p><a href="http://www.tonybhimani.com/files/openfire_server/clientlogin.jpg" title="Spark: Client Login Screen" target="_blank"><img src="http://www.tonybhimani.com/files/openfire_server/small_clientlogin.jpg" alt="Spark: Client Login Screen" border="0" height="348" width="425" /></a></p>
<p>3. The contact list will appear once you have successfully logged in. The shared group(s) will be visible (NOTE: groups with no online users will be hidden unless you select the <strong>Show empty groups</strong> option from the <strong>Contacts</strong> menu) along with the users of those groups. My contacts are not online as you can see from the picture below.</p>
<p><a href="http://www.tonybhimani.com/files/openfire_server/spark.jpg" title="Spark: Contact List Window" target="_blank"><img src="http://www.tonybhimani.com/files/openfire_server/small_spark.jpg" alt="Spark: Contact List Window" border="0" height="400" width="187" /></a></p>
<p>You&#8217;re done. You now have the essentials of configuring your own Jabber server and clients.</p>
<p>This is my last tutorial, guide, howto, whatever you want to call it for 2007. Happy New Year!</p>
<div class="gpo_leftcontainer"><div class="gpo_buttons"><g:plusone size="tall" count="true"></g:plusone></div></div> <a href='http://twitter.com/share?url=http%3A%2F%2Fwww.tonybhimani.com%2F%3Fp%3D15&count=vertical&related=&text=Openfire%20Jabber%2FXMPP%20Server%20on%20CentOS%20mini-Howto' class='twitter-share-button' data-text='Openfire Jabber/XMPP Server on CentOS mini-Howto' data-url='http://www.tonybhimani.com/?p=15' data-counturl='http://www.tonybhimani.com/2007/12/31/openfire-jabberxmpp-server-on-centos-mini-howto/' data-count='vertical' data-via='TonyBhimani'></a> <script type='text/javascript'>
<!--
tweetmeme_source = 'TonyBhimani';
tweetmeme_url = 'http://www.tonybhimani.com/2007/12/31/openfire-jabberxmpp-server-on-centos-mini-howto/';
//-->
</script><script type="text/javascript" src="http://tweetmeme.com/i/scripts/button.js"></script>
]]></content:encoded>
			<wfw:commentRss>http://www.tonybhimani.com/2007/12/31/openfire-jabberxmpp-server-on-centos-mini-howto/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>

