[openserverplatform] r119 committed - Merge with mainline GitHub OSP 0.4 progress to reflect changes made in...

3 views
Skip to first unread message

openserve...@googlecode.com

unread,
Nov 4, 2009, 8:37:18 AM11/4/09
to openserve...@googlegroups.com
Revision: 119
Author: discipleofranok
Date: Wed Nov 4 05:36:34 2009
Log: Merge with mainline GitHub OSP 0.4 progress to reflect changes made in
Github to the SVN repo

http://code.google.com/p/openserverplatform/source/detail?r=119

Added:
/trunk/apps
/trunk/apps/.gitignore
/trunk/bin
/trunk/bin/osp_ctl
/trunk/doc
/trunk/doc/edoc-info
/trunk/doc/erlang.png
/trunk/doc/index.html
/trunk/doc/manual
/trunk/doc/manual/OSP-Manual.tex
/trunk/doc/modules-frame.html
/trunk/doc/osp.html
/trunk/doc/osp_admin.html
/trunk/doc/osp_app.html
/trunk/doc/osp_broker.html
/trunk/doc/osp_compile.html
/trunk/doc/osp_file.html
/trunk/doc/osp_mnesia.html
/trunk/doc/osp_proto.html
/trunk/doc/osp_servlet.html
/trunk/doc/osp_socket.html
/trunk/doc/osp_sup.html
/trunk/doc/osp_web.html
/trunk/doc/overview-summary.html
/trunk/doc/overview.edoc
/trunk/doc/packages-frame.html
/trunk/doc/stylesheet.css
/trunk/ebin
/trunk/ebin/osp.app
/trunk/include
/trunk/include/conf.hrl
/trunk/include/httpd.conf
/trunk/log
/trunk/log/.gitignore
/trunk/servlets
/trunk/servlets/db.sdf
/trunk/servlets/echo.sap
/trunk/servlets/echo.sdf
/trunk/servlets/echo2.sdf
/trunk/servlets/my_httpd.sdf
/trunk/src
/trunk/src/Makefile
/trunk/src/osp.erl
/trunk/src/osp_admin.erl
/trunk/src/osp_app.erl
/trunk/src/osp_broker.erl
/trunk/src/osp_compile.erl
/trunk/src/osp_file.erl
/trunk/src/osp_mnesia.erl
/trunk/src/osp_proto.erl
/trunk/src/osp_recover.erl
/trunk/src/osp_servlet.erl
/trunk/src/osp_socket.erl
/trunk/src/osp_sup.erl
/trunk/src/osp_web.erl
/trunk/www
/trunk/www/app.html
/trunk/www/app.js
/trunk/www/compile.html
/trunk/www/images
/trunk/www/images/ui-bg_flat_0_aaaaaa_40x100.png
/trunk/www/images/ui-bg_flat_75_ffffff_40x100.png
/trunk/www/images/ui-bg_glass_55_fbf9ee_1x400.png
/trunk/www/images/ui-bg_glass_65_ffffff_1x400.png
/trunk/www/images/ui-bg_glass_75_dadada_1x400.png
/trunk/www/images/ui-bg_glass_75_e6e6e6_1x400.png
/trunk/www/images/ui-bg_glass_95_fef1ec_1x400.png
/trunk/www/images/ui-bg_highlight-soft_75_cccccc_1x100.png
/trunk/www/images/ui-icons_222222_256x240.png
/trunk/www/images/ui-icons_2e83ff_256x240.png
/trunk/www/images/ui-icons_454545_256x240.png
/trunk/www/images/ui-icons_888888_256x240.png
/trunk/www/images/ui-icons_cd0a0a_256x240.png
/trunk/www/index.html
/trunk/www/jquery-ui.css
/trunk/www/jquery-ui.js
/trunk/www/jquery.js
/trunk/www/style.css
Deleted:
/trunk/Makefile
/trunk/OSP-ADMIN
/trunk/docs
/trunk/osp.conf
/trunk/osp.erl
/trunk/osp_admin.erl
/trunk/osp_app.erl
/trunk/osp_broker.erl
/trunk/osp_mnesia.erl
/trunk/osp_proto.erl
/trunk/osp_socket.erl
/trunk/osp_sup.erl
/trunk/servlet_examples
Modified:
/trunk/AUTHORS
/trunk/COPYING
/trunk/README
/trunk/compile_servlet.pl
/trunk/gen-join.pl
/trunk/header.erl
/trunk/join.sh.sample
/trunk/setup-osp.sh
/trunk/start-osp.sh

=======================================
--- /dev/null
+++ /trunk/bin/osp_ctl Wed Nov 4 05:36:34 2009
@@ -0,0 +1,70 @@
+#!/bin/bash
+
+# OSP Control Panel
+# (C) 2009 Jacob Torrey
+# http://www.openserverplatform.com
+
+ABSPATH="$(cd "${0%/*}" 2>/dev/null; echo "$PWD"/"${0##*/}")"
+ABSDIR=`dirname $ABSPATH`
+
+cd $ABSDIR
+
+if [ $# -eq 0 ] || [ ${1} == "help" ]
+then
+ echo "osp_ctl - A CLI interface to Open Server Platform"
+ echo "(C) 2009 http://www.openserverplatform.com"
+ echo "Commands:"
+ echo " help - display this help"
+ echo " start - start the OSP cluster"
+ echo " stop - stop the OSP cluster"
+ echo " stats - print some information about the running cluster"
+ echo " webadmin - opens the web based administration system"
+ exit 0
+fi
+
+if [ ${1} == "webadmin" ]; then
+ xdg-open http://localhost:9877
+ exit 0
+fi
+
+if [ ${1} == "start" ]; then
+ if [ ! -d ../mnesia ] || [ ! -e ../osp_rel*.boot ]; then
+ echo "Detected first run, setting up database"
+ (cd .. && ./setup-osp.sh)
+ sleep 1
+ fi
+ nc localhost -w 0 9876 > /dev/null
+ if [ $? -eq 1 ]; then
+ (cd .. && ./start-osp.sh)
+ exit 0
+ else
+ echo "OSP already running"
+ exit 1
+ fi
+fi
+
+if [ ${1} == "stop" ]; then
+ echo "shutdown" | nc localhost 9876 > /dev/null
+ if [ $? -eq 1 ]; then
+ echo "OSP not started"
+ exit 1
+ else
+ exit 0
+ fi
+fi
+
+if [ ${1} == "stats" ]; then
+ RET=`echo "stats" | nc localhost 9876`
+ VAL=$?
+ RET=`echo "$RET" | sed -e 's/-> //'`
+ if [ $VAL -eq 1 ]; then
+ echo "OSP not started"
+ exit 1
+ else
+ echo "$RET"
+ exit 0
+ fi
+fi
+
+echo "Sorry, invalid command, try 'help'"
+exit 1
=======================================
--- /dev/null
+++ /trunk/doc/edoc-info Wed Nov 4 05:36:34 2009
@@ -0,0 +1,4 @@
+{application,osp}.
+{packages,[]}.
+{modules,[osp,osp_admin,osp_app,osp_broker,osp_compile,osp_file,osp_mnesia,
+ osp_proto,osp_servlet,osp_socket,osp_sup,osp_web]}.
=======================================
--- /dev/null
+++ /trunk/doc/erlang.png Wed Nov 4 05:36:34 2009
Binary file, no diff available.
=======================================
--- /dev/null
+++ /trunk/doc/index.html Wed Nov 4 05:36:34 2009
@@ -0,0 +1,17 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>The osp application</title>
+</head>
+<frameset cols="20%,80%">
+<frame src="modules-frame.html" name="modulesFrame" title="">
+
+<frame src="overview-summary.html" name="overviewFrame" title="">
+<noframes>
+<h2>This page uses frames</h2>
+<p>Your browser does not accept frames.
+<br>You should go to the <a href="overview-summary.html">non-frame
version</a> instead.
+</p>
+</noframes>
+</frameset>
+</html>
=======================================
--- /dev/null
+++ /trunk/doc/modules-frame.html Wed Nov 4 05:36:34 2009
@@ -0,0 +1,23 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>The osp application</title>
+<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
+</head>
+<body bgcolor="white">
+<h2 class="indextitle">Modules</h2>
+<table width="100%" border="0" summary="list of modules">
+<tr><td><a href="osp.html" target="overviewFrame"
class="module">osp</a></td></tr>
+<tr><td><a href="osp_admin.html" target="overviewFrame"
class="module">osp_admin</a></td></tr>
+<tr><td><a href="osp_app.html" target="overviewFrame"
class="module">osp_app</a></td></tr>
+<tr><td><a href="osp_broker.html" target="overviewFrame"
class="module">osp_broker</a></td></tr>
+<tr><td><a href="osp_compile.html" target="overviewFrame"
class="module">osp_compile</a></td></tr>
+<tr><td><a href="osp_file.html" target="overviewFrame"
class="module">osp_file</a></td></tr>
+<tr><td><a href="osp_mnesia.html" target="overviewFrame"
class="module">osp_mnesia</a></td></tr>
+<tr><td><a href="osp_proto.html" target="overviewFrame"
class="module">osp_proto</a></td></tr>
+<tr><td><a href="osp_servlet.html" target="overviewFrame"
class="module">osp_servlet</a></td></tr>
+<tr><td><a href="osp_socket.html" target="overviewFrame"
class="module">osp_socket</a></td></tr>
+<tr><td><a href="osp_sup.html" target="overviewFrame"
class="module">osp_sup</a></td></tr>
+<tr><td><a href="osp_web.html" target="overviewFrame"
class="module">osp_web</a></td></tr></table>
+</body>
+</html>
=======================================
--- /dev/null
+++ /trunk/doc/osp.html Wed Nov 4 05:36:34 2009
@@ -0,0 +1,57 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>Module osp</title>
+<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
+</head>
+<body bgcolor="white">
+<div class="navbar"><a name="#navbar_top"></a><table width="100%"
border="0" cellspacing="0" cellpadding="2" summary="navigation
bar"><tr><td><a href="overview-summary.html"
target="overviewFrame">Overview</a></td><td><a
href="http://www.erlang.org/"><img src="erlang.png" align="right"
border="0" alt="erlang logo"></a></td></tr></table></div>
+<hr>
+
+<h1>Module osp</h1>
+<ul class="index"><li><a href="#description">Description</a></li><li><a
href="#index">Function Index</a></li><li><a href="#functions">Function
Details</a></li></ul>The exports for controlling the OSP system as a whole.
+<p>Copyright © 2009 Jacob Torrey &lt;torr...@clarkson.edu&gt;</p>
+
+<p><b>Authors:</b> Jacob Torrey (<a
href="mailto:torr...@clarkson.edu"><tt>torr...@clarkson.edu</tt></a>).</p>
+
+<h2><a name="description">Description</a></h2>The exports for controlling
the OSP system as a whole
+<h2><a name="index">Function Index</a></h2>
+<table width="100%" border="1" cellspacing="0" cellpadding="2"
summary="function index"><tr><td valign="top"><a
href="#gen_docs-0">gen_docs/0</a></td><td>Provides an export to regenerate
the documentation with edoc.</td></tr>
+<tr><td valign="top"><a href="#join-1">join/1</a></td><td>Joins node to an
existing OSP cluster.</td></tr>
+<tr><td valign="top"><a href="#setup-0">setup/0</a></td><td>Setups mnesia
and the OTP rel scripts for the first time.</td></tr>
+<tr><td valign="top"><a href="#start-0">start/0</a></td><td>Starts the
first 'master' node.</td></tr>
+<tr><td valign="top"><a href="#stop-1">stop/1</a></td><td>Stops OSP on
this node.</td></tr>
+</table>
+
+<h2><a name="functions">Function Details</a></h2>
+
+<h3 class="function"><a name="gen_docs-0">gen_docs/0</a></h3>
+<div class="spec">
+<p><tt>gen_docs() -&gt; ok</tt></p>
+</div><p>Provides an export to regenerate the documentation with edoc</p>
+
+<h3 class="function"><a name="join-1">join/1</a></h3>
+<div class="spec">
+<p><tt>join(X1::list()) -&gt; pong | pang</tt></p>
+</div><p>Joins node to an existing OSP cluster</p>
+
+<h3 class="function"><a name="setup-0">setup/0</a></h3>
+<div class="spec">
+<p><tt>setup() -&gt; ok</tt></p>
+</div><p>Setups mnesia and the OTP rel scripts for the first time</p>
+
+<h3 class="function"><a name="start-0">start/0</a></h3>
+<div class="spec">
+<p><tt>start() -&gt; {ok, Pid, pid()} | {error, Reason}</tt></p>
+</div><p>Starts the first 'master' node</p>
+
+<h3 class="function"><a name="stop-1">stop/1</a></h3>
+<div class="spec">
+<p><tt>stop(Pid) -&gt; ok</tt></p>
+</div><p>Stops OSP on this node</p>
+<hr>
+
+<div class="navbar"><a name="#navbar_bottom"></a><table width="100%"
border="0" cellspacing="0" cellpadding="2" summary="navigation
bar"><tr><td><a href="overview-summary.html"
target="overviewFrame">Overview</a></td><td><a
href="http://www.erlang.org/"><img src="erlang.png" align="right"
border="0" alt="erlang logo"></a></td></tr></table></div>
+<p><i>Generated by EDoc, Oct 30 2009, 20:13:44.</i></p>
+</body>
+</html>
=======================================
--- /dev/null
+++ /trunk/doc/osp_admin.html Wed Nov 4 05:36:34 2009
@@ -0,0 +1,82 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>Module osp_admin</title>
+<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
+</head>
+<body bgcolor="white">
+<div class="navbar"><a name="#navbar_top"></a><table width="100%"
border="0" cellspacing="0" cellpadding="2" summary="navigation
bar"><tr><td><a href="overview-summary.html"
target="overviewFrame">Overview</a></td><td><a
href="http://www.erlang.org/"><img src="erlang.png" align="right"
border="0" alt="erlang logo"></a></td></tr></table></div>
+<hr>
+
+<h1>Module osp_admin</h1>
+<ul class="index"><li><a href="#description">Description</a></li><li><a
href="#index">Function Index</a></li><li><a href="#functions">Function
Details</a></li></ul>Provides an interface to administer the OSP cluster.
+<p>Copyright © 2009 Jacob Torrey &lt;torr...@clarkson.edu&gt;</p>
+
+<p><b>Version:</b> 0.4</p>
+<p><b>Authors:</b> Jacob Ian Torrey (<a
href="mailto:torr...@clarkson.edu"><tt>torr...@clarkson.edu</tt></a>).</p>
+
+<h2><a name="description">Description</a></h2>Provides an interface to
administer the OSP cluster
+<h2><a name="index">Function Index</a></h2>
+<table width="100%" border="1" cellspacing="0" cellpadding="2"
summary="function index"><tr><td valign="top"><a
href="#cleanup-0">cleanup/0</a></td><td>A callback for the OSP broker
service.</td></tr>
+<tr><td valign="top"><a href="#init-0">init/0</a></td><td>Routine for
starting the master boot server and autostarted applications.</td></tr>
+<tr><td valign="top"><a href="#nodeapp-0">nodeapp/0</a></td><td>Returns
the App-Node listing for the cluster.</td></tr>
+<tr><td valign="top"><a href="#proto-0">proto/0</a></td><td>Returns the
protocol for the application (this is a TCP applcation).</td></tr>
+<tr><td valign="top"><a href="#server-1">server/1</a></td><td>The main
server loop.</td></tr>
+<tr><td valign="top"><a
href="#shutdown_osp-0">shutdown_osp/0</a></td><td>Shuts down the entire OSP
cluster, and quits the Erlang VM.</td></tr>
+<tr><td valign="top"><a
href="#start_mnesia-0">start_mnesia/0</a></td><td>The mnesia startup
routine for osp_admin.</td></tr>
+<tr><td valign="top"><a href="#stats_osp-0">stats_osp/0</a></td><td>This
returns a string of the OSP cluster statistics.</td></tr>
+<tr><td valign="top"><a
href="#uptime_osp-0">uptime_osp/0</a></td><td>Returns a human readable
string of the cluster uptime.</td></tr>
+</table>
+
+<h2><a name="functions">Function Details</a></h2>
+
+<h3 class="function"><a name="cleanup-0">cleanup/0</a></h3>
+<div class="spec">
+<p><tt>cleanup() -&gt; ok</tt></p>
+</div><p>A callback for the OSP broker service</p>
+
+<h3 class="function"><a name="init-0">init/0</a></h3>
+<div class="spec">
+<p><tt>init() -&gt; ok</tt></p>
+</div><p>Routine for starting the master boot server and autostarted
applications</p>
+
+<h3 class="function"><a name="nodeapp-0">nodeapp/0</a></h3>
+<div class="spec">
+<p><tt>nodeapp() -&gt; list()</tt></p>
+</div><p>Returns the App-Node listing for the cluster</p>
+
+<h3 class="function"><a name="proto-0">proto/0</a></h3>
+<div class="spec">
+<p><tt>proto() -&gt; tcp</tt></p>
+</div><p>Returns the protocol for the application (this is a TCP
applcation)</p>
+
+<h3 class="function"><a name="server-1">server/1</a></h3>
+<div class="spec">
+<p><tt>server(Sock::tuple()) -&gt; none()</tt></p>
+</div><p>The main server loop</p>
+
+<h3 class="function"><a name="shutdown_osp-0">shutdown_osp/0</a></h3>
+<div class="spec">
+<p><tt>shutdown_osp() -&gt; ok</tt></p>
+</div><p>Shuts down the entire OSP cluster, and quits the Erlang VM</p>
+
+<h3 class="function"><a name="start_mnesia-0">start_mnesia/0</a></h3>
+<div class="spec">
+<p><tt>start_mnesia() -&gt; ok</tt></p>
+</div><p>The mnesia startup routine for osp_admin</p>
+
+<h3 class="function"><a name="stats_osp-0">stats_osp/0</a></h3>
+<div class="spec">
+<p><tt>stats_osp() -&gt; list()</tt></p>
+</div><p>This returns a string of the OSP cluster statistics</p>
+
+<h3 class="function"><a name="uptime_osp-0">uptime_osp/0</a></h3>
+<div class="spec">
+<p><tt>uptime_osp() -&gt; list()</tt></p>
+</div><p>Returns a human readable string of the cluster uptime</p>
+<hr>
+
+<div class="navbar"><a name="#navbar_bottom"></a><table width="100%"
border="0" cellspacing="0" cellpadding="2" summary="navigation
bar"><tr><td><a href="overview-summary.html"
target="overviewFrame">Overview</a></td><td><a
href="http://www.erlang.org/"><img src="erlang.png" align="right"
border="0" alt="erlang logo"></a></td></tr></table></div>
+<p><i>Generated by EDoc, Oct 30 2009, 20:13:45.</i></p>
+</body>
+</html>
=======================================
--- /dev/null
+++ /trunk/doc/osp_app.html Wed Nov 4 05:36:34 2009
@@ -0,0 +1,39 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>Module osp_app</title>
+<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
+</head>
+<body bgcolor="white">
+<div class="navbar"><a name="#navbar_top"></a><table width="100%"
border="0" cellspacing="0" cellpadding="2" summary="navigation
bar"><tr><td><a href="overview-summary.html"
target="overviewFrame">Overview</a></td><td><a
href="http://www.erlang.org/"><img src="erlang.png" align="right"
border="0" alt="erlang logo"></a></td></tr></table></div>
+<hr>
+
+<h1>Module osp_app</h1>
+<ul class="index"><li><a href="#description">Description</a></li><li><a
href="#index">Function Index</a></li><li><a href="#functions">Function
Details</a></li></ul>Provides the application callbacks for OSP.
+<p>Copyright © 2009 Jacob Torrey &lt;torr...@clarkson.edu&gt;</p>
+
+<p><b>Authors:</b> Jacob Torrey (<a
href="mailto:torr...@clarkson.edu"><tt>torr...@clarkson.edu</tt></a>).</p>
+
+<h2><a name="description">Description</a></h2>Provides the application
callbacks for OSP
+<h2><a name="index">Function Index</a></h2>
+<table width="100%" border="1" cellspacing="0" cellpadding="2"
summary="function index"><tr><td valign="top"><a
href="#start-2">start/2</a></td><td>Starts the OSP application.</td></tr>
+<tr><td valign="top"><a href="#stop-1">stop/1</a></td><td>Stops the OSP
application.</td></tr>
+</table>
+
+<h2><a name="functions">Function Details</a></h2>
+
+<h3 class="function"><a name="start-2">start/2</a></h3>
+<div class="spec">
+<p><tt>start(Type, StartArgs) -&gt; any()</tt></p>
+</div><p>Starts the OSP application</p>
+
+<h3 class="function"><a name="stop-1">stop/1</a></h3>
+<div class="spec">
+<p><tt>stop(State) -&gt; any()</tt></p>
+</div><p>Stops the OSP application</p>
+<hr>
+
+<div class="navbar"><a name="#navbar_bottom"></a><table width="100%"
border="0" cellspacing="0" cellpadding="2" summary="navigation
bar"><tr><td><a href="overview-summary.html"
target="overviewFrame">Overview</a></td><td><a
href="http://www.erlang.org/"><img src="erlang.png" align="right"
border="0" alt="erlang logo"></a></td></tr></table></div>
+<p><i>Generated by EDoc, Oct 30 2009, 20:13:44.</i></p>
+</body>
+</html>
=======================================
--- /dev/null
+++ /trunk/doc/osp_broker.html Wed Nov 4 05:36:34 2009
@@ -0,0 +1,45 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>Module osp_broker</title>
+<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
+</head>
+<body bgcolor="white">
+<div class="navbar"><a name="#navbar_top"></a><table width="100%"
border="0" cellspacing="0" cellpadding="2" summary="navigation
bar"><tr><td><a href="overview-summary.html"
target="overviewFrame">Overview</a></td><td><a
href="http://www.erlang.org/"><img src="erlang.png" align="right"
border="0" alt="erlang logo"></a></td></tr></table></div>
+<hr>
+
+<h1>Module osp_broker</h1>
+<ul class="index"><li><a href="#description">Description</a></li><li><a
href="#index">Function Index</a></li><li><a href="#functions">Function
Details</a></li></ul>A socket request broker.
+<p>Copyright © 2009 Jacob Torrey &lt;torr...@clarkson.edu&gt;</p>
+
+<p><b>Authors:</b> Jacob Torrey (<a
href="mailto:torr...@clarkson.edu"><tt>torr...@clarkson.edu</tt></a>).</p>
+
+<h2><a name="description">Description</a></h2>A socket request broker
+<h2><a name="index">Function Index</a></h2>
+<table width="100%" border="1" cellspacing="0" cellpadding="2"
summary="function index"><tr><td valign="top"><a
href="#shutdown-0">shutdown/0</a></td><td>Shuts down the Mnesia
database.</td></tr>
+<tr><td valign="top"><a href="#start-2">start/2</a></td><td>Starts the
server named Name on port Port.</td></tr>
+<tr><td valign="top"><a href="#stop-1">stop/1</a></td><td>Stops the server
broker and all it's children processes.</td></tr>
+</table>
+
+<h2><a name="functions">Function Details</a></h2>
+
+<h3 class="function"><a name="shutdown-0">shutdown/0</a></h3>
+<div class="spec">
+<p><tt>shutdown() -&gt; ok</tt></p>
+</div><p>Shuts down the Mnesia database</p>
+
+<h3 class="function"><a name="start-2">start/2</a></h3>
+<div class="spec">
+<p><tt>start(Name::atom(), Port::<a href="#type-int">int()</a>) -&gt; ok |
{error, Reason}</tt></p>
+</div><p>Starts the server named Name on port Port</p>
+
+<h3 class="function"><a name="stop-1">stop/1</a></h3>
+<div class="spec">
+<p><tt>stop(Name::atom()) -&gt; ok</tt></p>
+</div><p>Stops the server broker and all it's children processes</p>
+<hr>
+
+<div class="navbar"><a name="#navbar_bottom"></a><table width="100%"
border="0" cellspacing="0" cellpadding="2" summary="navigation
bar"><tr><td><a href="overview-summary.html"
target="overviewFrame">Overview</a></td><td><a
href="http://www.erlang.org/"><img src="erlang.png" align="right"
border="0" alt="erlang logo"></a></td></tr></table></div>
+<p><i>Generated by EDoc, Oct 30 2009, 20:13:45.</i></p>
+</body>
+</html>
=======================================
--- /dev/null
+++ /trunk/doc/osp_compile.html Wed Nov 4 05:36:34 2009
@@ -0,0 +1,45 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>Module osp_compile</title>
+<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
+</head>
+<body bgcolor="white">
+<div class="navbar"><a name="#navbar_top"></a><table width="100%"
border="0" cellspacing="0" cellpadding="2" summary="navigation
bar"><tr><td><a href="overview-summary.html"
target="overviewFrame">Overview</a></td><td><a
href="http://www.erlang.org/"><img src="erlang.png" align="right"
border="0" alt="erlang logo"></a></td></tr></table></div>
+<hr>
+
+<h1>Module osp_compile</h1>
+<ul class="index"><li><a href="#description">Description</a></li><li><a
href="#index">Function Index</a></li><li><a href="#functions">Function
Details</a></li></ul>Provides servlet compilation functionality.
+<p>Copyright © 2009 Jacob Torrey &lt;torr...@clarkson.edu&gt;</p>
+
+<p><b>Authors:</b> Jacob Torrey (<a
href="mailto:torr...@clarkson.edu"><tt>torr...@clarkson.edu</tt></a>).</p>
+
+<h2><a name="description">Description</a></h2>Provides servlet compilation
functionality
+<h2><a name="index">Function Index</a></h2>
+<table width="100%" border="1" cellspacing="0" cellpadding="2"
summary="function index"><tr><td valign="top"><a
href="#compile-1">compile/1</a></td><td>Generates and compiles a servlet
from a .sdf.</td></tr>
+<tr><td valign="top"><a
href="#distribute-2">distribute/2</a></td><td>Distributes the application
to a given node to be run.</td></tr>
+<tr><td valign="top"><a
href="#servlet_to_app-1">servlet_to_app/1</a></td><td>Compiles a servlet
and moves it to the application directory if compilation is
successful.</td></tr>
+</table>
+
+<h2><a name="functions">Function Details</a></h2>
+
+<h3 class="function"><a name="compile-1">compile/1</a></h3>
+<div class="spec">
+<p><tt>compile(Filename::list()) -&gt; {ok, list()} | {error,
list()}</tt></p>
+</div><p>Generates and compiles a servlet from a .sdf</p>
+
+<h3 class="function"><a name="distribute-2">distribute/2</a></h3>
+<div class="spec">
+<p><tt>distribute(Module::atom(), Node::<a href="#type-node">node()</a>)
-&gt; ok | {error, atom()}</tt></p>
+</div><p>Distributes the application to a given node to be run</p>
+
+<h3 class="function"><a name="servlet_to_app-1">servlet_to_app/1</a></h3>
+<div class="spec">
+<p><tt>servlet_to_app(Filename::list()) -&gt; {ok, list()} | {error,
list()}</tt></p>
+</div><p>Compiles a servlet and moves it to the application directory if
compilation is successful</p>
+<hr>
+
+<div class="navbar"><a name="#navbar_bottom"></a><table width="100%"
border="0" cellspacing="0" cellpadding="2" summary="navigation
bar"><tr><td><a href="overview-summary.html"
target="overviewFrame">Overview</a></td><td><a
href="http://www.erlang.org/"><img src="erlang.png" align="right"
border="0" alt="erlang logo"></a></td></tr></table></div>
+<p><i>Generated by EDoc, Oct 30 2009, 20:13:44.</i></p>
+</body>
+</html>
=======================================
--- /dev/null
+++ /trunk/doc/osp_file.html Wed Nov 4 05:36:34 2009
@@ -0,0 +1,57 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>Module osp_file</title>
+<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
+</head>
+<body bgcolor="white">
+<div class="navbar"><a name="#navbar_top"></a><table width="100%"
border="0" cellspacing="0" cellpadding="2" summary="navigation
bar"><tr><td><a href="overview-summary.html"
target="overviewFrame">Overview</a></td><td><a
href="http://www.erlang.org/"><img src="erlang.png" align="right"
border="0" alt="erlang logo"></a></td></tr></table></div>
+<hr>
+
+<h1>Module osp_file</h1>
+<ul class="index"><li><a href="#description">Description</a></li><li><a
href="#index">Function Index</a></li><li><a href="#functions">Function
Details</a></li></ul>File operations for OSP programs.
+<p>Copyright © 2009 Jacob Torrey &lt;torr...@clarkson.edu&gt;</p>
+
+<p><b>Authors:</b> Jacob Torrey (<a
href="mailto:torr...@clarkson.edu"><tt>torr...@clarkson.edu</tt></a>).</p>
+
+<h2><a name="description">Description</a></h2>File operations for OSP
programs
+<h2><a name="index">Function Index</a></h2>
+<table width="100%" border="1" cellspacing="0" cellpadding="2"
summary="function index"><tr><td valign="top"><a
href="#fclose-1">fclose/1</a></td><td>Closes an open file.</td></tr>
+<tr><td valign="top"><a href="#fopen-3">fopen/3</a></td><td>Opens a file
for reading or writing.</td></tr>
+<tr><td valign="top"><a href="#fread-2">fread/2</a></td><td>Reads from a
file.</td></tr>
+<tr><td valign="top"><a href="#fseek-3">fseek/3</a></td><td>Seeks to a
position in a file.</td></tr>
+<tr><td valign="top"><a href="#fwrite-2">fwrite/2</a></td><td>Writes to a
file.</td></tr>
+</table>
+
+<h2><a name="functions">Function Details</a></h2>
+
+<h3 class="function"><a name="fclose-1">fclose/1</a></h3>
+<div class="spec">
+<p><tt>fclose(FP::<a href="#type-io_device">io_device()</a>) -&gt; ok |
{err, Reason}</tt></p>
+</div><p>Closes an open file</p>
+
+<h3 class="function"><a name="fopen-3">fopen/3</a></h3>
+<div class="spec">
+<p><tt>fopen(App::list(), Filename::list(), Flags::list()) -&gt; <a
href="#type-io_device">io_device()</a> | {err, list()}</tt></p>
+</div><p>Opens a file for reading or writing</p>
+
+<h3 class="function"><a name="fread-2">fread/2</a></h3>
+<div class="spec">
+<p><tt>fread(FP::<a href="#type-io_device">io_device()</a>, Num::<a
href="#type-int">int()</a>) -&gt; any() | {eof} | {err, list()}</tt></p>
+</div><p>Reads from a file</p>
+
+<h3 class="function"><a name="fseek-3">fseek/3</a></h3>
+<div class="spec">
+<p><tt>fseek(FP::<a href="#type-io_device">io_device()</a>, X2::atom(),
Off::<a href="#type-int">int()</a>) -&gt; ok | {err, list()}</tt></p>
+</div><p>Seeks to a position in a file</p>
+
+<h3 class="function"><a name="fwrite-2">fwrite/2</a></h3>
+<div class="spec">
+<p><tt>fwrite(FP::<a href="#type-io_device">io_device()</a>, Dat::any())
-&gt; ok | {err, list()}</tt></p>
+</div><p>Writes to a file</p>
+<hr>
+
+<div class="navbar"><a name="#navbar_bottom"></a><table width="100%"
border="0" cellspacing="0" cellpadding="2" summary="navigation
bar"><tr><td><a href="overview-summary.html"
target="overviewFrame">Overview</a></td><td><a
href="http://www.erlang.org/"><img src="erlang.png" align="right"
border="0" alt="erlang logo"></a></td></tr></table></div>
+<p><i>Generated by EDoc, Oct 30 2009, 20:13:45.</i></p>
+</body>
+</html>
=======================================
--- /dev/null
+++ /trunk/doc/osp_mnesia.html Wed Nov 4 05:36:34 2009
@@ -0,0 +1,51 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>Module osp_mnesia</title>
+<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
+</head>
+<body bgcolor="white">
+<div class="navbar"><a name="#navbar_top"></a><table width="100%"
border="0" cellspacing="0" cellpadding="2" summary="navigation
bar"><tr><td><a href="overview-summary.html"
target="overviewFrame">Overview</a></td><td><a
href="http://www.erlang.org/"><img src="erlang.png" align="right"
border="0" alt="erlang logo"></a></td></tr></table></div>
+<hr>
+
+<h1>Module osp_mnesia</h1>
+<ul class="index"><li><a href="#description">Description</a></li><li><a
href="#index">Function Index</a></li><li><a href="#functions">Function
Details</a></li></ul>A Mnesia interface for OSP.
+<p>Copyright © 2009 Jacob Torrey &lt;torr...@clarkson.edu&gt;</p>
+
+<p><b>Authors:</b> Jacob Torrey (<a
href="mailto:torr...@clarkson.edu"><tt>torr...@clarkson.edu</tt></a>).</p>
+
+<h2><a name="description">Description</a></h2>A Mnesia interface for OSP
+<h2><a name="index">Function Index</a></h2>
+<table width="100%" border="1" cellspacing="0" cellpadding="2"
summary="function index"><tr><td valign="top"><a
href="#flush-1">flush/1</a></td><td>Flushes the variables to the
database.</td></tr>
+<tr><td valign="top"><a
href="#retrieve-2">retrieve/2</a></td><td>Retrieves the value associated
with the key from the database.</td></tr>
+<tr><td valign="top"><a
href="#start_atomic-0">start_atomic/0</a></td><td>Sets the process to be
atomic.</td></tr>
+<tr><td valign="top"><a href="#store-3">store/3</a></td><td>Stores a key
value set to the database.</td></tr>
+</table>
+
+<h2><a name="functions">Function Details</a></h2>
+
+<h3 class="function"><a name="flush-1">flush/1</a></h3>
+<div class="spec">
+<p><tt>flush(Tab) -&gt; any()</tt></p>
+</div><p>Flushes the variables to the database</p>
+
+<h3 class="function"><a name="retrieve-2">retrieve/2</a></h3>
+<div class="spec">
+<p><tt>retrieve(Tab, Key) -&gt; any()</tt></p>
+</div><p>Retrieves the value associated with the key from the database</p>
+
+<h3 class="function"><a name="start_atomic-0">start_atomic/0</a></h3>
+<div class="spec">
+<p><tt>start_atomic() -&gt; ok</tt></p>
+</div><p>Sets the process to be atomic</p>
+
+<h3 class="function"><a name="store-3">store/3</a></h3>
+<div class="spec">
+<p><tt>store(Tab, Key, Val) -&gt; any()</tt></p>
+</div><p>Stores a key value set to the database</p>
+<hr>
+
+<div class="navbar"><a name="#navbar_bottom"></a><table width="100%"
border="0" cellspacing="0" cellpadding="2" summary="navigation
bar"><tr><td><a href="overview-summary.html"
target="overviewFrame">Overview</a></td><td><a
href="http://www.erlang.org/"><img src="erlang.png" align="right"
border="0" alt="erlang logo"></a></td></tr></table></div>
+<p><i>Generated by EDoc, Oct 30 2009, 20:13:44.</i></p>
+</body>
+</html>
=======================================
--- /dev/null
+++ /trunk/doc/osp_proto.html Wed Nov 4 05:36:34 2009
@@ -0,0 +1,51 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>Module osp_proto</title>
+<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
+</head>
+<body bgcolor="white">
+<div class="navbar"><a name="#navbar_top"></a><table width="100%"
border="0" cellspacing="0" cellpadding="2" summary="navigation
bar"><tr><td><a href="overview-summary.html"
target="overviewFrame">Overview</a></td><td><a
href="http://www.erlang.org/"><img src="erlang.png" align="right"
border="0" alt="erlang logo"></a></td></tr></table></div>
+<hr>
+
+<h1>Module osp_proto</h1>
+<ul class="index"><li><a href="#description">Description</a></li><li><a
href="#index">Function Index</a></li><li><a href="#functions">Function
Details</a></li></ul>A module for abstracting protocols from OSP servlets.
+<p>Copyright © 2009 Jacob Torrey &lt;torr...@clarkson.edu&gt;</p>
+
+<p><b>Authors:</b> Jacob Torrey (<a
href="mailto:torr...@clarkson.edu"><tt>torr...@clarkson.edu</tt></a>).</p>
+
+<h2><a name="description">Description</a></h2>A module for abstracting
protocols from OSP servlets
+<h2><a name="index">Function Index</a></h2>
+<table width="100%" border="1" cellspacing="0" cellpadding="2"
summary="function index"><tr><td valign="top"><a
href="#accept-1">accept/1</a></td><td>Returns a function to accept a socket
or connection.</td></tr>
+<tr><td valign="top"><a href="#close-1">close/1</a></td><td>Returns a
function to close the socket.</td></tr>
+<tr><td valign="top"><a
href="#set_control-1">set_control/1</a></td><td>Returns a function that
sets the controlling process of Sock to Pid.</td></tr>
+<tr><td valign="top"><a href="#start-1">start/1</a></td><td>Returns a
function (arity 1) for starting a server socket.</td></tr>
+</table>
+
+<h2><a name="functions">Function Details</a></h2>
+
+<h3 class="function"><a name="accept-1">accept/1</a></h3>
+<div class="spec">
+<p><tt>accept(X1) -&gt; any()</tt></p>
+</div><p>Returns a function to accept a socket or connection</p>
+
+<h3 class="function"><a name="close-1">close/1</a></h3>
+<div class="spec">
+<p><tt>close(X1) -&gt; any()</tt></p>
+</div><p>Returns a function to close the socket</p>
+
+<h3 class="function"><a name="set_control-1">set_control/1</a></h3>
+<div class="spec">
+<p><tt>set_control(X1) -&gt; any()</tt></p>
+</div><p>Returns a function that sets the controlling process of Sock to
Pid</p>
+
+<h3 class="function"><a name="start-1">start/1</a></h3>
+<div class="spec">
+<p><tt>start(X1) -&gt; any()</tt></p>
+</div><p>Returns a function (arity 1) for starting a server socket</p>
+<hr>
+
+<div class="navbar"><a name="#navbar_bottom"></a><table width="100%"
border="0" cellspacing="0" cellpadding="2" summary="navigation
bar"><tr><td><a href="overview-summary.html"
target="overviewFrame">Overview</a></td><td><a
href="http://www.erlang.org/"><img src="erlang.png" align="right"
border="0" alt="erlang logo"></a></td></tr></table></div>
+<p><i>Generated by EDoc, Oct 30 2009, 20:13:45.</i></p>
+</body>
+</html>
=======================================
--- /dev/null
+++ /trunk/doc/osp_servlet.html Wed Nov 4 05:36:34 2009
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>Module osp_servlet</title>
+<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
+</head>
+<body bgcolor="white">
+<div class="navbar"><a name="#navbar_top"></a><table width="100%"
border="0" cellspacing="0" cellpadding="2" summary="navigation
bar"><tr><td><a href="overview-summary.html"
target="overviewFrame">Overview</a></td><td><a
href="http://www.erlang.org/"><img src="erlang.png" align="right"
border="0" alt="erlang logo"></a></td></tr></table></div>
+<hr>
+
+<h1>Module osp_servlet</h1>
+<ul class="index"><li><a href="#description">Description</a></li><li><a
href="#index">Function Index</a></li><li><a href="#functions">Function
Details</a></li></ul>Provides the osp_servlet behavior.
+<p>Copyright © 2009 Jacob Torrey &lt;torr...@clarkson.edu&gt;</p>
+
+<p><b>This module defines the <tt>osp_servlet</tt> behaviour.</b><br>
Required callback functions: <tt>init/0</tt>, <tt>cleanup/0</tt>,
<tt>server/1</tt>, <tt>proto/0</tt>, <tt>start_mnesia/0</tt>.</p>
+<p><b>Authors:</b> Jacob Torrey (<a
href="mailto:torr...@clarkson.edu"><tt>torr...@clarkson.edu</tt></a>).</p>
+
+<h2><a name="description">Description</a></h2>Provides the osp_servlet
behavior
+<h2><a name="index">Function Index</a></h2>
+<table width="100%" border="1" cellspacing="0" cellpadding="2"
summary="function index"><tr><td valign="top"><a
href="#behaviour_info-1">behaviour_info/1</a></td><td>Provides the
information about the behavior.</td></tr>
+</table>
+
+<h2><a name="functions">Function Details</a></h2>
+
+<h3 class="function"><a name="behaviour_info-1">behaviour_info/1</a></h3>
+<div class="spec">
+<p><tt>behaviour_info(X1::atom()) -&gt; undefined | list()</tt></p>
+</div><p>Provides the information about the behavior</p>
+<hr>
+
+<div class="navbar"><a name="#navbar_bottom"></a><table width="100%"
border="0" cellspacing="0" cellpadding="2" summary="navigation
bar"><tr><td><a href="overview-summary.html"
target="overviewFrame">Overview</a></td><td><a
href="http://www.erlang.org/"><img src="erlang.png" align="right"
border="0" alt="erlang logo"></a></td></tr></table></div>
+<p><i>Generated by EDoc, Oct 30 2009, 20:13:44.</i></p>
+</body>
+</html>
=======================================
--- /dev/null
+++ /trunk/doc/osp_socket.html Wed Nov 4 05:36:34 2009
@@ -0,0 +1,51 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>Module osp_socket</title>
+<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
+</head>
+<body bgcolor="white">
+<div class="navbar"><a name="#navbar_top"></a><table width="100%"
border="0" cellspacing="0" cellpadding="2" summary="navigation
bar"><tr><td><a href="overview-summary.html"
target="overviewFrame">Overview</a></td><td><a
href="http://www.erlang.org/"><img src="erlang.png" align="right"
border="0" alt="erlang logo"></a></td></tr></table></div>
+<hr>
+
+<h1>Module osp_socket</h1>
+<ul class="index"><li><a href="#description">Description</a></li><li><a
href="#index">Function Index</a></li><li><a href="#functions">Function
Details</a></li></ul>Socket operations for OSP programs.
+<p>Copyright © 2009 Jacob Torrey &lt;torr...@clarkson.edu&gt;</p>
+
+<p><b>Authors:</b> Jacob Torrey (<a
href="mailto:torr...@clarkson.edu"><tt>torr...@clarkson.edu</tt></a>).</p>
+
+<h2><a name="description">Description</a></h2>Socket operations for OSP
programs
+<h2><a name="index">Function Index</a></h2>
+<table width="100%" border="1" cellspacing="0" cellpadding="2"
summary="function index"><tr><td valign="top"><a
href="#close-1">close/1</a></td><td>Closes a socket (protocol
inspecific).</td></tr>
+<tr><td valign="top"><a href="#recv-2">recv/2</a></td><td>A 'safe'
receive.</td></tr>
+<tr><td valign="top"><a href="#send-2">send/2</a></td><td>A type/protocol
inspecific send function.</td></tr>
+<tr><td valign="top"><a href="#sendf-3">sendf/3</a></td><td>A formatted
send that uses the same arguments as io:format.</td></tr>
+</table>
+
+<h2><a name="functions">Function Details</a></h2>
+
+<h3 class="function"><a name="close-1">close/1</a></h3>
+<div class="spec">
+<p><tt>close(X1::<a href="#type-genericSocket">genericSocket()</a>) -&gt;
ok</tt></p>
+</div><p>Closes a socket (protocol inspecific)</p>
+
+<h3 class="function"><a name="recv-2">recv/2</a></h3>
+<div class="spec">
+<p><tt>recv(X1::<a href="#type-genericSocket">genericSocket()</a>, Len::<a
href="#type-int">int()</a>) -&gt; binary() | {error, closed}</tt></p>
+</div><p>A 'safe' receive. A length of 0 will get a 'line' of data</p>
+
+<h3 class="function"><a name="send-2">send/2</a></h3>
+<div class="spec">
+<p><tt>send(X1::<a href="#type-genericSock">genericSock()</a>,
Data::any()) -&gt; ok</tt></p>
+</div><p>A type/protocol inspecific send function</p>
+
+<h3 class="function"><a name="sendf-3">sendf/3</a></h3>
+<div class="spec">
+<p><tt>sendf(Sock::<a href="#type-genericSocket">genericSocket()</a>,
Template::list(), Args::list()) -&gt; ok</tt></p>
+</div><p>A formatted send that uses the same arguments as io:format</p>
+<hr>
+
+<div class="navbar"><a name="#navbar_bottom"></a><table width="100%"
border="0" cellspacing="0" cellpadding="2" summary="navigation
bar"><tr><td><a href="overview-summary.html"
target="overviewFrame">Overview</a></td><td><a
href="http://www.erlang.org/"><img src="erlang.png" align="right"
border="0" alt="erlang logo"></a></td></tr></table></div>
+<p><i>Generated by EDoc, Oct 30 2009, 20:13:44.</i></p>
+</body>
+</html>
=======================================
--- /dev/null
+++ /trunk/doc/osp_sup.html Wed Nov 4 05:36:34 2009
@@ -0,0 +1,39 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>Module osp_sup</title>
+<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
+</head>
+<body bgcolor="white">
+<div class="navbar"><a name="#navbar_top"></a><table width="100%"
border="0" cellspacing="0" cellpadding="2" summary="navigation
bar"><tr><td><a href="overview-summary.html"
target="overviewFrame">Overview</a></td><td><a
href="http://www.erlang.org/"><img src="erlang.png" align="right"
border="0" alt="erlang logo"></a></td></tr></table></div>
+<hr>
+
+<h1>Module osp_sup</h1>
+<ul class="index"><li><a href="#description">Description</a></li><li><a
href="#index">Function Index</a></li><li><a href="#functions">Function
Details</a></li></ul>Provides a way for OSP to be integrated into an OTP
tree.
+<p>Copyright © 2009 Jacob Torrey &lt;torr...@clarkson.edu&gt;</p>
+
+<p><b>Authors:</b> Jacob Torrey (<a
href="mailto:torr...@clarkson.edu"><tt>torr...@clarkson.edu</tt></a>).</p>
+
+<h2><a name="description">Description</a></h2>Provides a way for OSP to be
integrated into an OTP tree
+<h2><a name="index">Function Index</a></h2>
+<table width="100%" border="1" cellspacing="0" cellpadding="2"
summary="function index"><tr><td valign="top"><a
href="#init-1">init/1</a></td><td>Provides an OTP-eqse init function for
application integration.</td></tr>
+<tr><td valign="top"><a href="#terminate-2">terminate/2</a></td><td>Shuts
down the OSP application.</td></tr>
+</table>
+
+<h2><a name="functions">Function Details</a></h2>
+
+<h3 class="function"><a name="init-1">init/1</a></h3>
+<div class="spec">
+<p><tt>init(Args::list()) -&gt; {ok, pid(), pid()} | {error,
Reason}</tt></p>
+</div><p>Provides an OTP-eqse init function for application integration</p>
+
+<h3 class="function"><a name="terminate-2">terminate/2</a></h3>
+<div class="spec">
+<p><tt>terminate(Reason::atom(), State::pid()) -&gt; ok</tt></p>
+</div><p>Shuts down the OSP application</p>
+<hr>
+
+<div class="navbar"><a name="#navbar_bottom"></a><table width="100%"
border="0" cellspacing="0" cellpadding="2" summary="navigation
bar"><tr><td><a href="overview-summary.html"
target="overviewFrame">Overview</a></td><td><a
href="http://www.erlang.org/"><img src="erlang.png" align="right"
border="0" alt="erlang logo"></a></td></tr></table></div>
+<p><i>Generated by EDoc, Oct 30 2009, 20:13:44.</i></p>
+</body>
+</html>
=======================================
--- /dev/null
+++ /trunk/doc/osp_web.html Wed Nov 4 05:36:34 2009
@@ -0,0 +1,51 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>Module osp_web</title>
+<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
+</head>
+<body bgcolor="white">
+<div class="navbar"><a name="#navbar_top"></a><table width="100%"
border="0" cellspacing="0" cellpadding="2" summary="navigation
bar"><tr><td><a href="overview-summary.html"
target="overviewFrame">Overview</a></td><td><a
href="http://www.erlang.org/"><img src="erlang.png" align="right"
border="0" alt="erlang logo"></a></td></tr></table></div>
+<hr>
+
+<h1>Module osp_web</h1>
+<ul class="index"><li><a href="#description">Description</a></li><li><a
href="#index">Function Index</a></li><li><a href="#functions">Function
Details</a></li></ul>Provides the httpd and web interface for OSP.
+<p>Copyright © 2009 Jacob Torrey &lt;torr...@clarkson.edu&gt;</p>
+
+<p><b>Authors:</b> Jacob Torrey (<a
href="mailto:torr...@clarkson.edu"><tt>torr...@clarkson.edu</tt></a>).</p>
+
+<h2><a name="description">Description</a></h2>Provides the httpd and web
interface for OSP
+<h2><a name="index">Function Index</a></h2>
+<table width="100%" border="1" cellspacing="0" cellpadding="2"
summary="function index"><tr><td valign="top"><a
href="#clusterwide-3">clusterwide/3</a></td><td>Provides cluster wide ajax
callbacks for the web administrative system.</td></tr>
+<tr><td valign="top"><a href="#reload-0">reload/0</a></td><td>Reloads the
webserver configuration from file.</td></tr>
+<tr><td valign="top"><a href="#start-0">start/0</a></td><td>Starts the OSP
Web server.</td></tr>
+<tr><td valign="top"><a href="#stop-1">stop/1</a></td><td>Stops the Inets
web service.</td></tr>
+</table>
+
+<h2><a name="functions">Function Details</a></h2>
+
+<h3 class="function"><a name="clusterwide-3">clusterwide/3</a></h3>
+<div class="spec">
+<p><tt>clusterwide(Session, Env, Input) -&gt; any()</tt></p>
+</div><p>Provides cluster wide ajax callbacks for the web administrative
system</p>
+
+<h3 class="function"><a name="reload-0">reload/0</a></h3>
+<div class="spec">
+<p><tt>reload() -&gt; ok</tt></p>
+</div><p>Reloads the webserver configuration from file</p>
+
+<h3 class="function"><a name="start-0">start/0</a></h3>
+<div class="spec">
+<p><tt>start() -&gt; {ok, pid()}</tt></p>
+</div><p>Starts the OSP Web server</p>
+
+<h3 class="function"><a name="stop-1">stop/1</a></h3>
+<div class="spec">
+<p><tt>stop(Pid) -&gt; any()</tt></p>
+</div><p>Stops the Inets web service</p>
+<hr>
+
+<div class="navbar"><a name="#navbar_bottom"></a><table width="100%"
border="0" cellspacing="0" cellpadding="2" summary="navigation
bar"><tr><td><a href="overview-summary.html"
target="overviewFrame">Overview</a></td><td><a
href="http://www.erlang.org/"><img src="erlang.png" align="right"
border="0" alt="erlang logo"></a></td></tr></table></div>
+<p><i>Generated by EDoc, Oct 30 2009, 20:13:44.</i></p>
+</body>
+</html>
=======================================
--- /dev/null
+++ /trunk/doc/overview-summary.html Wed Nov 4 05:36:34 2009
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>The osp application</title>
+<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
+</head>
+<body bgcolor="white">
+<div class="navbar"><a name="#navbar_top"></a><table width="100%"
border="0" cellspacing="0" cellpadding="2" summary="navigation
bar"><tr><td><a href="overview-summary.html"
target="overviewFrame">Overview</a></td><td><a
href="http://www.erlang.org/"><img src="erlang.png" align="right"
border="0" alt="erlang logo"></a></td></tr></table></div>
+<h1>The osp application</h1>
+<p>Copyright © 2009 Jacob Torrey</p>
+<p><b>Authors:</b> Jacob Torrey (<a
href="mailto:torr...@clarkson.edu"><tt>torr...@clarkson.edu</tt></a>).</p>
+The Open Server Platform (OSP) is a framework designed to remove all but
the core server logic from
+developing highly-available, multi-threaded networked applications.
+<hr>
+<div class="navbar"><a name="#navbar_bottom"></a><table width="100%"
border="0" cellspacing="0" cellpadding="2" summary="navigation
bar"><tr><td><a href="overview-summary.html"
target="overviewFrame">Overview</a></td><td><a
href="http://www.erlang.org/"><img src="erlang.png" align="right"
border="0" alt="erlang logo"></a></td></tr></table></div>
+<p><i>Generated by EDoc, Oct 30 2009, 20:13:45.</i></p>
+</body>
+</html>
=======================================
--- /dev/null
+++ /trunk/doc/overview.edoc Wed Nov 4 05:36:34 2009
@@ -0,0 +1,4 @@
+@author Jacob Torrey <torr...@clarkson.edu>
+@copyright 2009 Jacob Torrey
+@doc The Open Server Platform (OSP) is a framework designed to remove all
but the core server logic from
+developing highly-available, multi-threaded networked applications.
=======================================
--- /dev/null
+++ /trunk/doc/packages-frame.html Wed Nov 4 05:36:34 2009
@@ -0,0 +1,11 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>The osp application</title>
+<link rel="stylesheet" type="text/css" href="stylesheet.css" title="EDoc">
+</head>
+<body bgcolor="white">
+<h2 class="indextitle">Packages</h2>
+<table width="100%" border="0" summary="list of packages"></table>
+</body>
+</html>
=======================================
--- /dev/null
+++ /trunk/doc/stylesheet.css Wed Nov 4 05:36:34 2009
@@ -0,0 +1,55 @@
+/* standard EDoc style sheet */
+body {
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ margin-left: .25in;
+ margin-right: .2in;
+ margin-top: 0.2in;
+ margin-bottom: 0.2in;
+ color: #000000;
+ background-color: #ffffff;
+}
+h1,h2 {
+ margin-left: -0.2in;
+}
+div.navbar {
+ background-color: #add8e6;
+ padding: 0.2em;
+}
+h2.indextitle {
+ padding: 0.4em;
+ background-color: #add8e6;
+}
+h3.function,h3.typedecl {
+ background-color: #add8e6;
+ padding-left: 1em;
+}
+div.spec {
+ margin-left: 2em;
+ background-color: #eeeeee;
+}
+a.module,a.package {
+ text-decoration:none
+}
+a.module:hover,a.package:hover {
+ background-color: #eeeeee;
+}
+ul.definitions {
+ list-style-type: none;
+}
+ul.index {
+ list-style-type: none;
+ background-color: #eeeeee;
+}
+
+/*
+ * Minor style tweaks
+ */
+ul {
+ list-style-type: square;
+}
+table {
+ border-collapse: collapse;
+}
+td {
+ padding: 3
+}
=======================================
--- /dev/null
+++ /trunk/ebin/osp.app Wed Nov 4 05:36:34 2009
@@ -0,0 +1,8 @@
+{application, osp,
+ [{description, "Open Server Platform"},
+ {vsn, "0.4"},
+ {modules, [osp, osp_app, osp_admin, osp_broker, osp_mnesia,
osp_socket, osp_proto, osp_servlet, osp_compile, osp_file, osp_sup,
osp_web, osp_recover]},
+ {registered, [osp_admin]},
+ {applications, [kernel, sasl, stdlib, os_mon, inets]},
+ {mod, {osp_app, []}}
+]}.
=======================================
--- /dev/null
+++ /trunk/include/conf.hrl Wed Nov 4 05:36:34 2009
@@ -0,0 +1,31 @@
+% OSP Server Configuration
+
+% Use FQDNs
+-define(USEFQDN, false).
+
+% The name of this node (if the above is true, this must be a FQDN)
+-define(NODENAME, 'master@localhost').
+
+% Port the admin console should listen on
+-define(ADMINPORT, 9876).
+
+% The secret cookie
+-define(COOKIE, 'AMOJDKFJHEJDHJKSJDY').
+
+% Auto started applications as {name, port} tuples
+-define(AUTO_STARTED, []).
+
+% Allowed diskless client IPs
+-define(ALLOWED_DISKLESS, ['127.0.0.1']).
+
+% Whether the application filesystem is just on the master node, or shared
(like NFS)
+-define(SHARED_FS, false).
+
+% The prefix of the application file area
+-define(FS_PREFIX, "/tmp").
+
+% Where OSP will store the compiled applications
+-define(APP_DIR, "apps").
+
+% Where OSP will store the application source code
+-define(SRC_DIR, "servlets").
=======================================
--- /dev/null
+++ /trunk/include/httpd.conf Wed Nov 4 05:36:34 2009
@@ -0,0 +1,25 @@
+[
+ {modules, [
+ mod_log,
+ mod_alias,
+ mod_esi,
+ mod_actions,
+ mod_get,
+ mod_head,
+ mod_range
+ ]}, {port, 9877},
+ {server_name, "osp_serv"},
+ {server_root, "log"},
+ {document_root, "www"},
+ {error_log, "error.log"},
+ {security_log, "security.log"},
+ {transfer_log, "transfer.log"},
+ {directory_index, ["index.html"]},
+ {mime_types, [
+ {"html","text/html"},
+ {"css","text/css"},
+ {"js","application/x-javascript"}
+ ]},
+ {erl_script_alias, {"/app", [osp_web]}},
+ {bind_address, any}
+].
=======================================
--- /dev/null
+++ /trunk/log/.gitignore Wed Nov 4 05:36:34 2009
@@ -0,0 +1,1 @@
+*
=======================================
--- /dev/null
+++ /trunk/servlets/db.sdf Wed Nov 4 05:36:34 2009
@@ -0,0 +1,53 @@
+<?xml version="1.0"?>
+<!DOCTYPE osp-servlet PUBLIC "-//Jacob Torrey//Open Server Platform
Servlet//EN" "http://www.openserverplatform.com/osp-servlet.dtd">
+<osp-servlet>
+ <author>Jacob Ian Torrey</author>
+ <name>db</name>
+ <version>0.1</version>
+ <proto>tcp</proto>
+ <code>
+ <init><![CDATA[
+ init() ->
+ io:format("~p is starting!~n", [?MODULE]).
+ ]]></init>
+ <server><![CDATA[
+ server(Sock) ->
+ ReqBin = recv(Sock, 0),
+ Req = erlang:binary_to_list(ReqBin),
+ Req1 = string:strip(Req, right, $\n),
+ Req2 = string:strip(Req1, right, $\r),
+ Comm = string:tokens(Req2, " "),
+ case lists:nth(1, Comm) of
+ "set" ->
+ case length(Comm) of
+ 3 ->
+ Var = erlang:list_to_atom(lists:nth(2, Comm)),
+ Val = lists:last(Comm),
+ store(Var, Val),
+ sendf(Sock, "Wrote ~p ~p~n", [Var, Val]),
+ close(Sock);
+ _ ->
+ send(Sock, "ERROR\n"),
+ close(Sock)
+ end;
+ "get" ->
+ case length(Comm) of
+ 2 ->
+ Var = erlang:list_to_atom(lists:last(Comm)),
+ sendf(Sock, "~p~n", [retrieve(Var)]),
+ close(Sock);
+ _ ->
+ send(Sock, "ERROR\n"),
+ close(Sock)
+ end;
+ _ ->
+ send(Sock, "ERROR\n"),
+ close(Sock)
+ end.
+ ]]></server>
+ <cleanup><![CDATA[
+ cleanup() ->
+ io:format("~p is stopping!~n", [?MODULE]).
+ ]]></cleanup>
+ </code>
+</osp-servlet>
=======================================
--- /dev/null
+++ /trunk/servlets/echo.sap Wed Nov 4 05:36:34 2009
@@ -0,0 +1,37 @@
+PK
+°Š:
+RÍ T
+ echo.sdfUT
ºùßIyíéJux è è }RÁnâ0 =“¯ ,­”H!¦W6 µÀ U» -=T Ui2 kƒmÙ ŠVÛo_Û1l¹TòÁ~óæÍ¼ ç£÷] Tš
>$7YŸŒŠ(ïNæãåób
+BËžFuhÐÀâéî~6 Ò£ôGY‰WX
+¥ðDé\"‡GËB ‹¦4 ¡vþm³( þ$@¶ÆÈ ¥Çã1 –­=Y nV‰
+ýT)«MMl Ÿ " È˽Ù
+U´Åg%
+ä4
+‡—;,°ÚŠœú«Ã‚½¢ŸÝäôüp ©„
+©dNÛ« +Q·iŒ3SäÝÕxr»¼]YÄ q = µ/1pÍ—&& ˜ mJe ë~p’Âjô0Ÿ<ÝO×Iféëu‘S/è”[ûWÚ- ?Šê÷¥‚6Baìl¤@
+Nàl b—$©çüB
+CPX
+|n
+ý `›¨ó
+f 0[ mCvƒ¶Éª k rÀwf¢ŽW á *%T ]
+'äX1wN›ä»ÓœÛdudÚv¥P6§¨cÔ
+/ü빸ãÇ ª)ùÛà•ñR ^Œxi˜6±-ž8 £
+Z¯ÉÚ:ðJ y
+\yÞ ý?)ïÔ².# “õ{l°ä{y5å€}¹D!åWK<˺ ´ý+9½ú©ÿ PK
+°Š: jºñ ¼
+ echo2.sdfUT ºùßIúgèJux è è }SÁn 1 =³_1lUiQa
+=ÒeQ
+
+¨’€ r¨ Š6»C°jlË6 T5ß^Ûk ¨Uoö›7óÞŒÇÙðuË` JSÁ q/íÆÃ<ÊšãÙhñc> ¡eG£Ú340 üz;
+AÜ!ä[QŠgX ¥ðHÈL"‡ ËB sV˜µP[ ·Y„Lîcˆ7ÆÈ>!‡Ã! –­=Y nZŠ-¹PJ+SÅÖÅ ”G Y±3 ¡òZ|
Zð` #!à8¼ØbŽåF|Έ?;0ô—wÓ^FN J ‘›Rf¤>:° U F95yÖ\ŽÆ7‹›¥E
+ ´ ã¢ Ú
+I)vÜ´¡Ûj{ оk©0Iü& jË*”¡ü¥ùÆã6,‡w³ñãídÕJ-}µÊ3âUœ\=”+Á J
+Dùó,{¿Û Eq ôƒø•#Çû ½¿} EnàƒõW
+α4X w6g ˜ ² Ný=º„N^¾£ö^ʽÇ/Æ°Ž aº ³AÐ6d÷Ç £dBcå@ øJMÔð ú ø
+J Õ ŒßN á
+9V sÖúâjÎl²:P m«+Ù1j µÃ3ÿjþuS¨XÁ_úÏ” êødÄ £Ú$V¸åzõY y :px@ßûõ=YÎùÑÂ[ùuaXð ¼z·€½ïÊ?ÖBHù¿µ8•u ¤^ÉŒ\ýˆ?PK
+
+°Š:
+RÍ T ¤ echo.sdfUT ºùßIux è è PK
+
+°Š: jºñ ¼
¤ echo2.sdfUT ºùßIux è è PK C
=======================================
--- /dev/null
+++ /trunk/servlets/echo.sdf Wed Nov 4 05:36:34 2009
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+<!DOCTYPE osp-servlet PUBLIC "-//Jacob Torrey//Open Server Platform
Servlet//EN" "http://www.openserverplatform.com/osp-servlet.dtd">
+<osp-servlet>
+ <author>Jacob Ian Torrey</author>
+ <name>echo</name>
+ <version>0.1</version>
+ <proto>tcp</proto>
+ <code>
+ <init><![CDATA[
+ init() ->
+ io:format("~p is starting!~n", [?MODULE]).
+ ]]></init>
+ <server><![CDATA[
+ server(Sock) ->
+ store(name, "My echo server!"),
+ Res = recv(Sock, 0),
+ if
+ % If the socket is closed then exit
+ Res =:= {error, closed} ->
+ exit(normal);
+ % Otherwise, reply
+ true ->
+ io:format("~p ~p ~n", [erlang:binary_to_list(Res), retrieve(name)]),
+ send(Sock, Res),
+ server(Sock)
+ end.
+ ]]></server>
+ <cleanup><![CDATA[
+ cleanup() ->
+ io:format("~p is stopping!~n", [?MODULE]).
+ ]]></cleanup>
+ </code>
+</osp-servlet>
=======================================
--- /dev/null
+++ /trunk/servlets/echo2.sdf Wed Nov 4 05:36:34 2009
@@ -0,0 +1,39 @@
+<?xml version="1.0"?>
+<!DOCTYPE osp-servlet PUBLIC "-//Jacob Torrey//Open Server Platform
Servlet//EN" "http://www.openserverplatform.com/osp-servlet.dtd">
+<osp-servlet>
+ <author>Jacob Ian Torrey</author>
+ <name>echo2</name>
+ <version>0.1</version>
+ <proto>tcp</proto>
+ <code>
+ <init><![CDATA[
+ init() ->
+ store(count, 0),
+ io:format("~p is starting!~n", [?MODULE]).
+ ]]></init>
+ <server><![CDATA[
+ server(Sock) ->
+ Num = retrieve(count),
+ store(count, Num + 1),
+ io:format("Client #~p connected!~n", [Num]),
+ loop(Sock).
+
+ loop(Sock) ->
+ Res = recv(Sock, 0),
+ if
+ % If the socket is closed then exit
+ Res =:= {error, closed} ->
+ exit(normal);
+ % Otherwise, reply
+ true ->
+ io:format("~p~n", [erlang:binary_to_list(Res)]),
+ send(Sock, Res),
+ loop(Sock)
+ end.
+ ]]></server>
+ <cleanup><![CDATA[
+ cleanup() ->
+ io:format("~p is stopping!~n", [?MODULE]).
+ ]]></cleanup>
+ </code>
+</osp-servlet>
=======================================
--- /dev/null
+++ /trunk/servlets/my_httpd.sdf Wed Nov 4 05:36:34 2009
@@ -0,0 +1,134 @@
+<?xml version="1.0"?>
+<!DOCTYPE osp-servlet PUBLIC "-//Jacob Torrey//Open Server Platform
Servlet//EN" "http://www.openserverplatform.com/osp-servlet.dtd">
+<osp-servlet>
+ <author>Jacob Ian Torrey</author>
+ <name>my_httpd</name>
+ <version>0.1</version>
+ <proto>tcp</proto>
+ <code>
+ <init><![CDATA[
+ init() ->
+ ok.
+ ]]></init>
+ <server><![CDATA[
+
+-define(DIR, ".").
+
+server(Sock) ->
+ case recv(Sock, 0) of
+ {error, closed} ->
+ exit(normal);
+ D ->
+ Str = erlang:binary_to_list(D),
+ Tokens = string:tokens(Str, " "),
+ [Req, Dir | _] = Tokens,
+ case Req of
+ "GET" ->
+ case filelib:is_file(?DIR ++ Dir) of
+ true ->
+ send(Sock, "HTTP/1.0 200 OK\r\n"),
+ {Size, FP} = handle(?DIR ++ Dir),
+ send(Sock, "Content-Length: " ++ erlang:integer_to_list(Size)
++ "\r\n"),
+ send_file(Sock, FP),
+ close_file(FP),
+ close(Sock);
+ false ->
+ send(Sock, "HTTP/1.0 404 Not Found\r\nContent-Type:
text/html\r\n\r\n<html><head><title>File Not Found</title></head><body>404
File Not Found</body></html>"),
+ close(Sock)
+ end;
+ "HEAD" ->
+ case filelib:is_file(?DIR ++ Dir) of
+ true ->
+ send(Sock, "HTTP/1.0 200 OK\r\n"),
+ {Size, FP} = handle(?DIR ++ Dir),
+ send(Sock, "Content-Length: " ++ erlang:integer_to_list(Size)
++ "\r\n"),
+ close_file(FP),
+ close(Sock);
+ false ->
+ send(Sock, "HTTP/1.0 404 Not Found\r\nContent-Type:
text/html\r\n\r\n<html><head><title>File Not Found</title></head><body>404
File Not Found</body></html>"),
+ close(Sock)
+ end
+ end
+ end,
+ exit(normal).
+
+%% @doc Sends the data to the client, automagically switching between
dumping and reading/dumping
+send_file(Sock, {data, Data}) ->
+ send(Sock, Data);
+send_file(Sock, {handle, Mime, FP}) ->
+ send(Sock, "Content-Type: " ++ Mime ++ "\r\n\r\n"),
+ send_rec(Sock, FP).
+
+%% @doc The recursize helper to send large files in chunks
+send_rec(Sock, FP) ->
+ case file:read(FP, 1024) of
+ {ok, Data} ->
+ send(Sock, Data),
+ send_rec(Sock, FP);
+ _ ->
+ ok
+ end.
+
+%% @doc Closes the file (if needed)
+close_file({handle, _, FP}) ->
+ file:close(FP);
+close_file(_) ->
+ ok.
+
+%% @doc Handles different types of files
+handle(File) ->
+ Tokens = string:tokens(File, "."),
+ [Type|_] = lists:reverse(Tokens),
+ case Type of
+ "/" ->
+ Mime = get_mime("html"),
+ Dat = "<html>\n<head>\n<title>Welcome to the OSP test
webserver</title>\n</head>\n<body>Welcome to OSP's test
webserver\n</body>\n</html>",
+ Res = {data, add_res(Mime, Dat)};
+ "cgi" ->
+ Res = {data, os:cmd(File)};
+ "pl" ->
+ Res = {data, os:cmd(File)};
+ "php" ->
+ Res = {data, os:cmd("php-cgi " ++ File)};
+ _ ->
+ Mime = get_mime(string:to_lower(Type)),
+ {ok, FP} = file:open(File, [read, binary]),
+ Res = {handle, Mime, FP}
+ end,
+ case Res of
+ {data, Data} ->
+ Tuple = {string:len(Data), {data, Data}};
+ {handle, M, F} ->
+ Tuple = {filelib:file_size(File), {handle, M, F}}
+ end,
+ Tuple.
+
+%% @doc A function to auotmatically add the Content-Type header to the
response
+add_res(Mime, Dat) when is_binary(Dat) ->
+ "Content-Type: " ++ Mime ++ "\r\n\r\n" ++ erlang:binary_to_list(Dat);
+add_res(Mime, Dat) when is_list(Dat) ->
+ "Content-Type: " ++ Mime ++ "\r\n\r\n" ++ Dat;
+add_res(Mime, Dat) ->
+ "Content-Type: " ++ Mime ++ "\r\n\r\n" ++ erlang:atom_to_list(Dat).
+
+%% @doc Returns the MIME type of a file
+get_mime("html") ->
+ "text/html";
+get_mime("css") ->
+ "text/css";
+get_mime("js") ->
+ "text/javascript";
+get_mime("jpg") ->
+ "image/jpeg";
+get_mime("jpeg") ->
+ "image/jpeg";
+get_mime(_) ->
+ "text/plain".
+
+]]></server>
+ <cleanup><![CDATA[
+ cleanup() ->
+ ok.
+ ]]></cleanup>
+</code>
+</osp-servlet>
=======================================
--- /dev/null
+++ /trunk/src/Makefile Wed Nov 4 05:36:34 2009
@@ -0,0 +1,12 @@
+osp:
+ erlc osp_servlet.erl
+ erlc -o ../ebin *.erl
+ rm osp_servlet.beam
+hipe:
+ erlc -smp +"[native, {hipe, [o3]}]" osp_servlet.erl
+ erlc -smp +"[native, {hipe, [o3]}]" -o ../ebin *.erl
+ rm osp_servlet.beam
+clean:
+ -rm ../ebin/osp*.beam *~ ../erl_crash.dump ../osp_rel* ../mnesia/*
+docs:
+ cd .. && erl -pa ./ebin -s osp gen_docs
=======================================
--- /dev/null
+++ /trunk/src/osp.erl Wed Nov 4 05:36:34 2009
@@ -0,0 +1,84 @@
+%% @copyright 2009 Jacob Torrey <torr...@clarkson.edu>
+%% @author Jacob Torrey <torr...@clarkson.edu>
+%% @doc The exports for controlling the OSP system as a whole
+-module(osp).
+-export([start/0, stop/1, join/1, setup/0, gen_docs/0]).
+
+-include("../include/conf.hrl").
+
+-define(VERSION, "0.4").
+
+%% @doc Starts the first 'master' node
+%% @spec start() -> {ok, Pid, pid()} | {error, Reason}
+start() ->
+ case ?USEFQDN of
+ true ->
+ net_kernel:start([?NODENAME]);
+ false ->
+ net_kernel:start([?NODENAME, shortnames])
+ end,
+ erlang:set_cookie(node(), ?COOKIE),
+ code:add_path(?APP_DIR),
+ application:start(mnesia),
+ Pid = osp_broker:start(osp_admin, ?ADMINPORT),
+ case Pid of
+ {error, Err} ->
+ {error, Err};
+ _ ->
+ {ok, Pid, osp_web:start()}
+ end.
+
+%% @doc Stops OSP on this node
+%% @spec stop(Pid) -> ok
+stop(Pid) ->
+ osp_broker:stop(osp_admin),
+ osp_broker:shutdown(),
+ osp_web:stop(Pid).
+
+%% @doc Setups mnesia and the OTP rel scripts for the first time
+%% @spec setup() -> ok
+setup() ->
+ case ?USEFQDN of
+ true ->
+ net_kernel:start([?NODENAME]);
+ false ->
+ net_kernel:start([?NODENAME, shortnames])
+ end,
+ erlang:set_cookie(node(), ?COOKIE),
+ write_rel(),
+ mnesia:create_schema([node()]),
+ init:stop().
+
+%% @doc Joins node to an existing OSP cluster
+%% @spec join(list()) -> pong | pang
+join([Node]) ->
+ application:start(sasl),
+ application:start(os_mon),
+ net_adm:ping(Node).
+
+%% @doc Dynamically gets the version of all the required applications to
run OSP
+%% @spec get_vsn(atom()) -> list()
+get_vsn(Module) ->
+ AppFile = code:lib_dir(Module) ++ "/ebin/" ++ atom_to_list(Module)
++ ".app",
+ {ok, [{application, _App, Attrs}]} = file:consult(AppFile),
+ {value, {vsn, Vsn}} = lists:keysearch(vsn, 1, Attrs),
+ Vsn.
+
+%% @doc Writes the .rel file and generates the boot scripts for the first
OSP run
+%% @spec write_rel() -> ok
+write_rel() ->
+ F = lists:append(["{release, {\"osp_rel\",\"",?VERSION,"\"}, \n",
+ "{erts,\"",erlang:system_info(version),"\"},\n"
+ "[{kernel,\"",get_vsn(kernel),"\"},\n",
+ "{stdlib,\"",get_vsn(stdlib),"\"},\n",
+ "{os_mon,\"",get_vsn(os_mon),"\"},\n",
+ "{inets,\"",get_vsn(inets),"\"},\n",
+ "{sasl,\"",get_vsn(sasl),"\"},\n",
+ "{osp,\"",?VERSION,"\"}]}.\n"]),
+ ok = file:write_file("osp_rel-" ++ ?VERSION ++ ".rel", F),
+ systools:make_script("osp_rel-" ++ ?VERSION, [local]).
+
+%% @doc Provides an export to regenerate the documentation with edoc
+%% @spec gen_docs() -> ok
+gen_docs() ->
+ edoc:application(osp, ".", []).
=======================================
--- /dev/null
+++ /trunk/src/osp_admin.erl Wed Nov 4 05:36:34 2009
@@ -0,0 +1,312 @@
+%% @author Jacob Ian Torrey <torr...@clarkson.edu>
+%% @copyright 2009 Jacob Torrey <torr...@clarkson.edu>
+%% @version 0.4
+%% @doc Provides an interface to administer the OSP cluster
+-module(osp_admin).
+-behavior(osp_servlet).
+
+% Export OSP server callback
+-export([start_mnesia/0, server/1, init/0, cleanup/0, proto/0]).
+
+% Export the admin functions for the web console
+-export([shutdown_osp/0, stats_osp/0, uptime_osp/0, nodeapp/0]).
+
+% Include the OSP configuration
+-include("../include/conf.hrl").
+
+% Import the OSP socket library
+-import(osp_socket, [send/2, recv/2, sendf/3, close/1]).
+
+% Define the Mnesia record
+-record(osp_table, {key, val}).
+
+%% @doc Stores a value in the mnesia database
+%% @spec store(atom(), any()) -> ok
+store(Key, Val) ->
+ osp_mnesia:store(osp_admin_table, Key, Val).
+
+%% @doc Gets a value from the mnesia database
+retrieve(Key) ->
+ osp_mnesia:retrieve(osp_admin_table, Key).
+
+%% @doc Returns the protocol for the application (this is a TCP applcation)
+%% @spec proto() -> tcp
+proto() ->
+ tcp.
+
+%% @doc The mnesia startup routine for osp_admin
+%% @spec start_mnesia() -> ok
+start_mnesia() ->
+ case lists:member(mnesia_sup, erlang:registered()) of
+ true ->
+ ok;
+ false ->
+ mnesia:start()
+ end,
+ case catch(mnesia:table_info(osp_admin_table, all)) of
+ {'EXIT', _} ->
+ mnesia:create_table(osp_admin_table, [{record_name, osp_table},
{disc_copies, [node()]}, {attributes, record_info(fields, osp_table)}]);
+ _ ->
+ ok
+ end,
+ ok.
+
+%% @doc Returns the App-Node listing for the cluster
+%% @spec nodeapp() -> list()
+nodeapp() ->
+ retrieve(nodeapp).
+
+%% @doc The main server loop
+%% @spec server(tuple()) -> none()
+server(Sock) ->
+ {tcp, S} = Sock,
+ RH = inet:peername(S),
+ case RH of
+ {ok, {{127, 0, 0, 1}, _}} ->
+ send(Sock, <<"-> ">>),
+ handlecommand(Sock, recv(Sock, 0)),
+ server(Sock);
+ _ ->
+ close(Sock)
+ end.
+
+%% @doc Parses incoming command from the telnet console and performs the
command if valid
+handlecommand(Sock, Msg) ->
+ String = erlang:binary_to_list(Msg),
+ String2 = string:strip(String, right, $\n),
+ String3 = string:strip(String2, right, $\r),
+ case String3 of
+ "help" -> % Print out the help message
+ send(Sock, <<"OSP Admin Console\n\tquit - Quits the console\n\tstats
- Prints general stats about the OSP cluster\n\tstart <appname> <port>
<node> - Starts appname on node\n\tadd-diskless-ip <ip> - Adds IP to the
allowed diskless server pool\n\tshutdown - Shutdown OSP on all
nodes\n\tadd-backup-server <node> <type> - Makes node a backup server
keeping an up-to-date copy of all the shared state in the cluster; type may
be ram for faster, non-persistant storage, or disk for data
persistance\n\tstop <appname> <node> - Stops the given servlet on
node\n\tmigrate <appname> <fromnode> <tonode> <port> - Migrates a servlet
from fromnode to tonode, starting it on the given port\n">>);
+ "stats" -> % Display some stats
+ send(Sock, stats_osp());
+ "quit" ->
+ close(Sock),
+ exit(normal);
+ "shutdown" ->
+ send(Sock, "Shutting down\r\n"),
+ close(Sock),
+ shutdown_osp();
+ "" ->
+ ok;
+ Unknown -> % Handle multi-word command
+ Split = string:tokens(Unknown, " "),
+ [Comm | _] = Split, % Parse out the command from the arguments
+ case Comm of
+ "start" ->
+ [Comm, AppList, PortList, NodeList ] = Split,
+ Port = erlang:list_to_integer(PortList),
+ App = erlang:list_to_atom(AppList),
+ Node = erlang:list_to_atom(NodeList),
+ case start_servlet(App, Port, Node) of
+ ok ->
+ sendf(Sock, "~p started on ~p port ~p~n", [App, Node, Port]);
+ error ->
+ send(Sock, "Sorry, the node you requested couldn't be found\r\n")
+ end;
+ "migrate" ->
+ [Comm, AppList, FromNodeList, NodeList, PortList ] = Split,
+ Port = erlang:list_to_integer(PortList),
+ From = erlang:list_to_atom(FromNodeList),
+ App = erlang:list_to_atom(AppList),
+ Node = erlang:list_to_atom(NodeList),
+ case start_servlet(App, Port, Node) of
+ ok ->
+ sendf(Sock, "~p started on ~p port ~p~n", [App, Node, Port]);
+ error ->
+ send(Sock, "Sorry, the node you requested couldn't be found\r\n")
+ end,
+ case stop_servlet(App, From) of
+ ok ->
+ sendf(Sock, "Stopped ~p on ~p ~n", [App, Node]);
+ error ->
+ send(Sock, "Sorry, the node you requested couldn't be found\r\n")
+ end;
+ "add-diskless-ip" ->
+ [Comm, IPList] = Split,
+ IP = erlang:list_to_atom(IPList),
+ erl_boot_server:add_slave(IP),
+ sendf(Sock, "Added ~p to the allowed diskless server pool~n", [IP]);
+ "add-backup-server" ->
+ [Comm, NodeL, TypeL] = Split,
+ Node = erlang:list_to_atom(NodeL),
+ Type = erlang:list_to_atom(TypeL),
+ rpc:call(Node, mnesia, start, []),
+ case Type of
+ ram ->
+ rpc:call(Node, mnesia, change_config, [extra_db_nodes, [node()]]),
+ bkup_db(Node, ram_copies);
+ disk ->
+ rpc:call(Node, mnesia, change_config, [extra_db_nodes, [node()]]),
+ rpc:call(Node, mnesia, change_table_copy_type, [schema, Node,
disc_copies]),
+ bkup_db(Node, disc_copies);
+ _ ->
+ send(Sock, "Sorry, unknown backup type: " ++ TypeL ++ "\r\n")
+ end;
+ "stop" ->
+ [Comm, AppL, NodeL] = Split,
+ App = erlang:list_to_atom(AppL),
+ Node = erlang:list_to_atom(NodeL),
+ case stop_servlet(App, Node) of
+ ok ->
+ sendf(Sock, "Stopped ~p on ~p ~n", [App, Node]);
+ error ->
+ send(Sock, "Sorry, the node you requested couldn't be found\r\n")
+ end;
+ _ ->
+ send(Sock, "Sorry, unknown command " ++ Unknown ++ "\r\n")
+ end
+ end.
+
+%% @todo This needs to update on every start of a new application
+%% @spec bkup_db(node(), atom()) -> ok
+bkup_db(Node, Type) ->
+ Tables = mnesia:system_info(tables),
+ F = fun(TableName) ->
+ mnesia:add_table_copy(TableName, Node, Type),
+ rpc:call(Node, mnesia, wait_for_tables, [[TableName], 1000])
+ end,
+ lists:foreach(F, Tables),
+ ok.
+
+%% @doc Starts an appropriately typed table copy for a passed
+%% @spec start_db(node(), atom()) -> ok | error
+start_db(Node, App) ->
+ TableName = erlang:list_to_atom(erlang:atom_to_list(App) ++ "_table"),
+ rpc:call(Node, mnesia, start, []),
+ case rpc:call(Node, init, get_argument, [loader]) of
+ error ->
+ rpc:call(Node, mnesia, change_config, [extra_db_nodes, [node()]]),
+ rpc:call(Node, mnesia, change_table_copy_type, [schema, Node,
disc_copies]),
+ mnesia:add_table_copy(TableName, Node, disc_copies);
+ {ok, [["inet"]]} ->
+ mnesia:add_table_copy(TableName, Node, ram_copies),
+ rpc:call(Node, mnesia, change_config, [extra_db_nodes, [node()]]);
+ {ok, [["efile"]]} ->
+ rpc:call(Node, mnesia, change_config, [extra_db_nodes, [node()]]),
+ rpc:call(Node, mnesia, change_table_copy_type, [schema, Node,
disc_copies]),
+ mnesia:add_table_copy(TableName, Node, disc_copies)
+ end,
+ rpc:call(Node, mnesia, wait_for_tables, [[TableName], 1000]),
+ ok.
+
+%% @doc Returns a human readable string from a tuple version of an IP
address
+%% @spec ip_to_string(tuple()) -> string()
+ip_to_string({A, B, C, D}) ->
+ erlang:integer_to_list(A) ++ "." ++ erlang:integer_to_list(B) ++ "."
++ erlang:integer_to_list(C) ++ "." ++ erlang:integer_to_list(D).
+
+%% @doc Returns a string of the allowed slave IPs
+%% @spec get_ok_slaves() -> string()
+get_ok_slaves() ->
+ Slaves = erl_boot_server:which_slaves(),
+ Fun = fun({NM, IP}, A) ->
+ A ++ "\tIP: " ++ ip_to_string(IP) ++ " Netmask: " ++ ip_to_string(NM)
++ "\r\n"
+ end,
+ lists:foldl(Fun, [], Slaves).
+
+%% @doc This returns a string of the OSP cluster statistics
+%% @spec stats_osp() -> list()
+stats_osp() ->
+ F = fun(Node, A) -> A ++ io_lib:format("~p: ~.2f\r\n", [Node,
round(100 * rpc:call(Node, cpu_sup, avg1, []) / 256) / 100]) end,
+ Out1 = "Nodes in the cluster and their CPU Utilization: \r\n",
+ Out2 = lists:foldl(F, Out1, [node() | nodes()]),
+ Out2 ++ "The following IPs are allowed to be diskless:\r\n" ++
get_ok_slaves().
+
+%% @doc Attempts to find and stop an application on the cluster
+%% @spec stop_servlet(atom(), node()) -> ok | error
+stop_servlet(App, Node) ->
+ case lists:member(Node, [node() | nodes()]) of
+ true ->
+ if
+ Node =:= node() ->
+ osp_broker:stop(App);
+ true->
+ rpc:call(Node, osp_broker, stop, [App])
+ end,
+ del_app_from_list(Node, App),
+ ok;
+ false ->
+ error
+ end.
+
+%% @doc Starts a servlet application on a given node
+%% @spec start_servlet(atom(), int(), node()) -> ok | error
+start_servlet(App, Port, Node) ->
+ case lists:member(Node, [node() | nodes()]) of
+ true ->
+ if
+ Node =:= node() ->
+ osp_broker:start(App, Port);
+ true->
+ start_db(Node, App),
+ rpc:call(Node, osp_broker, start, [App, Port])
+ end,
+ add_app_to_list(Node, App, Port),
+ ok;
+ false ->
+ error
+ end.
+
+%% @doc Returns a human readable string of the cluster uptime
+%% @spec uptime_osp() -> list()
+uptime_osp() ->
+ Seconds = retrieve(uptime),
+ NSeconds =
calendar:datetime_to_gregorian_seconds(erlang:universaltime()),
+ {{_, _, Days}, {Hours, Mins, Secs}} =
calendar:gregorian_seconds_to_datetime(NSeconds - Seconds),
+ erlang:integer_to_list(Days - 1) ++ " days " ++
erlang:integer_to_list(Hours) ++ " hrs " ++ erlang:integer_to_list(Mins)
++ " mins " ++ erlang:integer_to_list(Secs) ++ " secs".
+
+%% @doc Shuts down the entire OSP cluster, and quits the Erlang VM
+%% @spec shutdown_osp() -> ok
+shutdown_osp() ->
+ F = fun(Node) ->
+ rpc:call(Node, init, stop, [])
+ end,
+ lists:foreach(F, nodes()),
+ init:stop().
+
+%% @doc Routine for starting the master boot server and autostarted
applications
+%% @spec init() -> ok
+init() ->
+ erl_boot_server:start(['127.0.0.1']),
+ DL = fun(IP) ->
+ erl_boot_server:add_slave(IP)
+ end,
+ lists:foreach(DL, ?ALLOWED_DISKLESS),
+ store(uptime,
calendar:datetime_to_gregorian_seconds(erlang:universaltime())),
+ case retrieve(nodeapp) of
+ undefined ->
+ store(nodeapp, [{node(), [{osp_admin, ?ADMINPORT}]}]);
+ _ ->
+ add_app_to_list(node(), osp_admin, ?ADMINPORT)
+ end,
+ F = fun({App, Port}) ->
+ start_servlet(App, Port, node())
+ end,
+ lists:foreach(F, ?AUTO_STARTED),
+ ok.
+
+%% @doc A callback for the OSP broker service
+%% @spec cleanup() -> ok
+cleanup() ->
+ ok.
+
+%% @doc Deletes an application from the list of running applications
+%% @spec del_app_from_list(atom(), atom()) -> ok
+del_app_from_list(Node, App) ->
+ NodeApp = retrieve(nodeapp),
+ {Node, AppList} = lists:keyfind(Node, 1, NodeApp),
+ AL2 = lists:keydelete(App, 1, AppList),
+ store(nodeapp, lists:keyreplace(Node, 1, NodeApp, {Node, AL2})),
+ ok.
+
+%% @doc Adds an application to the list of running applications
+%% @spec add_app_to_list(atom(), atom(), integer()) -> ok
+add_app_to_list(Node, App, Port) ->
+ Nodeapp = retrieve(nodeapp),
+ case lists:keyfind(Node, 1, Nodeapp) of
+ false ->
+ store(nodeapp, [{Node, [{App, Port}]} | Nodeapp]);
+ {Node, AppList} ->
+ store(nodeapp, lists:keyreplace(Node, 1, Nodeapp, {Node, AppList ++
[{App, Port}]}))
+ end,
+ ok.
=======================================
--- /dev/null
+++ /trunk/src/osp_app.erl Wed Nov 4 05:36:34 2009
@@ -0,0 +1,15 @@
+%% @copyright 2009 Jacob Torrey <torr...@clarkson.edu>
+%% @author Jacob Torrey <torr...@clarkson.edu>
+%% @doc Provides the application callbacks for OSP
+-module(osp_app).
+-behavior(application).
+
+-export([start/2, stop/1]).
+
+%% @doc Starts the OSP application
+start(_Type, _StartArgs) ->
+ supervisor_bridge:start_link({local, osp_supervisor}, osp_sup, []).
+
+%% @doc Stops the OSP application
+stop(_State) ->
+ exit(whereis(osp_supervisor), shutdown).
=======================================
--- /dev/null
+++ /trunk/src/osp_broker.erl Wed Nov 4 05:36:34 2009
@@ -0,0 +1,96 @@
+%% @author Jacob Torrey <torr...@clarkson.edu>
+%% @copyright 2009 Jacob Torrey <torr...@clarkson.edu>
+%% @doc A socket request broker
+-module(osp_broker).
+-author('Jacob Torrey <torr...@clarkson.edu>').
+
+-export([start/2, stop/1, shutdown/0]).
+
+%% @doc Shuts down the Mnesia database
+%% @spec shutdown() -> ok
+shutdown() ->
+ ok.
+
+%% @doc Stops the server broker and all it's children processes
+%% @spec stop(atom()) -> ok
+stop(Name) ->
+ Name ! stop,
+ ok.
+
+%% @doc Ensures that there are no options that will break OSP's
functionality (i.e. {active, true})
+%% @spec ensure_valid_opts(list()) -> list()
+%% @todo Finish this function!!!
+ensure_valid_opts(Opts) ->
+ Opts.
+
+%% @doc Starts the server named Name on port Port
+%% @spec start(atom(), int()) -> ok | {error, Reason}
+start(Name, Port) ->
+ Proto = apply(Name, proto, []),
+ code:load_file(Name),
+ case erlang:function_exported(Name, sockopts, 1) of
+ true ->
+ case catch(apply(Name, sockopts, [Proto])) of
+ {'EXIT', _} ->
+ Start = osp_proto:start(Proto);
+ _ ->
+ Start = osp_proto:start(Proto, ensure_valid_opts(apply(Name,
sockopts, [Proto])))
+ end;
+ false ->
+ Start = osp_proto:start(Proto)
+ end,
+ case Start(Port) of
+ {ok, LSock} ->
+ apply(Name, start_mnesia, []),
+ apply(Name, init, []),
+ Pid = spawn(fun() -> server_loop(Name, LSock) end),
+ CP = osp_proto:set_control(apply(Name, proto, [])),
+ CP(LSock, Pid),
+ erlang:register(Name, Pid),
+ Pid;
+ Error ->
+ {error, Error}
+ end.
+
+%% @doc The server broker main code
+%% @spec server_loop(atom(), socket()) -> none()
+server_loop(Name, LSock) ->
+ process_flag(trap_exit, true),
+ receive
+ stop ->
+ Close = osp_proto:close(apply(Name, proto, [])),
+ Close(LSock),
+ apply(Name, cleanup, []),
+ exit(shutdown);
+ {'EXIT', Pid, _} ->
+ Address = get(Pid),
+ put(Pid, undefined),
+ put(Address, undefined),
+ server_loop(Name, LSock);
+ _ ->
+ server_loop(Name, LSock) % Clean up the mailbox to prevent slowdown
+ after 0 ->
+ Accept = osp_proto:accept(apply(Name, proto, [])),
+ case Accept(LSock, 500) of
+ {ok, {Address, Port, Packet}} ->
+ case get(Address) of
+ undefined ->
+ Pid = spawn_link(Name, server, [{udp, {LSock, Address, Port}}]),
+ Pid ! {packet, Packet},
+ put(Pid, Address),
+ put(Address, Pid);
+ Pid ->
+ Pid ! {packet, Packet}
+ end,
+ server_loop(Name, LSock);
+ {ok, Sock} ->
+ Pid = spawn_link(Name, server, [{tcp, Sock}]),
+ gen_tcp:controlling_process(Sock, Pid),
+ server_loop(Name, LSock);
+ {error, timeout} ->
+ server_loop(Name, LSock);
+ Error ->
+ error_logger:error_msg("There was an error accepting a socket in
~p's socket broker: ~p~n", [Name, Error]),
+ exit(Error)
+ end
+ end.
=======================================
--- /dev/null
+++ /trunk/src/osp_compile.erl Wed Nov 4 05:36:34 2009
@@ -0,0 +1,57 @@
+%% @author Jacob Torrey <torr...@clarkson.edu>
+%% @copyright 2009 Jacob Torrey <torr...@clarkson.edu>
+%% @doc Provides servlet compilation functionality
+-module(osp_compile).
+
+-include("../include/conf.hrl").
+
+-export([compile/1, distribute/2, servlet_to_app/1]).
+
+%% @doc Generates and compiles a servlet from a .sdf
+%% @spec compile(string()) -> {ok, list()} | {error, list()}
+compile(Filename) ->
+ Basename = lists:last(string:tokens(Filename, "/")),
+ ModuleName = string:join(lists:reverse(lists:nthtail(1,
lists:reverse(string:tokens(Basename, ".")))), "."),
+ Ret = os:cmd("./compile_servlet.pl " ++ Filename), % Generate the
servlet
+ ModuleAtom = erlang:list_to_atom(ModuleName),
+ case Ret of
+ "File does" ++ _ ->
+ {error, ["The file failed to upload correctly"]};
+ _ ->
+ case lists:prefix(ModuleName, Ret) of
+ true ->
+ CompileRet = compile:file(ModuleName ++ ".erl", [verbose, return]),
+ case CompileRet of
+ {ok, ModuleAtom, Warnings} ->
+ {ok, ["File " ++ Filename ++ " compiled with warnings", Warnings]};
+ {ok, ModuleAtom} ->
+ {ok, ["File " ++ Filename ++ " compiled successfully"]};
+ error ->
+ {error, ["There was an error in the compilation stage"]};
+ {error, Errors, Warnings} ->
+ {error, ["There were the errors and warnings in the compilation
stage", Errors, Warnings]}
+ end;
+ false ->
+ {error, ["Invalid servlet file"]}
+ end
+ end.
+
+%% @doc Compiles a servlet and moves it to the application directory if
compilation is successful
+%% @spec servlet_to_app(string()) -> {ok, list()} | {error, list()}
+servlet_to_app(Filename) ->
+ Compile = compile(Filename),
+ Basename = lists:last(string:tokens(Filename, "/")),
+ ModuleName = string:join(lists:reverse(lists:nthtail(1,
lists:reverse(string:tokens(Basename, ".")))), "."),
+ case Compile of
+ {ok, _} = Output ->
+ file:rename(ModuleName ++ ".beam", ?APP_DIR ++ "/" ++ ModuleName
++ ".beam"),
+ file:delete(ModuleName ++ ".erl");
+ {error, _} = Output ->
+ file:delete(ModuleName ++ ".erl")
+ end,
+ Output.
+
+%% @doc Distributes the application to a given node to be run
+%% @spec distribute(atom(), node()) -> ok | {error, atom()}
+distribute(Module, Node) ->
+ ok.
=======================================
--- /dev/null
+++ /trunk/src/osp_file.erl Wed Nov 4 05:36:34 2009
@@ -0,0 +1,93 @@
+%% @author Jacob Torrey <torr...@clarkson.edu>
+%% @copyright 2009 Jacob Torrey <torr...@clarkson.edu>
+%% @doc File operations for OSP programs
+-module(osp_file).
+
+-include("../include/conf.hrl").
+-export([fopen/3, fread/2, fwrite/2, fclose/1, fseek/3]).
+
+%% @doc Calls a command either on the local FS, or the remote FS depending
on how the FS is setup
+%% @spec call_func(atom(), atom(), list()) -> any()
+call_func(M, F, A) ->
+ case ?SHARED_FS of
+ true ->
+ Ret = apply(M, F, A);
+ false ->
+ Ret = rpc:call(?NODENAME, M, F, A)
+ end,
+ Ret.
+
+%% @doc Opens a file for reading or writing
+%% @spec fopen(list(), string(), list()) -> io_device() | {err, list()}
+%% @todo Harden the file jailing system
+fopen(App, Filename, Flags) ->
+ Filename2 = ?FS_PREFIX ++ "/" ++ App ++ "/" ++ Filename,
+ Ret = call_func(file, open, [Filename2, Flags]),
+ case Ret of
+ {ok, FP} ->
+ FP;
+ {error, Res} ->
+ {err, Res}
+ end.
+
+%% @doc Closes an open file
+%% @spec fclose(io_device()) -> ok | {err, Reason}
+fclose(FP) ->
+ Ret = call_func(file, close, [FP]),
+ case Ret of
+ ok ->
+ ok;
+ {error, Res} ->
+ {err, Res}
+ end.
+
+%% @doc Seeks to a position in a file
+%% @spec fseek(io_device(), atom(), int()) -> ok | {err, list()}
+fseek(FP, cur, Off) ->
+ Ret = call_func(file, position, [FP, {cur, Off}]),
+ case Ret of
+ {ok, _NOff} ->
+ ok;
+ {error, Reason} ->
+ {err, Reason}
+ end;
+fseek(FP, set, Off) ->
+ Ret = call_func(file, position, [FP, {bof, Off}]),
+ case Ret of
+ {ok, _NOff} ->
+ ok;
+ {error, Reason} ->
+ {err, Reason}
+ end;
+fseek(FP, eof, Off) ->
+ Ret = call_func(file, position, [FP, {eof, Off}]),
+ case Ret of
+ {ok, _NOff} ->
+ ok;
+ {error, Reason} ->
+ {err, Reason}
+ end.
+
+%% @doc Writes to a file
+%% @spec fwrite(io_device(), any()) -> ok | {err, list()}
+fwrite(FP, Dat) ->
+ Ret = call_func(file, write, [FP, Dat]),
+ case Ret of
+ ok ->
+ ok;
+ {error, Reason} ->
+ {err, Reason}
+ end.
+
+%% @doc Reads from a file
+%% @spec fread(io_device(), int()) -> any() | {eof} | {err, list()}
+fread(FP, Num) ->
+ Ret = call_func(file, read, [FP, Num]),
+ case Ret of
+ {ok, Data} ->
+ Data;
+ eof ->
+ {eof};
+ {error, Reason} ->
+ {err, Reason}
+ end.
=======================================
--- /dev/null
+++ /trunk/src/osp_mnesia.erl Wed Nov 4 05:36:34 2009
@@ -0,0 +1,98 @@
+%% @copyright 2009 Jacob Torrey <torr...@clarkson.edu>
+%% @author Jacob Torrey <torr...@clarkson.edu>
+%% @doc A Mnesia interface for OSP
+-module(osp_mnesia).
+
+-export([store/3, retrieve/2, start_atomic/0, flush/1]).
+
+% Define the Mnesia record
+-record(osp_table, {key, val}).
+
+%% @doc Stores a key value set to the database
+%% @spec(name(), name(), any()) -> ok
+store(Tab, Key, Val) ->
+ case get(atomic) of
+ true ->
+ % Add to transaction log
+ Log = get(transaction_log),
+ case Log of
+ undefined ->
+ put(transaction_log, [{Key, Val}]);
+ [_] ->
+ case lists:keymember(Key, 1, Log) of
+ true ->
+ put(transaction_list, lists:keyreplace(Key, 1, Log, {Key, Val}));
+ false ->
+ put(transaction_log, lists:append(Log, [{Key, Val}]))
+ end
+ end;
+ undefined ->
+ % Write right away
+ Row = #osp_table{key = Key, val = Val},
+ F = fun() ->
+ mnesia:write(Tab, Row, write)
+ end,
+ {atomic, ok} = mnesia:transaction(F)
+ end,
+ ok.
+
+%% @doc Retrieves the value associated with the key from the database
+%% @spec(name(), name()) -> any() | undefined
+retrieve(Tab, Key) ->
+ case get(atomic) of
+ undefined ->
+ F = fun() ->
+ mnesia:read({Tab, Key})
+ end,
+ {atomic, Res} = mnesia:transaction(F),
+ case Res of
+ [] ->
+ undefined;
+ [{_, Key, Val}] ->
+ Val
+ end;
+ true ->
+ Log = get(transaction_log),
+ TV = lists:keysearch(Key, 1, Log),
+ case TV of
+ false ->
+ F = fun() ->
+ mnesia:read({Tab, Key})
+ end,
+ {atomic, Res} = mnesia:transaction(F),
+ case Res of
+ [] ->
+ undefined;
+ {_, Key, Val} ->
+ Val
+ end;
+ {value, {Key, Val}} ->
+ Val
+ end
+ end.
+
+%% @doc Sets the process to be atomic
+%% @spec start_atomic() -> ok
+start_atomic() ->
+ put(atomic, true),
+ ok.
+
+%% @doc Flushes the variables to the database
+%% @spec(name()) -> ok
+flush(Tab) ->
+ Log = get(transaction_log),
+ case Log of
+ undefined ->
+ ok;
+ [_] ->
+ F = fun() ->
+ WF = fun(Item) ->
+ {Key, Val} = Item,
+ Rec = #osp_table{key = Key, val = Val},
+ mnesia:write(Tab, Rec, write)
+ end,
+ lists:foreach(WF, Log)
+ end,
+ {atomic, ok} = mnesia:transaction(F),
+ ok
+ end.
=======================================
--- /dev/null
+++ /trunk/src/osp_proto.erl Wed Nov 4 05:36:34 2009
@@ -0,0 +1,79 @@
+%% @author Jacob Torrey <torr...@clarkson.edu>
+%% @copyright 2009 Jacob Torrey <torr...@clarkson.edu>
+%% @doc A module for abstracting protocols from OSP servlets
+-module(osp_proto).
+
+% Definitions
+-define(TCPOPTS, [{reuseaddr, true}, binary, {packet, 0}, {active,
false}]).
+-define(UDPOPTS, [binary, {reuseaddr, true}, {active, false}]).
+-define(SCTPOPTS, [binary, {reuseadr, true}, {active, false}]).
+
+% Exports
+-export([start/1, start/2, set_control/1, accept/1, close/1]).
+
+%% @doc Returnes a function (arity 1) for starting a server socket with
passed socket options
+%% @spec start(tcp | udp | sctp, list()) -> fun()
+start(tcp, Options) ->
+ fun(Port) ->
+ gen_tcp:listen(Port, Options)
+ end;
+start(sctp, Options) ->
+ fun(Port) ->
+ gen_sctp:listen(Port, Options)
+ end;
+start(udp, Options) ->
+ fun(Port) ->
+ gen_udp:open(Port, Options)
+ end.
+
+%% @doc Returns a function (arity 1) for starting a server socket with
default socket options
+%% @spec start(tcp | udp | sctp) -> fun()
+start(tcp) ->
+ start(tcp, ?TCPOPTS);
+start(sctp) ->
+ start(sctp, ?SCTPOPTS);
+start(udp) ->
+ start(udp, ?UDPOPTS).
+
+%% @doc Returns a function that sets the controlling process of Sock to Pid
+%% @spec set_control(tcp | udp | sctp) -> fun()
+set_control(tcp) ->
+ fun(Sock, Pid) ->
+ gen_tcp:controlling_process(Sock, Pid)
+ end;
+set_control(sctp) ->
+ fun(Sock, Pid) ->
+ gen_sctp:controlling_process(Sock, Pid)
+ end;
+set_control(udp) ->
+ fun(Sock, Pid) ->
+ gen_udp:controlling_process(Sock, Pid)
+ end.
+
+%% @doc Returns a function to close the socket
+close(tcp) ->
+ fun(Sock) ->
+ gen_tcp:close(Sock)
+ end;
+close(sctp) ->
+ fun(Sock) ->
+ gen_sctp:close(Sock)
+ end;
+close(udp) ->
+ fun(Sock) ->
+ gen_udp:close(Sock)
+ end.
+
+%% @doc Returns a function to accept a socket or connection
+accept(tcp) ->
+ fun(Sock, Timeout) ->
+ gen_tcp:accept(Sock, Timeout)
+ end;
+accept(sctp) ->
+ fun(Sock, Timeout) ->
+ gen_sctp:recv(Sock, 0, Timeout)
+ end;
+accept(udp) ->
+ fun(Sock, Timeout) ->
+ gen_udp:recv(Sock, 0, Timeout)
+ end.
=======================================
***Additional files exist in this changeset.***
Reply all
Reply to author
Forward
0 new messages