*** kernellib/include/config.h Thu May 21 15:10:42 2009
--- kernellib/include/config.h Thu May 21 15:10:52 2009
***************
*** 6,8 ****
--- 6,15 ----
# undef SYS_PERSISTENT /* off by default */
# define CALLOUTRSRC FALSE /* don't have callouts as a resource */
+
+ # ifdef SYS_NETWORKING
+ # define TELNET_PORT 6047 /* default telnet port */
+ # define BINARY_PORT 6048 /* default binary port */
+ # define EMERGENCY_PORT 6049 /* emergency binary port */
+ # endif
+
*** kernellib/include/kernel/kernel.h Thu May 21 15:10:42 2009
--- kernellib/include/kernel/kernel.h Thu May 21 15:10:52 2009
***************
*** 1,4 ****
--- 1,7 ----
# include <config.h>
+ # ifndef SYS_NETWORKING
+ # define SYS_NETWORKING
+ # endif
# define DRIVER "/kernel/sys/driver"
# define AUTO ("/kernel" + INHERITABLE_SUBDIR + "auto")
*** kernellib/include/kernel/net.h Thu Jan 1 00:00:00 1970
--- kernellib/include/kernel/net.h Thu May 21 15:10:52 2009
***************
*** 0 ****
--- 1,10 ----
+ # ifdef SYS_NETWORKING
+ # define LIB_PORT "/kernel/lib/network/port"
+ # define PORT_OBJECT "/kernel/obj/port"
+ # define PORT_TELNET "/kernel/sys/telnet_port"
+ # define PORT_BINARY "/kernel/sys/binary_port"
+ # define PORT_EMERGENCY "/kernel/sys/emergency_port"
+ # define PORT_UDP "/kernel/obj/udp"
+ # else
+ # error networking capabilities required
+ # endif
*** kernellib/include/kernel/user.h Thu May 21 15:10:42 2009
--- kernellib/include/kernel/user.h Thu May 21 15:10:52 2009
***************
*** 6,11 ****
--- 6,15 ----
# define BINARY_CONN ("/kernel" + CLONABLE_SUBDIR + "binary")
# define API_USER ("/kernel" + INHERITABLE_SUBDIR + "api/user")
+ #ifdef __NETWORK_EXTENSIONS__
+ #define LIB_PORT "/kernel/lib/network/port"
+ #endif
+
# define DEFAULT_USER ("/kernel" + CLONABLE_SUBDIR + "user")
# define DEFAULT_WIZTOOL ("/kernel" + CLONABLE_SUBDIR + "wiztool")
# define DEFAULT_USER_DIR "/kernel/data"
*** kernellib/include/std.h Thu May 21 15:10:42 2009
--- kernellib/include/std.h Thu May 21 15:10:52 2009
***************
*** 1,2 ****
--- 1,8 ----
+ #ifdef __NETWORK_EXTENSIONS__
+ #ifndef SYS_NETWORKING
+ #define SYS_NETWORKING
+ #endif
+ #endif
+
# define TRUE 1
# define FALSE 0
*** kernellib/kernel/lib/auto.c Thu May 21 15:10:42 2009
--- kernellib/kernel/lib/auto.c Thu May 21 15:10:52 2009
***************
*** 3,8 ****
--- 3,12 ----
# include <kernel/rsrc.h>
# include <kernel/access.h>
# include <kernel/user.h>
+ # ifdef SYS_NETWORKING
+ # include <kernel/net.h>
+ # endif
+
# include <status.h>
# include <type.h>
# include <trace.h>
***************
*** 1547,1549 ****
--- 1551,1614 ----
} : error(TLSVAR2);
return result;
}
+
+ # ifdef SYS_NETWORKING
+ /*
+ * NAME: connect()
+ * DESCRIPTION: open an outbound connection
+ */
+ static void connect(string destination, int port,varargs string proto)
+ {
+ object conn;
+ string err;
+
+ if (previous_program() == LIB_CONN) {
+ if(!proto) proto = "tcp";
+ ::connect(destination, port,proto);
+ } else {
+ CHECKARG(destination, 1, "connect");
+
+ if (creator == "System" && this_object()) {
+ if (function_object("query_conn", this_object()) != LIB_USER) {
+ error("Not a user object");
+ }
+ conn = clone_object(BINARY_CONN, "System");
+ call_other(this_object(),"connection",conn);
+ conn->connect(destination, port,proto);
+ if(err) {
+ rlimits (-1; -1) {
+ destruct_object(conn);
+ }
+ error(err);
+ }
+ }
+ }
+ }
+
+ static object port_object;
+
+ /*
+ * NAME: open_port()
+ * DESCRIPTION: open a port to listen on
+ */
+ static void open_port(string protocol, varargs int port)
+ {
+ CHECKARG(protocol, 1, "open_port");
+
+ if (KERNEL() && this_object()) {
+ ::open_port(protocol, port);
+ }
+ }
+
+ /*
+ * NAME: ports()
+ * DESCRIPTION: return list of open ports
+ */
+ static object *ports()
+ {
+ if (creator == "System") {
+ return ::ports();
+ }
+ }
+ # endif /* SYS_NETWORKING */
+
*** kernellib/kernel/lib/connection.c Thu May 21 15:10:42 2009
--- kernellib/kernel/lib/connection.c Thu May 21 15:10:52 2009
***************
*** 6,11 ****
--- 6,12 ----
private object user; /* user object */
private string conntype; /* connection type */
private int mode; /* connection mode */
+ private int outgoing;
private int blocked; /* connection blocked? */
private string buffer; /* buffered output string */
***************
*** 66,71 ****
--- 67,77 ----
int timeout;
string banner;
+ if(outgoing) {
+ user->login("now");
+ return;
+ }
+
banner = call_other(userd, "query_" + conntype + "_banner", port,
this_object());
if (banner) {
***************
*** 74,80 ****
timeout = call_other(userd, "query_" + conntype + "_timeout", port,
this_object());
! if (timeout < 0) {
/* disconnect immediately */
destruct_object(this_object());
return;
--- 80,86 ----
timeout = call_other(userd, "query_" + conntype + "_timeout", port,
this_object());
! if (timeout < 0 && !outgoing) {
/* disconnect immediately */
destruct_object(this_object());
return;
***************
*** 83,88 ****
--- 89,99 ----
if (!user && timeout != 0) {
call_out("timeout", timeout);
}
+ # ifdef SYS_NETWORKING
+ else {
+ set_mode(user->login(nil));
+ }
+ # endif
}
/*
***************
*** 136,142 ****
*/
void set_port(int num)
{
! if (previous_object() == userd) {
port = num;
}
}
--- 147,154 ----
*/
void set_port(int num)
{
! if(num == 0) error("port is 0\n");
! if (previous_object() == userd || SYSTEM()) {
port = num;
}
}
***************
*** 194,200 ****
user = call_other(userd, conntype + "_user", port, str);
set_mode(mode = user->login(str));
} else {
! set_mode(mode = user->receive_message(str));
}
return mode;
}
--- 206,216 ----
user = call_other(userd, conntype + "_user", port, str);
set_mode(mode = user->login(str));
} else {
! mixed m;
! m = user->receive_message(str);
! if(m) mode = m;
! else mode = 0;
! set_mode(mode);
}
return mode;
}
***************
*** 223,228 ****
--- 239,246 ----
return TRUE;
}
}
+ } else {
+ error(object_name(previous_object())+" is not allowed to do that");
}
}
***************
*** 240,245 ****
--- 258,264 ----
}
}
+ #ifndef SYS_NETWORKING
/*
* NAME: datagram_challenge()
* DESCRIPTION: set the challenge for the datagram channel
***************
*** 283,285 ****
--- 302,324 ----
return (send_datagram(str) == strlen(str));
}
}
+ #else
+ /*
+ * NAME: connect()
+ * DESCRIPTION: establish an outbount connection
+ */
+ void connect(string destination, int n,varargs string protocol)
+ {
+ if (previous_program() == AUTO || previous_program() == LIB_USER) {
+ outgoing = 1;
+ user = previous_object();
+ port = n;
+ ::connect(destination, n, protocol);
+ }
+ }
+
+ void receive_error(string str) {
+ DRIVER->message("NETWORK ERROR: "+str+"\n");
+ }
+ # endif
+
*** kernellib/kernel/lib/network/port.c Thu Jan 1 00:00:00 1970
--- kernellib/kernel/lib/network/port.c Thu May 21 15:10:52 2009
***************
*** 0 ****
--- 1,68 ----
+ # include <kernel/kernel.h>
+ # include <kernel/user.h>
+ # include <trace.h>
+ # include <type.h>
+
+ private object driver; /* driver object */
+ private object userd; /* user manager object */
+ private string protocol; /* telnet, tcp or udp */
+
+ /*
+ * NAME: create()
+ * DESCRIPTION: initialize port object
+ */
+ static void create()
+ {
+ driver = find_object(DRIVER);
+ userd = find_object(USERD);
+ }
+
+ /*
+ * NAME: open_port()
+ * DESCRIPTION: start listening on a port
+ */
+ static
+ void open_port(string prot, varargs int port)
+ {
+ rlimits (-1; -1) {
+ /* catch {*/
+ if (typeof(port)==T_INT && port !=0) {
+ ::open_port(prot, port);
+ } else {
+ ::open_port(prot);
+ }
+ protocol = prot;
+ return;
+ /* } : {
+ error(::call_trace()[1][TRACE_FIRSTARG][1]);
+ return;
+ }*/
+ }
+ }
+
+ object
+ connection(mixed *tls, string ip, int port)
+ {
+ object conn;
+
+ switch(protocol) {
+ case "telnet" : conn = clone_object(TELNET_CONN);
+ break;
+ default : conn = clone_object(BINARY_CONN);
+ break;
+ }
+ conn->set_port(port);
+ return conn;
+ }
+
+ int
+ open(mixed *tls,int port)
+ {
+ return FALSE;
+ }
+
+ void
+ close(mixed *tls, int force)
+ {
+ }
+
*** kernellib/kernel/obj/binary.c Thu May 21 15:10:42 2009
--- kernellib/kernel/obj/binary.c Thu May 21 15:10:52 2009
***************
*** 1,5 ****
--- 1,9 ----
# include <kernel/kernel.h>
# include <kernel/user.h>
+ # ifdef SYS_NETWORKING
+ # include <kernel/net.h>
+ # endif
+
inherit LIB_CONN; /* basic connection object */
***************
*** 25,33 ****
* NAME: open()
* DESCRIPTION: open the connection
*/
! static void open()
{
::open(allocate(driver->query_tls_size()));
}
/*
--- 29,42 ----
* NAME: open()
* DESCRIPTION: open the connection
*/
! static int open()
{
::open(allocate(driver->query_tls_size()));
+ # ifdef SYS_NETWORKING
+ return TRUE;
+ # else
+ return FALSE;
+ # endif
}
/*
***************
*** 153,158 ****
--- 162,168 ----
::message_done(allocate(driver->query_tls_size()));
}
+ #ifndef SYS_NETWORKING
/*
* NAME: open_datagram()
* DESCRIPTION: open a datagram channel for this connection
***************
*** 170,172 ****
--- 180,229 ----
{
::receive_datagram(allocate(driver->query_tls_size()), str);
}
+ #endif
+
+ #ifdef SYS_NETWORKING
+
+ object udpchannel; /* UDP channel object */
+
+ /*
+ * NAME: set_udpchannel()
+ * DESCRIPTION: set the UDP channel for this connection
+ */
+ void set_udpchannel(object udp, string host, int port)
+ {
+ if (previous_program() == LIB_PORT) {
+ udpchannel = udp;
+ udp->add_connection(this_object(), host, port);
+ }
+ }
+
+ /*
+ * NAME: receive_datagram()
+ * DESCRIPTION: receive a datagram
+ */
+ void receive_datagram(mixed *tls, string str)
+ {
+ if (previous_object() == udpchannel) {
+ object user;
+
+ user = query_user();
+ if (user) {
+ user->receive_datagram(str);
+ }
+ }
+ }
+
+ /*
+ * NAME: datagram()
+ * DESCRIPTION: send a datagram on the UDP channel
+ */
+ int datagram(string str)
+ {
+ if (previous_object() == query_user() && udpchannel) {
+ return udpchannel->datagram(str);
+ }
+ }
+
+ #endif
+
*** kernellib/kernel/obj/port.c Thu Jan 1 00:00:00 1970
--- kernellib/kernel/obj/port.c Thu May 21 15:10:52 2009
***************
*** 0 ****
--- 1,49 ----
+ # include <kernel/kernel.h>
+ # include <kernel/user.h>
+ # include <kernel/net.h>
+
+ inherit LIB_PORT;
+
+ /*
+ * NAME: create()
+ * DESCRIPTION: initialize port object
+ */
+ static void create(int clone)
+ {
+ if (clone) {
+ ::create();
+ }
+ }
+
+ /*
+ * NAME: listen()
+ * DESCRIPTION: start listening on a port
+ */
+ void listen(string protocol, int port)
+ {
+ #ifndef SYS_NETWORKING
+ if (previous_program() == DRIVER) {
+ #else
+ if (previous_program() == DRIVER || previous_program() == USERD) {
+ #endif
+ ::open_port(protocol, port);
+ }
+ }
+
+ /*
+ * NAME: open_connection()
+ * DESCRIPTION: don't return a user object, select it by first line of input
+ */
+ static object open_connection(string ipaddr, int port)
+ {
+ return nil;
+ }
+
+ void open(int port) {
+ ::open(allocate(DRIVER->query_tls_size()),port);
+ }
+
+ object connection(string ip, int port) {
+ ::connection(allocate(DRIVER->query_tls_size()),ip,port);
+ }
+
*** kernellib/kernel/sys/binary_port.c Thu Jan 1 00:00:00 1970
--- kernellib/kernel/sys/binary_port.c Thu May 21 15:10:52 2009
***************
*** 0 ****
--- 1,47 ----
+ #include <kernel/net.h>
+ #include <kernel/user.h>
+ #include <kernel/kernel.h>
+
+ inherit LIB_PORT; /* basic port object */
+
+ object driver; /* driver object */
+
+ void
+ create()
+ {
+ ::create();
+ driver = find_object(DRIVER);
+ open_port("tcp", BINARY_PORT);
+ }
+
+ object
+ connection(string ip, int port)
+ {
+ return ::connection(allocate(driver->query_tls_size()), ip, port);
+ }
+
+ void
+ done()
+ {
+ close_user();
+ }
+
+ /*
+ * NAME: open()
+ * DESCRIPTION: open the connection
+ */
+ static int open(int port)
+ {
+ ::open(allocate(driver->query_tls_size()), port);
+ return FALSE;
+ }
+
+ /*
+ * NAME: close()
+ * DESCRIPTION: close the connection
+ */
+ static void close(int force)
+ {
+ ::close(allocate(driver->query_tls_size()), force);
+ }
+
*** kernellib/kernel/sys/driver.c Thu May 21 15:10:42 2009
--- kernellib/kernel/sys/driver.c Thu May 21 15:10:52 2009
***************
*** 4,9 ****
--- 4,15 ----
# include <kernel/access.h>
# include <kernel/user.h>
# include <kernel/tls.h>
+ # ifdef __NETWORK_EXTENSIONS__
+ # ifndef SYS_NETWORKING
+ # define SYS_NETWORKING
+ # endif
+ # include <kernel/net.h>
+ # endif
# include <status.h>
# include <trace.h>
***************
*** 16,23 ****
--- 22,38 ----
object initd; /* init manager object */
object objectd; /* object manager object */
object errord; /* error manager object */
+ # ifdef SYS_NETWORKING
+ static object port_master; /* port master object */
+ static object telnet; /* default telnet port object */
+ static object binary; /* default binary port object */
+ static object emergency; /* emergency port object */
+ # endif
+
int tls_size; /* thread local storage size */
+
+
/*
* NAME: creator()
* DESCRIPTION: get creator of file
***************
*** 408,413 ****
--- 423,432 ----
call_other(accessd = load(ACCESSD), "???");
call_other(userd = load(USERD), "???");
call_other(load(DEFAULT_WIZTOOL), "???");
+ # ifdef SYS_NETWORKING
+ call_other(port_master = load(PORT_OBJECT), "???");
+ call_other(emergency = load(PORT_EMERGENCY), "???");
+ # endif
/* initialize other users as resource owners */
users = (accessd->query_users() - ({ "System" })) | ({ "admin" });
***************
*** 432,439 ****
shutdown();
return;
}
}
-
message("Initialization complete.\n\n");
}
--- 451,463 ----
shutdown();
return;
}
+ # ifdef SYS_NETWORKING
+ } else {
+ call_other(telnet = load(PORT_TELNET),"???");
+ call_other(binary = load(PORT_BINARY),"???");
+ rsrcd->rsrc_incr("System", "objects", nil, 2, 1);
+ #endif
}
message("Initialization complete.\n\n");
}
***************
*** 477,483 ****
initd->reboot();
}
}
!
message("State restored.\n\n");
}
--- 501,519 ----
initd->reboot();
}
}
! # ifdef SYS_NETWORKING
! if (telnet) {
! telnet->listen("telnet", TELNET_PORT);
! }
! if (binary) {
! binary->listen("tcp", BINARY_PORT);
! }
! if(!emergency) {
! emergency = clone_object(port_master);
! rsrcd->rsrc_incr("System", "objects", nil, 1, 1);
! }
! emergency->listen("tcp", EMERGENCY_PORT);
! # endif
message("State restored.\n\n");
}
*** kernellib/kernel/sys/emergency_port.c Thu Jan 1 00:00:00 1970
--- kernellib/kernel/sys/emergency_port.c Thu May 21 15:10:52 2009
***************
*** 0 ****
--- 1,47 ----
+ #include <kernel/net.h>
+ #include <kernel/user.h>
+ #include <kernel/kernel.h>
+
+ inherit LIB_PORT; /* basic port object */
+
+ object driver; /* driver object */
+
+ void
+ create()
+ {
+ ::create();
+ driver = find_object(DRIVER);
+ open_port("tcp", EMERGENCY_PORT);
+ }
+
+ object
+ connection(string ip, int port)
+ {
+ return ::connection(allocate(driver->query_tls_size()), ip, port);
+ }
+
+ void
+ done()
+ {
+ close_user();
+ }
+
+ /*
+ * NAME: open()
+ * DESCRIPTION: open the connection
+ */
+ static int open(int port)
+ {
+ ::open(allocate(driver->query_tls_size()), port);
+ return FALSE;
+ }
+
+ /*
+ * NAME: close()
+ * DESCRIPTION: close the connection
+ */
+ static void close(int force)
+ {
+ ::close(allocate(driver->query_tls_size()), force);
+ }
+
*** kernellib/kernel/sys/telnet_port.c Thu Jan 1 00:00:00 1970
--- kernellib/kernel/sys/telnet_port.c Thu May 21 15:10:52 2009
***************
*** 0 ****
--- 1,47 ----
+ #include <kernel/net.h>
+ #include <kernel/user.h>
+ #include <kernel/kernel.h>
+
+ inherit LIB_PORT; /* basic port object */
+
+ object driver; /* driver object */
+
+ void
+ create()
+ {
+ ::create();
+ driver = find_object(DRIVER);
+ open_port("telnet", TELNET_PORT);
+ }
+
+ object
+ connection(string ip, int port)
+ {
+ return ::connection(allocate(driver->query_tls_size()), ip, port);
+ }
+
+ void
+ done()
+ {
+ close_user();
+ }
+
+ /*
+ * NAME: open()
+ * DESCRIPTION: open the connection
+ */
+ static int open(int port)
+ {
+ ::open(allocate(driver->query_tls_size()), port);
+ return FALSE;
+ }
+
+ /*
+ * NAME: close()
+ * DESCRIPTION: close the connection
+ */
+ static void close(int force)
+ {
+ ::close(allocate(driver->query_tls_size()), force);
+ }
+
*** kernellib/kernel/sys/userd.c Thu May 21 15:10:42 2009
--- kernellib/kernel/sys/userd.c Thu May 21 15:10:52 2009
***************
*** 1,11 ****
--- 1,18 ----
# include <kernel/kernel.h>
# include <kernel/user.h>
+ # ifdef SYS_NETWORKING
+ # include <kernel/net.h>
+ # define PORT PORT_OBJECT
+ # else
+ # define PORT DRIVER
+ # endif
# include <status.h>
object *users; /* user mappings */
mapping names; /* name : connection object */
object *connections; /* saved connections */
+ mapping listeners_telnet, listeners_tcp; /* port objects */
mapping telnet, binary; /* port managers */
/*
***************
*** 18,23 ****
--- 25,31 ----
if (!find_object(TELNET_CONN)) { compile_object(TELNET_CONN); }
if (!find_object(BINARY_CONN)) { compile_object(BINARY_CONN); }
if (!find_object(DEFAULT_USER)) { compile_object(DEFAULT_USER); }
+ if (!find_object(PORT_OBJECT)) { compile_object(PORT_OBJECT); }
/* initialize user arrays */
users = ({ });
***************
*** 32,38 ****
*/
object telnet_connection(mixed *tls, int port)
{
! if (previous_program() == DRIVER) {
object conn;
conn = clone_object(TELNET_CONN);
--- 40,46 ----
*/
object telnet_connection(mixed *tls, int port)
{
! if (previous_program() == PORT) {
object conn;
conn = clone_object(TELNET_CONN);
***************
*** 47,53 ****
*/
object binary_connection(mixed *tls, int port)
{
! if (previous_program() == DRIVER) {
object conn;
conn = clone_object(BINARY_CONN);
--- 55,61 ----
*/
object binary_connection(mixed *tls, int port)
{
! if (previous_program() == PORT) {
object conn;
conn = clone_object(BINARY_CONN);
***************
*** 57,62 ****
--- 65,113 ----
}
/*
+ * NAME:
+ * DESCRIPTION:
+ */
+ private void start_telnet_listener(int port)
+ {
+ if(!listeners_telnet) {
+ listeners_telnet = ([ ]);
+ }
+ if(!listeners_tcp) {
+ listeners_tcp = ([ ]);
+ }
+
+ if(!listeners_telnet[port] && !listeners_tcp[port]) {
+ listeners_telnet[port] = clone_object(PORT_OBJECT);
+ listeners_telnet[port]->listen("telnet",port);
+ } else {
+ error("Port "+port+" is already in use.");
+ }
+ }
+
+ /*
+ * NAME:
+ * DESCRIPTION:
+ */
+ private void start_tcp_listener(int port)
+ {
+ if(!listeners_telnet) {
+ listeners_telnet = ([ ]);
+ }
+
+ if(!listeners_tcp) {
+ listeners_tcp = ([ ]);
+ }
+
+ if(!listeners_telnet[port] && !listeners_tcp[port]) {
+ listeners_tcp[port] = clone_object(PORT_OBJECT);
+ listeners_tcp[port]->listen("tcp",port);
+ } else {
+ error("Port "+port+" is already in use.");
+ }
+ }
+
+ /*
* NAME: set_telnet_manager()
* DESCRIPTION: set the telnet manager object, which determines what the
* user object is, based on the first line of input
***************
*** 67,73 ****
--- 118,128 ----
void set_telnet_manager(int port, object manager)
{
if (SYSTEM()) {
+ if(!port) port = TELNET_PORT;
telnet[port] = manager;
+ DRIVER->message("telnet manager for port "+port+ " is now "+
+ object_name(manager)+"\n");
+ start_telnet_listener(port);
}
}
***************
*** 82,88 ****
--- 137,147 ----
void set_binary_manager(int port, object manager)
{
if (SYSTEM()) {
+ if(!port) port = BINARY_PORT;
binary[port] = manager;
+ DRIVER->message("binary manager for port "+port+ " is now "+
+ object_name(manager)+"\n");
+ start_tcp_listener(port);
}
}
***************
*** 100,105 ****
--- 159,165 ----
user = names[str];
if (!user) {
user = telnet[port];
+ if(!user) user = binary[port];
if (user) {
user = (object LIB_USER) user->select(str);
} else {
***************
*** 123,129 ****
user = names[str];
if (!user) {
user = binary[port];
! if (user && (str != "admin" || port != 0)) {
user = (object LIB_USER) user->select(str);
} else {
user = clone_object(DEFAULT_USER);
--- 183,190 ----
user = names[str];
if (!user) {
user = binary[port];
! if(!user) user = telnet[port];
! if (user && (str != "admin" || port != EMERGENCY_PORT)) {
user = (object LIB_USER) user->select(str);
} else {
user = clone_object(DEFAULT_USER);
*** kernellib/usr/System/initd.c Thu Jan 1 00:00:00 1970
--- kernellib/usr/System/initd.c Thu May 21 15:10:52 2009
***************
*** 0 ****
--- 1,32 ----
+ # include <kernel/kernel.h>
+
+ private void
+ load(string filename)
+ {
+ if (!find_object(filename)) {
+ compile_object(filename);
+ }
+ }
+
+ static void
+ create()
+ {
+ load("/kernel/sys/telnet_port");
+ load("/kernel/sys/binary_port");
+ }
+
+ void
+ prepare_reboot()
+ {
+ if (previous_program() == DRIVER) {
+ /* ... */
+ }
+ }
+
+ void
+ reboot()
+ {
+ if (previous_program() == DRIVER) {
+ /* ... */
+ }
+ }