Netware-specific changes,

PR: 780
Submitted by: Verdon Walker <VWalker@novell.com>
Reviewed by: Richard Levitte
diff --git a/crypto/bf/bf_opts.c b/crypto/bf/bf_opts.c
index 171dada..1721bb9 100644
--- a/crypto/bf/bf_opts.c
+++ b/crypto/bf/bf_opts.c
@@ -69,7 +69,10 @@
 #include OPENSSL_UNISTD_IO
 OPENSSL_DECLARE_EXIT
 
+#ifndef OPENSSL_SYS_NETWARE
 #include <signal.h>
+#endif
+
 #ifndef _IRIX
 #include <time.h>
 #endif
diff --git a/crypto/bf/bfspeed.c b/crypto/bf/bfspeed.c
index f346af6..c41ef3b 100644
--- a/crypto/bf/bfspeed.c
+++ b/crypto/bf/bfspeed.c
@@ -69,7 +69,10 @@
 #include OPENSSL_UNISTD_IO
 OPENSSL_DECLARE_EXIT
 
+#ifndef OPENSSL_SYS_NETWARE
 #include <signal.h>
+#endif
+
 #ifndef _IRIX
 #include <time.h>
 #endif
diff --git a/crypto/bf/bftest.c b/crypto/bf/bftest.c
index 14bc4d7..97e6634 100644
--- a/crypto/bf/bftest.c
+++ b/crypto/bf/bftest.c
@@ -278,6 +278,9 @@
 	else
 		ret=test();
 
+#ifdef OPENSSL_SYS_NETWARE
+    if (ret) printf("ERROR: %d\n", ret);
+#endif
 	EXIT(ret);
 	return(0);
 	}
diff --git a/crypto/bio/b_sock.c b/crypto/bio/b_sock.c
index c501008..d619bcf 100644
--- a/crypto/bio/b_sock.c
+++ b/crypto/bio/b_sock.c
@@ -79,7 +79,7 @@
 #define MAX_LISTEN  32
 #endif
 
-#ifdef OPENSSL_SYS_WINDOWS
+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_NETWARE)
 static int wsa_init_done=0;
 #endif
 
@@ -473,6 +473,31 @@
 	if (sock_init())
 		return (-1);
 #endif
+
+#if defined(OPENSSL_SYS_NETWARE)
+    WORD wVerReq;
+    WSADATA wsaData;
+    int err;
+
+    if (!wsa_init_done)
+    {
+   
+# ifdef SIGINT
+        signal(SIGINT,(void (*)(int))BIO_sock_cleanup);
+# endif
+
+        wsa_init_done=1;
+        wVerReq = MAKEWORD( 2, 0 );
+        err = WSAStartup(wVerReq,&wsaData);
+        if (err != 0)
+        {
+            SYSerr(SYS_F_WSASTARTUP,err);
+            BIOerr(BIO_F_BIO_SOCK_INIT,BIO_R_WSASTARTUP);
+            return(-1);
+			}
+		}
+#endif
+
 	return(1);
 	}
 
@@ -487,6 +512,12 @@
 #endif
 		WSACleanup();
 		}
+#elif defined(OPENSSL_SYS_NETWARE)
+   if (wsa_init_done)
+        {
+        wsa_init_done=0;
+        WSACleanup();
+		}
 #endif
 	}
 
diff --git a/crypto/bio/bss_file.c b/crypto/bio/bss_file.c
index 1f9bd33..774bc5a 100644
--- a/crypto/bio/bss_file.c
+++ b/crypto/bio/bss_file.c
@@ -218,6 +218,13 @@
 			_setmode(fd,_O_TEXT);
 		else
 			_setmode(fd,_O_BINARY);
+#elif defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_CLIB)
+         /* Under CLib there are differences in file modes
+         */
+		if (num & BIO_FP_TEXT)
+			_setmode(fileno((FILE *)ptr),O_TEXT);
+		else
+			_setmode(fileno((FILE *)ptr),O_BINARY);
 #elif defined(OPENSSL_SYS_MSDOS)
 		{
 		int fd = fileno((FILE*)ptr);
@@ -270,7 +277,13 @@
 		else
 			strcat(p,"t");
 #endif
-		fp=fopen(ptr,p);
+#if defined(OPENSSL_SYS_NETWARE)
+		if (!(num & BIO_FP_TEXT))
+			strcat(p,"b");
+		else
+			strcat(p,"t");
+#endif
+fp=fopen(ptr,p);
 		if (fp == NULL)
 			{
 			SYSerr(SYS_F_FOPEN,get_last_sys_error());
diff --git a/crypto/bio/bss_log.c b/crypto/bio/bss_log.c
index 1eb678c..6360dbc 100644
--- a/crypto/bio/bss_log.c
+++ b/crypto/bio/bss_log.c
@@ -78,6 +78,8 @@
 #  include <starlet.h>
 #elif defined(__ultrix)
 #  include <sys/syslog.h>
+#elif defined(OPENSSL_SYS_NETWARE)
+#  define NO_SYSLOG
 #elif (!defined(MSDOS) || defined(WATT32)) && !defined(OPENSSL_SYS_VXWORKS) && !defined(NO_SYSLOG)
 #  include <syslog.h>
 #endif
diff --git a/crypto/bio/bss_sock.c b/crypto/bio/bss_sock.c
index 7207a1f..472dd75 100644
--- a/crypto/bio/bss_sock.c
+++ b/crypto/bio/bss_sock.c
@@ -246,7 +246,7 @@
 	{
 	switch (err)
 		{
-#if defined(OPENSSL_SYS_WINDOWS)
+#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_NETWARE)
 # if defined(WSAEWOULDBLOCK)
 	case WSAEWOULDBLOCK:
 # endif
diff --git a/crypto/bn/exptest.c b/crypto/bn/exptest.c
index b09cf88..37aec55 100644
--- a/crypto/bn/exptest.c
+++ b/crypto/bn/exptest.c
@@ -181,6 +181,9 @@
 err:
 	ERR_load_crypto_strings();
 	ERR_print_errors(out);
+#ifdef OPENSSL_SYS_NETWARE
+    printf("ERROR\n");
+#endif
 	EXIT(1);
 	return(1);
 	}
diff --git a/crypto/buffer/buffer.h b/crypto/buffer/buffer.h
index 164f8aa..7f557c2 100644
--- a/crypto/buffer/buffer.h
+++ b/crypto/buffer/buffer.h
@@ -64,7 +64,10 @@
 #endif
 
 #include <stddef.h>
+
+#if !defined(NO_SYS_TYPES_H)
 #include <sys/types.h>
+#endif
 
 typedef struct buf_mem_st
 	{
diff --git a/crypto/cast/cast_spd.c b/crypto/cast/cast_spd.c
index 76abf50..d650af4 100644
--- a/crypto/cast/cast_spd.c
+++ b/crypto/cast/cast_spd.c
@@ -69,7 +69,10 @@
 #include OPENSSL_UNISTD_IO
 OPENSSL_DECLARE_EXIT
 
+#ifndef OPENSSL_SYS_NETWARE
 #include <signal.h>
+#endif
+
 #ifndef _IRIX
 #include <time.h>
 #endif
diff --git a/crypto/cast/castopts.c b/crypto/cast/castopts.c
index 1b858d1..33b2c7b 100644
--- a/crypto/cast/castopts.c
+++ b/crypto/cast/castopts.c
@@ -69,7 +69,10 @@
 #include OPENSSL_UNISTD_IO
 OPENSSL_DECLARE_EXIT
 
+#ifndef OPENSSL_SYS_NETWARE
 #include <signal.h>
+#endif
+
 #ifndef _IRIX
 #include <time.h>
 #endif
diff --git a/crypto/des/des_opts.c b/crypto/des/des_opts.c
index 79278b9..2df8296 100644
--- a/crypto/des/des_opts.c
+++ b/crypto/des/des_opts.c
@@ -71,7 +71,11 @@
 #include <io.h>
 extern void exit();
 #endif
+
+#ifndef OPENSSL_SYS_NETWARE
 #include <signal.h>
+#endif
+
 #ifndef _IRIX
 #include <time.h>
 #endif
diff --git a/crypto/des/destest.c b/crypto/des/destest.c
index 788f552..4584cf3 100644
--- a/crypto/des/destest.c
+++ b/crypto/des/destest.c
@@ -821,6 +821,9 @@
 		printf("fast crypt error, %s should be yA1Rp/1hZXIJk\n",str);
 		err=1;
 		}
+#ifdef OPENSSL_SYS_NETWARE
+    if (err) printf("ERROR: %d\n", err);
+#endif
 	printf("\n");
 	return(err);
 	}
diff --git a/crypto/des/speed.c b/crypto/des/speed.c
index 48fc1d4..1616f4b 100644
--- a/crypto/des/speed.c
+++ b/crypto/des/speed.c
@@ -69,7 +69,11 @@
 #include OPENSSL_UNISTD_IO
 OPENSSL_DECLARE_EXIT
 
+#ifndef OPENSSL_SYS_NETWARE
 #include <signal.h>
+#define crypt(c,s) (des_crypt((c),(s)))
+#endif
+
 #ifndef _IRIX
 #include <time.h>
 #endif
diff --git a/crypto/dh/dhtest.c b/crypto/dh/dhtest.c
index 492fbee..1b19364 100644
--- a/crypto/dh/dhtest.c
+++ b/crypto/dh/dhtest.c
@@ -197,9 +197,9 @@
 	if(b != NULL) DH_free(b);
 	if(a != NULL) DH_free(a);
 	BIO_free(out);
-	CRYPTO_cleanup_all_ex_data();
-	ERR_remove_state(0);
-	CRYPTO_mem_leaks_fp(stderr);
+#ifdef OPENSSL_SYS_NETWARE
+    if (ret) printf("ERROR: %d\n", ret);
+#endif
 	EXIT(ret);
 	return(ret);
 	}
diff --git a/crypto/dsa/dsatest.c b/crypto/dsa/dsatest.c
index 1dbda68..ccc456e 100644
--- a/crypto/dsa/dsatest.c
+++ b/crypto/dsa/dsatest.c
@@ -221,6 +221,9 @@
 		BIO_free(bio_err);
 		bio_err = NULL;
 		}
+#ifdef OPENSSL_SYS_NETWARE
+    if (!ret) printf("ERROR\n");
+#endif
 	EXIT(!ret);
 	return(0);
 	}
diff --git a/crypto/idea/idea_spd.c b/crypto/idea/idea_spd.c
index 48ffaff..699353e 100644
--- a/crypto/idea/idea_spd.c
+++ b/crypto/idea/idea_spd.c
@@ -69,7 +69,10 @@
 #include OPENSSL_UNISTD_IO
 OPENSSL_DECLARE_EXIT
 
+#ifndef OPENSSL_SYS_NETWARE
 #include <signal.h>
+#endif
+
 #ifndef _IRIX
 #include <time.h>
 #endif
diff --git a/crypto/idea/ideatest.c b/crypto/idea/ideatest.c
index 98f805d..e6ffc70 100644
--- a/crypto/idea/ideatest.c
+++ b/crypto/idea/ideatest.c
@@ -169,6 +169,9 @@
 	else
 		printf("ok\n");
 
+#ifdef OPENSSL_SYS_NETWARE
+    if (err) printf("ERROR: %d\n", err);
+#endif
 	EXIT(err);
 	return(err);
 	}
diff --git a/crypto/md2/md2test.c b/crypto/md2/md2test.c
index 9c1e28b..13cbec4 100644
--- a/crypto/md2/md2test.c
+++ b/crypto/md2/md2test.c
@@ -124,6 +124,9 @@
 		R++;
 		P++;
 		}
+#ifdef OPENSSL_SYS_NETWARE
+    if (err) printf("ERROR: %d\n", err);
+#endif
 	EXIT(err);
 	}
 
diff --git a/crypto/md32_common.h b/crypto/md32_common.h
index 511e5b2..0cdc06e 100644
--- a/crypto/md32_common.h
+++ b/crypto/md32_common.h
@@ -184,6 +184,8 @@
 # elif defined(__MWERKS__)
 #  if defined(__POWERPC__)
 #   define ROTATE(a,n)	__rlwinm(a,n,0,31)
+#  elif defined(OPENSSL_SYSNAME_NETWARE)
+#   define ROTATE(a,n)  _lrotl(a,n)
 #  elif defined(__MC68K__)
     /* Motorola specific tweak. <appro@fy.chalmers.se> */
 #   define ROTATE(a,n)	( n<24 ? __rol(a,n) : __ror(a,32-n) )
diff --git a/crypto/md5/md5test.c b/crypto/md5/md5test.c
index bfd6262..667b6be 100644
--- a/crypto/md5/md5test.c
+++ b/crypto/md5/md5test.c
@@ -120,6 +120,10 @@
 		R++;
 		P++;
 		}
+
+#ifdef OPENSSL_SYS_NETWARE
+    if (err) printf("ERROR: %d\n", err);
+#endif
 	EXIT(err);
 	return(0);
 	}
diff --git a/crypto/mdc2/mdc2test.c b/crypto/mdc2/mdc2test.c
index c9abe99..017b31a 100644
--- a/crypto/mdc2/mdc2test.c
+++ b/crypto/mdc2/mdc2test.c
@@ -140,6 +140,9 @@
 		printf("pad2 - ok\n");
 
 	EVP_MD_CTX_cleanup(&c);
+#ifdef OPENSSL_SYS_NETWARE
+    if (ret) printf("ERROR: %d\n", ret);
+#endif
 	EXIT(ret);
 	return(ret);
 	}
diff --git a/crypto/perlasm/x86asm.pl b/crypto/perlasm/x86asm.pl
index 1cb96e9..f9c7c37 100644
--- a/crypto/perlasm/x86asm.pl
+++ b/crypto/perlasm/x86asm.pl
@@ -18,7 +18,7 @@
 	($type,$fn,$i386)=@_;
 	$filename=$fn;
 
-	$elf=$cpp=$sol=$aout=$win32=$gaswin=0;
+	$elf=$cpp=$sol=$aout=$win32=$gaswin=$netware=0;
 	if (	($type eq "elf"))
 		{ $elf=1; require "x86unix.pl"; }
 	elsif (	($type eq "a.out"))
@@ -33,6 +33,10 @@
 		{ $win32=1; require "x86ms.pl"; }
 	elsif (	($type eq "win32n"))
 		{ $win32=1; require "x86nasm.pl"; }
+	elsif (	($type eq "nw-nasm"))
+		{ $netware=1; require "x86nasm_nw.pl"; }
+	elsif (	($type eq "nw-mwasm"))
+		{ $netware=1; require "x86mwasm_nw.pl"; }
 	else
 		{
 		print STDERR <<"EOF";
@@ -43,6 +47,8 @@
 	cpp	- format so x86unix.cpp can be used
 	win32	- Windows 95/Windows NT
 	win32n	- Windows 95/Windows NT NASM format
+	nw-nasm - NetWare NASM format
+	nw-mwasm- NetWare Metrowerks Assembler
 EOF
 		exit(1);
 		}
diff --git a/crypto/perlasm/x86mwasm_nw.pl b/crypto/perlasm/x86mwasm_nw.pl
new file mode 100644
index 0000000..7a69185
--- /dev/null
+++ b/crypto/perlasm/x86mwasm_nw.pl
@@ -0,0 +1,363 @@
+#!/usr/local/bin/perl
+
+# x86 CodeWarrior assembler for NetWare 
+
+#  This file is a slightly modified version of x86nasm.pl.  The Metrowerks 
+#  compiler for NetWare doesn't prefix symbols with an underscore.  
+# 
+
+$label="L000";
+
+%lb=(	'eax',	'al',
+	'ebx',	'bl',
+	'ecx',	'cl',
+	'edx',	'dl',
+	'ax',	'al',
+	'bx',	'bl',
+	'cx',	'cl',
+	'dx',	'dl',
+	);
+
+%hb=(	'eax',	'ah',
+	'ebx',	'bh',
+	'ecx',	'ch',
+	'edx',	'dh',
+	'ax',	'ah',
+	'bx',	'bh',
+	'cx',	'ch',
+	'dx',	'dh',
+	);
+
+sub main'asm_init_output
+{ 
+	@out=(); 
+	&comment("NetWare: assembly for CodeWarrior assembler (mwasmnlm)");
+}
+sub main'asm_get_output { return(@out); }
+sub main'get_labels { return(@labels); }
+
+sub main'external_label
+{
+	push(@labels,@_);
+	foreach (@_) {
+		push(@out, ".extern\t$_\n");
+	}
+}
+
+sub main'LB
+	{
+	(defined($lb{$_[0]})) || die "$_[0] does not have a 'low byte'\n";
+	return($lb{$_[0]});
+	}
+
+sub main'HB
+	{
+	(defined($hb{$_[0]})) || die "$_[0] does not have a 'high byte'\n";
+	return($hb{$_[0]});
+	}
+
+sub main'BP
+	{
+	&get_mem("BYTE",@_);
+	}
+
+sub main'DWP
+	{
+	&get_mem("DWORD",@_);
+	}
+
+sub main'BC
+	{
+	return "@_";
+	}
+
+sub main'DWC
+	{
+	return "@_";
+	}
+
+sub main'stack_push
+	{
+	my($num)=@_;
+	$stack+=$num*4;
+	&main'sub("esp",$num*4);
+	}
+
+sub main'stack_pop
+	{
+	my($num)=@_;
+	$stack-=$num*4;
+	&main'add("esp",$num*4);
+	}
+
+sub get_mem
+	{
+	my($size,$addr,$reg1,$reg2,$idx)=@_;
+	my($t,$post);
+	my($ret)="$size PTR [";
+	$addr =~ s/^\s+//;
+	if ($addr =~ /^(.+)\+(.+)$/)
+		{
+		$reg2=&conv($1);
+		$addr="$2";
+		}
+	elsif ($addr =~ /^[_a-zA-Z]/)
+		{
+		$addr="$addr";
+		}
+
+	if ($addr =~ /^.+\-.+$/) { $addr="($addr)"; }
+
+	$reg1="$regs{$reg1}" if defined($regs{$reg1});
+	$reg2="$regs{$reg2}" if defined($regs{$reg2});
+	if (($addr ne "") && ($addr ne 0))
+		{
+		if ($addr !~ /^-/)
+			{ $ret.="${addr}+"; }
+		else	{ $post=$addr; }
+		}
+	if ($reg2 ne "")
+		{
+		$t="";
+		$t="*$idx" if ($idx != 0);
+		$reg1="+".$reg1 if ("$reg1$post" ne "");
+		$ret.="$reg2$t$reg1$post]";
+		}
+	else
+		{
+		$ret.="$reg1$post]"
+		}
+	$ret =~ s/\+\]/]/; # in case $addr was the only argument
+	return($ret);
+	}
+
+sub main'mov	{ &out2("mov",@_); }
+sub main'movb	{ &out2("mov",@_); }
+sub main'and	{ &out2("and",@_); }
+sub main'or	{ &out2("or",@_); }
+sub main'shl	{ &out2("shl",@_); }
+sub main'shr	{ &out2("shr",@_); }
+sub main'xor	{ &out2("xor",@_); }
+sub main'xorb	{ &out2("xor",@_); }
+sub main'add	{ &out2("add",@_); }
+sub main'adc	{ &out2("adc",@_); }
+sub main'sub	{ &out2("sub",@_); }
+sub main'rotl	{ &out2("rol",@_); }
+sub main'rotr	{ &out2("ror",@_); }
+sub main'exch	{ &out2("xchg",@_); }
+sub main'cmp	{ &out2("cmp",@_); }
+sub main'lea	{ &out2("lea",@_); }
+sub main'mul	{ &out1("mul",@_); }
+sub main'div	{ &out1("div",@_); }
+sub main'dec	{ &out1("dec",@_); }
+sub main'inc	{ &out1("inc",@_); }
+sub main'jmp	{ &out1("jmp",@_); }
+sub main'jmp_ptr { &out1p("jmp",@_); }
+
+sub main'je	{ &out1("je ",@_); }
+sub main'jle	{ &out1("jle ",@_); }
+sub main'jz	{ &out1("jz ",@_); }
+sub main'jge	{ &out1("jge ",@_); }
+sub main'jl	{ &out1("jl ",@_); }
+sub main'ja	{ &out1("ja ",@_); }
+sub main'jae	{ &out1("jae ",@_); }
+sub main'jb	{ &out1("jb ",@_); }
+sub main'jbe	{ &out1("jbe ",@_); }
+sub main'jc	{ &out1("jc ",@_); }
+sub main'jnc	{ &out1("jnc ",@_); }
+sub main'jnz	{ &out1("jnz ",@_); }
+sub main'jne	{ &out1("jne ",@_); }
+sub main'jno	{ &out1("jno ",@_); }
+
+sub main'push	{ &out1("push",@_); $stack+=4; }
+sub main'pop	{ &out1("pop",@_); $stack-=4; }
+sub main'bswap	{ &out1("bswap",@_); &using486(); }
+sub main'not	{ &out1("not",@_); }
+sub main'call	{ &out1("call",$_[0]); }
+sub main'ret	{ &out0("ret"); }
+sub main'nop	{ &out0("nop"); }
+
+sub out2
+	{
+	my($name,$p1,$p2)=@_;
+	my($l,$t);
+
+	push(@out,"\t$name\t");
+	$t=&conv($p1).",";
+	$l=length($t);
+	push(@out,$t);
+	$l=4-($l+9)/8;
+	push(@out,"\t" x $l);
+	push(@out,&conv($p2));
+	push(@out,"\n");
+	}
+
+sub out0
+	{
+	my($name)=@_;
+
+	push(@out,"\t$name\n");
+	}
+
+sub out1
+	{
+	my($name,$p1)=@_;
+	my($l,$t);
+	push(@out,"\t$name\t".&conv($p1)."\n");
+	}
+
+sub conv
+	{
+	my($p)=@_;
+	$p =~ s/0x([0-9A-Fa-f]+)/0$1h/;
+	return $p;
+	}
+
+sub using486
+	{
+	return if $using486;
+	$using486++;
+	grep(s/\.386/\.486/,@out);
+	}
+
+sub main'file
+	{
+	push(@out, ".section .text\n");
+	}
+
+sub main'function_begin
+	{
+	my($func,$extra)=@_;
+
+	push(@labels,$func);
+	my($tmp)=<<"EOF";
+.global	$func
+$func:
+	push	ebp
+	push	ebx
+	push	esi
+	push	edi
+EOF
+	push(@out,$tmp);
+	$stack=20;
+	}
+
+sub main'function_begin_B
+	{
+	my($func,$extra)=@_;
+	my($tmp)=<<"EOF";
+.global	$func
+$func:
+EOF
+	push(@out,$tmp);
+	$stack=4;
+	}
+
+sub main'function_end
+	{
+	my($func)=@_;
+
+	my($tmp)=<<"EOF";
+	pop	edi
+	pop	esi
+	pop	ebx
+	pop	ebp
+	ret
+EOF
+	push(@out,$tmp);
+	$stack=0;
+	%label=();
+	}
+
+sub main'function_end_B
+	{
+	$stack=0;
+	%label=();
+	}
+
+sub main'function_end_A
+	{
+	my($func)=@_;
+
+	my($tmp)=<<"EOF";
+	pop	edi
+	pop	esi
+	pop	ebx
+	pop	ebp
+	ret
+EOF
+	push(@out,$tmp);
+	}
+
+sub main'file_end
+	{
+	}
+
+sub main'wparam
+	{
+	my($num)=@_;
+
+	return(&main'DWP($stack+$num*4,"esp","",0));
+	}
+
+sub main'swtmp
+	{
+	return(&main'DWP($_[0]*4,"esp","",0));
+	}
+
+# Should use swtmp, which is above esp.  Linix can trash the stack above esp
+#sub main'wtmp
+#	{
+#	my($num)=@_;
+#
+#	return(&main'DWP(-(($num+1)*4),"esp","",0));
+#	}
+
+sub main'comment
+	{
+	foreach (@_)
+		{
+		push(@out,"\t; $_\n");
+		}
+	}
+
+sub main'label
+	{
+	if (!defined($label{$_[0]}))
+		{
+		$label{$_[0]}="${label}${_[0]}";
+		$label++;
+		}
+	return($label{$_[0]});
+	}
+
+sub main'set_label
+	{
+	if (!defined($label{$_[0]}))
+		{
+		$label{$_[0]}="${label}${_[0]}";
+		$label++;
+		}
+	push(@out,"$label{$_[0]}:\n");
+	}
+
+sub main'data_word
+	{
+	push(@out,"\t.long\t$_[0]\n");
+	}
+
+sub out1p
+	{
+	my($name,$p1)=@_;
+	my($l,$t);
+
+	push(@out,"\t$name\t ".&conv($p1)."\n");
+	}
+
+sub main'picmeup
+	{
+	local($dst,$sym)=@_;
+	&main'lea($dst,&main'DWP($sym));
+	}
+
+sub main'blindpop { &out1("pop",@_); }
diff --git a/crypto/perlasm/x86nasm_nw.pl b/crypto/perlasm/x86nasm_nw.pl
new file mode 100644
index 0000000..e64766c
--- /dev/null
+++ b/crypto/perlasm/x86nasm_nw.pl
@@ -0,0 +1,364 @@
+#!/usr/local/bin/perl
+
+# x86 nasm assembler for NetWare 
+
+#  This file is a slightly modified version of x86nasm.pl.  The Metrowerks 
+#  compiler for NetWare doesn't prefix symbols with an underscore.  
+# 
+
+$label="L000";
+
+%lb=(	'eax',	'al',
+	'ebx',	'bl',
+	'ecx',	'cl',
+	'edx',	'dl',
+	'ax',	'al',
+	'bx',	'bl',
+	'cx',	'cl',
+	'dx',	'dl',
+	);
+
+%hb=(	'eax',	'ah',
+	'ebx',	'bh',
+	'ecx',	'ch',
+	'edx',	'dh',
+	'ax',	'ah',
+	'bx',	'bh',
+	'cx',	'ch',
+	'dx',	'dh',
+	);
+
+sub main'asm_init_output
+{ 
+	@out=(); 
+	&comment("NetWare: assembly for NASM assembler (nasmw)");
+}
+sub main'asm_get_output { return(@out); }
+sub main'get_labels { return(@labels); }
+
+sub main'external_label
+{
+	push(@labels,@_);
+	foreach (@_) {
+		push(@out, "extern\t$_\n");
+	}
+}
+
+sub main'LB
+	{
+	(defined($lb{$_[0]})) || die "$_[0] does not have a 'low byte'\n";
+	return($lb{$_[0]});
+	}
+
+sub main'HB
+	{
+	(defined($hb{$_[0]})) || die "$_[0] does not have a 'high byte'\n";
+	return($hb{$_[0]});
+	}
+
+sub main'BP
+	{
+	&get_mem("BYTE",@_);
+	}
+
+sub main'DWP
+	{
+	&get_mem("DWORD",@_);
+	}
+
+sub main'BC
+	{
+	return "BYTE @_";
+	}
+
+sub main'DWC
+	{
+	return "DWORD @_";
+	}
+
+sub main'stack_push
+	{
+	my($num)=@_;
+	$stack+=$num*4;
+	&main'sub("esp",$num*4);
+	}
+
+sub main'stack_pop
+	{
+	my($num)=@_;
+	$stack-=$num*4;
+	&main'add("esp",$num*4);
+	}
+
+sub get_mem
+	{
+	my($size,$addr,$reg1,$reg2,$idx)=@_;
+	my($t,$post);
+	my($ret)="[";
+	$addr =~ s/^\s+//;
+	if ($addr =~ /^(.+)\+(.+)$/)
+		{
+		$reg2=&conv($1);
+		$addr="$2";
+		}
+	elsif ($addr =~ /^[_a-zA-Z]/)
+		{
+		$addr="$addr";
+		}
+
+	if ($addr =~ /^.+\-.+$/) { $addr="($addr)"; }
+
+	$reg1="$regs{$reg1}" if defined($regs{$reg1});
+	$reg2="$regs{$reg2}" if defined($regs{$reg2});
+	if (($addr ne "") && ($addr ne 0))
+		{
+		if ($addr !~ /^-/)
+			{ $ret.="${addr}+"; }
+		else	{ $post=$addr; }
+		}
+	if ($reg2 ne "")
+		{
+		$t="";
+		$t="*$idx" if ($idx != 0);
+		$reg1="+".$reg1 if ("$reg1$post" ne "");
+		$ret.="$reg2$t$reg1$post]";
+		}
+	else
+		{
+		$ret.="$reg1$post]"
+		}
+	$ret =~ s/\+\]/]/; # in case $addr was the only argument
+	return($ret);
+	}
+
+sub main'mov	{ &out2("mov",@_); }
+sub main'movb	{ &out2("mov",@_); }
+sub main'and	{ &out2("and",@_); }
+sub main'or	{ &out2("or",@_); }
+sub main'shl	{ &out2("shl",@_); }
+sub main'shr	{ &out2("shr",@_); }
+sub main'xor	{ &out2("xor",@_); }
+sub main'xorb	{ &out2("xor",@_); }
+sub main'add	{ &out2("add",@_); }
+sub main'adc	{ &out2("adc",@_); }
+sub main'sub	{ &out2("sub",@_); }
+sub main'rotl	{ &out2("rol",@_); }
+sub main'rotr	{ &out2("ror",@_); }
+sub main'exch	{ &out2("xchg",@_); }
+sub main'cmp	{ &out2("cmp",@_); }
+sub main'lea	{ &out2("lea",@_); }
+sub main'mul	{ &out1("mul",@_); }
+sub main'div	{ &out1("div",@_); }
+sub main'dec	{ &out1("dec",@_); }
+sub main'inc	{ &out1("inc",@_); }
+sub main'jmp	{ &out1("jmp",@_); }
+sub main'jmp_ptr { &out1p("jmp",@_); }
+
+# This is a bit of a kludge: declare all branches as NEAR.
+sub main'je	{ &out1("je NEAR",@_); }
+sub main'jle	{ &out1("jle NEAR",@_); }
+sub main'jz	{ &out1("jz NEAR",@_); }
+sub main'jge	{ &out1("jge NEAR",@_); }
+sub main'jl	{ &out1("jl NEAR",@_); }
+sub main'ja	{ &out1("ja NEAR",@_); }
+sub main'jae	{ &out1("jae NEAR",@_); }
+sub main'jb	{ &out1("jb NEAR",@_); }
+sub main'jbe	{ &out1("jbe NEAR",@_); }
+sub main'jc	{ &out1("jc NEAR",@_); }
+sub main'jnc	{ &out1("jnc NEAR",@_); }
+sub main'jnz	{ &out1("jnz NEAR",@_); }
+sub main'jne	{ &out1("jne NEAR",@_); }
+sub main'jno	{ &out1("jno NEAR",@_); }
+
+sub main'push	{ &out1("push",@_); $stack+=4; }
+sub main'pop	{ &out1("pop",@_); $stack-=4; }
+sub main'bswap	{ &out1("bswap",@_); &using486(); }
+sub main'not	{ &out1("not",@_); }
+sub main'call	{ &out1("call",$_[0]); }
+sub main'ret	{ &out0("ret"); }
+sub main'nop	{ &out0("nop"); }
+
+sub out2
+	{
+	my($name,$p1,$p2)=@_;
+	my($l,$t);
+
+	push(@out,"\t$name\t");
+	$t=&conv($p1).",";
+	$l=length($t);
+	push(@out,$t);
+	$l=4-($l+9)/8;
+	push(@out,"\t" x $l);
+	push(@out,&conv($p2));
+	push(@out,"\n");
+	}
+
+sub out0
+	{
+	my($name)=@_;
+
+	push(@out,"\t$name\n");
+	}
+
+sub out1
+	{
+	my($name,$p1)=@_;
+	my($l,$t);
+	push(@out,"\t$name\t".&conv($p1)."\n");
+	}
+
+sub conv
+	{
+	my($p)=@_;
+	$p =~ s/0x([0-9A-Fa-f]+)/0$1h/;
+	return $p;
+	}
+
+sub using486
+	{
+	return if $using486;
+	$using486++;
+	grep(s/\.386/\.486/,@out);
+	}
+
+sub main'file
+	{
+	push(@out, "segment .text\n");
+	}
+
+sub main'function_begin
+	{
+	my($func,$extra)=@_;
+
+	push(@labels,$func);
+	my($tmp)=<<"EOF";
+global	$func
+$func:
+	push	ebp
+	push	ebx
+	push	esi
+	push	edi
+EOF
+	push(@out,$tmp);
+	$stack=20;
+	}
+
+sub main'function_begin_B
+	{
+	my($func,$extra)=@_;
+	my($tmp)=<<"EOF";
+global	$func
+$func:
+EOF
+	push(@out,$tmp);
+	$stack=4;
+	}
+
+sub main'function_end
+	{
+	my($func)=@_;
+
+	my($tmp)=<<"EOF";
+	pop	edi
+	pop	esi
+	pop	ebx
+	pop	ebp
+	ret
+EOF
+	push(@out,$tmp);
+	$stack=0;
+	%label=();
+	}
+
+sub main'function_end_B
+	{
+	$stack=0;
+	%label=();
+	}
+
+sub main'function_end_A
+	{
+	my($func)=@_;
+
+	my($tmp)=<<"EOF";
+	pop	edi
+	pop	esi
+	pop	ebx
+	pop	ebp
+	ret
+EOF
+	push(@out,$tmp);
+	}
+
+sub main'file_end
+	{
+	}
+
+sub main'wparam
+	{
+	my($num)=@_;
+
+	return(&main'DWP($stack+$num*4,"esp","",0));
+	}
+
+sub main'swtmp
+	{
+	return(&main'DWP($_[0]*4,"esp","",0));
+	}
+
+# Should use swtmp, which is above esp.  Linix can trash the stack above esp
+#sub main'wtmp
+#	{
+#	my($num)=@_;
+#
+#	return(&main'DWP(-(($num+1)*4),"esp","",0));
+#	}
+
+sub main'comment
+	{
+	foreach (@_)
+		{
+		push(@out,"\t; $_\n");
+		}
+	}
+
+sub main'label
+	{
+	if (!defined($label{$_[0]}))
+		{
+		$label{$_[0]}="\$${label}${_[0]}";
+		$label++;
+		}
+	return($label{$_[0]});
+	}
+
+sub main'set_label
+	{
+	if (!defined($label{$_[0]}))
+		{
+		$label{$_[0]}="${label}${_[0]}";
+		$label++;
+		}
+	push(@out,"$label{$_[0]}:\n");
+	}
+
+sub main'data_word
+	{
+	push(@out,"\tDD\t$_[0]\n");
+	}
+
+sub out1p
+	{
+	my($name,$p1)=@_;
+	my($l,$t);
+
+	push(@out,"\t$name\t ".&conv($p1)."\n");
+	}
+
+sub main'picmeup
+	{
+	local($dst,$sym)=@_;
+	&main'lea($dst,&main'DWP($sym));
+	}
+
+sub main'blindpop { &out1("pop",@_); }
diff --git a/crypto/rand/Makefile.ssl b/crypto/rand/Makefile.ssl
index 3065234..0f7899c 100644
--- a/crypto/rand/Makefile.ssl
+++ b/crypto/rand/Makefile.ssl
@@ -24,9 +24,9 @@
 
 LIB=$(TOP)/libcrypto.a
 LIBSRC=md_rand.c randfile.c rand_lib.c rand_err.c rand_egd.c \
-	rand_win.c rand_unix.c rand_os2.c
+	rand_win.c rand_unix.c rand_os2.c rand_nw.c
 LIBOBJ=md_rand.o randfile.o rand_lib.o rand_err.o rand_egd.o \
-	rand_win.o rand_unix.o rand_os2.o
+	rand_win.o rand_unix.o rand_os2.o rand_nw.o
 
 SRC= $(LIBSRC)
 
diff --git a/crypto/rand/rand_egd.c b/crypto/rand/rand_egd.c
index 1f16822..8e1efc1 100644
--- a/crypto/rand/rand_egd.c
+++ b/crypto/rand/rand_egd.c
@@ -94,7 +94,7 @@
  *   RAND_egd() is a wrapper for RAND_egd_bytes() with numbytes=255.
  */
 
-#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_VXWORKS)
+#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE)
 int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes)
 	{
 	return(-1);
diff --git a/crypto/rand/rand_nw.c b/crypto/rand/rand_nw.c
new file mode 100644
index 0000000..0ff8847
--- /dev/null
+++ b/crypto/rand/rand_nw.c
@@ -0,0 +1,171 @@
+/* crypto/rand/rand_win.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young (eay@cryptsoft.com)"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com).  This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include "cryptlib.h"
+#include <openssl/rand.h>
+#include "rand_lcl.h"
+
+#if defined (OPENSSL_SYS_NETWARE)
+
+#if defined(NETWARE_LIBC)
+#include <nks\thread.h>
+#endif
+
+extern long RunningProcess;
+
+   /* the FAQ indicates we need to provide at least 20 bytes (160 bits) of seed
+   */
+int RAND_poll(void)
+{
+   unsigned long l;
+   unsigned long tsc;
+   int i; 
+
+      /* There are several options to gather miscellaneous data
+       * but for now we will loop checking the time stamp counter (rdtsc) and
+       * the SuperHighResolutionTimer.  Each iteration will collect 8 bytes
+       * of data but it is treated as only 1 byte of entropy.  The call to
+       * ThreadSwitchWithDelay() will introduce additional variability into
+       * the data returned by rdtsc.
+       *
+       * Applications can agument the seed material by adding additional
+       * stuff with RAND_add() and should probably do so.
+      */
+   l = GetProcessSwitchCount();
+   RAND_add(&l,sizeof(l),1);
+   
+   l=RunningProcess;
+   RAND_add(&l,sizeof(l),1);
+
+   for( i=2; i<ENTROPY_NEEDED; i++)
+   {
+      asm 
+      {
+         rdtsc
+         mov tsc, eax        
+      }
+      RAND_add(&tsc, sizeof(tsc), 1);
+
+      l = GetSuperHighResolutionTimer();
+      RAND_add(&l, sizeof(l), 0);
+
+# if defined(NETWARE_LIBC)
+         NXThreadYield();
+# else /* NETWARE_CLIB */
+      ThreadSwitchWithDelay();
+# endif
+   }
+
+   return 1;
+}
+
+#endif 
+
diff --git a/crypto/rand/rand_unix.c b/crypto/rand/rand_unix.c
index a776e52..8b4c483 100644
--- a/crypto/rand/rand_unix.c
+++ b/crypto/rand/rand_unix.c
@@ -108,6 +108,7 @@
  * Hudson (tjh@cryptsoft.com).
  *
  */
+#include <stdio.h>
 
 #define USE_SOCKETS
 #include "e_os.h"
@@ -115,7 +116,7 @@
 #include <openssl/rand.h>
 #include "rand_lcl.h"
 
-#if !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_VXWORKS))
+#if !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE)) 
 
 #include <sys/types.h>
 #include <sys/time.h>
diff --git a/crypto/rand/randtest.c b/crypto/rand/randtest.c
index 701932e..ef057c2 100644
--- a/crypto/rand/randtest.c
+++ b/crypto/rand/randtest.c
@@ -211,6 +211,9 @@
 	printf("test 4 done\n");
  err:
 	err=((err)?1:0);
+#ifdef OPENSSL_SYS_NETWARE
+    if (err) printf("ERROR: %d\n", err);
+#endif
 	EXIT(err);
 	return(err);
 	}
diff --git a/crypto/rc2/rc2speed.c b/crypto/rc2/rc2speed.c
index 47d34b4..b16e6e2 100644
--- a/crypto/rc2/rc2speed.c
+++ b/crypto/rc2/rc2speed.c
@@ -69,7 +69,10 @@
 #include OPENSSL_UNISTD_IO
 OPENSSL_DECLARE_EXIT
 
+#ifndef OPENSSL_SYS_NETWARE
 #include <signal.h>
+#endif
+
 #ifndef _IRIX
 #include <time.h>
 #endif
diff --git a/crypto/rc2/rc2test.c b/crypto/rc2/rc2test.c
index b67bafb..0e11743 100644
--- a/crypto/rc2/rc2test.c
+++ b/crypto/rc2/rc2test.c
@@ -205,6 +205,9 @@
 		printf("ok\n");
 #endif
 
+#ifdef OPENSSL_SYS_NETWARE
+    if (err) printf("ERROR: %d\n", err);
+#endif
 	EXIT(err);
 	return(err);
 	}
diff --git a/crypto/rc4/rc4speed.c b/crypto/rc4/rc4speed.c
index ced98c5..0ebd381 100644
--- a/crypto/rc4/rc4speed.c
+++ b/crypto/rc4/rc4speed.c
@@ -69,7 +69,10 @@
 #include OPENSSL_UNISTD_IO
 OPENSSL_DECLARE_EXIT
 
+#ifndef OPENSSL_SYS_NETWARE
 #include <signal.h>
+#endif
+
 #ifndef _IRIX
 #include <time.h>
 #endif
diff --git a/crypto/rc4/rc4test.c b/crypto/rc4/rc4test.c
index b9d8f20..1815402 100644
--- a/crypto/rc4/rc4test.c
+++ b/crypto/rc4/rc4test.c
@@ -197,6 +197,9 @@
 			}
 		}
 	printf("done\n");
+#ifdef OPENSSL_SYS_NETWARE
+    if (err) printf("ERROR: %d\n", err);
+#endif
 	EXIT(err);
 	return(0);
 	}
diff --git a/crypto/rc5/rc5speed.c b/crypto/rc5/rc5speed.c
index 7d490d5..8e363be 100644
--- a/crypto/rc5/rc5speed.c
+++ b/crypto/rc5/rc5speed.c
@@ -69,7 +69,10 @@
 #include OPENSSL_UNISTD_IO
 OPENSSL_DECLARE_EXIT
 
+#ifndef OPENSSL_SYS_NETWARE
 #include <signal.h>
+#endif
+
 #ifndef _IRIX
 #include <time.h>
 #endif
diff --git a/crypto/rsa/rsa_test.c b/crypto/rsa/rsa_test.c
index 924e9ad..236842a 100644
--- a/crypto/rsa/rsa_test.c
+++ b/crypto/rsa/rsa_test.c
@@ -312,6 +312,9 @@
 
     CRYPTO_mem_leaks_fp(stderr);
 
+#ifdef OPENSSL_SYS_NETWARE
+    if (err) printf("ERROR: %d\n", err);
+#endif
     return err;
     }
 #endif
diff --git a/crypto/sha/sha1test.c b/crypto/sha/sha1test.c
index 4f2e4ad..cddd598 100644
--- a/crypto/sha/sha1test.c
+++ b/crypto/sha/sha1test.c
@@ -157,6 +157,10 @@
 		}
 	else
 		printf("test 3 ok\n");
+
+#ifdef OPENSSL_SYS_NETWARE
+    if (err) printf("ERROR: %d\n", err);
+#endif
 	EXIT(err);
 	EVP_MD_CTX_cleanup(&c);
 	return(0);
diff --git a/crypto/sha/shatest.c b/crypto/sha/shatest.c
index 5d2b1d3..0e026c1 100644
--- a/crypto/sha/shatest.c
+++ b/crypto/sha/shatest.c
@@ -157,7 +157,10 @@
 		}
 	else
 		printf("test 3 ok\n");
-	EVP_MD_CTX_cleanup(&c);
+
+#ifdef OPENSSL_SYS_NETWARE
+    if (err) printf("ERROR: %d\n", err);
+#endif
 	EXIT(err);
 	return(0);
 	}
diff --git a/crypto/threads/mttest.c b/crypto/threads/mttest.c
index 54d5985..d0e0882 100644
--- a/crypto/threads/mttest.c
+++ b/crypto/threads/mttest.c
@@ -77,6 +77,12 @@
 #ifdef PTHREADS
 #include <pthread.h>
 #endif
+#ifdef OPENSSL_SYS_NETWARE
+#if !defined __int64
+#  define __int64 long long
+#endif   
+#include <nwmpk.h>
+#endif
 #include <openssl/lhash.h>
 #include <openssl/crypto.h>
 #include <openssl/buffer.h>
@@ -86,8 +92,18 @@
 #include <openssl/err.h>
 #include <openssl/rand.h>
 
+#ifdef OPENSSL_NO_FP_API
+#define APPS_WIN16
+#include "../buffer/bss_file.c"
+#endif
+
+#ifdef OPENSSL_SYS_NETWARE
+#define TEST_SERVER_CERT "/openssl/apps/server.pem"
+#define TEST_CLIENT_CERT "/openssl/apps/client.pem"
+#else
 #define TEST_SERVER_CERT "../../apps/server.pem"
 #define TEST_CLIENT_CERT "../../apps/client.pem"
+#endif
 
 #define MAX_THREAD_NUMBER	100
 
@@ -100,10 +116,18 @@
 void solaris_locking_callback(int mode,int type,char *file,int line);
 void win32_locking_callback(int mode,int type,char *file,int line);
 void pthreads_locking_callback(int mode,int type,char *file,int line);
+void netware_locking_callback(int mode,int type,char *file,int line);
 
 unsigned long irix_thread_id(void );
 unsigned long solaris_thread_id(void );
 unsigned long pthreads_thread_id(void );
+unsigned long netware_thread_id(void );
+
+#if defined(OPENSSL_SYS_NETWARE)
+static MPKMutex *lock_cs;
+static MPKSema ThreadSem;
+static long *lock_count;
+#endif
 
 BIO *bio_err=NULL;
 BIO *bio_stdout=NULL;
@@ -383,6 +407,9 @@
 		SSL_free((SSL *)ctx[2]);
 		SSL_free((SSL *)ctx[3]);
 		}
+#   ifdef OPENSSL_SYS_NETWARE
+        MPKSemaphoreSignal(ThreadSem);
+#   endif
 	return(0);
 	}
 
@@ -626,6 +653,9 @@
 			}
 
 		if ((done & S_DONE) && (done & C_DONE)) break;
+#   if defined(OPENSSL_SYS_NETWARE)
+        ThreadSwitchWithDelay();
+#   endif
 		}
 
 	SSL_set_shutdown(c_ssl,SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN);
@@ -1093,3 +1123,88 @@
 
 
 
+#ifdef OPENSSL_SYS_NETWARE
+
+void thread_setup(void)
+{
+   int i;
+
+   lock_cs=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(MPKMutex));
+   lock_count=OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));
+   for (i=0; i<CRYPTO_num_locks(); i++)
+   {
+      lock_count[i]=0;
+      lock_cs[i]=MPKMutexAlloc("OpenSSL mutex");
+   }
+
+   ThreadSem = MPKSemaphoreAlloc("OpenSSL mttest semaphore", 0 );
+
+   CRYPTO_set_id_callback((unsigned long (*)())netware_thread_id);
+   CRYPTO_set_locking_callback((void (*)())netware_locking_callback);
+}
+
+void thread_cleanup(void)
+{
+   int i;
+
+   CRYPTO_set_locking_callback(NULL);
+
+   fprintf(stdout,"thread_cleanup\n");
+
+   for (i=0; i<CRYPTO_num_locks(); i++)
+   {
+      MPKMutexFree(lock_cs[i]);
+      fprintf(stdout,"%8ld:%s\n",lock_count[i],CRYPTO_get_lock_name(i));
+   }
+   OPENSSL_free(lock_cs);
+   OPENSSL_free(lock_count);
+
+   MPKSemaphoreFree(ThreadSem);
+
+   fprintf(stdout,"done cleanup\n");
+}
+
+void netware_locking_callback(int mode, int type, char *file, int line)
+{
+   if (mode & CRYPTO_LOCK)
+   {
+      MPKMutexLock(lock_cs[type]);
+      lock_count[type]++;
+   }
+   else
+      MPKMutexUnlock(lock_cs[type]);
+}
+
+void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx)
+{
+   SSL_CTX *ssl_ctx[2];
+   int i;
+   ssl_ctx[0]=s_ctx;
+   ssl_ctx[1]=c_ctx;
+
+   for (i=0; i<thread_number; i++)
+   {
+      BeginThread( (void(*)(void*))ndoit, NULL, THREAD_STACK_SIZE, 
+                   (void*)ssl_ctx);
+      ThreadSwitchWithDelay();
+   }
+
+   printf("reaping\n");
+
+      /* loop until all threads have signaled the semaphore */
+   for (i=0; i<thread_number; i++)
+   {
+      MPKSemaphoreWait(ThreadSem);
+   }
+   printf("netware threads done (%d,%d)\n",
+         s_ctx->references,c_ctx->references);
+}
+
+unsigned long netware_thread_id(void)
+{
+   unsigned long ret;
+
+   ret=(unsigned long)GetThreadID();
+   return(ret);
+}
+#endif /* NETWARE */
diff --git a/crypto/threads/netware.bat b/crypto/threads/netware.bat
new file mode 100644
index 0000000..0b3eca3
--- /dev/null
+++ b/crypto/threads/netware.bat
@@ -0,0 +1,79 @@
+@echo off
+rem batch file to build multi-thread test ( mttest.nlm )
+
+rem command line arguments:
+rem      debug => build using debug settings
+
+rem
+rem After building, copy mttest.nlm to the server and run it, you'll probably
+rem want to redirect stdout and stderr.  An example command line would be
+rem "mttest.nlm -thread 20 -loops 10 -CAfile \openssl\apps\server.pem >mttest.out 2>mttest.err"
+rem 
+
+del mttest.nlm
+
+set BLD_DEBUG=
+set CFLAGS=
+set LFLAGS=
+set LIBS=
+
+if "%1" == "DEBUG" set BLD_DEBUG=YES
+if "%1" == "debug" set BLD_DEBUG=YES
+
+if "%MWCIncludes%" == "" goto inc_error
+if "%PRELUDE%" == "" goto prelude_error
+if "%IMPORTS%" == "" goto imports_error
+
+set CFLAGS=-c -I..\..\outinc_nw -nosyspath -DOPENSSL_SYS_NETWARE -opt off -g -sym internal -maxerrors 20
+
+if "%BLD_DEBUG%" == "YES" set LIBS=..\..\out_nw.dbg\ssl.lib ..\..\out_nw.dbg\crypto.lib
+if "%BLD_DEBUG%" == ""  set LIBS=..\..\out_nw\ssl.lib ..\..\out_nw\crypto.lib
+
+set LFLAGS=-msgstyle gcc -zerobss -stacksize 32768 -nostdlib -sym internal 
+  
+rem generate command file for metrowerks
+echo.
+echo Generating Metrowerks command file: mttest.def
+echo # dynamically generated command file for metrowerks build > mttest.def
+echo IMPORT @%IMPORTS%\clib.imp              >> mttest.def 
+echo IMPORT @%IMPORTS%\threads.imp           >> mttest.def 
+echo IMPORT @%IMPORTS%\ws2nlm.imp            >> mttest.def 
+echo IMPORT GetProcessSwitchCount            >> mttest.def
+echo MODULE clib                             >> mttest.def 
+
+rem compile
+echo.
+echo Compiling mttest.c
+mwccnlm.exe mttest.c %CFLAGS% 
+if errorlevel 1 goto end
+
+rem link               
+echo.
+echo Linking mttest.nlm
+mwldnlm.exe %LFLAGS% -screenname mttest -commandfile mttest.def mttest.o "%PRELUDE%" %LIBS% -o mttest.nlm
+if errorlevel 1 goto end
+
+goto end
+
+:inc_error
+echo.
+echo Environment variable MWCIncludes is not set - see install.nw
+goto end
+
+:prelude_error
+echo.
+echo Environment variable PRELUDE is not set - see install.nw
+goto end
+
+:imports_error
+echo.
+echo Environment variable IMPORTS is not set - see install.nw
+goto end
+    
+    
+:end
+set BLD_DEBUG=
+set CFLAGS=
+set LFLAGS=
+set LIBS=
+
diff --git a/crypto/tmdiff.c b/crypto/tmdiff.c
index cbec38e..1c6e052 100644
--- a/crypto/tmdiff.c
+++ b/crypto/tmdiff.c
@@ -72,7 +72,11 @@
 # define TIMES
 #endif
 
-#ifndef _IRIX
+#ifdef OPENSSL_SYS_NETWARE
+#undef TIMES
+#endif
+
+#if !defined(_IRIX) || defined (OPENSSL_SYS_NETWARE)
 #  include <time.h>
 #endif
 #ifdef TIMES
@@ -94,7 +98,7 @@
 #include <sys/param.h>
 #endif
 
-#if !defined(TIMES) && !defined(OPENSSL_SYS_VXWORKS)
+#if !defined(TIMES) && !defined(OPENSSL_SYS_VXWORKS) && !defined(OPENSSL_SYS_NETWARE)
 #include <sys/timeb.h>
 #endif
 
@@ -129,6 +133,8 @@
 #  ifdef OPENSSL_SYS_WIN32
 	HANDLE thread_id;
 	FILETIME ms_win32;
+#  elif defined (OPENSSL_SYS_NETWARE)
+   clock_t ms_clock;
 #  else
 #    ifdef OPENSSL_SYS_VXWORKS
           unsigned long ticks;
@@ -170,6 +176,8 @@
 #else
 #  ifdef OPENSSL_SYS_WIN32
 	GetThreadTimes(tm->thread_id,&tmpa,&tmpb,&tmpc,&(tm->ms_win32));
+#  elif defined (OPENSSL_SYS_NETWARE)
+   tm->ms_clock = clock();
 #  else
 #    ifdef OPENSSL_SYS_VXWORKS
         tm->ticks = tickGet();
@@ -203,6 +211,8 @@
 	lb+=b->ms_win32.dwLowDateTime;
 	ret=((double)(lb-la))/1e7;
 	}
+# elif defined (OPENSSL_SYS_NETWARE)
+    ret= (double)(b->ms_clock - a->ms_clock);
 # else
 #  ifdef OPENSSL_SYS_VXWORKS
         ret = (double)(b->ticks - a->ticks) / (double)sysClkRateGet();
@@ -228,6 +238,8 @@
 # ifdef OPENSSL_SYS_WIN32
 	d =(b->ms_win32.dwHighDateTime&0x000fffff)*10+b->ms_win32.dwLowDateTime/1e7;
 	d-=(a->ms_win32.dwHighDateTime&0x000fffff)*10+a->ms_win32.dwLowDateTime/1e7;
+# elif defined (OPENSSL_SYS_NETWARE)
+    d= (double)(b->ms_clock - a->ms_clock);
 # else
 #  ifdef OPENSSL_SYS_VXWORKS
         d = (b->ticks - a->ticks);
diff --git a/crypto/ui/ui_openssl.c b/crypto/ui/ui_openssl.c
index ce1cb1d..fad1702 100644
--- a/crypto/ui/ui_openssl.c
+++ b/crypto/ui/ui_openssl.c
@@ -202,6 +202,12 @@
 #undef SGTTY
 #endif
 
+#if defined(OPENSSL_SYS_NETWARE)
+#undef TERMIOS
+#undef TERMIO
+#undef SGTTY
+#endif
+
 #ifdef TERMIOS
 # include <termios.h>
 # define TTY_STRUCT		struct termios
@@ -250,7 +256,7 @@
 	typedef int sig_atomic_t;
 #endif
 
-#if defined(OPENSSL_SYS_MACINTOSH_CLASSIC) || defined(MAC_OS_GUSI_SOURCE)
+#if defined(OPENSSL_SYS_MACINTOSH_CLASSIC) || defined(MAC_OS_GUSI_SOURCE) || defined(OPENSSL_SYS_NETWARE)
 /*
  * This one needs work. As a matter of fact the code is unoperational
  * and this is only a trick to get it compiled.
@@ -463,7 +469,7 @@
 	CRYPTO_w_lock(CRYPTO_LOCK_UI);
 	is_a_tty = 1;
 
-#if defined(OPENSSL_SYS_MACINTOSH_CLASSIC) || defined(OPENSSL_SYS_VXWORKS)
+#if defined(OPENSSL_SYS_MACINTOSH_CLASSIC) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE)
 	tty_in=stdin;
 	tty_out=stderr;
 #else
diff --git a/crypto/uid.c b/crypto/uid.c
index 73205a4..b1fd52b 100644
--- a/crypto/uid.c
+++ b/crypto/uid.c
@@ -65,7 +65,7 @@
 	return issetugid();
 	}
 
-#elif defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VXWORKS)
+#elif defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE)
 
 int OPENSSL_issetugid(void)
 	{