[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

DNA



At Penn we use Vaxen for login and file service.  We are currently using CHAOS
to communicate because prior DNA software has been buggy.  We have not
tried the latest release of DNA.

I wrote a few network routines which utilize DNA.  One is a remote zmacs call,
ie.. from the vax I can tell zmacs to edit a file.  Another is a "ping"
service, this merely executes some piece of code on
each symbolics on the network.  The label of code to be executed is provided
as an argument across the net. We used it to poll whether each machine
was in use or not.  Finally, I wrote an eval-server which enabled one
to to fire up a read-eval-print loop on the vax, with a symbolics
performing the evaluation.  I used the ping service to connect to a 
free machine.  The eval service was the trickiest as it was difficult
to figure out how to do asynchronous I/O on the VAX side so that
I could support a pseudo-interactive stream.

The bulk of the effort was spent figuring out the the networking
calls on the VAX side, the networking on the Symbolics side was
quite easy. Below are some small pieces of code which you will
probably find useful:

typedef long int LINT;
typedef unsigned long int ULINT;
typedef short int SINT;
typedef unsigned short int USINT;

typedef struct iosb_rec {
	USINT status;
	union {
		USINT size;
		struct { unsigned char trans_speed, rec_speed;};
	} a;
	union {
		USINT pid;
		struct { unsigned char term_char, reserved;};
		struct { unsigned char cr_fill, lf_fill;};
	} b;
	union {
		USINT garb;
		struct { unsigned char term_len, cur_off;};
		struct { unsigned char parity, reserved2;};
	} c;
} status_block;

struct VMS_Descriptor *descr(String)
register char *String;
{
	static struct VMS_Descriptor VMS_Descriptors[NDESCRS];
	static int index = 0;
	register int size = 0;

	if( index==NDESCRS ) index = 0;
	VMS_Descriptors[index].ptr = String;
	while( *String++ ) size++;	/* no nulls inside strings! */
	VMS_Descriptors[index].size = size;
	return(&VMS_Descriptors[index++]);
}

#include <iodef.h>                  /* IO$_READVBLK, IO$_WRITEVBLK */
#include <ssdef.h>			/* SS$... */

	/* Following are some useful functions to access network hosts.*/

	/* Given a hostname, the task will return a host channel upon success, else ERROR */

int net$get_host(host_name,service)
string host_name,service;
{
	char name[MAX_LINE], s[MAX_LINE], task[MAX_LINE], quote[MAX_LINE];

	strcpy(s, service);
	strcpy(name, host_name);
	strncpy(task, "::\"TASK=", 9);
	strncpy(quote,"\"",2);
	return(net$get_channel(strcat(name,strcat(strcat(task,s), quote))));
}

int net$get_channel(port)
string port;
{
	int status, channel;

	status = sys$assign(descr(port),&channel,0,0);
	if( !(status&1) ) {
		fprintf(stderr,"Couldn't open %s, error number %d.\n",port, status);
		return(ERROR);}
	return(channel);
}

net$string_in(channel,buffer, size)
int channel, size;
string buffer;
{
	status_block netiosb;

	sys$qiow(0, channel, IO$_READVBLK, &netiosb, 0, 0, buffer, size, 0,0,0,0);
	return(check_status(netiosb));
}

net$string_out(channel, buffer, size)
int channel,size;
string buffer;
{	
	status_block netiosb;
	
	sys$qiow(1,channel,IO$_WRITEVBLK,&netiosb,0,0,buffer,size,0,0,0,0);
	return(check_status(netiosb));
}

check_status(netiosb)
status_block netiosb;
{
	if (netiosb.status != SS$_NORMAL){
		fprintf(stderr,"Error number %d.\n", netiosb.status);
		return(ERROR);}
	else return(1);
}

	/* Does a synchronous disconnect*/

net$disconnect(host)
int host;
{
		sys$qio(0, host, (IO$_DEACCESS | IO$M_SYNCH), 0,0,0,0,0,0,0,0,0);
		sys$dassgn(host);
}	

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

/* Here is the code to implement the eval editing service on the Vax side */

main(argc,argv)
int argc;
string argv[];
{
	int host;
	status_block netiosb;
	char path[MAX_LINE];
	string p;

	if (argc != 3) {
		fprintf(stderr,"edit <machine-name> <file-name>");
		exit(1);}
	if ((host = get_host(*++argv, "EDIT")) == ERROR){
		fprintf(stderr, "Could not connect to host %s\n", *argv);
		exit(1);}
	sleep(1);
	*++argv;
	strcpy(path, getenv("PATH"));
	p = strcat(path, *argv);

	/* strip the device */

	p = p + 4;
	net$string_out(host, p, strlen(p));
	disconnect(host);
}

;;; The code below implements the editing service on the lisp side

(net:define-server :edit (:medium :byte-stream :reject-unless-trusted t
					  :who-line nil
					   :error-disposition :debugger
					   :stream (stream :ascii-translation t))
 (edit stream))

(defun edit(stream)
 (let ((path (fs:parse-pathname (string (read stream)))))
  (cl:sleep 1)
  (ed path)))

(dna:add-dna-contact-id-for-protocol :edit "edit")


Andrew@Upenn