$title('nclient - client library routines') $compact nclient:DO; /************************************************************************** * * MODULE NAME: nclient * * DESCRIPTION: This module implements the nameserver library routines. * These routines provide an interface to the nameserver * Each routine has two components, a remote part and a local * part. * The following library routines are implemented in this * module: insert_name, * delete_name, * get_socket, * change_sock, * get_table, * get_host_id * **************************************************************************/ $include(:rmx:inc/rmxplm.ext) $include(:rmx:inc/error.lit) $include(nservr.lit) $include(nstabl.lit) $include(dcom.lit) $include(dcom.ext) $include(nclient.lit) DECLARE /* literals */ ROOTJOB LITERALLY '3', /* indicates root job */ DATAMBFLAG LITERALLY '20H', /* data mailbox creation flag */ LOCALHOST LITERALLY '0FFFEH', /* indicates local nameserver */ MBBUFSIZE LITERALLY '128', /* receive buffer size */ CONSIZE LITERALLY '20'; /* size of control message */ $eject $subtitle('copy_name') /******************************************************************** * * PROC NAME: copy_name * * DESCRIPTION: Fill string buffer pointed to by dest_ptr with spaces, then * copy buffer associated with src_ptr to buffer associated with * dest_ptr. * * CALL: CALL copy_name(src_ptr, dest_ptr) * * INPUTS: src_ptr - points to source string * dest_ptr - points to destination string * *********************************************************************/ copy_name:PROCEDURE(src_ptr, dest_ptr); DECLARE /* params */ src_ptr POINTER, dest_ptr POINTER; DECLARE /* locals */ dest_buf BASED dest_ptr(NAMESIZE) BYTE, src_buf BASED src_ptr(NAMESIZE) BYTE, i BYTE; i = 0; DO WHILE i < NAMESIZE; dest_buf(i) = ' '; i = i+1; END; CALL movb(src_ptr, dest_ptr, src_buf(0)+1); dest_buf(0) = NAMESIZE - 1; end copy_name; $eject $subtitle('delete_port') /******************************************************************** * * PROC NAME: delete_port * * DESCRIPTION: Delete the port and buffer pool passed by the caller * * CALL: CALL delete_port(port_t) * * INPUT: port_t - port to be deleted * *********************************************************************/ delete_port:PROCEDURE(port_t); DECLARE /* params */ port_t TOKEN; DECLARE /* locals */ buf_pool TOKEN, /* buffer pool associated with port */ status WORD; buf_pool = rq$detach$buffer$pool(port_t, @status); CALL rq$delete$buffer$pool(buf_pool, @status); CALL rq$delete$port(port_t, @status); END delete_port; $eject $subtitle('get_local_servr') /******************************************************************** * * PROC NAME: get_local_servr * * DESCRIPTION: Check if nameserver is local and return the mailbox * associated with it if it is. * * CALL: result = get_local_servr(servr_mbx_ptr) * * INPUTS: servr_mbx_ptr - points to server mailbox token * * RETURNS: result - indicates success of lookup * *********************************************************************/ get_local_servr:PROCEDURE(servr_mbx_ptr) BYTE REENTRANT; DECLARE /* params */ servr_mbx_ptr POINTER; /* points to server mailbox token */ DECLARE /* locals */ root_job TOKEN, /* root job token */ status WORD, servr_mbx BASED servr_mbx_ptr TOKEN; root_job = rq$get$task$tokens(ROOTJOB, @status); IF status <> E$OK THEN RETURN REQNOTCOMPLETE; servr_mbx = rq$lookup$object(root_job, @(10,'nameserver'), 0, @status); IF status <> E$OK THEN RETURN REQNOTCOMPLETE; ELSE RETURN REQCOMPLETED; END get_local_servr; $eject $subtitle('rem_insert_name') /******************************************************************** * * PROC NAME: rem_insert_name * * DESCRIPTION: Insert library routine for nameserver. Create a port, send a * request message to the nameserver and wait for a response. * Return the result of the request. * * CALL: result = rem_insert_name(host_id, name_ptr, new_socket * time_limit, stat_ptr) * * INPUTS: host_id - host id of name server * name_ptr - points to name for nameserver table entry * new_socket - socket to be inserted in nameserver table * OUTPUT: stat_ptr - points to status word * *********************************************************************/ rem_insert_name:PROCEDURE(host_id, name_ptr, new_socket, time_limit, stat_ptr) BYTE REENTRANT PUBLIC; DECLARE /* params */ host_id WORD, name_ptr POINTER, new_socket DWORD, time_limit WORD, stat_ptr POINTER; DECLARE /* locals */ status BASED stat_ptr WORD, info rec_info, /* receive information structure */ port_t TOKEN, /* client port */ buf_pool TOKEN, /* token for buffer pool attached to port_t */ con_msg(CONSIZE) BYTE, /* control message buffer */ trans_id WORD, /* transaction id for request */ rsp_ptr POINTER, /* points to response message */ new_entry ns_ent, /* new entry for insert request */ server_socket socket, /* nameserver socket */ server_sock DWORD AT (@server_socket), /* nameserver socket */ new_name BASED name_ptr BYTE; port_t = get$dport(0, @buf_pool, CHAIN, stat_ptr); IF status = E$OK THEN DO; server_socket.port_id = SERVERPORT; server_socket.host_id = host_id; con_msg(0) = INSERTREQ; CALL copy_name(name_ptr, @new_entry.name); new_entry.sock = new_socket; trans_id = rq$send$rsvp(port_t, server_sock, @con_msg, @new_entry, size(new_entry), NIL, 0, 0, stat_ptr); IF status <> E$OK THEN DO; CALL delete_port(port_t); RETURN REQNOTCOMPLETE; END; rsp_ptr = rq$receive$reply(port_t, trans_id, time_limit, @info, stat_ptr); CALL delete_port(port_t); IF status <> E$OK THEN RETURN REQNOTCOMPLETE; ELSE RETURN info.con$msg(0); END; ELSE RETURN REQNOTCOMPLETE; END rem_insert_name; $eject $subtitle('loc_insert_name') /******************************************************************** * * PROC NAME: loc_insert_name * * DESCRIPTION: Local insert library routine for nameserver. Create a mail- * box, send a request message to the nameserver and wait for a * response. Return the result of the request. * * CALL: result = loc_insert_name(name_ptr, new_socket, time_limit, stat_ptr) * * INPUTS: name_ptr - points to name for nameserver table entry * new_socket - socket to be inserted in nameserver table * time_limit - time wait for request to be processed * OUTPUT: stat_ptr - points to status word * RETURNS: result - result of requested operation * *********************************************************************/ loc_insert_name:PROCEDURE(name_ptr, new_socket, time_limit, stat_ptr) BYTE REENTRANT PUBLIC; DECLARE /* params */ name_ptr POINTER, new_socket DWORD, time_limit WORD, stat_ptr POINTER; DECLARE /* locals */ status BASED stat_ptr WORD, servr_mbx TOKEN, /* local server mailbox */ client_mbx TOKEN, /* client mailbox */ msgbuf(MBBUFSIZE) BYTE, req STRUCTURE ( /* client request structure */ req_type BYTE, /* request byte */ client_mbx TOKEN, /* mailbox accepting response */ sock DWORD, /* socket to be inserted */ name(NAMESIZE) BYTE) AT (@msgbuf), /* name to be inserted */ rsp STRUCTURE ( /* response structure */ rsp_type BYTE, /* response byte */ sock DWORD, name(NAMESIZE) BYTE) AT (@msgbuf), /* name to be inserted */ loc_status WORD, /* local status word */ rsp_ptr POINTER, /* points to response message */ result BYTE, /* indicates result of operation */ bytes_rec WORD, /* num bytes received */ new_entry ns_ent; /* new entry for insert request */ result = get_local_servr(@servr_mbx); IF result <> REQCOMPLETED THEN RETURN REQNOTCOMPLETE; client_mbx = rq$create$mailbox(DATAMBFLAG, @status); IF status <> E$OK THEN RETURN REQNOTCOMPLETE; req.req_type = INSERTREQ; req.client_mbx = client_mbx; req.sock = new_socket; CALL copy_name(name_ptr, @req.name); CALL rq$send$data(servr_mbx, @req, size(req), stat_ptr); IF status <> E$OK THEN DO; CALL rq$delete$mailbox(client_mbx, @loc_status); RETURN REQNOTCOMPLETE; END; bytes_rec = rq$receive$data(client_mbx, @msgbuf, time_limit, stat_ptr); CALL rq$delete$mailbox(client_mbx, @loc_status); IF status <> E$OK THEN RETURN REQNOTCOMPLETE; ELSE RETURN rsp.rsp_type; END loc_insert_name; $eject $subtitle('insert_name') /******************************************************************** * * PROC NAME: insert_name * * DESCRIPTION: Insert library routine for nameserver. Determine whether * nameserver is remote or local and send request accordingly. * * CALL: result = insert_name(host_id, name_ptr, new_socket, time_limit, stat_ptr) * * INPUTS: host_id - nameserver host id * name_ptr - points to name for nameserver table entry * new_socket - socket to be inserted in nameserver table * time_limit - time wait for request to be processed * OUTPUT: stat_ptr - points to status word * RETURNS: result - result of requested operation * *********************************************************************/ insert_name:PROCEDURE(host_id, name_ptr, new_socket, time_limit, stat_ptr) BYTE REENTRANT PUBLIC; DECLARE /* params */ host_id WORD, name_ptr POINTER, new_socket DWORD, time_limit WORD, stat_ptr POINTER; DECLARE /* locals */ status BASED stat_ptr WORD, result BYTE; /* result of requested operation */ IF host_id = LOCALHOST then result = loc_insert_name(name_ptr, new_socket, time_limit, stat_ptr); ELSE result = rem_insert_name(host_id, name_ptr, new_socket, time_limit, stat_ptr); RETURN result; END insert_name; $eject $subtitle('get_socket') /******************************************************************** * * PROC NAME: rem_get_socket * * CALL: result = rem_get_socket(host_id, name_ptr, socket_ptr, * time_limit, stat_ptr) * * DESCRIPTION: Remote get_socket library routine. Send a get_socket request to the * nameserver. If an entry exists for the name referenced by * name_ptr, return the socket to the caller via socket_ptr. Also * return an indication of reqeuest success. * * INPUTS: host_id - nameserver host id * name_ptr - points to name associated with requested * socket * time_limit - specifies max time to wait for response * from server * OUTPUTS: socket_ptr - points to requested socket * stat_ptr - points to status word * * RETURNS: result - indicates success of request * *********************************************************************/ rem_get_socket:PROCEDURE(host_id, name_ptr, socket_ptr, time_limit, stat_ptr) BYTE REENTRANT PUBLIC; DECLARE /* params */ host_id WORD, name_ptr POINTER, socket_ptr POINTER, time_limit WORD, stat_ptr POINTER; DECLARE /* locals */ status BASED stat_ptr WORD, info rec_info, /* receive information structure */ port_t TOKEN, /* client port */ buf_pool TOKEN, /* token for buffer pool attached to port_t */ con_msg(CONSIZE) BYTE, /* control message buffer */ trans_id WORD, /* transaction id for request */ rsp_ptr POINTER, /* points to response message */ server_socket socket, /* nameserver socket */ server_sock DWORD AT (@server_socket), /* nameserver socket */ name_sock_buf ns_ent; /* contains name whose socket is req */ port_t = get$dport(0, @buf_pool, CHAIN, stat_ptr); IF status = E$OK THEN DO; server_socket.port_id = SERVERPORT; server_socket.host_id = host_id; con_msg(0) = LOOKUPREQ; CALL copy_name(name_ptr, @name_sock_buf.name); trans_id = rq$send$rsvp(port_t, server_sock, @con_msg, @name_sock_buf, size(name_sock_buf), socket_ptr, SOCKETSIZE, 0, stat_ptr); IF status <> E$OK THEN DO; CALL delete_port(port_t); RETURN REQNOTCOMPLETE; END; rsp_ptr = rq$receive$reply(port_t, trans_id, time_limit, @info, stat_ptr); CALL delete_port(port_t); IF status <> E$OK THEN RETURN REQNOTCOMPLETE; ELSE RETURN info.con$msg(0); END; ELSE RETURN REQNOTCOMPLETE; END rem_get_socket; $eject $subtitle('loc_get_socket') /******************************************************************** * * PROC NAME: loc_get_socket * * DESCRIPTION: Local get_socket library routine for nameserver. Create a mail- * box, send a request message to the nameserver and wait for a * response. Return the result of the request. * * CALL: result = loc_get_socket(name_ptr, socket_ptr, time_limit, stat_ptr)) * * INPUTS: name_ptr - points to name for nameserver table entry * time_limit - time wait for request to be processed * OUTPUT: stat_ptr - points to status word * socket_ptr - points to socket returned to caller * RETURNS: result - result of requested operation * *********************************************************************/ loc_get_socket:PROCEDURE(name_ptr, socket_ptr, time_limit, stat_ptr) BYTE REENTRANT PUBLIC; DECLARE /* params */ name_ptr POINTER, socket_ptr POINTER, time_limit WORD, stat_ptr POINTER; DECLARE /* locals */ status BASED stat_ptr WORD, sock BASED socket_ptr DWORD, /* socket to be returned to caller */ servr_mbx TOKEN, /* local server mailbox */ client_mbx TOKEN, /* client mailbox */ cur_time_limit WORD, /* time to wait for current op */ msgbuf(MBBUFSIZE) BYTE, req STRUCTURE ( /* client request structure */ req_type BYTE, /* request byte */ client_mbx TOKEN, /* mailbox accepting response */ sock DWORD, /* socket to be inserted */ name(NAMESIZE) BYTE) AT (@msgbuf), /* name to be inserted */ rsp STRUCTURE ( /* response structure */ rsp_type BYTE, /* response byte */ sock DWORD, name(NAMESIZE) BYTE) AT (@msgbuf), /* name to be inserted */ loc_status WORD, /* local status word */ rsp_ptr POINTER, /* points to response message */ result BYTE, /* indicates result of operation */ bytes_rec WORD; /* num bytes received */ result = get_local_servr(@servr_mbx); IF result <> REQCOMPLETED THEN RETURN REQNOTCOMPLETE; client_mbx = rq$create$mailbox(DATAMBFLAG, @status); IF status <> E$OK THEN RETURN REQNOTCOMPLETE; req.req_type = LOOKUPREQ; req.client_mbx = client_mbx; CALL copy_name(name_ptr, @req.name); CALL rq$send$data(servr_mbx, @req, size(req), stat_ptr); IF status <> E$OK THEN DO; CALL rq$delete$mailbox(client_mbx, @loc_status); RETURN REQNOTCOMPLETE; END; bytes_rec = rq$receive$data(client_mbx, @msgbuf, time_limit, stat_ptr); sock = rsp.sock; CALL rq$delete$mailbox(client_mbx, @loc_status); IF status <> E$OK THEN RETURN REQNOTCOMPLETE; ELSE RETURN rsp.rsp_type; END loc_get_socket; $subtitle('get_socket') /******************************************************************** * * PROC NAME: get_socket * * DESCRIPTION: Get_socket library routine for nameserver. Determine whether * nameserver is remote or local and send request accordingly. * * CALL: result = get_socket(host_id, name_ptr, socket_ptr, time_limit, stat_ptr) * * INPUTS: host_id - nameserver host id * name_ptr - points to name for nameserver lookup * socket_ptr - points to socket to be returned to caller * time_limit - time wait for request to be processed * OUTPUT: stat_ptr - points to status word * RETURNS: result - result of requested operation * *********************************************************************/ get_socket:PROCEDURE(host_id, name_ptr, socket_ptr, time_limit, stat_ptr) BYTE REENTRANT PUBLIC; DECLARE /* params */ host_id WORD, name_ptr POINTER, socket_ptr POINTER, time_limit WORD, stat_ptr POINTER; DECLARE /* locals */ status BASED stat_ptr WORD, result BYTE; /* result of requested operation */ IF host_id = LOCALHOST then result = loc_get_socket(name_ptr, socket_ptr, time_limit, stat_ptr); ELSE result = rem_get_socket(host_id, name_ptr, socket_ptr, time_limit, stat_ptr); RETURN result; END get_socket; $eject $subtitle('rem_delete_name') /******************************************************************** * * PROC NAME: rem_delete_name * * DESCRIPTION: remote delete_name library routine for nameserver. Send delete request * and name of entry to be deleted to nameserver. Wait for result * and return result to caller. * * CALL: result = delete_name(host_id, name_ptr, time_limit, stat_ptr) * * INPUTS: host_id - nameserver socket * name_ptr - points to name associated with entry to * be deleted * time_limit - specifies max time to wait for response * stat_ptr - points to status word * RETURNS: result - indicates result of operation * *********************************************************************/ rem_delete_name:PROCEDURE(host_id, name_ptr, time_limit, stat_ptr) BYTE REENTRANT PUBLIC; DECLARE /* params */ host_id WORD, name_ptr POINTER, time_limit WORD, stat_ptr POINTER; DECLARE /* locals */ status BASED stat_ptr WORD, info rec_info, /* receive information structure */ port_t TOKEN, /* client port */ buf_pool TOKEN, /* token for buffer pool attached to port_t */ con_msg(CONSIZE) BYTE, /* control message buffer */ trans_id WORD, /* transaction id for request */ rsp_ptr POINTER, /* points to response message */ server_socket socket, /* nameserver socket */ server_sock DWORD AT (@server_socket), /* nameserver socket */ del_name_ent ns_ent; /* contains name of entry to be deleted */ port_t = get$dport(0, @buf_pool, CHAIN, @status); IF status = E$OK THEN DO; server_socket.port_id = SERVERPORT; server_socket.host_id = host_id; con_msg(0) = DELETEREQ; CALL copy_name(name_ptr, @del_name_ent.name); trans_id = rq$send$rsvp(port_t, server_sock, @con_msg, @del_name_ent, size(del_name_ent), NIL, 0, 0, stat_ptr); IF status <> E$OK THEN DO; CALL delete_port(port_t); RETURN REQNOTCOMPLETE; END; rsp_ptr = rq$receive$reply(port_t, trans_id, time_limit, @info, stat_ptr); CALL delete_port(port_t); IF status <> E$OK THEN RETURN REQNOTCOMPLETE; ELSE RETURN info.con$msg(0); END; ELSE RETURN REQNOTCOMPLETE; END rem_delete_name; $eject $subtitle('loc_delete_name') /******************************************************************** * * PROC NAME: loc_delete_name * * DESCRIPTION: Local delete_name library routine for nameserver. Create a mail- * box, send a request message to the nameserver and wait for a * response. Return the result of the request. * * CALL: result = loc_delete_name(name_ptr, time_limit, stat_ptr)) * * INPUTS: name_ptr - points to name for nameserver table entry * time_limit - time wait for request to be processed * OUTPUT: stat_ptr - points to status word * RETURNS: result - result of requested operation * *********************************************************************/ loc_delete_name:PROCEDURE(name_ptr, time_limit, stat_ptr) BYTE REENTRANT PUBLIC; DECLARE /* params */ name_ptr POINTER, time_limit WORD, stat_ptr POINTER; DECLARE /* locals */ status BASED stat_ptr WORD, servr_mbx TOKEN, /* local server mailbox */ client_mbx TOKEN, /* client mailbox */ cur_time_limit WORD, /* time to wait for current op */ msgbuf(MBBUFSIZE) BYTE, req STRUCTURE ( /* client request structure */ req_type BYTE, /* request byte */ client_mbx TOKEN, /* mailbox accepting response */ sock DWORD, /* socket to be inserted */ name(NAMESIZE) BYTE) AT (@msgbuf), /* name to be inserted */ rsp STRUCTURE ( /* response structure */ rsp_type BYTE, /* response byte */ sock DWORD, name(NAMESIZE) BYTE) AT (@msgbuf), /* name to be inserted */ loc_status WORD, /* local status word */ rsp_ptr POINTER, /* points to response message */ result BYTE, /* indicates result of operation */ bytes_rec WORD; /* num bytes received */ result = get_local_servr(@servr_mbx); IF result <> REQCOMPLETED THEN RETURN REQNOTCOMPLETE; client_mbx = rq$create$mailbox(DATAMBFLAG, @status); IF status <> E$OK THEN RETURN REQNOTCOMPLETE; req.req_type = DELETEREQ; req.client_mbx = client_mbx; CALL copy_name(name_ptr, @req.name); CALL rq$send$data(servr_mbx, @req, size(req), stat_ptr); IF status <> E$OK THEN DO; CALL rq$delete$mailbox(client_mbx, @loc_status); RETURN REQNOTCOMPLETE; END; bytes_rec = rq$receive$data(client_mbx, @msgbuf, time_limit, stat_ptr); CALL rq$delete$mailbox(client_mbx, @loc_status); IF status <> E$OK THEN RETURN REQNOTCOMPLETE; ELSE RETURN rsp.rsp_type; END loc_delete_name; $subtitle('delete_name') /******************************************************************** * * PROC NAME: delete_name * * DESCRIPTION: Get_socket library routine for nameserver. Determine whether * nameserver is remote or local and send request accordingly. * * CALL: result = delete_name(host_id, name_ptr, time_limit, stat_ptr) * * INPUTS: host_id - nameserver host id * name_ptr - points to name for nameserver lookup * time_limit - time wait for request to be processed * OUTPUT: stat_ptr - points to status word * RETURNS: result - result of requested operation * *********************************************************************/ delete_name:PROCEDURE(host_id, name_ptr, time_limit, stat_ptr) BYTE REENTRANT PUBLIC; DECLARE /* params */ host_id WORD, name_ptr POINTER, time_limit WORD, stat_ptr POINTER; DECLARE /* locals */ status BASED stat_ptr WORD, result BYTE; /* result of requested operation */ IF host_id = LOCALHOST then result = loc_delete_name(name_ptr, time_limit, stat_ptr); ELSE result = rem_delete_name(host_id, name_ptr, time_limit, stat_ptr); RETURN result; END delete_name; $eject $subtitle('rem_change_sock') /******************************************************************** * * PROC NAME: rem_change_sock * * DESCRIPTION: change_sock library routine for nameserver. Send change request, * name of entry to be deleted, and new socket value to nameserver. * Wait for result and return result to caller. * * CALL: result = rem_change_sock(host_id, name_ptr, new_sock, * time_limit, stat_ptr) * * INPUTS: host_id - nameserver host id * name_ptr - points to name associated with entry to * be deleted * new_sock - new socket value to be assoc with name * time_limit - specifies max time to wait for response * stat_ptr - points to status word * RETURNS: result - indicates result of operation * *********************************************************************/ rem_change_sock:PROCEDURE(host_id, name_ptr, new_sock, time_limit, stat_ptr) BYTE REENTRANT PUBLIC; DECLARE /* params */ host_id WORD, name_ptr POINTER, new_sock DWORD, time_limit WORD, stat_ptr POINTER; DECLARE /* locals */ status BASED stat_ptr WORD, info rec_info, /* receive information structure */ port_t TOKEN, /* client port */ buf_pool TOKEN, /* token for buffer pool attached to port_t */ con_msg(CONSIZE) BYTE, /* control message buffer */ trans_id WORD, /* transaction id for request */ rsp_ptr POINTER, /* points to response message */ server_socket socket, /* nameserver socket */ server_sock DWORD AT (@server_socket), /* nameserver socket */ chng_name_ent ns_ent; /* contains name of entry to be changed */ port_t = get$dport(0, @buf_pool, CHAIN, @status); IF status = E$OK THEN DO; server_socket.port_id = SERVERPORT; server_socket.host_id = host_id; con_msg(0) = CHANGEREQ; CALL copy_name(name_ptr, @chng_name_ent.name); chng_name_ent.sock = new_sock; trans_id = rq$send$rsvp(port_t, server_sock, @con_msg, @chng_name_ent, size(chng_name_ent), NIL, 0, 0, stat_ptr); IF status <> E$OK THEN DO; CALL delete_port(port_t); RETURN REQNOTCOMPLETE; END; rsp_ptr = rq$receive$reply(port_t, trans_id, time_limit, @info, stat_ptr); CALL delete_port(port_t); IF status <> E$OK THEN RETURN REQNOTCOMPLETE; ELSE RETURN info.con$msg(0); END; ELSE RETURN REQNOTCOMPLETE; END rem_change_sock; $eject $subtitle('loc_change_sock') /******************************************************************** * * PROC NAME: loc_change_sock * * DESCRIPTION: Local change_sock library routine for nameserver. Create a mail- * box, send a request message to the nameserver and wait for a * response. Return the result of the request. * * CALL: result = loc_change_sock(name_ptr, new_socket, time_limit, stat_ptr) * * INPUTS: name_ptr - points to name for nameserver table entry * new_socket - new socket to be inserted in nameserver table * time_limit - time wait for request to be processed * OUTPUT: stat_ptr - points to status word * RETURNS: result - result of requested operation * *********************************************************************/ loc_change_sock:PROCEDURE(name_ptr, new_socket, time_limit, stat_ptr) BYTE REENTRANT PUBLIC; DECLARE /* params */ name_ptr POINTER, new_socket DWORD, time_limit WORD, stat_ptr POINTER; DECLARE /* locals */ status BASED stat_ptr WORD, servr_mbx TOKEN, /* local server mailbox */ client_mbx TOKEN, /* client mailbox */ cur_time_limit WORD, /* time to wait for current op */ msgbuf(MBBUFSIZE) BYTE, req STRUCTURE ( /* client request structure */ req_type BYTE, /* request byte */ client_mbx TOKEN, /* mailbox accepting response */ sock DWORD, /* socket to be inserted */ name(NAMESIZE) BYTE) AT (@msgbuf), /* name to be inserted */ rsp STRUCTURE ( /* response structure */ rsp_type BYTE, /* response byte */ sock DWORD, name(NAMESIZE) BYTE) AT (@msgbuf), /* name to be inserted */ loc_status WORD, /* local status word */ rsp_ptr POINTER, /* points to response message */ result BYTE, /* indicates result of operation */ bytes_rec WORD, /* num bytes received */ new_entry ns_ent; /* new entry for insert request */ result = get_local_servr(@servr_mbx); IF result <> REQCOMPLETED THEN RETURN REQNOTCOMPLETE; client_mbx = rq$create$mailbox(DATAMBFLAG, @status); IF status <> E$OK THEN RETURN REQNOTCOMPLETE; req.req_type = CHANGEREQ; req.client_mbx = client_mbx; req.sock = new_socket; CALL copy_name(name_ptr, @req.name); CALL rq$send$data(servr_mbx, @req, size(req), stat_ptr); IF status <> E$OK THEN DO; CALL rq$delete$mailbox(client_mbx, @loc_status); RETURN REQNOTCOMPLETE; END; bytes_rec = rq$receive$data(client_mbx, @msgbuf, time_limit, stat_ptr); CALL rq$delete$mailbox(client_mbx, @loc_status); IF status <> E$OK THEN RETURN REQNOTCOMPLETE; ELSE RETURN rsp.rsp_type; END loc_change_sock; $subtitle('change_sock') /******************************************************************** * * PROC NAME: change_sock * * DESCRIPTION: Change_sock library routine for nameserver. Determine whether * nameserver is remote or local and send request accordingly. * * CALL: result = change_sock(host_id, name_ptr, new_sock, time_limit, stat_ptr) * * INPUTS: host_id - nameserver host id * name_ptr - points to name for nameserver lookup * new_sock - new socket value * time_limit - time wait for request to be processed * OUTPUT: stat_ptr - points to status word * RETURNS: result - result of requested operation * *********************************************************************/ change_sock:PROCEDURE(host_id, name_ptr, new_sock, time_limit, stat_ptr) BYTE REENTRANT PUBLIC; DECLARE /* params */ host_id WORD, name_ptr POINTER, new_sock DWORD, time_limit WORD, stat_ptr POINTER; DECLARE /* locals */ status BASED stat_ptr WORD, result BYTE; /* result of requested operation */ IF host_id = LOCALHOST then result = loc_change_sock(name_ptr, new_sock, time_limit, stat_ptr); ELSE result = rem_change_sock(host_id, name_ptr, new_sock, time_limit, stat_ptr); RETURN result; END change_sock; $subtitle('rem_get_table') /******************************************************************** * * PROC NAME: rem_get_table * * DESCRIPTION: Remote get_table library routine for nameserver. Send * get_table request to nameserver. Allocate a 64K segment * for the table. Wait for result and return result to * caller. * * CALL: result = rem_get_table(host_id, tab_ptr, time_limit, stat_ptr) * * INPUT: host_id - nameserver host id * time_limit - specifies max time to wait for response * OUTPUTS: tab_ptr - pointer to nameserver table pointer * tab_size_ptr - points to table size * stat_ptr - points to status word * RETURNS: result - indicates result of operation * *********************************************************************/ rem_get_table:PROCEDURE(host_id, tab_ptr_ptr, tab_size_ptr, time_limit, stat_ptr) BYTE REENTRANT PUBLIC; DECLARE /* params */ host_id WORD, tab_ptr_ptr POINTER, tab_size_ptr POINTER, time_limit WORD, stat_ptr POINTER; DECLARE /* locals */ status BASED stat_ptr WORD, info rec_info, /* receive information structure */ t_size BASED tab_size_ptr DWORD, port_t TOKEN, /* client port */ buf_pool TOKEN, /* token for buffer pool attached to port_t */ con_msg(CONSIZE) BYTE, /* control message buffer */ trans_id WORD, /* transaction id for request */ rsp_ptr POINTER, /* points to response message */ server_socket socket, /* nameserver socket */ server_sock DWORD AT (@server_socket), /* nameserver socket */ tab_t TOKEN, /* segment token for nameserver table */ tab_ptr BASED tab_ptr_ptr POINTER; /* points to nameserver table */ port_t = get$dport(0, @buf_pool, CHAIN, @status); IF status = E$OK THEN DO; tab_t = rq$create$segment(0,stat_ptr); IF status <> E$OK THEN RETURN REQNOTCOMPLETE; tab_ptr = build$ptr(tab_t, 0); server_socket.port_id = SERVERPORT; server_socket.host_id = host_id; con_msg(0) = TABLEREQ; trans_id = rq$send$rsvp(port_t, server_sock, @con_msg, NIL, 0, tab_ptr,0FFFFH, 0, stat_ptr); IF status <> E$OK THEN DO; CALL delete_port(port_t); RETURN REQNOTCOMPLETE; END; rsp_ptr = rq$receive$reply(port_t, trans_id, time_limit, @info, stat_ptr); CALL delete_port(port_t); IF status <> E$OK THEN RETURN REQNOTCOMPLETE; ELSE DO; t_size = info.data$length; RETURN info.con$msg(0); END; END; ELSE RETURN REQNOTCOMPLETE; END rem_get_table; $eject $subtitle('loc_get_table') /******************************************************************** * * PROC NAME: loc_get_table * * DESCRIPTION: Local get_table library routine for nameserver. Create a mail- * box, send a request message to the nameserver and wait for a * response. Return the result of the request. Since the segment * containing the table is from another job, copy the segment and * delete it. * * CALL: result = loc_get_table(tab_ptr_ptr, tab_size_ptr, time_limit, stat_ptr) * * INPUTS: time_limit - time wait for request to be processed * OUTPUT: tab_ptr_ptr - points to the table pointer * tab_size_ptr - points to table size * stat_ptr - points to status word * RETURNS: result - result of requested operation * *********************************************************************/ loc_get_table:PROCEDURE(tab_ptr_ptr, tab_size_ptr, time_limit, stat_ptr) BYTE REENTRANT PUBLIC; DECLARE /* params */ tab_ptr_ptr POINTER, tab_size_ptr POINTER, time_limit WORD, stat_ptr POINTER; DECLARE /* locals */ status BASED stat_ptr WORD, tab_size BASED tab_size_ptr DWORD, servr_mbx TOKEN, /* local server mailbox */ client_mbx TOKEN, /* client mailbox */ msgbuf(MBBUFSIZE) BYTE, req STRUCTURE ( /* client request structure */ req_type BYTE, /* request byte */ client_mbx TOKEN) /* mailbox accepting response */ AT (@msgbuf), /* name to be inserted */ rsp STRUCTURE ( /* response structure */ rsp_type BYTE, /* response byte */ tab_size DWORD, /* size of table */ tab_ptr POINTER) /* points to table */ AT (@msgbuf), /* name to be inserted */ loc_status WORD, /* local status word */ result BYTE, /* indicates result of operation */ bytes_rec WORD, /* num bytes received */ tab_buf_sel TOKEN, /* selector to server's table segment */ tab_tok TOKEN, /* local job table segment token */ tab_ptr BASED tab_ptr_ptr POINTER; /* points to local table */ result = get_local_servr(@servr_mbx); IF result <> REQCOMPLETED THEN RETURN REQNOTCOMPLETE; client_mbx = rq$create$mailbox(DATAMBFLAG, @status); IF status <> E$OK THEN RETURN REQNOTCOMPLETE; req.req_type = TABLEREQ; req.client_mbx = client_mbx; CALL rq$send$data(servr_mbx, @req, size(req), stat_ptr); IF status <> E$OK THEN DO; CALL rq$delete$mailbox(client_mbx, @loc_status); RETURN REQNOTCOMPLETE; END; bytes_rec = rq$receive$data(client_mbx, @msgbuf, time_limit, stat_ptr); IF bytes_rec > 1 THEN DO; tab_tok = rq$create$segment(rsp.tab_size, stat_ptr); IF status <> E$OK THEN RETURN REQNOTCOMPLETE; tab_ptr = build$ptr(tab_tok, 0); tab_size = rsp.tab_size; CALL movb(rsp.tab_ptr, tab_ptr, rsp.tab_size); tab_buf_sel = selector$of(rsp.tab_ptr); CALL rq$delete$segment(tab_buf_sel, stat_ptr); END; CALL rq$delete$mailbox(client_mbx, @loc_status); IF status <> E$OK THEN RETURN REQNOTCOMPLETE; ELSE RETURN rsp.rsp_type; END loc_get_table; $subtitle('get_table') /******************************************************************** * * PROC NAME: get_table * * DESCRIPTION: Get_table library routine for nameserver. Determine whether * nameserver is remote or local and send request accordingly. * * CALL: result = get_table(host_id, tab_ptr_ptr, tab_size_ptr, time_limit, stat_ptr) * * INPUTS: host_id - nameserver host id * time_limit - time wait for request to be processed * OUTPUT: stat_ptr - points to status word * tab_ptr_ptr - points to table pointer * tab_size_ptr - points to table size * RETURNS: result - result of requested operation * *********************************************************************/ get_table:PROCEDURE(host_id, tab_ptr_ptr, tab_size_ptr, time_limit, stat_ptr) BYTE REENTRANT PUBLIC; DECLARE /* params */ host_id WORD, tab_ptr_ptr POINTER, tab_size_ptr POINTER, time_limit WORD, stat_ptr POINTER; DECLARE /* locals */ status BASED stat_ptr WORD, result BYTE; /* result of requested operation */ IF host_id = LOCALHOST then result = loc_get_table(tab_ptr_ptr, tab_size_ptr, time_limit, stat_ptr); ELSE result = rem_get_table(host_id, tab_ptr_ptr, tab_size_ptr, time_limit, stat_ptr); RETURN result; END get_table; $eject $subtitle('get_host_id') /******************************************************************** * * PROC NAME: get_host_id * * DESCRIPTION: Check if the server is local; if so, return LOCALHOST * which indicates the server is local. If the server is * not local, broadcast a request for nameserver host id to a * well-known nameserver port. Return the host id if one * exists, 0FFFFH if not. * * CALL: host_id = get_host_id(time_limit, stat_ptr) * * INPUT: time_limit - specifies max time to wait for response from server * OUTPUT: stat_ptr - points to status word * RETURNS: host_id - host id of nameserver * * *********************************************************************/ get_host_id:PROCEDURE(time_limit, stat_ptr) WORD REENTRANT PUBLIC; DECLARE /* params */ time_limit WORD, stat_ptr POINTER; DECLARE /* locals */ status BASED stat_ptr WORD, root_job TOKEN, /* token for root job */ info rec_info, /* receive information structure */ port_t TOKEN, /* client port */ buf_pool TOKEN, /* token for buffer pool attached to port_t */ con_msg(CONSIZE) BYTE, /* control message buffer */ trans_id WORD, /* transaction id for request */ serv_socket socket, /* broadcast socket for name server */ serv_sock DWORD AT (@serv_socket), h_id_ptr POINTER, host_id BASED h_id_ptr WORD, /* nameserver host id */ result BYTE, /* result of local get server */ servr_mbx TOKEN; /* local server mailbox */ result = get_local_servr(@servr_mbx); IF result = REQCOMPLETED THEN RETURN LOCALHOST; port_t = get$dport(0, @buf_pool, CHAIN, @status); IF status = E$OK THEN DO; con_msg(0) = HOSTREQ; serv_socket.port_id = SERVERPORT; CALL rq$broadcast(port_t, serv_sock, @con_msg, stat_ptr); IF status <> E$OK THEN DO; CALL delete_port(port_t); RETURN SERVERNOTFOUND; END; h_id_ptr = rq$receive(port_t, time_limit, @info, stat_ptr); CALL delete_port(port_t); IF status <> E$OK THEN RETURN SERVERNOTFOUND; ELSE RETURN host_id; END; ELSE RETURN SERVERNOTFOUND; END get_host_id; END nclient;