<?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>Jason's Computer Science Blog &#187; Tutorials</title>
	<atom:link href="http://www.jasonernst.com/category/tutorials/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.jasonernst.com</link>
	<description>By Jason Ernst</description>
	<lastBuildDate>Wed, 25 Jan 2012 14:04:58 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>OpenGL Console Library for Blackberry Native SDK (Playbook)</title>
		<link>http://www.jasonernst.com/2012/01/24/opengl-console-library-for-blackberry-native-sdk-playbook/</link>
		<comments>http://www.jasonernst.com/2012/01/24/opengl-console-library-for-blackberry-native-sdk-playbook/#comments</comments>
		<pubDate>Tue, 24 Jan 2012 20:41:29 +0000</pubDate>
		<dc:creator>Jason Ernst</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Blackberry]]></category>
		<category><![CDATA[Console]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Guide]]></category>
		<category><![CDATA[Native]]></category>
		<category><![CDATA[OpenGL]]></category>
		<category><![CDATA[Playbook]]></category>
		<category><![CDATA[SDK]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.jasonernst.com/?p=1897</guid>
		<description><![CDATA[Over the break, I decided to try my hand at some Blackberry native SDK programming since I recently got a playbook. I looked around the App World and noticed there weren&#8217;t any telnet/ssh tools available for free (that worked the way I wanted) so I thought this would be a good starter project. However, for [...]]]></description>
			<content:encoded><![CDATA[<p>Over the break, I decided to try my hand at some Blackberry native SDK programming since I recently got a playbook. I looked around the App World and noticed there weren&#8217;t any telnet/ssh tools available for free (that worked the way I wanted) so I thought this would be a good starter project.</p>
<p>However, for the look I wanted, I wanted to maximize the screen space for the console application to show as much text as possible and worked off the hello world example on the SDK webpage. Essentially, the simple &#8220;library&#8221; (note: library is used very loosely here) initializes the display, shows the keyboard and supports some simple output using putch and puts functions that I implemented. It can also show a blinking cursor and user input at a prompt. In case someone else can use the code I have made it available. Check back soon to see the source for the telnet portion of the app I made as well or look for it on the App World.</p>
<p><center>
<div class="image"><a href="http://www.jasonernst.com/wp-content/uploads/2012/01/simple_telnet.png"><img src="http://www.jasonernst.com/wp-content/uploads/2012/01/simple_telnet-300x185.png" alt="Simple Telnet - Example Application" title="Simple Telnet - Example Application" width="300" height="185" class="aligncenter size-medium wp-image-1902" /></a><br/>Simple Telnet &#8211; Example Application using the conosole library</div>
<p></center></p>
<p>In order to use the library, you need to make use of the bbutil.c and bbutil.h files that are included in many of the examples provided by RIM. I have provided them here alongside my own code so that it is easier to follow along. I also provide two more files: glconsole.c and glconsole.h. You just need to #include &#8220;glconsole.h&#8221; in your source in order to use the library. All of the functions available to you are listed in the &#8220;glconsole.h&#8221; file as well. I will go over the important ones in this article.</p>
<p>First is gl_init(). This function initializes the library, the screen, font etc. This function should be called before using anything else in the library. Similarly, gl_cleanup() is used to free memory and should be called before your app is terminated.</p>
<p>After initialization, you may now use the puts and putch functions to display characters to the screen. gl_putch(char c) takes a single character and displays it onto the screen. It can handle newlines which are represented as &#8216;\n&#8217; and tabs which are represented as &#8216;\t&#8217;. Backspaces by user input is handled as a &#8216;\b&#8217; character. This is similar to how people on <a href="http://forum.osdev.org/">The osdev.rg website</a> often handle character output in their custom operating systems. I&#8217;m not sure how it relates with normal c standards, but I imagine it is similar. Eventually I hope to implement a printf() type of function, but at the moment the putch() and puts() functions serve what I am doing well enough. Note: puts() is the same as putch() but instead takes a (char *) ie) a string. The string should also be null-terminated, or it will just continue until it hits a null character. The characters are automatically scrolled when the bottom of the screen is reached. </p>
<p>The only other really important function is gl_render(). This function is what should be called everytime the screen needs to be refreshed. This is usually in a for loop within your main() function in your app.</p>
<p>It is also possible to resize the screen using the gl_resize() function. By default the screen starts at 80X29 which is the maximum size with no virtualkeyboard showing, at the font size I selected. When the keyboard shows up, it fits 80&#215;14. In some sample code I&#8217;ll also show how keyboard input can be handled, how to blink the cursor and how to detect when the keyboard is shown or hidden.</p>
<p>For the rest of this guide, I&#8217;ll assume you are using the QNX Momentix IDE available from RIM&#8217;s developer website. To start, create a new project by going to File->New Blackberry Tablet OS C/C++ Project. Name it whatever you like, click next. Then choose the C language, and empty Application Project. You can now drag the gl_console.c, glconsole.h, bbutil.c and bbutil.h files into the src folder within the IDE to include them. You will probably want to copy the files and not link them when it asks. Before compiling, there are several libaries which must be linked to the project. You can do this by right clicking your project, going to properties. Then go to C/C++ General->Paths and Symbols->Libraries. Here you can add libraries. Each time you add one, be sure to check &#8220;add to all Configurations&#8221; so that you don&#8217;t need to do this again if you change from a device-debug to device-release build. The following libraries should be included:</p>
<ul style="margin-left:30px; margin-bottom: 10px;">
<li>bps</li>
<li>EGL</li>
<li>GLESv1_CM</li>
<li>freetype</li>
<li>png</li>
</ul>
<p>Now that all this is setup, it is possible to start you main() function and use the library. If you like you can right click on your src folder and click &#8220;new file&#8221; and create a main.c file or whatever you like to name it. While this isn&#8217;t the typical way you would include a library into a project, this way lets you edit the library source to your liking in case you want to further extend it. </p>
<p>The following example shows a skeleton of what is required to get the code to display some text:</p>
<div class="snippet"><pre><code>#include &lt;stdlib.h&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* EXIT_FAILURE */
#include &lt;stddef.h&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* NULL */
#include &lt;bps/bps.h&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* BPS_SUCCESS */
#include &lt;bps/screen.h&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* screen_event_get_event() */
#include &lt;bps/navigator.h&gt;&nbsp;&nbsp;/* NAVIGATOR_EXIT */
#include &quot;glconsole.h&quot;

void handleScreenEvent(bps_event_t *event);

int main(int argc, char * argv[])
{
&nbsp;&nbsp;int exit_application = 0;

&nbsp;&nbsp;if(EXIT_SUCCESS != gl_init())
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr, &quot;error init\n&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;return 0;
&nbsp;&nbsp;}

&nbsp;&nbsp;gl_puts(&quot;Hello gl console world!\n&quot;);

&nbsp;&nbsp;for(;;)
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;bps_event_t *event = NULL;
&nbsp;&nbsp;&nbsp;&nbsp;if (bps_get_event(&amp;event, 0) != BPS_SUCCESS)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return EXIT_FAILURE;

&nbsp;&nbsp;&nbsp;&nbsp;if (event)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int domain = bps_event_get_domain(event);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (domain == screen_get_domain())
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;handleScreenEvent(event);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else if ((domain == navigator_get_domain()) &amp;&amp; (NAVIGATOR_EXIT == bps_event_get_code(event)))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit_application = 1;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (exit_application)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;gl_render();
&nbsp;&nbsp;}

&nbsp;&nbsp;gl_cleanup();
&nbsp;&nbsp;return 0;
}

void handleScreenEvent(bps_event_t *event)
{
&nbsp;&nbsp;/* do normal event handling here, see other bb examples */
}</code></pre></div>
<p>The key parts are calling gl_init() which initializes the library. Then within the main loop, the gl_render() function should be called which will actually render the text. Finally gl_cleanup() should be called before termination to properly free memory.</p>
<p>In the near future I plan to add some support to handle ansi encoded text (specifically for my telnet application) so that it can display colours and move the cursor around the screen using this standard.</p>
<p>Here are the files:<br />
<a href='http://www.jasonernst.com/wp-content/uploads/2012/01/glconsole.h'>glconsole.h</a><br />
<a href='http://www.jasonernst.com/wp-content/uploads/2012/01/glconsole.c'>glconsole.c</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.jasonernst.com/2012/01/24/opengl-console-library-for-blackberry-native-sdk-playbook/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating a Bluetooth Access point (NAP) in Ubuntu 11.10</title>
		<link>http://www.jasonernst.com/2011/11/29/creating-a-bluetooth-access-point-nap-in-ubuntu-11-10/</link>
		<comments>http://www.jasonernst.com/2011/11/29/creating-a-bluetooth-access-point-nap-in-ubuntu-11-10/#comments</comments>
		<pubDate>Wed, 30 Nov 2011 01:06:13 +0000</pubDate>
		<dc:creator>Jason Ernst</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Wireless Networks]]></category>
		<category><![CDATA[11.10]]></category>
		<category><![CDATA[2011]]></category>
		<category><![CDATA[Access Point]]></category>
		<category><![CDATA[Bluetooth]]></category>
		<category><![CDATA[Bluez]]></category>
		<category><![CDATA[NAP]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://www.jasonernst.com/?p=1848</guid>
		<description><![CDATA[A Bluetooth NAP is similar to a Wi-Fi access point. In this case, we will be using NAP to share an Internet connection to another computer with Bluetooth. It is supposed to be able to support 7 or 8 devices connected at once in this manner. Eventually my personal goal is to use this in [...]]]></description>
			<content:encoded><![CDATA[<p>A Bluetooth NAP is similar to a Wi-Fi access point. In this case, we will be using NAP to share an Internet connection to another computer with Bluetooth. It is supposed to be able to support 7 or 8 devices connected at once in this manner. Eventually my personal goal is to use this in conjunction with a Wi-Fi connection to get slightly more speed at once or for some redundancy to help achieve a more ubiquitous/pervasive connection.</p>
<p>It turns out what should be a simple process is a bit tricky in Ubuntu. You would expect to be able to create an IP access point fairly easily so that you can share your Internet connection to other devices using Bluetooth. (It turns out it may be possible with Blueman &#8211; http://blog.larsstrand.org/2009/04/sharing-internet-connection-over.html, but I&#8217;ve never had any luck with setting it up this way.) Here&#8217;s some of the steps and resources I used to get it to work. I am using one laptop with a generic usb dongle and another toshiba netbook with built-in Bluetooth for this.</p>
<p>Before anything is started, you need to make sure the devices are paired and trusted with one another. I found the easiest way to get this to work is with blueman (it is in the Ubuntu repos). Also it seems to work better if you initiate the pairing from the client (the computer not sharing the connection).</p>
<p>First, you need a bridge interface. This is easy enough in Ubuntu, by editing the /etc/network/interfaces file. If the interface you wish to share is eth0 (if you want to share a Wi-Fi connection instead, you could switch this with something like wlan0 or whatever your Wi-Fi interface is), you could add something like this:</p>
<p><pre><pre>auto br1
iface br1 inet dhcp
&nbsp;&nbsp;bridge_ports eth0
&nbsp;&nbsp;bridge_fd 9
&nbsp;&nbsp;bridge_hello 2
&nbsp;&nbsp;bridge_maxage 12
&nbsp;&nbsp;bridge_stp off
</pre></pre></p>
<p>Next you need to make sure both computers can see each other via Bluetooth. This requires enabling scanning and turning the NAP into a master and the client(s) into slaves. This can be done as follows:<br />
<pre>sudo hciconfig hci0 piscan</pre><br />
and<br />
<pre>sudo hciconfig hci0 lm MASTER,ACCEPT</pre><br />
or<br />
<pre>sudo hciconfig hci0 lm SLAVE,ACCEPT</pre></p>
<p>You can now check to see if each of the computers can see each other on bluetooth by running:<br />
<pre>hcitool scan</pre><br />
where you should be able to see the opposite computer on each. </p>
<p>Next you want to start the NAP server on the computer you wish to share the connection from. (This is the computer with the bridge device). This script, which is available on the git repository will allow you to start up the NAP server. (it may also be possible to use pand, but I haven&#8217;t had any luck yet with it)<br />
This script is called test-nap. It takes a single argument, which is the name of the bridge device. So in our case we would first need to chmod +x the file (to make it executable), then run it like this: <pre>./test-nap br1</pre></p>
<div class="snippet"><pre><code>#!/usr/bin/python

import sys
import time
import dbus
from optparse import OptionParser, make_option

bus = dbus.SystemBus()

manager = dbus.Interface(bus.get_object(&quot;org.bluez&quot;, &quot;/&quot;),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;org.bluez.Manager&quot;)

option_list = [
&nbsp;&nbsp;&nbsp;&nbsp;make_option(&quot;-i&quot;, &quot;--device&quot;, action=&quot;store&quot;,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;type=&quot;string&quot;, dest=&quot;dev_id&quot;),
&nbsp;&nbsp;&nbsp;&nbsp;]
parser = OptionParser(option_list=option_list)

(options, args) = parser.parse_args()

if options.dev_id:
&nbsp;&nbsp;adapter_path = manager.FindAdapter(options.dev_id)
else:
&nbsp;&nbsp;adapter_path = manager.DefaultAdapter()

server = dbus.Interface(bus.get_object(&quot;org.bluez&quot;, adapter_path),
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;org.bluez.NetworkServer&quot;)

service = &quot;nap&quot;

if (len(args) &lt; 1):
&nbsp;&nbsp;bridge = &quot;tether&quot;
else:
&nbsp;&nbsp;bridge = args[0]

server.Register(service, bridge)

print &quot;Server for %s registered for %s&quot; % (service, bridge)

print &quot;Press CTRL-C to disconnect&quot;

try:
&nbsp;&nbsp;time.sleep(1000)
&nbsp;&nbsp;print &quot;Terminating connection&quot;
except:
&nbsp;&nbsp;pass

server.Unregister(service)</code></pre></div>
<p>After this, you can search from the client to see if the NAP service can be discovered with the command:<br />
<pre>sdptool search NAP</pre><br />
You should be able to see the NAP service from your server machine at this point.</p>
<p>The last thing to do is edit the /etc/network/interfaces file on the client side (the device which will connect to the Internet via Bluetooth. When pand connects, it uses a bnep0 interface. You need to add the following to your file:<br />
<pre>iface bnep0 inet dhcp</pre></p>
<p>Now we are ready to connect. This is how you connect:<br />
<pre><pre>pand -c &lt;mac address of your server BT device&gt;
sudo ifup bnep0</pre></pre></p>
<h3>Links:</h3>
<ul style="margin-left: 15px;">
<li><a href="http://global.hkepc.com/forum/redirect.php?tid=1710030&#038;goto=lastpost">http://global.hkepc.com/forum/redirect.php?tid=1710030&#038;goto=lastpost</a></li>
<li><a href="https://www.linux.com/learn/tutorials/346552-personal-area-networking-with-bluetooth">https://www.linux.com/learn/tutorials/346552-personal-area-networking-with-bluetooth</a></li>
<li><a href="http://ubuntuforums.org/showthread.php?t=1632825">http://ubuntuforums.org/showthread.php?t=1632825</a></li>
<li><a href="http://forum.doozan.com/read.php?2,2698">http://forum.doozan.com/read.php?2,2698</a></li>
<li><a href="http://xn--9bi.net/2009/06/17/tethering-iphone-3-0-to-ubuntu-9-04/">http://xn--9bi.net/2009/06/17/tethering-iphone-3-0-to-ubuntu-9-04/</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.jasonernst.com/2011/11/29/creating-a-bluetooth-access-point-nap-in-ubuntu-11-10/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>uShare autostart &#8211; Ubuntu 11.04</title>
		<link>http://www.jasonernst.com/2011/07/17/ushare-autostart-ubuntu-11-04/</link>
		<comments>http://www.jasonernst.com/2011/07/17/ushare-autostart-ubuntu-11-04/#comments</comments>
		<pubDate>Sun, 17 Jul 2011 14:34:29 +0000</pubDate>
		<dc:creator>Jason Ernst</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[autostart]]></category>
		<category><![CDATA[Ubuntu 11.04]]></category>
		<category><![CDATA[ushare]]></category>

		<guid isPermaLink="false">http://www.jasonernst.com/?p=1687</guid>
		<description><![CDATA[Previously, I installed ushare easily on Ubuntu following a process similar to this: https://help.ubuntu.com/community/Xbox360Media I&#8217;ve recently become annoyed that ushare hasn&#8217;t been autostarting in Ubuntu 11.04. I suspect it may have something to do with the fact that I am using the same machine to host vpn so I have a bridged connection br0 as [...]]]></description>
			<content:encoded><![CDATA[<p>Previously, I installed ushare easily on Ubuntu following a process similar to this: <a href="https://help.ubuntu.com/community/Xbox360Media">https://help.ubuntu.com/community/Xbox360Media</a></p>
<p>I&#8217;ve recently become annoyed that ushare hasn&#8217;t been autostarting in Ubuntu 11.04. I suspect it may have something to do with the fact that I am using the same machine to host vpn so I have a bridged connection br0 as my main connection. The default script in /etc/init.d/ushare should be able to autostart, and I have tried adding it to rc.d using variation of this command &#8220;sudo update-rc.d ushare defaults 80&#8243;, however it fails to start. I have no trouble running it manually with the &#8220;/etc/init.d/ushare start&#8221; command however. So I&#8217;m guessing it is just trying to start before the network interfaces come up and failing. The workaround I found tries to solve this by explicitly running after the interface is up. The way to do it, is to add it to the &#8220;/etc/network/interfaces&#8221; file using something called &#8220;post-up&#8221;. Since I wanted to have ushare run after my br0 interface is brought up, I added it like at the bottom of the br0 section, see below:</p>
<div class="snippet"><pre><code>iface br0 inet static
&nbsp;&nbsp;address 192.168.0.198
&nbsp;&nbsp;netmask 255.255.255.0
&nbsp;&nbsp;gateway 192.168.0.1
&nbsp;&nbsp;bridge_ports eth1
&nbsp;&nbsp;post-up /etc/init.d/ushare start
</code></pre></snippet></p>
<p>And, now on restart &#8220;ps ax | grep ushare&#8221; shows the process running. I am also able to connect on my xbox just as before <img src='http://www.jasonernst.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Sources: <a href="http://www.cyberciti.biz/tips/how-do-i-run-firewall-script-as-soon-as-eth0-interface-brings-up.html">http://www.cyberciti.biz/tips/how-do-i-run-firewall-script-as-soon-as-eth0-interface-brings-up.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.jasonernst.com/2011/07/17/ushare-autostart-ubuntu-11-04/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MediaWiki + Ubuntu 11.04 &amp; Customizations</title>
		<link>http://www.jasonernst.com/2011/07/05/mediawiki-ubuntu-11-04-customizations/</link>
		<comments>http://www.jasonernst.com/2011/07/05/mediawiki-ubuntu-11-04-customizations/#comments</comments>
		<pubDate>Tue, 05 Jul 2011 21:03:03 +0000</pubDate>
		<dc:creator>Jason Ernst</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[customize]]></category>
		<category><![CDATA[HowTo]]></category>
		<category><![CDATA[mediawiki]]></category>
		<category><![CDATA[Ubuntu 11.04]]></category>

		<guid isPermaLink="false">http://www.jasonernst.com/?p=1663</guid>
		<description><![CDATA[Recently, I setup a personal wiki for myself since I&#8217;m always encountering more information than I have time to read, but always want to go back later. Its also a way for me to organize topics I don&#8217;t know as much about as I&#8217;d like so that I can remember to come back to those [...]]]></description>
			<content:encoded><![CDATA[<p>Recently, I setup a personal wiki for myself since I&#8217;m always encountering more information than I have time to read, but always want to go back later. Its also a way for me to organize topics I don&#8217;t know as much about as I&#8217;d like so that I can remember to come back to those areas later on. (Inspired by fellow UoG Student Eddia Ma: <a href="http://eddiema.ca/wiki/" title="Eddie Ma - Wiki">http://eddiema.ca/wiki/</a>) The default install from Ubuntu is pretty simple. I just installed it with the expected:</p>
<div class="snippet"><code>sudo apt-get install mediawiki</code></div>
<p>There are some simple steps to follow as you install with the package manager such as setting up the database and first configuration which should be easy enough to get through. However, the wiki required much customization before it would be good for what I was planning on using it for. </p>
<h2>Citation Support</h2>
<p>First of all, it had to support citations so that I could source the original papers, websites and others. This required the <a href="http://www.mediawiki.org/wiki/Extension:Cite/Cite.php" title="Cite Extension" target="_blank">Cite Extension</a> which can be downloaded here: <a href="http://www.mediawiki.org/wiki/Special:ExtensionDistributor/Cite" title="Cite Extension Download" target="_blank">http://www.mediawiki.org/wiki/Special:ExtensionDistributor/Cite</a> (make sure you select the version that corresponds to the mediawiki version you have installed. Next extract to your extensions folder (likely /var/lib/mediawiki/extensions/ on Ubuntu 11.04). Finally add the following line to your mediawiki configuration file LocalSettings.php (likely in /etc/mediawiki).</p>
<div class="snippet"><code>require_once(&quot;$IP/extensions/Cite/Cite.php&quot;);</code></div>
<h2>Attachments</h2>
<p>I wanted to be able to attach papers directly into my wiki (pdfs and other documents from academic papers). For this I had to add the following line to my LocalSettings.php file (likely in /etc/mediawiki):</p>
<div class="snippet"><code>$wgFileExtensions = array(&#039;png&#039;,&#039;gif&#039;,&#039;jpg&#039;,&#039;jpeg&#039;,&#039;doc&#039;,&#039;xls&#039;,&#039;mpp&#039;,&#039;pdf&#039;,&#039;ppt&#039;,&#039;tiff&#039;,&#039;bmp&#039;,&#039;docx&#039;, &#039;xlsx&#039;, &#039;pptx&#039;,&#039;ps&#039;,&#039;odt&#039;,&#039;ods&#039;,&#039;odp&#039;,&#039;odg&#039;);</code></div>
<p>Additionally, I encountered problems uploading many larger pdfs since they are larger than the default php upload size. In ubuntu, this can be changed by modifying the php.ini file (likely located in /etc/php5/apache). Look for &#8216;upload_max_filesize&#8217; and &#8216;post_max_size&#8217; in order to change this to whatever size you like.</p>
<h2>Math!</h2>
<p>Of course being a CS student, I need to be able to add math equations into my wiki. The math formulas are entered using Latex which most CS grad students (and many undergrads) should know how to use. This one is in the Ubuntu repositories so it is easy to do:</p>
<div class="snippet"><code>sudo apt-get install mediawiki-math</code></div>
<p>Then you have to edit the LocalSettings.php file again (/etc/mediawiki) so that the wgUseTex flag is true:</p>
<div class="snippet"><code>$wgUseTeX&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = true;</code></div>
<h2>Source Code &#8211; Syntax Highlighting</h2>
<p>Again since I am a CS student, my wiki <em>needs</em> to be able to display source code easily in a readable way. For this I use the Ubuntu package manager again:</p>
<div class="snippet"><code>sudo apt-get install mediawiki-extensions-geshi</code></div>
<p>And edit the LocalSettings.php file (/etc/mediawiki) &#8211; For some reason, other instructions I have online have different paths and names for the plugin, so this will only work using the plugin from the repository. If you download it yourself directly, the name and location may be different:</p>
<div class="snippet"><code>require_once(&quot;$IP/extensions/SyntaxHighlight_GeSHi/SyntaxHighlight_GeSHi.php&quot;);</code></div>
<h2>Wiki Privacy</h2>
<p>Lastly, as I previously mentioned the wiki is private (at least for now). To do this it is quite simple. Just paste this into the bottom of your LocalSettings.php file. (There are other variations on how private you can make the wiki, but if you want to do that, check out the official mediawiki page)</p>
<div class="snippet"><pre><code># Disable reading by anonymous users
# See: http://www.mediawiki.org/wiki/Manual:Preventing_access#Restrict_viewing_of_all_pages
$wgGroupPermissions[&#039;*&#039;][&#039;read&#039;] = false;

# But allow them to access the login page or else there will be no way to log in!
# NOTE: You also need to provide access here to the .css and .js files that the
# allowed pages attempt to load; otherwise, users will get errors on the page
# when they attempt to load it (IE will complain about the errors;
# FF will show them in its error console)
# [You also might want to add access to &quot;Main Page&quot;, &quot;Wikipedia:Help&quot;, etc.)
$wgWhitelistRead = array (&quot;Special:Userlogin&quot;, &quot;MediaWiki:Common.css&quot;,
&quot;MediaWiki:Common.js&quot;, &quot;MediaWiki:Monobook.css&quot;, &quot;MediaWiki:Monobook.js&quot;, &quot;-&quot;);

# Disable anonymous editing
$wgGroupPermissions[&#039;*&#039;][&#039;edit&#039;] = false;

# Prevent new user registrations except by sysops
$wgGroupPermissions[&#039;*&#039;][&#039;createaccount&#039;] = false;
</code></pre></div>
]]></content:encoded>
			<wfw:commentRss>http://www.jasonernst.com/2011/07/05/mediawiki-ubuntu-11-04-customizations/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Ubuntu 11.04 &#8211; WordPress updates and plugins through web interface</title>
		<link>http://www.jasonernst.com/2011/05/12/ubuntu-11-04-wordpress-updates-and-plugins-through-web-interface/</link>
		<comments>http://www.jasonernst.com/2011/05/12/ubuntu-11-04-wordpress-updates-and-plugins-through-web-interface/#comments</comments>
		<pubDate>Thu, 12 May 2011 16:54:52 +0000</pubDate>
		<dc:creator>Jason Ernst</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[11.04]]></category>
		<category><![CDATA[Plugins]]></category>
		<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[Updates]]></category>
		<category><![CDATA[Wordpress]]></category>

		<guid isPermaLink="false">http://www.jasonernst.com/?p=1603</guid>
		<description><![CDATA[If you have found this page, you likely know it is a bit of a pain to get updates and plugin installs to work within WordPress and a vanilla Ubuntu install. So this post a quickie to tell about what setup I am using to get it work. First, the ftp server I am using. [...]]]></description>
			<content:encoded><![CDATA[<p>If you have found this page, you likely know it is a bit of a pain to get updates and plugin installs to work within WordPress and a vanilla Ubuntu install. So this post a quickie to tell about what setup I am using to get it work.</p>
<p>First, the ftp server I am using. I tried vsftpd, but got lots of permissions problems when I tried to apply the updates or install patches. I played around with permissions and owners for a bit, but gave up.</p>
<p>Instead I tried proftpd, but it was also a pain to get working at first. It turns out, it worked fine once I changed the server type from &#8220;inet&#8221; to &#8220;standalone&#8221; in the /etc/proftpd/proftpd.conf file!</p>
<p>For permissions, I added my own user to the www-data group and then just give my login information to the wordpress interface to install the updates. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.jasonernst.com/2011/05/12/ubuntu-11-04-wordpress-updates-and-plugins-through-web-interface/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PHP Tutorial: Replace long link text</title>
		<link>http://www.jasonernst.com/2011/03/22/php-tutorial-replace-long-link-text/</link>
		<comments>http://www.jasonernst.com/2011/03/22/php-tutorial-replace-long-link-text/#comments</comments>
		<pubDate>Tue, 22 Mar 2011 17:07:40 +0000</pubDate>
		<dc:creator>Jason Ernst</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Facebook Status]]></category>
		<category><![CDATA[Link]]></category>
		<category><![CDATA[Long]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[Replacement]]></category>
		<category><![CDATA[Text]]></category>
		<category><![CDATA[Tweet]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.jasonernst.com/?p=1549</guid>
		<description><![CDATA[I created this function so that I could have a way of preventing very long non-breaking text links from breaking my web page layout. Paritcularly, this is used in my tweet / facebook section of my homepage. Whenever I posted a link to either of them, when the link URL was too long and could [...]]]></description>
			<content:encoded><![CDATA[<p>I created this function so that I could have a way of preventing very long non-breaking text links from breaking my web page layout. Paritcularly, this is used in my tweet / facebook section of my homepage. Whenever I posted a link to either of them, when the link URL was too long and could not be broken, it would overflow into the next column. Yes of course you could use css to do this, however the methods which are generally used are not valid with CSS2.1, so I came up with a way that programatically parses the link and replaces the text with &#8220;[Link]&#8220;. There are some limitations to this approach. First, since I use a simple solution, there is no way to preserve some information normally in the link such as target, title etc. Second it is being used for tweet and facebook statuses, so it is limited to checking only the first encountered link. It could be expanded to include multiple links, but I have no need for this at the moment so I left it out. <strong>Update:</strong> I noticed that it was also filtering my @links from twitter, so I made a slight change so that it will only shorten if it finds http:// in the url text now. Anyway here is the code:</p>
<div class="snippet"><pre><code>/*
 * Replaces all link-text with &#039;[Link]&#039; so that links which are very long do not break web page layouts
 * Note: some information is lost, such as custom title, target etc.
 * Jason Ernst- 2011
 */
function filter_long_url($content)
{
&nbsp;&nbsp;$startpos = strpos($content, &quot;&lt;a&quot;);
&nbsp;&nbsp;if($startpos !== false)
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;$midpos = strpos($content, &quot;&gt;&quot;, $startpos);
&nbsp;&nbsp;&nbsp;&nbsp;if($midpos !== false)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$endpos = strpos($content, &quot;&lt;/a&gt;&quot;, $midpos);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if($endpos !== false)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$url = substr($content, $midpos+1, ($endpos)-($midpos+1));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(strpos($url, &quot;http://&quot;)===false)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return $content;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$newcontent = substr($content, 0, $startpos);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$newcontent = $newcontent . &quot;&lt;a href=&#039;$url&#039; title=&#039;View Link&#039; target=&#039;_blank&#039;&gt;[Link]&lt;/a&gt;&quot; . substr($content, $endpos+4);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return $content;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return $content;
&nbsp;&nbsp;}
&nbsp;&nbsp;else
&nbsp;&nbsp;&nbsp;&nbsp;return $content;
&nbsp;&nbsp;
&nbsp;&nbsp;return $newcontent;
}</code></pre></div>
<p>If the function gets something with a half-completed <a> tag, it should just return the original content since it is impossible to find the other parts of the tag correctly.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jasonernst.com/2011/03/22/php-tutorial-replace-long-link-text/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WordPress Tutorial: Recent Posts Block with Images</title>
		<link>http://www.jasonernst.com/2011/03/22/wordpress-tutorial-recent-posts-block-with-images/</link>
		<comments>http://www.jasonernst.com/2011/03/22/wordpress-tutorial-recent-posts-block-with-images/#comments</comments>
		<pubDate>Tue, 22 Mar 2011 16:00:56 +0000</pubDate>
		<dc:creator>Jason Ernst</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[featured]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[Posts]]></category>
		<category><![CDATA[Recent]]></category>
		<category><![CDATA[Wordpress]]></category>
		<category><![CDATA[xhtml]]></category>

		<guid isPermaLink="false">http://www.jasonernst.com/?p=1528</guid>
		<description><![CDATA[This post follows up on the last WordPress tutorial which shows how to start using featured images. In this post, I show how you can display a block of recent posts along with the featured image, in the same way as my website. (See the bottom of the home page, or the bottom of individual [...]]]></description>
			<content:encoded><![CDATA[<p>This post follows up on the last WordPress tutorial which shows how to start <a href="http://www.jasonernst.com/2011/02/28/wordpress-tutorial-featured-images/">using featured images</a>. In this post, I show how you can display a block of recent posts along with the featured image, in the same way as my website. (See the bottom of the home page, or the bottom of individual posts).</p>
<p>You will likely need to play around with the styling (margins, padding, etc.) a bit to fit with your own templates, but this should give you a good start. This assumes that you have setup thumbnails for &#8220;mini-thumbnail&#8221; (see <a href="http://www.jasonernst.com/2011/02/28/wordpress-tutorial-featured-images/">previous tutorial</a> on how to do that). You can play around with how many posts you want to display using posts_per_page below.</p>
<p><center>
<div class="image"><a href="http://www.jasonernst.com/wp-content/uploads/2011/03/recent-articles.png"><img src="http://www.jasonernst.com/wp-content/uploads/2011/03/recent-articles-300x73.png" alt="" title="recent-articles" width="300" height="73" class="aligncenter size-medium wp-image-1537" /></a><br/>What the recent posts block will look something like</div>
<p></center></p>
<p>The first thing to pay attention to is the shorten_content function. This ensures that the content is not too long to display within the limited area we have. You can put this directly in the template file you are editing if you like, but I put mine in the functions.php file for the particular template.</p>
<div class="snippet"><pre><code>&lt;?
/*
 * Returns a shortened $content with &#039;...&#039; appended to the end. Also
 * removes any breaks in the content
 * 
 * todo: ensure we do not cut off html tags part way through and break the theme
 */
function shorten_content($content, $size)
{
&nbsp;&nbsp;//$content = preg_replace(&quot;/(\&lt;br\/\&gt;)|(\&lt;br\&gt;)|(\&lt;br \/\&gt;)/&quot;, &quot; &quot;, $content);
&nbsp;&nbsp;$content = strip_tags($content);
&nbsp;&nbsp;if(strlen($content) &lt; $size)
&nbsp;&nbsp;&nbsp;&nbsp;return $content;
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;$content = substr($content, 0, $size);
&nbsp;&nbsp;$spaceloc = strrpos($content, &quot; &quot;);
&nbsp;&nbsp;if($spaceloc)
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;$content = substr($content, 0, $spaceloc);
&nbsp;&nbsp;&nbsp;&nbsp;$content.= &quot;...&quot;;
&nbsp;&nbsp;}
&nbsp;&nbsp;return $content;
}
?&gt;</code></pre></div>
<p>Next we reset the query so that we can make a new query with the number of posts we would like and how we want to order them. For recent posts, we order by date and in this case we are showing 6 posts. Also one spot to pay attention to is the $count checking. You will notice when $count = 3, a clearing div is displayed. This controls how many recent posts to show per line. You can change this number to get more or less on one line.</p>
<div class="snippet"><pre><code>&lt;h1&gt;Recent Articles&lt;/h1&gt;
&lt;?
&nbsp;&nbsp;wp_reset_query();
&nbsp;&nbsp;query_posts(array(&quot;orderby&quot; =&gt; &quot;date&quot;, &quot;order&quot; =&gt; &quot;DESC&quot;, &quot;offset&quot; =&gt; 1, &quot;posts_per_page&quot; =&gt; 6));
&nbsp;&nbsp;if(have_posts())
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$count = 0;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(have_posts())
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $count++;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; the_post();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $postthumbnail = get_the_post_thumbnail($post-&gt;ID, &#039;mini-thumbnail&#039;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(!isset($postthumbnail) || $postthumbnail == &quot;&quot;)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $postthumbnail = &#039;&lt;img src=&quot;&#039;.get_bloginfo(&#039;stylesheet_directory&#039;).&#039;/img/default-thumb.jpg&quot; alt=&quot;&#039;. get_the_title() .&#039;&quot; style=&quot;border: 1px solid #333333;&quot;/&gt;&#039;;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ?&gt;&lt;div class=&quot;recent-entry&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;div style=&quot;float:left;&quot;&gt;&lt;a href=&quot;&lt;? the_permalink() ?&gt;&quot; title=&quot;&lt;?=get_the_title()?&gt;&quot;&gt;&lt;?=$postthumbnail?&gt;&lt;/a&gt;&lt;/div&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h2&gt;&lt;a href=&quot;&lt;? the_permalink() ?&gt;&quot; title=&quot;&lt;?=get_the_title()?&gt;&quot;&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;?=shorten_content(get_the_title(), 60)?&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/a&gt;&lt;/h2&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;p class=&quot;date&quot;&gt;&lt;? the_time(&#039;F j, Y&#039;); ?&gt;&lt;/p&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;p class=&quot;content&quot;&gt;&lt;?=shorten_content(get_the_content(), 75)?&gt;&lt;/p&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/div&gt;&lt;?
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if($count == 3)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{?&gt;&lt;div class=&quot;clear&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;?}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
&nbsp;&nbsp; }
?&gt;</code></pre></div>
<p>The last thing we need is the css to style things. This is likely where you will need to change things to suit your own site.</p>
<div class="snippet"><pre><code>.recent-entry { float:left; width: 30%; //change this width depending on how many entries you want on one line.}
.recent-entry h2 { font-size: 14px; }
.recent-entry img { padding-right: 2px; }
.recent-entry date { font-size: 9px; color: #333333; }
.recent-entry content { font-size: 10px; }
</code></pre></div>
]]></content:encoded>
			<wfw:commentRss>http://www.jasonernst.com/2011/03/22/wordpress-tutorial-recent-posts-block-with-images/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Tutorial: sockets &#8211; 3 ways to listen</title>
		<link>http://www.jasonernst.com/2011/03/22/tutorial-sockets-3-ways-to-listen/</link>
		<comments>http://www.jasonernst.com/2011/03/22/tutorial-sockets-3-ways-to-listen/#comments</comments>
		<pubDate>Tue, 22 Mar 2011 14:53:27 +0000</pubDate>
		<dc:creator>Jason Ernst</dc:creator>
				<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Networking]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[c]]></category>
		<category><![CDATA[Client]]></category>
		<category><![CDATA[fork()]]></category>
		<category><![CDATA[forking]]></category>
		<category><![CDATA[Jason B. Ernst]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[select()]]></category>
		<category><![CDATA[Server]]></category>
		<category><![CDATA[socket()]]></category>
		<category><![CDATA[source]]></category>
		<category><![CDATA[system]]></category>

		<guid isPermaLink="false">http://www.jasonernst.com/?p=1507</guid>
		<description><![CDATA[As you may know, I have been ta-ing a course in operating systems. We just finished covering sockets and in the last lab I gave a socket demo where I show three different ways a server can listen on a socket. First is a very basic case where the server can only accept and process [...]]]></description>
			<content:encoded><![CDATA[<p>As you may know, I have been ta-ing a course in operating systems. We just finished covering sockets and in the last lab I gave a socket demo where I show three different ways a server can listen on a socket. First is a very basic case where the server can only accept and process one connection at a time. Second I show the fork()ing case where multiple connections can be processed concurrently using multiple processes. Lastly, the multiple connection case is handled with select() so that everything can be handled in a single connection.</p>
<p><strong>Single connection server</strong><br />
This server is a basic echo server. A client connects to it on a specific port and enters strings on the stdin. The server maintains the connection until the client terminates the connection with a blank line.</p>
<p>The major weakness of this server is that it can only handle a single connection at once. So if the first connection is very slow, any subsequent connections must wait, even if they are ready to be handled. In the case of this server, the first user to connect may be very slow to type their strings, and even if the second user has already entered a string, it will not be displayed until the first user connection in completed.</p>
<p><center>
<div class="image"><a href="http://www.jasonernst.com/wp-content/uploads/2011/03/server.png"><img src="http://www.jasonernst.com/wp-content/uploads/2011/03/server-300x225.png" alt="" title="server" width="300" height="225" class="aligncenter size-medium wp-image-1519" /><br/>Single connection server</a></div>
<p></center></p>
<div class="snippet"><pre><code>#include &lt;sys/types.h&gt;
#include &lt;sys/socket.h&gt;
#include &lt;netinet/in.h&gt;
#include &lt;unistd.h&gt;
#include &lt;netdb.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;stdio.h&gt;
#include &lt;errno.h&gt;
#include &lt;string.h&gt;

#define ERROR(x) do { perror(x); exit(1); } while(0)

#define NAME&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 257
#define BUFSIZE&nbsp;&nbsp;&nbsp;&nbsp;257
#define MAXPENDING 1

int main(int argc, char *argv[])
{
&nbsp;&nbsp;unsigned short port;&nbsp;&nbsp;&nbsp;&nbsp;/* Port to which server will bind */
&nbsp;&nbsp;char servhost[NAME];&nbsp;&nbsp;&nbsp;&nbsp;/* Local host name */
&nbsp;&nbsp;struct sockaddr_in sock;&nbsp;&nbsp;/* INTERNET socket space */
&nbsp;&nbsp;struct hostent *server;&nbsp;&nbsp;&nbsp;&nbsp;/* Local host information */
&nbsp;&nbsp;int S;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* fd for socket */
&nbsp;&nbsp;int NS;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* fd for connected socket */
&nbsp;&nbsp;char buf[BUFSIZE];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* Input buffer */
&nbsp;&nbsp;FILE *fp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* Stream (converted file des.) */

&nbsp;&nbsp;if (argc != 2)
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr,&quot;usage: server &lt;port&gt;\n&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;exit(1);
&nbsp;&nbsp;}

&nbsp;&nbsp;port = atoi(argv[1]);

&nbsp;&nbsp;/*
&nbsp;&nbsp; * Get socket - INTERNET DOMAIN - TCP
&nbsp;&nbsp; */
&nbsp;&nbsp;if ((S = socket(AF_INET, SOCK_STREAM, 0)) &lt; 0)
&nbsp;&nbsp;&nbsp;&nbsp;ERROR(&quot;server: socket&quot;);

&nbsp;&nbsp;/*
&nbsp;&nbsp; * Obtain host name &amp; network address
&nbsp;&nbsp; */
&nbsp;&nbsp;gethostname(servhost, sizeof(servhost));
&nbsp;&nbsp;if ((server = gethostbyname(servhost)) == NULL)
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr,&quot;%s: unknown host\n&quot;,servhost);
&nbsp;&nbsp;&nbsp;&nbsp;exit(1);
&nbsp;&nbsp;}

&nbsp;&nbsp;/*
&nbsp;&nbsp; * Bind to server address - in network byte order
&nbsp;&nbsp; */
&nbsp;&nbsp;sock.sin_family = AF_INET;
&nbsp;&nbsp;sock.sin_port = htons(port);
&nbsp;&nbsp;memcpy(&amp;sock.sin_addr, server-&gt;h_addr, server-&gt;h_length);

&nbsp;&nbsp;/*
&nbsp;&nbsp; * Bind socket to port/addr
&nbsp;&nbsp; */
&nbsp;&nbsp;if (bind(S, (struct sockaddr *)&amp;sock, sizeof(sock)) &lt; 0)
&nbsp;&nbsp;&nbsp;&nbsp;ERROR(&quot;server: bind&quot;);

&nbsp;&nbsp;/*
&nbsp;&nbsp; * Listen on this socket
&nbsp;&nbsp; */
&nbsp;&nbsp;if (listen(S,MAXPENDING) &lt; 0)
&nbsp;&nbsp;&nbsp;&nbsp;ERROR(&quot;server: listen&quot;);
&nbsp;&nbsp;
&nbsp;&nbsp;
&nbsp;&nbsp;//loop to continue handling connections
&nbsp;&nbsp;while(1)
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;/*
&nbsp;&nbsp;&nbsp;&nbsp; * Accept connections.&nbsp;&nbsp;Once connected, the client will be
&nbsp;&nbsp;&nbsp;&nbsp; * connected on fd NS, a second and third parameter may be passed
&nbsp;&nbsp;&nbsp;&nbsp; * to accept which will be filled in with information regarding the
&nbsp;&nbsp;&nbsp;&nbsp; * client connection if desired.
&nbsp;&nbsp;&nbsp;&nbsp; *
&nbsp;&nbsp;&nbsp;&nbsp; * In this example, once connected the server is done with the
&nbsp;&nbsp;&nbsp;&nbsp; * master socket (so closes it).
&nbsp;&nbsp;&nbsp;&nbsp; */
&nbsp;&nbsp;&nbsp;&nbsp;if ((NS = accept(S,NULL,NULL)) &lt; 0)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ERROR(&quot;server: accept&quot;);

&nbsp;&nbsp;&nbsp;&nbsp;/*
&nbsp;&nbsp;&nbsp;&nbsp; * Using stdio library to read from socket
&nbsp;&nbsp;&nbsp;&nbsp; */
&nbsp;&nbsp;&nbsp;&nbsp;if (!(fp = fdopen(NS,&quot;r&quot;)))
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr,&quot;&gt;&gt;&gt; Error converting file des. to stream &lt;&lt;&lt;\n&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(1);
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;while (fgets(buf,BUFSIZE,fp))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;%s&quot;, buf);

&nbsp;&nbsp;&nbsp;&nbsp;/*
&nbsp;&nbsp;&nbsp;&nbsp; * DONE - simply close() connection
&nbsp;&nbsp;&nbsp;&nbsp; */
&nbsp;&nbsp;&nbsp;&nbsp;fclose(fp);
&nbsp;&nbsp;&nbsp;&nbsp;close(NS);
&nbsp;&nbsp;}
&nbsp;&nbsp;
&nbsp;&nbsp;return(0);
}</code></pre></div>
<p><strong>fork() &#8211; Multiple connection, multiple process</strong><br />
In this case, the server can now handle multiple connections successfully. If the first connection has a long processing time or the user is slow at entering data, the second connection may now continue freely without waiting in line. The downside to this approach is: 1) If the server must handle a large number of connections simultaneously, the server may run out of processes since each connection fork()s. 2) Since a fork() call duplicates variables, file descriptors etc., the server may run out of memory if each connection requires any significant processing.</p>
<p>Notice that the processing portion of the code has been moved into a function which is called when the fork() is executing within the child processes.</p>
<p><center>
<div class="image"><a href="http://www.jasonernst.com/wp-content/uploads/2011/03/fork-server.png"><img src="http://www.jasonernst.com/wp-content/uploads/2011/03/fork-server-300x236.png" alt="" title="fork-server" width="300" height="236" class="aligncenter size-medium wp-image-1517" /></a><br/>Fork Server</div>
<p></center></p>
<div class="snippet"><pre><code>#include &lt;sys/types.h&gt;
#include &lt;sys/socket.h&gt;
#include &lt;netinet/in.h&gt;
#include &lt;unistd.h&gt;
#include &lt;netdb.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;stdio.h&gt;
#include &lt;errno.h&gt;
#include &lt;string.h&gt;

#define ERROR(x) do { perror(x); exit(1); } while(0)

#define NAME&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 257
#define BUFSIZE&nbsp;&nbsp;&nbsp;&nbsp;257
#define MAXPENDING 1

void handle_connection(int NS);

int main(int argc, char *argv[])
{
&nbsp;&nbsp;unsigned short port;&nbsp;&nbsp;&nbsp;&nbsp;/* Port to which server will bind */
&nbsp;&nbsp;char servhost[NAME];&nbsp;&nbsp;&nbsp;&nbsp;/* Local host name */
&nbsp;&nbsp;struct sockaddr_in sock;&nbsp;&nbsp;/* INTERNET socket space */
&nbsp;&nbsp;struct hostent *server;&nbsp;&nbsp;&nbsp;&nbsp;/* Local host information */
&nbsp;&nbsp;int S;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* fd for socket */
&nbsp;&nbsp;int NS;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* fd for connected socket */
&nbsp;&nbsp;int pid;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* used to determine parent or child */

&nbsp;&nbsp;if (argc != 2)
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr,&quot;usage: fork-server &lt;port&gt;\n&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;exit(1);
&nbsp;&nbsp;}

&nbsp;&nbsp;port = atoi(argv[1]);

&nbsp;&nbsp;/*
&nbsp;&nbsp; * Get socket - INTERNET DOMAIN - TCP
&nbsp;&nbsp; */
&nbsp;&nbsp;if ((S = socket(AF_INET, SOCK_STREAM, 0)) &lt; 0)
&nbsp;&nbsp;&nbsp;&nbsp;ERROR(&quot;fork-server: socket&quot;);

&nbsp;&nbsp;/*
&nbsp;&nbsp; * Obtain host name &amp; network address
&nbsp;&nbsp; */
&nbsp;&nbsp;gethostname(servhost, sizeof(servhost));
&nbsp;&nbsp;if ((server = gethostbyname(servhost)) == NULL)
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr,&quot;%s: unknown host\n&quot;,servhost);
&nbsp;&nbsp;&nbsp;&nbsp;exit(1);
&nbsp;&nbsp;}

&nbsp;&nbsp;/*
&nbsp;&nbsp; * Bind to server address - in network byte order
&nbsp;&nbsp; */
&nbsp;&nbsp;sock.sin_family = AF_INET;
&nbsp;&nbsp;sock.sin_port = htons(port);
&nbsp;&nbsp;memcpy(&amp;sock.sin_addr, server-&gt;h_addr, server-&gt;h_length);

&nbsp;&nbsp;/*
&nbsp;&nbsp; * Bind socket to port/addr
&nbsp;&nbsp; */
&nbsp;&nbsp;if (bind(S, (struct sockaddr *)&amp;sock, sizeof(sock)) &lt; 0)
&nbsp;&nbsp;&nbsp;&nbsp;ERROR(&quot;server: bind&quot;);

&nbsp;&nbsp;/*
&nbsp;&nbsp; * Listen on this socket
&nbsp;&nbsp; */
&nbsp;&nbsp;if (listen(S,MAXPENDING) &lt; 0)
&nbsp;&nbsp;&nbsp;&nbsp;ERROR(&quot;server: listen&quot;);
&nbsp;&nbsp;
&nbsp;&nbsp;while(1)
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;/*
&nbsp;&nbsp;&nbsp;&nbsp; * Accept connections.&nbsp;&nbsp;Once connected, the client will be
&nbsp;&nbsp;&nbsp;&nbsp; * connected on fd NS, a second and third parameter may be passed
&nbsp;&nbsp;&nbsp;&nbsp; * to accept which will be filled in with information regarding the
&nbsp;&nbsp;&nbsp;&nbsp; * client connection if desired.
&nbsp;&nbsp;&nbsp;&nbsp; *
&nbsp;&nbsp;&nbsp;&nbsp; * In this example, once connected the server is done with the
&nbsp;&nbsp;&nbsp;&nbsp; * master socket (so closes it).
&nbsp;&nbsp;&nbsp;&nbsp; */
&nbsp;&nbsp;&nbsp;&nbsp;if ((NS = accept(S,NULL,NULL)) &lt; 0)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ERROR(&quot;server: accept&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;if((pid = fork()) &lt; 0)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ERROR(&quot;server: fork&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;if(pid == 0)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;handle_connection(NS);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(0);
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;close(NS);
&nbsp;&nbsp;}

&nbsp;&nbsp;return(0);
}

void handle_connection(int NS)
{
&nbsp;&nbsp;char buf[BUFSIZE];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* Input buffer */
&nbsp;&nbsp;FILE *fp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* Stream (converted file des.) */
&nbsp;&nbsp;
&nbsp;&nbsp;/*
&nbsp;&nbsp; * Using stdio library to read from socket
&nbsp;&nbsp; */
&nbsp;&nbsp;if (!(fp = fdopen(NS,&quot;r&quot;)))
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr,&quot;&gt;&gt;&gt; Error converting file des. to stream &lt;&lt;&lt;\n&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;exit(1);
&nbsp;&nbsp;}

&nbsp;&nbsp;while (fgets(buf,BUFSIZE,fp))
&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;%s&quot;, buf);

&nbsp;&nbsp;/*
&nbsp;&nbsp; * DONE - simply close() connection
&nbsp;&nbsp; */
&nbsp;&nbsp;fclose(fp);
&nbsp;&nbsp;close(NS);
}</code></pre></div>
<p><strong>select() &#8211; Multiple connection, single process</strong><br />
The last case still has the benefits of fork() but does so in a single process. In this case, select() is used. In this case, each socket descriptor is monitored by select which determines if any of the sockets are ready for I/O. Rather than sitting idly waiting for input on sockets that are not ready, data is processed as it arrives. The drawback to this approach is that it is little trickier to implement and understand, but if you start with a basic case like this it can be quite simple to get the hang of it. When using select(), we need to specify the groups of sockets we wish to monitor. This is done using the fd_set which you can see in the source.</p>
<p><center>
<div class="image"><a href="http://www.jasonernst.com/wp-content/uploads/2011/03/select-server.png"><img src="http://www.jasonernst.com/wp-content/uploads/2011/03/select-server-300x238.png" alt="" title="select-server" width="300" height="238" class="aligncenter size-medium wp-image-1520" /></a><br/>Select Server</div>
<p></center></p>
<div class="snippet"><pre><code>#include &lt;sys/types.h&gt;
#include &lt;sys/socket.h&gt;
#include &lt;netinet/in.h&gt;
#include &lt;unistd.h&gt;
#include &lt;netdb.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;stdio.h&gt;
#include &lt;errno.h&gt;
#include &lt;string.h&gt;

#define ERROR(x) do { perror(x); exit(1); } while(0)

#define NAME&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 257
#define BUFSIZE&nbsp;&nbsp;&nbsp;&nbsp;257
#define MAXPENDING 1

void handle_connection(int NS, fd_set * activefds);

int main(int argc, char *argv[])
{
&nbsp;&nbsp;fd_set readfds, activefds;&nbsp;&nbsp;/* the set of read descriptors */
&nbsp;&nbsp;unsigned short port;&nbsp;&nbsp;&nbsp;&nbsp;/* Port to which server will bind */
&nbsp;&nbsp;char servhost[NAME];&nbsp;&nbsp;&nbsp;&nbsp;/* Local host name */
&nbsp;&nbsp;struct sockaddr_in sock;&nbsp;&nbsp;/* INTERNET socket space */
&nbsp;&nbsp;struct hostent *server;&nbsp;&nbsp;&nbsp;&nbsp;/* Local host information */
&nbsp;&nbsp;int S;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* fd for socket */
&nbsp;&nbsp;int NS;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* fd for connected socket */
&nbsp;&nbsp;int i;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* counter to go through FDs in fdset */

&nbsp;&nbsp;if (argc != 2)
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr,&quot;usage: select-server &lt;port&gt;\n&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;exit(1);
&nbsp;&nbsp;}

&nbsp;&nbsp;port = atoi(argv[1]);

&nbsp;&nbsp;/*
&nbsp;&nbsp; * Get socket - INTERNET DOMAIN - TCP
&nbsp;&nbsp; */
&nbsp;&nbsp;if ((S = socket(AF_INET, SOCK_STREAM, 0)) &lt; 0)
&nbsp;&nbsp;&nbsp;&nbsp;ERROR(&quot;select-server: socket&quot;);

&nbsp;&nbsp;/*
&nbsp;&nbsp; * Obtain host name &amp; network address
&nbsp;&nbsp; */
&nbsp;&nbsp;gethostname(servhost, sizeof(servhost));
&nbsp;&nbsp;if ((server = gethostbyname(servhost)) == NULL)
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr,&quot;%s: unknown host\n&quot;,servhost);
&nbsp;&nbsp;&nbsp;&nbsp;exit(1);
&nbsp;&nbsp;}

&nbsp;&nbsp;/*
&nbsp;&nbsp; * Bind to server address - in network byte order
&nbsp;&nbsp; */
&nbsp;&nbsp;sock.sin_family = AF_INET;
&nbsp;&nbsp;sock.sin_port = htons(port);
&nbsp;&nbsp;memcpy(&amp;sock.sin_addr, server-&gt;h_addr, server-&gt;h_length);

&nbsp;&nbsp;/*
&nbsp;&nbsp; * Bind socket to port/addr
&nbsp;&nbsp; */
&nbsp;&nbsp;if (bind(S, (struct sockaddr *)&amp;sock, sizeof(sock)) &lt; 0)
&nbsp;&nbsp;&nbsp;&nbsp;ERROR(&quot;server: bind&quot;);

&nbsp;&nbsp;/*
&nbsp;&nbsp; * Listen on this socket
&nbsp;&nbsp; */
&nbsp;&nbsp;if (listen(S,MAXPENDING) &lt; 0)
&nbsp;&nbsp;&nbsp;&nbsp;ERROR(&quot;server: listen&quot;);
&nbsp;&nbsp;
&nbsp;&nbsp;/* Initialize the set of active sockets. */
&nbsp;&nbsp;&nbsp;&nbsp;FD_ZERO (&amp;activefds);
&nbsp;&nbsp;&nbsp;&nbsp;FD_SET (S, &amp;activefds);
&nbsp;&nbsp;
&nbsp;&nbsp;while(1)
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;/* Block until input arrives on one or more active sockets. */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;readfds = activefds;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (select (FD_SETSIZE, &amp;readfds, NULL, NULL, NULL) &lt; 0)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perror (&quot;select&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit (EXIT_FAILURE);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;/* Service all the sockets with input pending. */
&nbsp;&nbsp;&nbsp;&nbsp;for (i = 0; i &lt; FD_SETSIZE; ++i)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (FD_ISSET (i, &amp;readfds))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (i == S)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* Connection request on original socket. */

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Accept connections.&nbsp;&nbsp;Once connected, the client will be
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * connected on fd NS, a second and third parameter may be passed
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * to accept which will be filled in with information regarding the
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * client connection if desired.
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * In this example, once connected the server is done with the
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * master socket (so closes it).
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ((NS = accept(S,NULL,NULL)) &lt; 0)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ERROR(&quot;server: accept&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FD_SET(NS, &amp;activefds);&nbsp;&nbsp;//add the new socket desc to our active connections set
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* Data arriving on an already-connected socket. */
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;handle_connection(i, &amp;activefds);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;} /* //end of for */
&nbsp;&nbsp;} /* //end of while */

&nbsp;&nbsp;return(0);
}

void handle_connection(int NS, fd_set * activefds)
{
&nbsp;&nbsp;char buf[BUFSIZE];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* Input buffer */
&nbsp;&nbsp;FILE *fp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* Stream (converted file des.) */
&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;/*
&nbsp;&nbsp; * Using stdio library to read from socket
&nbsp;&nbsp; */
&nbsp;&nbsp;if (!(fp = fdopen(NS,&quot;r&quot;)))
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr,&quot;&gt;&gt;&gt; Error converting file des. to stream &lt;&lt;&lt;\n&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;exit(1);
&nbsp;&nbsp;}

&nbsp;&nbsp;//if fgets fails we have end of line, quit
&nbsp;&nbsp;if(!(fgets(buf,BUFSIZE,fp)))
&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;/*
&nbsp;&nbsp;&nbsp;&nbsp; * DONE - simply close() connection
&nbsp;&nbsp;&nbsp;&nbsp; */
&nbsp;&nbsp;&nbsp;&nbsp;fclose(fp);
&nbsp;&nbsp;&nbsp;&nbsp;close(NS);
&nbsp;&nbsp;&nbsp;&nbsp;FD_CLR(NS, activefds);
&nbsp;&nbsp;}
&nbsp;&nbsp;else
&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;%s&quot;, buf);
}</code></pre></div>
<p><strong>Additional Information</strong><br />
<a href="http://www.uoguelph.ca/~jernst/cis3110/cis3310-lab4.pdf">http://www.uoguelph.ca/~jernst/3110/cis3310-lab4.pdf</a><br />
<a href="http://www.socs.uoguelph.ca/~dbm/teaching/CIS3110/">http://www.socs.uoguelph.ca/~dbm/teaching/CIS3110/</a><br />
<a href="http://beej.us/guide/bgnet/">http://beej.us/guide/bgnet/</a><br />
manpages!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jasonernst.com/2011/03/22/tutorial-sockets-3-ways-to-listen/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>WordPress Tutorial: Featured Images</title>
		<link>http://www.jasonernst.com/2011/02/28/wordpress-tutorial-featured-images/</link>
		<comments>http://www.jasonernst.com/2011/02/28/wordpress-tutorial-featured-images/#comments</comments>
		<pubDate>Mon, 28 Feb 2011 16:02:05 +0000</pubDate>
		<dc:creator>Jason Ernst</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[featured]]></category>
		<category><![CDATA[image]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[Wordpress]]></category>
		<category><![CDATA[xhtml]]></category>

		<guid isPermaLink="false">http://www.jasonernst.com/?p=1415</guid>
		<description><![CDATA[This is a quick tutorial on how to get out featured images, which I use extensively on this blog (jasonernst.com). The featured image is what shows on the home page for the site, and on the individual entries. In the event that there is no featured image set for a given post, a default image [...]]]></description>
			<content:encoded><![CDATA[<p>This is a quick tutorial on how to get out featured images, which I use extensively on this blog (<a href="http://www.jasonernst.com">jasonernst.com</a>). The featured image is what shows on the home page for the site, and on the individual entries. In the event that there is no featured image set for a given post, a default image is displayed instead.</p>
<div class="image left" style="text-align:center;"><a href="http://www.jasonernst.com/wp-content/uploads/2011/02/featured-image.png"><img src="http://www.jasonernst.com/wp-content/uploads/2011/02/featured-image.png" alt="" title="featured-image" width="247" height="323" class="aligncenter size-full wp-image-1422" /></a><br/>An example of a featured image</div>
<p>For reference, I know this has worked since at least WordPress 3.0, but it may work with some earlier versions as well (I think earliest may be WP 2.9). This tutorial assumes you have some knowledge of how to work with php files, and have a basic idea of how WP templates work.</p>
<p><strong>Step 1: Thumbnail Sizes</strong><br />
You may wish to have some different thumbnail sizes from the usual ones which WordPress generates automatically. You can change this in Settings->Media and adjust the sizes to your liking. This will allow you to control the large, medium and thumbnail sizes. </p>
<p>Since WordPress 2.9, you can actually create your own image sizes and names using the <a href="http://codex.wordpress.org/Function_Reference/add_image_size">add_image_size function</a>. You can just add this into your functions.php file within your template. For example, my featured post thumbnail size is 240&#215;150 and I want the image to be cropped from the original (rather than stretched weirdly). </p>
<div class="clear">&nbsp;</div>
<p>This is what I added to my functions.php (note the check for the function, so that we don&#8217;t break older WP versions):</p>
<div class="snippet"><pre><code>if (function_exists(&#039;add_theme_support&#039;)) {
&nbsp;&nbsp;add_image_size(&#039;featured-thumbnail&#039;, 240, 150, true);
}</code></pre></div>
<p><strong>Step 2: Customize the template</strong><br />
Here we check if there are any thumbnails generated, and if not display the default image. You could also do other things, such as display nothing, or ignore the post altogether if there is no thumbnail image. This is an example of the main thumbnail I use for my featured article on my home page (in my home.php template file). If there is no featured image set for the post, it displays a default image found in the template&#8217;s &#8220;img&#8221; folder. Note: this is done within &#8220;the loop&#8221;.</p>
<div class="snippet"><pre><code>$postthumbnail = get_the_post_thumbnail($post-&gt;ID, &#039;single-post-thumbnail&#039;);
if(!isset($postthumbnail) || $postthumbnail == &quot;&quot;)
&nbsp;&nbsp;$postthumbnail = &#039;&lt;img src=&quot;&#039;.get_bloginfo(&#039;stylesheet_directory&#039;).&#039;/img/default.jpg&quot; alt=&quot;&#039;. get_the_title() .&#039;&quot;/&gt;&#039;;</code></pre></div>
<p><strong>Step 3: Add the thumbnail images to the posts</strong></p>
<p><center>
<div class="image" style="text-align:center;"><a href="http://www.jasonernst.com/wp-content/uploads/2011/02/featured-image-02.png"><img src="http://www.jasonernst.com/wp-content/uploads/2011/02/featured-image-02-300x209.png" alt="" title="featured-image-02" width="300" height="209" class="aligncenter size-medium wp-image-1423" /></a><br/>Click the featured image link to set an image as the featured image</div>
<p></center></p>
<p>This is the easy part, all you have to do is upload some images to the library. After the image you want is in the library you can select is using the &#8220;show&#8221; link and then use the link to select &#8220;set as featured image&#8221;. You should now see it show up in your template.</p>
<p>One last note, a useful plugin&#8230;especially when you are still working out the sizes of your images is the <a href="http://wordpress.org/extend/plugins/regenerate-thumbnails/">WordPress Regenerate Thumbnails plugin</a>. It will regenerate all of the images to the new size you have specified.</p>
<p><strong>Update:</strong> I have now added another related tutorial on how you can use <a href="http://www.jasonernst.com/2011/03/22/wordpress-tutorial-recent-posts-block-with-images/">featured images to display a block of recent articles alongside the image for each article</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jasonernst.com/2011/02/28/wordpress-tutorial-featured-images/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Sharethis WordPress Plugin &#8211; Invalid XHTML</title>
		<link>http://www.jasonernst.com/2011/02/21/sharethis-wordpress-plugin-invalid-xhtml/</link>
		<comments>http://www.jasonernst.com/2011/02/21/sharethis-wordpress-plugin-invalid-xhtml/#comments</comments>
		<pubDate>Tue, 22 Feb 2011 01:37:05 +0000</pubDate>
		<dc:creator>Jason Ernst</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Invalid XHTML]]></category>
		<category><![CDATA[Plugin]]></category>
		<category><![CDATA[Sharethis]]></category>
		<category><![CDATA[Wordpress]]></category>

		<guid isPermaLink="false">http://www.jasonernst.com/?p=1392</guid>
		<description><![CDATA[Building on my previous post regarding invalid XHTML (Version 1.0 Strict), I have been trying to find out why my site has not been validating. It turns out, the last bit of the problem is the &#8220;Sharethis&#8221; plugin for WordPress. In this plugin, the authors decided to define some custom parameter fields within the &#8216;span&#8217; [...]]]></description>
			<content:encoded><![CDATA[<p>Building on my previous post regarding invalid XHTML (Version 1.0 Strict), I have been trying to find out why my site has not been validating. It turns out, the last bit of the problem is the &#8220;Sharethis&#8221; plugin for WordPress. In this plugin, the authors decided to define some custom parameter fields within the &#8216;span&#8217; tag causing the validation problems. A post <a href="http://getsatisfaction.com/sharethis/topics/attribute_displaytext_is_not_valid_xhtml">here</a> indicates it is for &#8220;simplicity&#8221; for their less technically inclined users. So, this post is to show you how to modify the plugin to get valid XHTML out of it instead.</p>
<p>In the sharethis.php file, the offending lines are here:</p>
<div class="snippet"><pre><code>$tags=&quot;&lt;span class=&#039;st_sharethis&#039; st_title=&#039;&quot;.strip_tags(get_the_title()).&quot;&#039; st_url=&#039;&quot;.get_permalink($post-&gt;ID).&quot;&#039; displayText=&#039;ShareThis&#039;&gt;&lt;/span&gt;&quot;;
$tags.=&quot;&lt;span class=&#039;st_&quot;.$svc.&quot;_vcount&#039; st_title=&#039;{title}&#039; st_url=&#039;{url}&#039; displayText=&#039;share&#039;&gt;&lt;/span&gt;&quot;;</code></pre></div>
<p>And here are the updated lines:</p>
<div class="snippet"><pre><code>$tags=&quot;&lt;span class=&#039;st_sharethis&#039;&gt;&lt;/span&gt;&quot;;
$tags.=&quot;&lt;span class=&#039;st_&quot;.$svc.&quot;_vcount&#039;&gt;&lt;/span&gt;&quot;;</code></pre></div>
<p>In this case, disabling the extra fields means that the &#8220;sharethis&#8221; text and some minor styling disappear from the sharethis button. It seems the easiest way to have compliant XHTML and still a decent looking sharethis button is to use the a custom button style (see this <a href="http://help.sharethis.com/customization/custom-buttons">page</a>).</p>
<p>So the result is this:</p>
<div class="snippet"><pre><code>$tags=&quot;&lt;span class=&#039;st_sharethis_custom&#039;&gt;&lt;a href=&#039;&#039;&gt;ShareThis&lt;/a&gt;&lt;/span&gt;&quot;;
$tags.=&quot;&lt;span class=&#039;st_sharethis_custom&#039;&gt;&lt;a href=&#039;&#039;&gt;ShareThis&lt;/a&gt;&lt;/span&gt;&quot;;</code></pre></div>
<p>The &#8216;ShareThis&#8217; text is enclosed in an &#8220;a&#8221; tag so that we get the mouseover behaviour and link styling that it had previously. Additionally, the css file for your template must be changed. This is what I added to mine to make it work:</p>
<div class="snippet"><code>.st_sharethis_custom { background: url(&quot;img/sharethis.png&quot;) no-repeat scroll left top transparent; padding-left: 18px; padding-top:3px;}</code></div>
<p>You will want to change the url to wherever you have located the sharethis icon, and the padding and margins may need to be adjusted for your own template.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jasonernst.com/2011/02/21/sharethis-wordpress-plugin-invalid-xhtml/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

