
NOS on SunOS

Mike Westerhof, KA9WSB

November, 1991




This kit is intended to help folks port NOS to UNIX systems.  It is primarily
intended for Sun users, but I suspect many of the techniques are also
applicable to other UNIX systems.




The contents of this kit are broken into several directories:

common:		The modified source files needed for any UNIX version

lwp:		The Sun LWP library specific files

thread:		The longjmp/setjmp alternative to the LWP stuff (works
		better, for the most part)

old_OS:		Some fake/hacked system include files for SunOS releases
		4.0.2 and 4.0.3.  This stuff is not required for SunOS 4.1

tundrvr:	A copy of Julian Onion's tunnel driver for your UNIX OS

test:		An incomplete directory structure for testing NOS




The porting procedure is relatively simple, if somewhat tedious:

% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %

a) Obtain a copy of NOS to port.  This document describes the PA0GRI v1.7j
   version, but most NOS versions based on the same KA9Q core should port
   with minor changes.

% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %

b) Convert the NOS ".ZIP" file to a standard UNIX format.  The easiest way
   is to unzip the source on a PC or on a PC emulator.  You can ftp the
   the source to the UNIX machine, or you can use the "dos2unix" command
   on SunOS to convert the DOS text format to UNIX format.

% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %

c) Copy the contents of the "common" directory into your NOS source
   directory.  You will probably want to keep the original versions
   of the modified routines.

% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %

d) Rename the NOS "makefile" to "makefile.old" or something.

% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %

e) Copy the contents of the "thread" directory into your NOS source
   directory.  Again, you will want to keep the original versions around
   somewhere.

% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %

f) The 8250.h file is no longer necessary.  The easiest way to fix it
   is to add a "#ifndef UNIX" at the top, and a "#endif" at the bottom,
   like so:

*** grinos.orig/8250.h	Wed Nov 20 16:05:32 1991
--- g/8250.h	Tue Nov 26 10:29:44 1991
***************
*** 1,5 ****
--- 1,6 ----
  /* Various I/O definitions specific to asynch I/O on the IBM PC */
  /* Mods by G1EMM */
+ #ifndef UNIX
  #ifndef	_8250_H
  #define	_8250_H
  
***************
*** 164,166 ****
--- 165,168 ----
  INTERRUPT asy4vec __ARGS((void));
  
  #endif	/* _8250_H */
+ #endif  /* not UNIX */

% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %

g) The hardware.h file will give you a little grief; get rid of the
   "clrbit" and "setbit" definitions.

% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %

h) There is a little nasty bit of code in kernel.c that needs to
   be fixed to use the normal "free" technique.  See the comments
   in "bsdunix.c" for details, but start with this change:

*** grinos.orig/kernel.c	Fri Nov 22 10:05:50 1991
--- g/kernel.c	Tue Nov 26 10:35:15 1991
***************
*** 167,174 ****
  	/* Free allocated memory resources */
  	if(pp->freeargs){
  		argv = pp->parg1;
! 		while(pp->iarg-- != 0)
! 			free(*argv++);
  		free(pp->parg1);
  	}
  	free(pp->name);
--- 167,176 ----
  	/* Free allocated memory resources */
  	if(pp->freeargs){
  		argv = pp->parg1;
! 		while(pp->iarg-- != 0){
! 			free(*argv);
! 			argv++;
! 		}
  		free(pp->parg1);
  	}
  	free(pp->name);


% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %

i) There is some yucky bit of PC-specific code in NOS that is not
   ifdef'd properly.

*** grinos.orig/mbuf.c	Wed Nov 20 16:06:28 1991
--- g/mbuf.c	Tue Nov 26 10:35:25 1991
***************
*** 37,42 ****
--- 37,43 ----
  	while(Intqlen < Nibufs){
  		if((bp = alloc_mbuf(Ibufsize)) == NULLBUF)
  			break;
+ #ifndef UNIX
  #ifndef	notdef		/* Temp hack to satisfy PI DMA requirements */
  		dma_abs = ((long)FP_SEG(bp->data) << 4) + (long)FP_OFF(bp->data);
  		dma_page = dma_abs >> 16;
***************
*** 47,52 ****
--- 48,54 ----
  			restore(i_state);
  			continue;
  		}
+ #endif
  #endif
  
  		i_state = dirps();

% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %

j) And there are plenty of little compiler disagreements; some places in
   NOS where the definition of a function is "extern static int foo()", but
   the actual routine is declared as "int foo()"...  Some things the
   compiler just doesn't like.


*** grinos.orig/axheard.c	Wed Nov 20 16:05:45 1991
--- g/axheard.c	Tue Nov 26 10:30:11 1991
***************
*** 11,17 ****
  #include "ip.h"
  #include "timer.h"
  
! #define iscallsign(c) ((isupper(c)) || (isdigit(c)) || (c =='\x20'))
  int axheard_filter_flag = AXHEARD_PASS;
  
  static struct lq *al_create __ARGS((struct iface *ifp,char *addr));
--- 11,17 ----
  #include "ip.h"
  #include "timer.h"
  
! #define iscallsign(c) ((isupper(c)) || (isdigit(c)) || (c ==' '))
  int axheard_filter_flag = AXHEARD_PASS;
  
  static struct lq *al_create __ARGS((struct iface *ifp,char *addr));


*** grinos.orig/bootpcmd.c	Wed Nov 20 16:05:48 1991
--- g/bootpcmd.c	Tue Nov 26 10:30:38 1991
***************
*** 12,19 ****
  
  
  #include <stdio.h>
! #include <sys\types.h>
! #include <sys\stat.h>
  #include <time.h>
  #include <ctype.h>
  #ifdef	ANSIPROTO
--- 12,19 ----
  
  
  #include <stdio.h>
! #include <sys/types.h>
! #include <sys/stat.h>
  #include <time.h>
  #include <ctype.h>
  #ifdef	ANSIPROTO


*** grinos.orig/bootpd.c	Wed Nov 20 16:05:48 1991
--- g/bootpd.c	Tue Nov 26 10:30:55 1991
***************
*** 18,25 ****
  
  
  #include <stdio.h>
! #include <sys\types.h>
! #include <sys\stat.h>
  #include <ctype.h>
  #include <time.h>
  
--- 18,25 ----
  
  
  #include <stdio.h>
! #include <sys/types.h>
! #include <sys/stat.h>
  #include <ctype.h>
  #include <time.h>
  
***************
*** 379,389 ****
  struct iface *iface;
  struct host *hp;
  {
! 	char 	cookie[5] = {99, 130, 83, 99, 0};
  	int 	len;
  	int	mod;
  	int	i;
  	char	*sizep;
  
  	/* Magic cookie */
  	strcpy (vend, cookie); 
--- 379,395 ----
  struct iface *iface;
  struct host *hp;
  {
! 	char 	cookie[5];
  	int 	len;
  	int	mod;
  	int	i;
  	char	*sizep;
+ 
+ 	cookie[0] = 99;
+ 	cookie[1] = 130;
+ 	cookie[2] = 83;
+ 	cookie[3] = 99;
+ 	cookie[4] = 0;
  
  	/* Magic cookie */
  	strcpy (vend, cookie); 


*** grinos.orig/bootpdip.c	Wed Nov 20 16:05:49 1991
--- g/bootpdip.c	Tue Nov 26 10:31:07 1991
***************
*** 904,910 ****
   *      q_enqueue()
   *              Enqueue an element in a simple Q.
   */
! void
  q_enqueue(queue, elem)
  struct q *queue;
  struct q_elt *elem;
--- 904,910 ----
   *      q_enqueue()
   *              Enqueue an element in a simple Q.
   */
! static void
  q_enqueue(queue, elem)
  struct q *queue;
  struct q_elt *elem;


*** grinos.orig/domain.c	Wed Nov 20 16:05:55 1991
--- g/domain.c	Tue Nov 26 10:31:48 1991
***************
*** 158,164 ****
  	return subcmd(Dcmds,argc,argv,p);
  }
  
! int
  docache(argc,argv,p)
  int argc;
  char *argv[];
--- 158,164 ----
  	return subcmd(Dcmds,argc,argv,p);
  }
  
! static int
  docache(argc,argv,p)
  int argc;
  char *argv[];


*** grinos.orig/nrcmd.c	Wed Nov 20 16:06:37 1991
--- g/nrcmd.c	Tue Nov 26 10:35:40 1991
***************
*** 1063,1069 ****
  
  	return 0 ;
  }
! int
  donrload(argc,argv,p)
  int argc ;
  char *argv[] ;
--- 1063,1069 ----
  
  	return 0 ;
  }
! static int
  donrload(argc,argv,p)
  int argc ;
  char *argv[] ;
***************
*** 1135,1141 ****
  	return 0;
  }
  
! int
  donrsave(argc,argv,p)
  int argc ;
  char *argv[] ;
--- 1135,1141 ----
  	return 0;
  }
  
! static int
  donrsave(argc,argv,p)
  int argc ;
  char *argv[] ;


*** grinos.orig/popcli.c	Wed Nov 20 16:06:46 1991
--- g/popcli.c	Tue Nov 26 10:35:47 1991
***************
*** 278,285 ****
  	char *cp;
  	struct sockaddr_in fsocket;
  	struct pop_ccb	*ccb;
! 	void pop_csm(struct pop_ccb *);
! 	void quit_session(struct pop_ccb *);
  
  	ccb = (struct pop_ccb *)cb1;
  	fsocket.sin_family = AF_INET;
--- 278,285 ----
  	char *cp;
  	struct sockaddr_in fsocket;
  	struct pop_ccb	*ccb;
! 	void pop_csm __ARGS((struct pop_ccb *));
! 	void quit_session __ARGS((struct pop_ccb *));
  
  	ccb = (struct pop_ccb *)cb1;
  	fsocket.sin_family = AF_INET;
***************
*** 347,354 ****
  {
  	FILE *mf;
  
! 	int mlock (char *,char *);
! 	int rmlock (char * ,char *);
  	void quit_session __ARGS((struct pop_ccb *));
  	/* int mlock __ARGS((char *dir,char *id));   */
  	/* int rmlock __ARGS((char *dir,char *id));   */
--- 347,354 ----
  {
  	FILE *mf;
  
! 	int mlock __ARGS((char *,char *));
! 	int rmlock __ARGS((char * ,char *));
  	void quit_session __ARGS((struct pop_ccb *));
  	/* int mlock __ARGS((char *dir,char *id));   */
  	/* int rmlock __ARGS((char *dir,char *id));   */


*** grinos.orig/popserv.c	Wed Nov 20 16:06:46 1991
--- g/popserv.c	Tue Nov 26 10:35:52 1991
***************
*** 212,228 ****
  struct pop_scb *scb;
  {
  	char password[40];
! 	void state_error(struct pop_scb *,char *);
! 	void open_folder(struct pop_scb *);
! 	void do_cleanup(struct pop_scb *);
! 	void read_message(struct pop_scb *);
! 	void retrieve_message(struct pop_scb *);
! 	void deletemsg(struct pop_scb *,int);
! 	void get_message(struct pop_scb *,int);
! 	void print_message_length(struct pop_scb *);
! 	void close_folder(struct pop_scb *);
  #ifdef POP_FOLDERS
! 	void select_folder(struct pop_scb *);
  #endif
  
  	if(scb == NULLSCB)
--- 212,228 ----
  struct pop_scb *scb;
  {
  	char password[40];
! 	void state_error __ARGS((struct pop_scb *,char *));
! 	void open_folder __ARGS((struct pop_scb *));
! 	void do_cleanup __ARGS((struct pop_scb *));
! 	void read_message __ARGS((struct pop_scb *));
! 	void retrieve_message __ARGS((struct pop_scb *));
! 	void deletemsg __ARGS((struct pop_scb *,int));
! 	void get_message __ARGS((struct pop_scb *,int));
! 	void print_message_length __ARGS((struct pop_scb *));
! 	void close_folder __ARGS((struct pop_scb *));
  #ifdef POP_FOLDERS
! 	void select_folder __ARGS((struct pop_scb *));
  #endif
  
  	if(scb == NULLSCB)
***************
*** 369,376 ****
  	int deleted = FALSE;
  	int msg_no = 0;
  	struct stat folder_stat;
! 	int newmail(struct pop_scb *);
! 	int isdeleted(struct pop_scb *,int);
  
  	if (scb->wf == NULL)
  		return;
--- 369,376 ----
  	int deleted = FALSE;
  	int msg_no = 0;
  	struct stat folder_stat;
! 	int newmail __ARGS((struct pop_scb *));
! 	int isdeleted __ARGS((struct pop_scb *,int));
  


  	if (scb->wf == NULL)
  		return;
***************
*** 534,540 ****
  {
  	char line[BUF_LEN];
  	long cnt;
! 	void rrip(char *);
  
  	if(scb == NULLSCB)
  		return;
--- 534,540 ----
  {
  	char line[BUF_LEN];
  	long cnt;
! 	void rrip __ARGS((char *));
  
  	if(scb == NULLSCB)
  		return;
***************
*** 562,568 ****
  {
  	char line[BUF_LEN];
  	long ftell();
! 	void rrip(char *);
  
  	if(scb == NULLSCB)
  		return;
--- 562,568 ----
  {
  	char line[BUF_LEN];
  	long ftell();
! 	void rrip __ARGS((char *));
  
  	if(scb == NULLSCB)
  		return;



% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %

j) And... some outright bugs.  Here's one that you might fix if your
   version of NOS doesn't have it fixed.

*** grinos.orig/rspf.c	Wed Nov 20 16:06:57 1991
--- g/rspf.c	Tue Nov 26 10:36:01 1991
***************
*** 392,398 ****
  	    goodbadnews(adj);			/* ..that is good news */
  	break;
      }
!     stop_timer(&oldadj->timer);		/* stop timer before free() -- KZ1F */
      free((char *)oldadj);
  }
  
--- 392,399 ----
  	    goodbadnews(adj);			/* ..that is good news */
  	break;
      }
!     if(oldadj != NULLADJ)			/* Careful! KA9WSB */
! 	    stop_timer(&oldadj->timer);		/* stop timer before free() -- KZ1F */
      free((char *)oldadj);
  }
  

% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %

k) Don't forget to update the version.c file so that you know what version
   you happen to be running :-)

*** grinos.orig/version.c	Wed Nov 20 16:07:20 1991
--- g/version.c	Tue Nov 26 10:37:52 1991
***************
*** 2,10 ****
  #include "config.h"
  #include "global.h"
  #include "mbuf.h"
! char Version[] = "910618 (PA0GRI v1.7j)";
! char Version2[] = "This version produced by Gerard van der Grinten - PA0GRI";
! 
  int
  doinfo(argc,argv,p)
  int argc;
--- 2,9 ----
  #include "config.h"
  #include "global.h"
  #include "mbuf.h"
! char Version[] = "910618 (PA0GRI v1.7j) (KA9WSB Tb)";
! char Version2[] = "This version produced by Gerard van der Grinten - PA0GRI\nPorted to SunOS by KA9WSB";
  int
  doinfo(argc,argv,p)
  int argc;

% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %

l) If you have an older compiler, you might get complaints about a duplicate
   routine.  There is a declaration for "domotd" in the mailbox.c file that
   may upset the compiler.  The simplest fix is to change all references
   to "domotd" to "dombmotd" in the mailbox.c file.

% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %

m) Update the config.h file to reflect your environment.  Note! PPP is
   is so Turbo-C/DOS specific that I haven't been able to get it compiled
   at all.  The Makefile doesn't reference any PPP sources, so don't define
   PPP in config.h.  Following is the file I use:

/* Software options */
#define	MAILBOX		1	/* Include SM0RGV mailbox server */
#define	NNTP		1	/* Netnews client */
#define	SERVERS		1	/* Include TCP servers */
#define	TRACE		1	/* Include packet tracing code */
#define	RIP		1	/* Include RIP routing */
#define	HOPCHECK	1	/* IP path tracing command */
#define	DIALER		1	/* SLIP redial code */
#define	NRS		1	/* NET/ROM async interface */
#define	NETROM		1	/* NET/ROM network support */
#undef	LZW		1	/* LZW-compressed sockets */
#define RLOGINCLI	1	/* Rlogin client code */
#define	SLIP		1	/* Serial line IP on built-in ports */
#undef	PPP		1	/* Point-to-Point Protocol code */
#undef	VJCOMPRESS	1	/* Van Jacobson TCP compression for SLIP */
#define	POP		1	/* Include POP2 Post Office Protocol */
#define ESCAPE		1	/* Allow Unix style escape on PC */
#define	RSPF		1	/* Include Radio Shortest Path First Protocol */
#define AXIP		1	/* digipeater via ip port 93 interface */

/* Software tuning parameters */
#define	MTHRESH		8192	/* Default memory threshold */
#define	NROWS		25	/* Number of rows on screen */
#define	NIBUFS		5	/* Number of interrupt buffers */
#define	IBUFSIZE	2048	/* Size of interrupt buffers */
#define	NSESSIONS	10	/* Number of interactive clients */
#define DEFNSOCK	40	/* Default number of sockets */

/* Hardware driver options */
#undef	ARCNET		1	/* ARCnet via PACKET driver */
#undef	PC_EC		1	/* 3-Com 3C501 Ethernet controller */
#define	KISS		1	/* KISS TNC code */
#undef	HS		1	/* High speed (56kbps) modem driver */
#undef	HAPN		1	/* Hamilton Area Packet Network driver code */
#undef	EAGLE		1	/* Eagle card driver */
#define	PACKET		1	/* FTP Software's Packet Driver interface */
#undef	PC100		1	/* PAC-COM PC-100 driver code */
#undef	APPLETALK	1	/* Appletalk interface (Macintosh) */
#undef	DRSI		1	/* DRSI PCPA slow-speed driver */
#undef	SCC		1	/* PE1CHL generic scc driver */
#undef	PI		1	/* VE3IFB pi dma card scc driver */
#define	ASY		1	/* Asynch driver code */
#undef	SLFP		1	/* SLFP packet driver class supported */

% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %

n) If you want to use the nit driver instead the tunnel driver, you'll have
   to change the Makefile (and cross your fingers!).

% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %

m) Type "make"... then fix all the problems you encounter (easier said than
   done)!

% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %

n) Once you get it compiled, you can test it.  The "test" directory contains
   an incomplete sample directory structure, and a sample startup.nos file.

% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
