This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
NetWare port from Guruprasad S <SGURUPRASAD@novell.com>.
authorJarkko Hietaniemi <jhi@iki.fi>
Sat, 16 Jun 2001 19:46:38 +0000 (19:46 +0000)
committerJarkko Hietaniemi <jhi@iki.fi>
Sat, 16 Jun 2001 19:46:38 +0000 (19:46 +0000)
p4raw-id: //depot/perl@10643

132 files changed:
MANIFEST
NetWare/CLIBsdio.h [new file with mode: 0644]
NetWare/CLIBstr.h [new file with mode: 0644]
NetWare/CLIBstuf.c [new file with mode: 0644]
NetWare/CLIBstuf.h [new file with mode: 0644]
NetWare/Main.c [new file with mode: 0644]
NetWare/Makefile [new file with mode: 0644]
NetWare/NWTInfo.c [new file with mode: 0644]
NetWare/NWUtil.c [new file with mode: 0644]
NetWare/Nwmain.c [new file with mode: 0644]
NetWare/Nwpipe.c [new file with mode: 0644]
NetWare/bat/BldNWExt.bat [new file with mode: 0644]
NetWare/bat/Buildtype.bat [new file with mode: 0644]
NetWare/bat/MPKBuild.bat [new file with mode: 0644]
NetWare/bat/SetNWBld.bat [new file with mode: 0644]
NetWare/bat/Setmpksdk.bat [new file with mode: 0644]
NetWare/bat/Setnlmsdk.bat [new file with mode: 0644]
NetWare/bat/Setwatcom.bat [new file with mode: 0644]
NetWare/bat/ToggleD2.bat [new file with mode: 0644]
NetWare/bat/ToggleXDC.bat [new file with mode: 0644]
NetWare/config.wc [new file with mode: 0644]
NetWare/config_H.wc [new file with mode: 0644]
NetWare/config_h.PL [new file with mode: 0644]
NetWare/config_sh.PL [new file with mode: 0644]
NetWare/deb.h [new file with mode: 0644]
NetWare/dl_netware.xs [new file with mode: 0644]
NetWare/intdef.h [new file with mode: 0644]
NetWare/interface.c [new file with mode: 0644]
NetWare/interface.h [new file with mode: 0644]
NetWare/iperlhost.h [new file with mode: 0644]
NetWare/netware.h [new file with mode: 0644]
NetWare/nw5.c [new file with mode: 0644]
NetWare/nw5iop.h [new file with mode: 0644]
NetWare/nw5sck.c [new file with mode: 0644]
NetWare/nw5sck.h [new file with mode: 0644]
NetWare/nw5thread.c [new file with mode: 0644]
NetWare/nw5thread.h [new file with mode: 0644]
NetWare/nwperlsys.c [new file with mode: 0644]
NetWare/nwperlsys.h [new file with mode: 0644]
NetWare/nwpipe.h [new file with mode: 0644]
NetWare/nwplglob.c [new file with mode: 0644]
NetWare/nwplglob.h [new file with mode: 0644]
NetWare/nwtinfo.h [new file with mode: 0644]
NetWare/nwutil.h [new file with mode: 0644]
NetWare/t/NWModify.pl [new file with mode: 0644]
NetWare/t/NWScripts.pl [new file with mode: 0644]
NetWare/t/Readme.txt [new file with mode: 0644]
NetWare/testnlm/echo/echo.c [new file with mode: 0644]
NetWare/testnlm/type/type.c [new file with mode: 0644]
NetWare/win32ish.h [new file with mode: 0644]
README.netware [new file with mode: 0644]
XSUB.h
dosish.h
ext/Errno/Errno_pm.PL
ext/IO/IO.xs
ext/POSIX/POSIX.xs
ext/Socket/Socket.xs
installperl
iperlsys.h
lib/AutoLoader.pm
lib/AutoSplit.pm
lib/ExtUtils/MM_NW5.pm [new file with mode: 0644]
lib/ExtUtils/MakeMaker.pm
lib/File/Copy.pm
lib/File/Find.pm
lib/perl5db.pl
makedef.pl
perl.c
perl.h
perlio.c
perlio.h
pp_sys.c
t/comp/multiline.t
t/comp/script.t
t/io/argv.t
t/io/dup.t
t/io/fs.t
t/io/inplace.t
t/io/iprefix.t
t/io/tell.t
t/lib/anydbm.t
t/lib/b-stash.t
t/lib/cwd.t
t/lib/db-btree.t
t/lib/db-hash.t
t/lib/db-recno.t
t/lib/filehand.t
t/lib/filter-util.t
t/lib/ftmp-security.t
t/lib/gdbm.t
t/lib/glob-basic.t
t/lib/glob-case.t
t/lib/io_dup.t
t/lib/io_poll.t
t/lib/io_sel.t
t/lib/io_taint.t
t/lib/ndbm.t
t/lib/net-hostent.t
t/lib/odbm.t
t/lib/open2.t
t/lib/open3.t
t/lib/posix.t
t/lib/sdbm.t
t/lib/sigaction.t
t/lib/syslfs.t
t/op/anonsub.t
t/op/closure.t
t/op/die_exit.t
t/op/exec.t
t/op/fork.t
t/op/goto.t
t/op/groups.t
t/op/lfs.t
t/op/magic.t
t/op/misc.t
t/op/rand.t
t/op/runlevel.t
t/op/split.t
t/op/stat.t
t/op/sysio.t
t/op/taint.t
t/op/write.t
t/pragma/locale.t
t/pragma/strict.t
t/pragma/subs.t
t/pragma/warn/mg
t/pragma/warnings.t
thread.h
toke.c
util.c
util.h
x2p/a2py.c

index 7d8de3a..55591d5 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -17,6 +17,55 @@ INTERN.h             Included before domestic .h files
 MANIFEST               This list of files
 Makefile.SH            A script that generates Makefile
 Makefile.micro         microperl Makefile
+NetWare/CLIBsdio.h     Netware port
+NetWare/CLIBstr.h      Netware port
+NetWare/CLIBstuf.c     Netware port
+NetWare/CLIBstuf.h     Netware port
+NetWare/Main.c Netware port
+NetWare/Makefile       Netware port
+NetWare/NWTInfo.c      Netware port
+NetWare/NWUtil.c       Netware port
+NetWare/Nwmain.c       Netware port
+NetWare/Nwpipe.c       Netware port
+NetWare/bat/BldNWExt.bat       Netware port
+NetWare/bat/Buildtype.bat      Netware port
+NetWare/bat/MPKBuild.bat       Netware port
+NetWare/bat/SetNWBld.bat       Netware port
+NetWare/bat/Setmpksdk.bat      Netware port
+NetWare/bat/Setnlmsdk.bat      Netware port
+NetWare/bat/Setwatcom.bat      Netware port
+NetWare/bat/ToggleD2.bat       Netware port
+NetWare/bat/ToggleXDC.bat      Netware port
+NetWare/config.wc      Netware port
+NetWare/config_H.wc    Netware port
+NetWare/config_h.PL    Netware port
+NetWare/config_sh.PL   Netware port
+NetWare/deb.h  Netware port
+NetWare/dl_netware.xs  Netware port
+NetWare/intdef.h       Netware port
+NetWare/interface.c    Netware port
+NetWare/interface.h    Netware port
+NetWare/iperlhost.h    Netware port
+NetWare/netware.h      Netware port
+NetWare/nw5.c  Netware port
+NetWare/nw5iop.h       Netware port
+NetWare/nw5sck.c       Netware port
+NetWare/nw5sck.h       Netware port
+NetWare/nw5thread.c    Netware port
+NetWare/nw5thread.h    Netware port
+NetWare/nwperlsys.c    Netware port
+NetWare/nwperlsys.h    Netware port
+NetWare/nwpipe.h       Netware port
+NetWare/nwplglob.c     Netware port
+NetWare/nwplglob.h     Netware port
+NetWare/nwtinfo.h      Netware port
+NetWare/nwutil.h       Netware port
+NetWare/t/NWModify.pl  Netware port
+NetWare/t/NWScripts.pl Netware port
+NetWare/t/Readme.txt   Netware port
+NetWare/testnlm/echo/echo.c    Netware port
+NetWare/testnlm/type/type.c    Netware port
+NetWare/win32ish.h     Netware port
 Policy_sh.SH           Hold site-wide preferences between Configure runs.
 Porting/Contract       Social contract for contributed modules in Perl core
 Porting/Glossary       Glossary of config.sh variables
@@ -52,6 +101,7 @@ README.macos         Notes about Mac OS (Classic)
 README.micro           Notes about microperl
 README.mint            Notes about Atari MiNT port
 README.mpeix           Notes about MPE/iX port
+README.netware Netware port
 README.os2             Notes about OS/2 port
 README.os390           Notes about OS/390 (nee MVS) port
 README.plan9           Notes about Plan9 port
@@ -744,6 +794,7 @@ lib/ExtUtils/Installed.pm   Information on installed extensions
 lib/ExtUtils/Liblist.pm        Locates libraries
 lib/ExtUtils/MANIFEST.SKIP     The default MANIFEST.SKIP
 lib/ExtUtils/MM_Cygwin.pm      MakeMaker methods for Cygwin
+lib/ExtUtils/MM_NW5.pm Netware port
 lib/ExtUtils/MM_OS2.pm         MakeMaker methods for OS/2
 lib/ExtUtils/MM_Unix.pm                MakeMaker base class for Unix
 lib/ExtUtils/MM_VMS.pm         MakeMaker methods for VMS
diff --git a/NetWare/CLIBsdio.h b/NetWare/CLIBsdio.h
new file mode 100644 (file)
index 0000000..76aba02
--- /dev/null
@@ -0,0 +1,180 @@
+
+/*
+ * Copyright Â© 2001 Novell, Inc. All Rights Reserved.
+ *
+ * You may distribute under the terms of either the GNU General Public
+ * License or the Artistic License, as specified in the README file.
+ *
+ */
+
+/*
+ * FILENAME            :       CLIBsdio.h
+ * DESCRIPTION :       Forces the use of clib stdio.h calls over static watcom calls
+ *                  for C/C++ applications that statically link watcom libraries.
+ *
+ *                  This file must be included each time that stdio.h is included.
+ *                  In the case of the Perl project, just include stdio.h and
+ *                  the make should take care of the rest.
+ * Author              :       HYAK
+ * Date                        :       January 2001.
+ *
+ */
+
+
+
+#ifndef _CLIBSDIO_H_
+#define _CLIBSDIO_H_
+
+
+#ifdef DEFINE_GPF
+#define _GPFINIT =0
+#define _GPFEXT
+#else
+#define _GPFINIT
+#define _GPFEXT extern
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+_GPFEXT void* gpf___get_stdin _GPFINIT;
+_GPFEXT void* gpf___get_stdout _GPFINIT;
+_GPFEXT void* gpf___get_stderr _GPFINIT;
+
+_GPFEXT void* gpf_clearerr _GPFINIT;
+_GPFEXT void* gpf_fclose _GPFINIT;
+_GPFEXT void* gpf_feof _GPFINIT;
+_GPFEXT void* gpf_ferror _GPFINIT;
+_GPFEXT void* gpf_fflush _GPFINIT;
+_GPFEXT void* gpf_fgetc _GPFINIT;
+_GPFEXT void* gpf_fgetpos _GPFINIT;
+_GPFEXT void* gpf_fgets _GPFINIT;
+_GPFEXT void* gpf_fopen _GPFINIT;
+_GPFEXT void* gpf_fprintf _GPFINIT;
+_GPFEXT void* gpf_fputc _GPFINIT;
+_GPFEXT void* gpf_fputs _GPFINIT;
+_GPFEXT void* gpf_fread _GPFINIT;
+_GPFEXT void* gpf_freopen _GPFINIT;
+_GPFEXT void* gpf_fscanf _GPFINIT;
+_GPFEXT void* gpf_fseek _GPFINIT;
+_GPFEXT void* gpf_fsetpos _GPFINIT;
+_GPFEXT void* gpf_ftell _GPFINIT;
+_GPFEXT void* gpf_fwrite _GPFINIT;
+_GPFEXT void* gpf_getc _GPFINIT;
+_GPFEXT void* gpf_getchar _GPFINIT;
+_GPFEXT void* gpf_gets _GPFINIT;
+_GPFEXT void* gpf_perror _GPFINIT;
+_GPFEXT void* gpf_printf _GPFINIT;
+_GPFEXT void* gpf_putc _GPFINIT;
+_GPFEXT void* gpf_putchar _GPFINIT;
+_GPFEXT void* gpf_puts _GPFINIT;
+_GPFEXT void* gpf_rename _GPFINIT;
+_GPFEXT void* gpf_rewind _GPFINIT;
+_GPFEXT void* gpf_scanf _GPFINIT;
+_GPFEXT void* gpf_setbuf _GPFINIT;
+_GPFEXT void* gpf_setvbuf _GPFINIT;
+_GPFEXT void* gpf_sprintf _GPFINIT;
+_GPFEXT void* gpf_sscanf _GPFINIT;
+_GPFEXT void* gpf_tmpfile _GPFINIT;
+_GPFEXT void* gpf_tmpnam _GPFINIT;
+_GPFEXT void* gpf_ungetc _GPFINIT;
+_GPFEXT void* gpf_vfprintf _GPFINIT;
+_GPFEXT void* gpf_vfscanf _GPFINIT;
+_GPFEXT void* gpf_vprintf _GPFINIT;
+_GPFEXT void* gpf_vscanf _GPFINIT;
+_GPFEXT void* gpf_vsprintf _GPFINIT;
+_GPFEXT void* gpf_vsscanf _GPFINIT;
+
+_GPFEXT void* gpf_fdopen _GPFINIT;
+_GPFEXT void* gpf_fileno _GPFINIT;
+
+_GPFEXT void* gpf_cgets _GPFINIT;
+_GPFEXT void* gpf_cprintf _GPFINIT;
+_GPFEXT void* gpf_cputs _GPFINIT;
+_GPFEXT void* gpf_cscanf _GPFINIT;
+_GPFEXT void* gpf_fcloseall _GPFINIT;
+_GPFEXT void* gpf_fgetchar _GPFINIT;
+_GPFEXT void* gpf_flushall _GPFINIT;
+_GPFEXT void* gpf_fputchar _GPFINIT;
+_GPFEXT void* gpf_getch _GPFINIT;
+_GPFEXT void* gpf_getche _GPFINIT;
+_GPFEXT void* gpf_putch _GPFINIT;
+_GPFEXT void* gpf_ungetch _GPFINIT;
+_GPFEXT void* gpf_vcprintf _GPFINIT;
+_GPFEXT void* gpf_vcscanf _GPFINIT;
+
+#ifdef __cplusplus
+}
+#endif
+
+#pragma aux __get_stdin = "call gpf___get_stdin";
+#pragma aux __get_stdout = "call gpf___get_stdout";
+#pragma aux __get_stderr = "call gpf___get_stderr";
+
+#pragma aux clearerr = "call gpf_clearerr";
+#pragma aux fclose = "call gpf_fclose";
+#pragma aux feof = "call gpf_feof";
+#pragma aux ferror = "call gpf_ferror";
+#pragma aux fflush = "call gpf_fflush";
+#pragma aux fgetc = "call gpf_fgetc";
+#pragma aux fgetpos = "call gpf_fgetpos";
+#pragma aux fgets = "call gpf_fgets";
+#pragma aux fopen = "call gpf_fopen";
+#pragma aux fprintf = "call gpf_fprintf";
+#pragma aux fputc = "call gpf_fputc";
+#pragma aux fputs = "call gpf_fputs";
+#pragma aux fread = "call gpf_fread";
+#pragma aux freopen = "call gpf_freopen";
+#pragma aux fscanf = "call gpf_fscanf";
+#pragma aux fseek = "call gpf_fseek";
+#pragma aux fsetpos = "call gpf_fsetpos";
+#pragma aux ftell = "call gpf_ftell";
+#pragma aux fwrite = "call gpf_fwrite";
+#pragma aux getc = "call gpf_getc";
+#pragma aux getchar = "call gpf_getchar";
+#pragma aux gets = "call gpf_gets";
+#pragma aux perror = "call gpf_perror";
+#pragma aux printf = "call gpf_printf";
+#pragma aux putc = "call gpf_putc";
+#pragma aux putchar = "call gpf_putchar";
+#pragma aux puts = "call gpf_puts";
+#pragma aux rename = "call gpf_rename";
+#pragma aux rewind = "call gpf_rewind";
+#pragma aux scanf = "call gpf_scanf";
+#pragma aux setbuf = "call gpf_setbuf";
+#pragma aux setvbuf = "call gpf_setvbuf";
+#pragma aux sprintf = "call gpf_sprintf";
+#pragma aux sscanf = "call gpf_sscanf";
+#pragma aux tmpfile = "call gpf_tmpfile";
+#pragma aux tmpnam = "call gpf_tmpnam";
+#pragma aux ungetc = "call gpf_ungetc";
+#pragma aux vfprintf = "call gpf_vfprintf";
+#pragma aux vfscanf = "call gpf_vfscanf";
+#pragma aux vprintf = "call gpf_vprintf";
+#pragma aux vscanf = "call gpf_vscanf";
+#pragma aux vsprintf = "call gpf_vsprintf";
+#pragma aux vsscanf = "call gpf_vsscanf";
+
+#pragma aux fdopen = "call gpf_fdopen";
+#pragma aux fileno = "call gpf_fileno";
+
+#pragma aux cgets = "call gpf_cgets";
+#pragma aux cprintf = "call gpf_cprintf";
+#pragma aux cputs = "call gpf_cputs";
+#pragma aux cscanf = "call gpf_cscanf";
+#pragma aux fcloseall = "call gpf_fcloseall";
+#pragma aux fgetchar = "call gpf_fgetchar";
+#pragma aux flushall = "call gpf_flushall";
+#pragma aux fputchar = "call gpf_fputchar";
+#pragma aux getch = "call gpf_getch";
+#pragma aux getche = "call gpf_getche";
+#pragma aux putch = "call gpf_putch";
+#pragma aux ungetch = "call gpf_ungetch";
+#pragma aux vcprintf = "call gpf_vcprintf";
+#pragma aux vcscanf = "call gpf_vcscanf";
+
+
+#endif // _CLIBSDIO_H_
+
diff --git a/NetWare/CLIBstr.h b/NetWare/CLIBstr.h
new file mode 100644 (file)
index 0000000..e025c04
--- /dev/null
@@ -0,0 +1,120 @@
+
+/*
+ * Copyright Â© 2001 Novell, Inc. All Rights Reserved.
+ *
+ * You may distribute under the terms of either the GNU General Public
+ * License or the Artistic License, as specified in the README file.
+ *
+ */
+
+/*
+ * FILENAME            :       CLIBstr.h
+ * DESCRIPTION :       Forces the use of clib string.h calls over static watcom calls
+ *                  for C/C++ applications that statically link watcom libraries.
+ *
+ *                  This file must be included each time that string.h is included.
+ *                  In the case of the Perl project, just include string.h and
+ *                  the make should take care of the rest.
+ * Author              :       HYAK
+ * Date                        :       January 2001.
+ *
+ */
+
+
+
+#ifndef _CLIBSTR_H_
+#define _CLIBSTR_H_
+
+
+#ifdef DEFINE_GPF
+#define _GPFINIT =0
+#define _GPFEXT
+#else
+#define _GPFINIT
+#define _GPFEXT extern
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+_GPFEXT void* gpf_memchr _GPFINIT;
+_GPFEXT void* gpf_memcmp _GPFINIT;
+_GPFEXT void* gpf_memcpy _GPFINIT;
+_GPFEXT void* gpf_memmove _GPFINIT;
+_GPFEXT void* gpf_memset _GPFINIT;
+_GPFEXT void* gpf_strchr _GPFINIT;
+_GPFEXT void* gpf_strcmp _GPFINIT;
+_GPFEXT void* gpf_strcoll _GPFINIT;
+_GPFEXT void* gpf_strcspn _GPFINIT;
+_GPFEXT void* gpf_strerror _GPFINIT;
+_GPFEXT void* gpf_strtok_r _GPFINIT;
+_GPFEXT void* gpf_strpbrk _GPFINIT;
+_GPFEXT void* gpf_strrchr _GPFINIT;
+_GPFEXT void* gpf_strspn _GPFINIT;
+_GPFEXT void* gpf_strstr _GPFINIT;
+_GPFEXT void* gpf_strtok _GPFINIT;
+_GPFEXT void* gpf_strxfrm _GPFINIT;
+_GPFEXT void* gpf_memicmp _GPFINIT;
+_GPFEXT void* gpf_strcmpi _GPFINIT;
+_GPFEXT void* gpf_stricmp _GPFINIT;
+_GPFEXT void* gpf_strrev _GPFINIT;
+_GPFEXT void* gpf_strupr _GPFINIT;
+
+_GPFEXT void* gpf_strcpy _GPFINIT;
+_GPFEXT void* gpf_strcat _GPFINIT;
+_GPFEXT void* gpf_strlen _GPFINIT;
+_GPFEXT void* gpf_strncpy _GPFINIT;
+_GPFEXT void* gpf_strncat _GPFINIT;
+_GPFEXT void* gpf_strncmp _GPFINIT;
+_GPFEXT void* gpf_strnicmp _GPFINIT;
+_GPFEXT void* gpf_strdup _GPFINIT;
+_GPFEXT void* gpf_strlist _GPFINIT;
+_GPFEXT void* gpf_strlwr _GPFINIT;
+_GPFEXT void* gpf_strnset _GPFINIT;
+_GPFEXT void* gpf_strset _GPFINIT;
+
+#ifdef __cplusplus
+}
+#endif
+
+#pragma aux memchr = "call gpf_memchr";
+#pragma aux memcmp = "call gpf_memcmp";
+#pragma aux memcpy = "call gpf_memcpy";
+#pragma aux memmove = "call gpf_memmove";
+#pragma aux memset = "call gpf_memset";
+#pragma aux strchr = "call gpf_strchr";
+#pragma aux strcmp = "call gpf_strcmp";
+#pragma aux strcoll = "call gpf_strcoll";
+#pragma aux strcspn = "call gpf_strcspn";
+#pragma aux strerror = "call gpf_strerror";
+#pragma aux strtok_r = "call gpf_strtok_r";
+#pragma aux strpbrk = "call gpf_strpbrk";
+#pragma aux strrchr = "call gpf_strrchr";
+#pragma aux strspn = "call gpf_strspn";
+#pragma aux strstr = "call gpf_strstr";
+#pragma aux strtok = "call gpf_strtok";
+#pragma aux strxfrm = "call gpf_strxfrm";
+#pragma aux memicmp = "call gpf_memicmp";
+#pragma aux strcmpi = "call gpf_strcmpi";
+#pragma aux stricmp = "call gpf_stricmp";
+#pragma aux strrev = "call gpf_strrev";
+#pragma aux strupr = "call gpf_strupr";
+
+#pragma aux strcpy = "call gpf_strcpy";
+#pragma aux strcat = "call gpf_strcat";
+#pragma aux strlen = "call gpf_strlen";
+#pragma aux strncpy = "call gpf_strncpy";
+#pragma aux strncat = "call gpf_strncat";
+#pragma aux strncmp = "call gpf_strncmp";
+#pragma aux strnicmp = "call gpf_strnicmp";
+#pragma aux strdup = "call gpf_strdup";
+#pragma aux strlist = "call gpf_strlist";
+#pragma aux strlwr = "call gpf_strlwr";
+#pragma aux strnset = "call gpf_strnset";
+#pragma aux strset = "call gpf_strset";
+
+
+#endif // _CLIBSTR_H_
+
diff --git a/NetWare/CLIBstuf.c b/NetWare/CLIBstuf.c
new file mode 100644 (file)
index 0000000..0e649dc
--- /dev/null
@@ -0,0 +1,151 @@
+
+/*
+ * Copyright Â© 2001 Novell, Inc. All Rights Reserved.
+ *
+ * You may distribute under the terms of either the GNU General Public
+ * License or the Artistic License, as specified in the README file.
+ *
+ */
+
+/*
+ * FILENAME            :       CLIBstuf.c
+ * DESCRIPTION :       The purpose of clibstuf is to make sure that Perl, cgi2perl and
+ *                  all the perl extension nlm's (*.NLP) use the Novell Netware CLIB versions
+ *                  of standard functions. This code loads up a whole bunch of function pointers
+ *                  to point at the standard CLIB functions.
+ * Author              :       HYAK
+ * Date                        :       January 2001.
+ *
+ */
+
+
+
+#define DEFINE_GPF
+#include "string.h"            // Our version of string.h will include clibstr.h
+#include "stdio.h"             // Our version of stdio.h will include clibsdio.h
+#include "clibstuf.h"
+
+#include <nwthread.h>
+#include <nwadv.h>
+#include <nwconio.h>
+
+
+
+void ImportFromCLIB (unsigned int nlmHandle, void** psymbol, char* symbolName)
+{
+       *psymbol = ImportSymbol(nlmHandle, symbolName);
+       if (*psymbol == NULL)
+       {
+               ConsolePrintf("Symbol %s not found, unable to continue\n", symbolName);
+               exit(1);
+       }
+}
+
+
+void fnInitGpfGlobals(void)
+{
+       unsigned int nlmHandle = GetNLMHandle();
+
+       ImportFromCLIB(nlmHandle, &gpf___get_stdin, "__get_stdin");
+       ImportFromCLIB(nlmHandle, &gpf___get_stdout, "__get_stdout");
+       ImportFromCLIB(nlmHandle, &gpf___get_stderr, "__get_stderr");
+       ImportFromCLIB(nlmHandle, &gpf_clearerr, "clearerr");
+       ImportFromCLIB(nlmHandle, &gpf_fclose, "fclose");
+       ImportFromCLIB(nlmHandle, &gpf_feof, "feof");
+       ImportFromCLIB(nlmHandle, &gpf_ferror, "ferror");
+       ImportFromCLIB(nlmHandle, &gpf_fflush, "fflush");
+       ImportFromCLIB(nlmHandle, &gpf_fgetc, "fgetc");
+       ImportFromCLIB(nlmHandle, &gpf_fgetpos, "fgetpos");
+       ImportFromCLIB(nlmHandle, &gpf_fgets, "fgets");
+       ImportFromCLIB(nlmHandle, &gpf_fopen, "fopen");
+       ImportFromCLIB(nlmHandle, &gpf_fputc, "fputc");
+       ImportFromCLIB(nlmHandle, &gpf_fputs, "fputs");
+       ImportFromCLIB(nlmHandle, &gpf_fread, "fread");
+       ImportFromCLIB(nlmHandle, &gpf_freopen, "freopen");
+       ImportFromCLIB(nlmHandle, &gpf_fscanf, "fscanf");
+       ImportFromCLIB(nlmHandle, &gpf_fseek, "fseek");
+       ImportFromCLIB(nlmHandle, &gpf_fsetpos, "fsetpos");
+       ImportFromCLIB(nlmHandle, &gpf_ftell, "ftell");
+       ImportFromCLIB(nlmHandle, &gpf_fwrite, "fwrite");
+       ImportFromCLIB(nlmHandle, &gpf_getc, "getc");
+       ImportFromCLIB(nlmHandle, &gpf_getchar, "getchar");
+       ImportFromCLIB(nlmHandle, &gpf_gets, "gets");
+       ImportFromCLIB(nlmHandle, &gpf_perror, "perror");
+       ImportFromCLIB(nlmHandle, &gpf_putc, "putc");
+       ImportFromCLIB(nlmHandle, &gpf_putchar, "putchar");
+       ImportFromCLIB(nlmHandle, &gpf_puts, "puts");
+       ImportFromCLIB(nlmHandle, &gpf_rename, "rename");
+       ImportFromCLIB(nlmHandle, &gpf_rewind, "rewind");
+       ImportFromCLIB(nlmHandle, &gpf_scanf, "scanf");
+       ImportFromCLIB(nlmHandle, &gpf_setbuf, "setbuf");
+       ImportFromCLIB(nlmHandle, &gpf_setvbuf, "setvbuf");
+       ImportFromCLIB(nlmHandle, &gpf_sscanf, "sscanf");
+       ImportFromCLIB(nlmHandle, &gpf_tmpfile, "tmpfile");
+       ImportFromCLIB(nlmHandle, &gpf_tmpnam, "tmpnam");
+       ImportFromCLIB(nlmHandle, &gpf_ungetc, "ungetc");
+       ImportFromCLIB(nlmHandle, &gpf_vfscanf, "vfscanf");
+       ImportFromCLIB(nlmHandle, &gpf_vscanf, "vscanf");
+       ImportFromCLIB(nlmHandle, &gpf_vsscanf, "vsscanf");
+       ImportFromCLIB(nlmHandle, &gpf_fdopen, "fdopen");
+       ImportFromCLIB(nlmHandle, &gpf_fileno, "fileno");
+       ImportFromCLIB(nlmHandle, &gpf_cgets, "cgets");
+       ImportFromCLIB(nlmHandle, &gpf_cprintf, "cprintf");
+       ImportFromCLIB(nlmHandle, &gpf_cputs, "cputs");
+       ImportFromCLIB(nlmHandle, &gpf_cscanf, "cscanf");
+       ImportFromCLIB(nlmHandle, &gpf_fcloseall, "fcloseall");
+       ImportFromCLIB(nlmHandle, &gpf_fgetchar, "fgetchar");
+       ImportFromCLIB(nlmHandle, &gpf_flushall, "flushall");
+       ImportFromCLIB(nlmHandle, &gpf_fputchar, "fputchar");
+       ImportFromCLIB(nlmHandle, &gpf_getch, "getch");
+       ImportFromCLIB(nlmHandle, &gpf_getche, "getche");
+       ImportFromCLIB(nlmHandle, &gpf_putch, "putch");
+       ImportFromCLIB(nlmHandle, &gpf_ungetch, "ungetch");
+       ImportFromCLIB(nlmHandle, &gpf_vcprintf, "vcprintf");
+       ImportFromCLIB(nlmHandle, &gpf_vcscanf, "vcscanf");
+
+       ImportFromCLIB(nlmHandle, &gpf_memchr, "memchr");
+       ImportFromCLIB(nlmHandle, &gpf_memcmp, "memcmp");
+       ImportFromCLIB(nlmHandle, &gpf_memcpy, "memcpy");
+       ImportFromCLIB(nlmHandle, &gpf_memmove, "memmove");
+       ImportFromCLIB(nlmHandle, &gpf_memset, "memset");
+       ImportFromCLIB(nlmHandle, &gpf_memicmp, "memicmp");
+
+       ImportFromCLIB(nlmHandle, &gpf_strerror, "strerror");
+       ImportFromCLIB(nlmHandle, &gpf_strtok_r, "strtok_r");
+       
+       ImportFromCLIB(nlmHandle, &gpf_strcpy, "strcpy");
+       ImportFromCLIB(nlmHandle, &gpf_strcat, "strcat");
+       ImportFromCLIB(nlmHandle, &gpf_strchr, "strchr");
+       ImportFromCLIB(nlmHandle, &gpf_strstr, "strstr");
+       ImportFromCLIB(nlmHandle, &gpf_strcoll, "strcoll");
+       ImportFromCLIB(nlmHandle, &gpf_strcspn, "strcspn");
+       ImportFromCLIB(nlmHandle, &gpf_strpbrk, "strpbrk");
+       ImportFromCLIB(nlmHandle, &gpf_strrchr, "strrchr");
+       ImportFromCLIB(nlmHandle, &gpf_strrev, "strrev");
+       ImportFromCLIB(nlmHandle, &gpf_strspn, "strspn");
+       ImportFromCLIB(nlmHandle, &gpf_strupr, "strupr");
+       ImportFromCLIB(nlmHandle, &gpf_strxfrm, "strxfrm");
+       ImportFromCLIB(nlmHandle, &gpf_strcmp, "strcmp");
+       ImportFromCLIB(nlmHandle, &gpf_stricmp, "stricmp");
+       ImportFromCLIB(nlmHandle, &gpf_strtok, "strtok");
+       ImportFromCLIB(nlmHandle, &gpf_strlen, "strlen");
+       ImportFromCLIB(nlmHandle, &gpf_strncpy, "strncpy");
+       ImportFromCLIB(nlmHandle, &gpf_strncat, "strncat");
+       ImportFromCLIB(nlmHandle, &gpf_strncmp, "strncmp");
+       ImportFromCLIB(nlmHandle, &gpf_strcmpi, "strcmpi");
+       ImportFromCLIB(nlmHandle, &gpf_strnicmp, "strnicmp");
+       ImportFromCLIB(nlmHandle, &gpf_strdup, "strdup");
+       ImportFromCLIB(nlmHandle, &gpf_strlist, "strlist");
+       ImportFromCLIB(nlmHandle, &gpf_strlwr, "strlwr");
+       ImportFromCLIB(nlmHandle, &gpf_strnset, "strnset");
+       ImportFromCLIB(nlmHandle, &gpf_strset, "strset");
+       ImportFromCLIB(nlmHandle, &gpf_strtok_r, "strtok_r");
+       ImportFromCLIB(nlmHandle, &gpf_printf, "printf");
+       ImportFromCLIB(nlmHandle, &gpf_fprintf, "fprintf");
+       ImportFromCLIB(nlmHandle, &gpf_sprintf, "sprintf");
+       ImportFromCLIB(nlmHandle, &gpf_vprintf, "vprintf");
+       ImportFromCLIB(nlmHandle, &gpf_vfprintf, "vfprintf");
+       ImportFromCLIB(nlmHandle, &gpf_vsprintf, "vsprintf");
+
+}
+
diff --git a/NetWare/CLIBstuf.h b/NetWare/CLIBstuf.h
new file mode 100644 (file)
index 0000000..90f3557
--- /dev/null
@@ -0,0 +1,40 @@
+
+/*
+ * Copyright Â© 2001 Novell, Inc. All Rights Reserved.
+ *
+ * You may distribute under the terms of either the GNU General Public
+ * License or the Artistic License, as specified in the README file.
+ *
+ */
+
+/*
+ * FILENAME            :       CLIBstuf.h
+ * DESCRIPTION :       The purpose of clibstuf is to make sure that Perl, cgi2perl and
+ *                  all the perl extension nlm's (*.NLP) use the Novell Netware CLIB versions
+ *                  of standard functions. This code loads up a whole bunch of function pointers
+ *                  to point at the standard CLIB functions.
+ * Author              :       HYAK
+ * Date                        :       January 2001.
+ *
+ */
+
+
+
+#ifndef __CLIBstuf_H__
+#define __CLIBstuf_H__
+
+
+#ifdef __cplusplus
+  extern "C"
+  {
+#endif
+
+    void fnInitGpfGlobals(void);
+
+#ifdef __cplusplus
+  }
+#endif
+
+
+#endif // __CLIBstuf_H__
+
diff --git a/NetWare/Main.c b/NetWare/Main.c
new file mode 100644 (file)
index 0000000..d23ce68
--- /dev/null
@@ -0,0 +1,182 @@
+
+/*
+ * Copyright Â© 2001 Novell, Inc. All Rights Reserved.
+ *
+ * You may distribute under the terms of either the GNU General Public
+ * License or the Artistic License, as specified in the README file.
+ *
+ */
+
+/*
+ * FILENAME            :       Main.c
+ * DESCRIPTION :       The purpose of clibstuf is to make sure that Perl, cgi2perl and
+ *                  all the perl extension nlm's (*.NLP) use the Novell Netware CLIB versions
+ *                  of standard functions. This code loads up a whole bunch of function pointers
+ *                  to point at the standard CLIB functions.
+ * Author              :       HYAK
+ * Date                        :       January 2001.
+ *
+ */
+
+
+
+#define DEFINE_GPF
+
+#include <nwthread.h>
+#include <nwadv.h>
+#include <nwconio.h>
+
+#include "string.h"            // Our version of string.h will include clibstr.h
+#include "stdio.h"             // Our version of stdio.h will include clibsdio.h
+#include "clibstuf.h"
+#include "clibstuf.h"
+
+#ifdef MPK_ON
+       #include <mpktypes.h>
+       #include <mpkapis.h>
+#endif //MPK_ON
+
+
+
+/*============================================================================================
+
+ Function              :       main
+
+ Description   :       This is called as the first step in an extension.
+
+ Parameters            :       None
+
+ Returns               :       Nothing.
+
+==============================================================================================*/
+
+void main(void)
+{
+       fnInitGpfGlobals();             // For importing the CLIB calls in place of the Watcom calls
+       SynchronizeStart();             // Don't allow anything else to happen until all the symbols are imported
+       #ifdef MPK_ON
+               ExitThread(TSR_THREAD, 0);
+       #else
+               ExitThread(TSR_THREAD, 0);
+       #endif
+}
+
+
+void ImportFromCLIB (unsigned int nlmHandle, void** psymbol, char* symbolName)
+{
+       *psymbol = ImportSymbol(nlmHandle, symbolName);
+       if (*psymbol == NULL)
+       {
+               ConsolePrintf("Symbol %s not found, unable to continue\n", symbolName);
+               exit(1);
+       }
+}
+
+
+void fnInitGpfGlobals(void)
+{
+       unsigned int nlmHandle = GetNLMHandle();
+
+       ImportFromCLIB(nlmHandle, &gpf___get_stdin, "__get_stdin");
+       ImportFromCLIB(nlmHandle, &gpf___get_stdout, "__get_stdout");
+       ImportFromCLIB(nlmHandle, &gpf___get_stderr, "__get_stderr");
+       ImportFromCLIB(nlmHandle, &gpf_clearerr, "clearerr");
+       ImportFromCLIB(nlmHandle, &gpf_fclose, "fclose");
+       ImportFromCLIB(nlmHandle, &gpf_feof, "feof");
+       ImportFromCLIB(nlmHandle, &gpf_ferror, "ferror");
+       ImportFromCLIB(nlmHandle, &gpf_fflush, "fflush");
+       ImportFromCLIB(nlmHandle, &gpf_fgetc, "fgetc");
+       ImportFromCLIB(nlmHandle, &gpf_fgetpos, "fgetpos");
+       ImportFromCLIB(nlmHandle, &gpf_fgets, "fgets");
+       ImportFromCLIB(nlmHandle, &gpf_fopen, "fopen");
+       ImportFromCLIB(nlmHandle, &gpf_fputc, "fputc");
+       ImportFromCLIB(nlmHandle, &gpf_fputs, "fputs");
+       ImportFromCLIB(nlmHandle, &gpf_fread, "fread");
+       ImportFromCLIB(nlmHandle, &gpf_freopen, "freopen");
+       ImportFromCLIB(nlmHandle, &gpf_fscanf, "fscanf");
+       ImportFromCLIB(nlmHandle, &gpf_fseek, "fseek");
+       ImportFromCLIB(nlmHandle, &gpf_fsetpos, "fsetpos");
+       ImportFromCLIB(nlmHandle, &gpf_ftell, "ftell");
+       ImportFromCLIB(nlmHandle, &gpf_fwrite, "fwrite");
+       ImportFromCLIB(nlmHandle, &gpf_getc, "getc");
+       ImportFromCLIB(nlmHandle, &gpf_getchar, "getchar");
+       ImportFromCLIB(nlmHandle, &gpf_gets, "gets");
+       ImportFromCLIB(nlmHandle, &gpf_perror, "perror");
+       ImportFromCLIB(nlmHandle, &gpf_putc, "putc");
+       ImportFromCLIB(nlmHandle, &gpf_putchar, "putchar");
+       ImportFromCLIB(nlmHandle, &gpf_puts, "puts");
+       ImportFromCLIB(nlmHandle, &gpf_rename, "rename");
+       ImportFromCLIB(nlmHandle, &gpf_rewind, "rewind");
+       ImportFromCLIB(nlmHandle, &gpf_scanf, "scanf");
+       ImportFromCLIB(nlmHandle, &gpf_setbuf, "setbuf");
+       ImportFromCLIB(nlmHandle, &gpf_setvbuf, "setvbuf");
+       ImportFromCLIB(nlmHandle, &gpf_sscanf, "sscanf");
+       ImportFromCLIB(nlmHandle, &gpf_tmpfile, "tmpfile");
+       ImportFromCLIB(nlmHandle, &gpf_tmpnam, "tmpnam");
+       ImportFromCLIB(nlmHandle, &gpf_ungetc, "ungetc");
+       ImportFromCLIB(nlmHandle, &gpf_vfscanf, "vfscanf");
+       ImportFromCLIB(nlmHandle, &gpf_vscanf, "vscanf");
+       ImportFromCLIB(nlmHandle, &gpf_vsscanf, "vsscanf");
+       ImportFromCLIB(nlmHandle, &gpf_fdopen, "fdopen");
+       ImportFromCLIB(nlmHandle, &gpf_fileno, "fileno");
+       ImportFromCLIB(nlmHandle, &gpf_cgets, "cgets");
+       ImportFromCLIB(nlmHandle, &gpf_cprintf, "cprintf");
+       ImportFromCLIB(nlmHandle, &gpf_cputs, "cputs");
+       ImportFromCLIB(nlmHandle, &gpf_cscanf, "cscanf");
+       ImportFromCLIB(nlmHandle, &gpf_fcloseall, "fcloseall");
+       ImportFromCLIB(nlmHandle, &gpf_fgetchar, "fgetchar");
+       ImportFromCLIB(nlmHandle, &gpf_flushall, "flushall");
+       ImportFromCLIB(nlmHandle, &gpf_fputchar, "fputchar");
+       ImportFromCLIB(nlmHandle, &gpf_getch, "getch");
+       ImportFromCLIB(nlmHandle, &gpf_getche, "getche");
+       ImportFromCLIB(nlmHandle, &gpf_putch, "putch");
+       ImportFromCLIB(nlmHandle, &gpf_ungetch, "ungetch");
+       ImportFromCLIB(nlmHandle, &gpf_vcprintf, "vcprintf");
+       ImportFromCLIB(nlmHandle, &gpf_vcscanf, "vcscanf");
+
+       ImportFromCLIB(nlmHandle, &gpf_memchr, "memchr");
+       ImportFromCLIB(nlmHandle, &gpf_memcmp, "memcmp");
+       ImportFromCLIB(nlmHandle, &gpf_memcpy, "memcpy");
+       ImportFromCLIB(nlmHandle, &gpf_memmove, "memmove");
+       ImportFromCLIB(nlmHandle, &gpf_memset, "memset");
+       ImportFromCLIB(nlmHandle, &gpf_memicmp, "memicmp");
+
+       ImportFromCLIB(nlmHandle, &gpf_strerror, "strerror");
+       ImportFromCLIB(nlmHandle, &gpf_strtok_r, "strtok_r");
+       
+       ImportFromCLIB(nlmHandle, &gpf_strcpy, "strcpy");
+       ImportFromCLIB(nlmHandle, &gpf_strcat, "strcat");
+       ImportFromCLIB(nlmHandle, &gpf_strchr, "strchr");
+       ImportFromCLIB(nlmHandle, &gpf_strstr, "strstr");
+       ImportFromCLIB(nlmHandle, &gpf_strcoll, "strcoll");
+       ImportFromCLIB(nlmHandle, &gpf_strcspn, "strcspn");
+       ImportFromCLIB(nlmHandle, &gpf_strpbrk, "strpbrk");
+       ImportFromCLIB(nlmHandle, &gpf_strrchr, "strrchr");
+       ImportFromCLIB(nlmHandle, &gpf_strrev, "strrev");
+       ImportFromCLIB(nlmHandle, &gpf_strspn, "strspn");
+       ImportFromCLIB(nlmHandle, &gpf_strupr, "strupr");
+       ImportFromCLIB(nlmHandle, &gpf_strxfrm, "strxfrm");
+       ImportFromCLIB(nlmHandle, &gpf_strcmp, "strcmp");
+       ImportFromCLIB(nlmHandle, &gpf_stricmp, "stricmp");
+       ImportFromCLIB(nlmHandle, &gpf_strtok, "strtok");
+       ImportFromCLIB(nlmHandle, &gpf_strlen, "strlen");
+       ImportFromCLIB(nlmHandle, &gpf_strncpy, "strncpy");
+       ImportFromCLIB(nlmHandle, &gpf_strncat, "strncat");
+       ImportFromCLIB(nlmHandle, &gpf_strncmp, "strncmp");
+       ImportFromCLIB(nlmHandle, &gpf_strcmpi, "strcmpi");
+       ImportFromCLIB(nlmHandle, &gpf_strnicmp, "strnicmp");
+       ImportFromCLIB(nlmHandle, &gpf_strdup, "strdup");
+       ImportFromCLIB(nlmHandle, &gpf_strlist, "strlist");
+       ImportFromCLIB(nlmHandle, &gpf_strlwr, "strlwr");
+       ImportFromCLIB(nlmHandle, &gpf_strnset, "strnset");
+       ImportFromCLIB(nlmHandle, &gpf_strset, "strset");
+       ImportFromCLIB(nlmHandle, &gpf_strtok_r, "strtok_r");
+       ImportFromCLIB(nlmHandle, &gpf_printf, "printf");
+       ImportFromCLIB(nlmHandle, &gpf_fprintf, "fprintf");
+       ImportFromCLIB(nlmHandle, &gpf_sprintf, "sprintf");
+       ImportFromCLIB(nlmHandle, &gpf_vprintf, "vprintf");
+       ImportFromCLIB(nlmHandle, &gpf_vfprintf, "vfprintf");
+       ImportFromCLIB(nlmHandle, &gpf_vsprintf, "vsprintf");
+
+}
+
diff --git a/NetWare/Makefile b/NetWare/Makefile
new file mode 100644 (file)
index 0000000..1a8b622
--- /dev/null
@@ -0,0 +1,1456 @@
+##
+## Makefile to build Perl on NetWare using Microsoft NMAKE and Watcom tools
+##
+## This will build perl.nlm, perl.lib and extensions called NLPs
+##
+
+##
+## Please read README.netware before starting
+##
+
+##
+## Build configuration.  Edit the values below to suit your needs.
+##
+
+## This file is created by using the makefile that creates Windows Perl as the reference
+## Author: sgp
+## Date Created: 13th July 2000
+## Date Modified: 03th April 2001
+
+# Name of the NLM
+NLM_NAME               = perl.nlm
+NLM_NAME8              = Perl
+
+MAKE_ACTION            = Build
+
+# Flags
+DBG_FLAG       = -DDEBUGON
+
+NW_FLAGS       = -DNETWARE -DNLM_PLATFORM -DNETDB_USE_INTERNET
+
+REL_DIR        = Release
+DEB_DIR = Debug
+
+!ifndef MAKE_TYPE
+#MAKE_TYPE = Release
+!message "Run bat\buildtype.bat to set the build type before continuing.\n"
+!error
+!endif                                                                                                                         #!ifndef MAKE_TYPE
+
+!ifdef USE_MPK
+MPKFLAGS       = -DMPK_ON -DIAPX386
+MPKMESSAGE = MPK Build...
+XDCTOOL        = mpkxdc
+!ifndef MPKBASE
+#MPKBASE                       = p:\mpk
+!message "Run bat\setnwbld.bat to set the NetWare MPK SDK before continuing.\n"
+!error
+!endif                                                                                                                         #ifndef MPKBASE
+NLM_INCLUDE_MP         = $(MPKBASE)\include
+MPKTOOL = $(MPKBASE)\$(XDCTOOL)
+!else
+MPKMESSAGE = Non MPK Build...
+NLM_INCLUDE_MP =
+MPKTOOL = 
+!endif                                                                                                                         #ifdef USE_MPK
+
+!ifndef NLMSDKBASE
+#NLMSDKBASE            = P:\ndk\nwsdk
+!message "Run bat\setnwbld.bat to set the NetWare SDK before continuing.\n"
+!error
+!endif                                                                                                                         #ifndef NLMSDKBASE
+NLMIMPORTS      = $(NLMSDKBASE)\imports
+
+!ifdef WATCOM
+C_COMPILER             = wcc386
+CPP_COMPILER   = wpp386
+NLM_LINK               = wlink
+NLM_LIB                        = lib386
+TOOL_HEADERS   = $(WATCOM)\H;$(WATCOM)\H\NT
+TOOL_PATH              = $(WATCOM)\BINNT;$(WATCOM)\BINW
+CCFLAGS                        = /zp1 /5s /w1 /zq /ms /otexanih /fpi
+COMPILER_FLAG  = -DWATCOM
+ERROR_FLAG             = -Fr
+!if "$(MAKE_TYPE)"=="Debug"
+BLDDIR          = $(DEB_DIR)
+BLDMESG                        = Debug version,
+!ifdef USE_D2
+BS_CFLAGS      = /od /d2 /en /st /hc -DDEBUGGING -DUSE_D2 $(DBG_FLAG)
+BLDMESG                = $(BLDMESG) Using /d2 option
+!else
+BS_CFLAGS      = /od /d1 /en /st /hc -DDEBUGGING $(DBG_FLAG)
+BLDMESG                = $(BLDMESG) Using /d1 option
+!endif                                                                                                                         #!ifdef USE_D2  
+! else
+BLDDIR          = $(REL_DIR)
+BLDMESG                = Release version
+BS_CFLAGS      = 
+!endif                                                                                                                         #if "$(MAKE_TYPE)"=="Debug"
+!else                                                                                                                          #ifdef WATCOM
+!ifdef CODEWARRIOR
+# Here comes the CW tools - TO BE FILLED TO BUILD WITH CW -
+C_COMPILER             = 
+CPP_COMPILER   = 
+NLM_LINK               = 
+NLM_LIB                        = 
+TOOL_HEADERS   = 
+TOOL_PATH              = 
+CCFLAGS                        = 
+COMPILER_FLAG  = 
+ERROR_FLAG             =
+# Debug flags comes here - Not mandatory - required only for debug build
+!if "$(MAKE_TYPE)"=="Debug"
+BLDDIR          = $(DEB_DIR)
+BLDMESG                        = Debug version,
+!ifdef USE_D2
+BS_CFLAGS      = 
+BLDMESG                = $(BLDMESG) Using /d2 option
+!else
+BS_CFLAGS      = 
+BLDMESG                = $(BLDMESG) Using /d1 option
+!endif                                                                                                                         #!ifdef USE_D2  
+! else
+BLDDIR      = $(REL_DIR)
+BLDMESG                = Release version
+BS_CFLAGS      = 
+!endif                                                                                                                         #if "$(MAKE_TYPE)"=="Debug"
+!else                                                                                                                          #!ifdef CODEWARRIOR
+!message "Tools base directory is not defined. Run bat\setnwbld.bat before proceeding"
+!error
+Run bat\setnwbld.bat
+!endif                                                                                                                         #!ifdef CODEWARRIOR
+!endif                                                                                                                         #ifdef WATCOM
+
+ADD_LOCDEFS =  -DPERL_CORE
+
+NLM_INCLUDE                    = -I$(NLMSDKBASE)\include
+NLM_INCLUDE_NLM                = -I$(NLMSDKBASE)\include\nlm
+NLM_INCLUDE_NLM_SYS = -I$(NLMSDKBASE)\include\nlm\sys
+INCLUDE_NW          = -I.\include
+INC_PREV                       = -I..
+INC_THIS                       = -I.\
+
+NLM_INCLUDE_PATH = $(NLMSDKBASE)\include\nlm;$(NLMSDKBASE)\include;$(NLMSDKBASE)\include\nlm\sys;$(NLM_INCLUDE_MP);$(TOOL_HEADERS)
+
+INCLUDE = $(NLM_INCLUDE_PATH)
+
+PATH = $(PATH);$(TOOL_PATH)
+NLM_INCLUDES   =       -I$(COREDIR) $(INCLUDE_NW) $(INC_THIS) $(INC_PREV)
+
+COMPLER_FLAGS  =  $(CCFLAGS) $(BS_CFLAGS) $(ADD_BUILDOPT) $(NW_FLAGS) $(COMPILER_FLAG) $(MPKFLAGS)
+
+# Source file list
+NW_H_FILES                     =       \
+                                               .\iperlhost.h   \
+                                               .\interface.h   \
+                                               .\netware.h \
+                                               .\nw5iop.h      \
+                                               .\nw5sck.h      \
+                                               .\nwpipe.h      \
+                                               .\nwplglob.h    \
+                                               .\nwtinfo.h     \
+                                               .\nwutil.h      \
+                                               .\nwperlsys.h   \
+
+NW_HOST_H_FILES                =       \
+                                               .\iperlhost.h   \
+                                               .\interface.h   \
+                                               .\netware.h     \
+                                               .\nw5sck.h      \
+                                               .\nwperlsys.h   \
+
+CLIB_H_FILES           =       \
+                                               .\clibsdio.h    \
+                                               .\clibstr.h             \
+                                               .\clibstuf.h    \
+                                               .\stdio.h       \
+                                               .\string.h      \
+
+NW_SRC                         =       \
+                                               .\CLIBstuf.c    \
+                                               .\nw5.c         \
+                                               .\nw5sck.c      \
+                                               .\nw5thread.c \
+                                               .\nwmain.c      \
+                                               .\nwpipe.c  \
+                                               .\nwplglob.c    \
+                                               .\nwtinfo.c \
+                                               .\nwutil.c  \
+
+EXT_MAIN_SRC           =       \
+                                               .\Main.c        \
+
+PERL_IO_SRC                    =       \
+                                               ..\perlio.c     
+
+PERL_LIB_SRC           =       \
+                                               .\interface.c   \
+                                               .\nwperlsys.c \
+
+
+NW_SRC_OBJ                     = $(NW_SRC:.c=.obj)
+NLM_MICROCORE_OBJ      = $(MICROCORE_SRC:.c=.obj) 
+PERL_LIB_OBJ           = $(PERL_LIB_SRC:.c=.obj)
+PERL_IO_OBJ                    = $(PERL_IO_SRC:.c=.obj)
+NLM_CORE_OBJ       = $(NLM_MICROCORE_OBJ)
+EXT_MAIN_OBJ           = $(EXT_MAIN_SRC:.c=.obj)
+
+# For dependency checking 
+# $(BLDDIR) in place of Release or Debug is not working, should look into this - sgp
+!if "$(BLDDIR)"=="Release"
+NLM_OBJ                                = $(NLM_CORE_OBJ:..\=.\Release\)
+NEWTARE_OBJ_DEP                = $(NW_SRC_OBJ:.\=.\Release\)
+PERL_LIB_OBJ_DEP       = $(PERL_LIB_OBJ:.\=.\Release\)
+PERL_IO_OBJ_DEP                = $(PERL_IO_OBJ:..\=.\Release\)
+!else
+NLM_OBJ                                = $(NLM_CORE_OBJ:..\=.\Debug\)
+NEWTARE_OBJ_DEP                = $(NW_SRC_OBJ:.\=.\Debug\)
+PERL_LIB_OBJ_DEP       = $(PERL_LIB_OBJ:.\=.\Debug\)
+PERL_IO_OBJ_DEP                = $(PERL_IO_OBJ:..\=.\Debug\)
+!endif
+
+# Symbol base_import & version added for NETWARE
+NW_CFG_VARS = \
+               "INST_DRV=$(INST_DRV)"                  \
+               "INST_TOP=$(INST_TOP)"                  \
+               "INST_VER=$(INST_VER)"                  \
+               "INST_ARCH=$(INST_ARCH)"                \
+               "INST_NW_TOP1=$(INST_NW_TOP1)"  \
+               "INST_NW_TOP2=$(INST_NW_TOP2)"  \
+               "INST_NW_VER=$(INST_NW_VER)"    \
+               "archname=$(ARCHNAME)"                  \
+               "cc=$(C_COMPILER)"                              \
+               "ccflags=$(COMPLER_FLAGS)"      \
+               "cf_email=$(EMAIL)"                     \
+               "d_crypt=$(D_CRYPT)"                    \
+               "d_mymalloc=$(PERL_MALLOC)"             \
+#              "libs=$(LIBFILES)"                      \
+               "incpath=$(NLM_INCLUDE_PATH)"   \
+               "libperl=$(PERLIMPLIB:..\=)"            \
+               "libpth=$(LIBPATH)"     \
+#              "libc=$(LIBC)"                          \
+               "make=nmake"                            \
+               "static_ext=$(STATIC_EXT)"              \
+               "dynamic_ext=$(DYNAMIC_EXT)"            \
+               "nonxs_ext=$(NONXS_EXT)"                \
+               "use5005threads=$(USE_5005THREADS)"     \
+               "useithreads=$(USE_ITHREADS)"           \
+               "usethreads=$(USE_5005THREADS)"         \
+               "usemultiplicity=$(USE_MULTI)"          \
+               "ld=$(NLM_LINK)"                        \
+               "base_import=$(BASE_IMPORT_FILES)"      \
+               "LINK_FLAGS=$(LINK_FLAGS:"=\")"         \
+               "optimize="             \
+               "d_times=define"                                        \
+               "d_stdio_cnt_lval=undef"                \
+               "d_stdio_ptr_lval=undef"                \
+               "d_stdiobase=undef"                             \
+               "d_stdstdio=undef"                              \
+               "d_times=undef"                 \
+               "direntrytype=DIR"                              \
+               "nlm_version=$(NLM_VERSION)"            \
+               "d_archname=NetWare"    \
+               "mpktool=$(MPKTOOL) $(XDCFLAGS)"        \
+               "toolpath=$(TOOL_PATH)"
+
+
+NW_CFGSH_TMPL  = config.wc
+NW_CFGH_TMPL   = config_H.wc
+
+SOCKET_NLP     = $(AUTODIR)\Socket\Socket.nlp
+FCNTL_NLP      = $(AUTODIR)\Fcntl\Fcntl.nlp
+IO_NLP         = $(AUTODIR)\IO\IO.nlp
+OPCODE_NLP     = $(AUTODIR)\Opcode\Opcode.nlp
+SDBM_FILE_NLP  = $(AUTODIR)\SDBM_File\SDBM_File.nlp
+POSIX_NLP      = $(AUTODIR)\POSIX\POSIX.nlp
+ATTRS_NLP      = $(AUTODIR)\attrs\attrs.nlp
+THREAD_NLP     = $(AUTODIR)\Thread\Thread.nlp
+B_NLP          = $(AUTODIR)\B\B.nlp
+DUMPER_NLP     = $(AUTODIR)\Data\Dumper\Dumper.nlp
+PEEK_NLP       = $(AUTODIR)\Devel\Peek\Peek.nlp
+RE_NLP         = $(AUTODIR)\re\re.nlp
+BYTELOADER_NLP = $(AUTODIR)\ByteLoader\ByteLoader.nlp
+DPROF_NLP      = $(AUTODIR)\Devel\DProf\DProf.nlp
+GLOB_NLP       = $(AUTODIR)\File\Glob\Glob.nlp
+
+EXTENSION_NLP  =               \
+               $(FCNTL_NLP)    \
+               $(BYTELOADER_NLP)       \
+               $(IO_NLP)               \
+               $(SOCKET_NLP)   \
+               $(OPCODE_NLP)   \
+               $(B_NLP)                \
+               $(ATTRS_NLP)    \
+               $(SDBM_FILE_NLP)        \
+               $(POSIX_NLP)    \
+               $(THREAD_NLP)   \
+               $(DUMPER_NLP)   \
+               $(GLOB_NLP)             \
+               $(PEEK_NLP)             \
+               $(RE_NLP)       \
+               $(DPROF_NLP)
+
+# Begin - Following is required to build NetWare specific extensions Perl2UCS & CGI2Perl
+
+PERL2UCS               = $(EXTDIR)\Perl2UCS\Perl2UCS
+CGI2PERL               = CGI2Perl\CGI2Perl
+
+PERL2UCS_NLP = $(AUTODIR)\Perl2UCS\Perl2UCS.nlp
+CGI2PERL_NLP = \CGI2Perl\CGI2Perl.nlp
+
+NETWARE_EXTNS =        \
+               $(PERL2UCS_NLP) \
+               $(CGI2PERL_NLP)
+
+# End
+
+ECHO_SRC                       = TestNLM\echo\echo.c
+TYPE_SRC                       = TestNLM\type\type.c
+ECHO_SRC_OBJ                   = $(ECHO_SRC:.c=.obj)
+TYPE_SRC_OBJ                   = $(TYPE_SRC:.c=.obj)
+ECHO_NLM       = TestNLM\echo\echo.nlm
+TYPE_NLM       = TestNLM\type\type.nlm
+
+TEST_NLMS      =       \
+                       $(ECHO_NLM)     \
+                       $(TYPE_NLM)     \
+
+ERRNO_PM_NW    = $(LIBDIR)\Errno.pm
+
+EXTENSION_NPM =        \
+               $(ERRNO_PM_NW)  \
+
+
+!ifndef SCREEN
+SCREEN          = 'none'
+!endif
+
+!ifndef NLM_DESCRIPTION
+NLM_DESCRIPTION = $(NLM_NAME8) for Netware
+!endif
+
+!ifndef NLM_VERSION
+NLM_VERSION    = 1.0.0
+!endif
+
+!ifndef NLM_EXT
+NLM_EXT         = NLM
+!endif
+
+!ifndef BUILT
+BUILT     = $(BLDDIR)\$(NLM_NAME8).$(NLM_EXT)
+!endif
+
+!ifndef BASE_IMPORT_FILES
+BASE_IMPORT_FILES = Import @$(NLMIMPORTS)\clib.imp, @$(NLMIMPORTS)\nlmlib.imp, @$(NLMIMPORTS)\threads.imp, @$(NLMIMPORTS)\nit.imp, @$(NLMIMPORTS)\socklib.imp, @$(NLMIMPORTS)\fpsm.imp, @$(NLMIMPORTS)\lib0.imp
+!endif
+
+!ifdef USE_MPK
+BASE_IMPORT_FILES = $(BASE_IMPORT_FILES), @$(MPKBASE)\import\mpkorg.imp
+!endif
+
+!ifndef BASE_IMPORT_FNS
+BASE_IMPORT_FNS = Import ImportSymbol, GetSystemConsoleScreen, LoadModule
+!endif
+
+!ifdef WATCOM
+NWLIBPATH  = $(WATCOM)\lib386\netware
+LIBPATH386 = $(WATCOM)\lib386
+LIBPATH = $(NWLIBPATH);$(LIBPATH386)
+!else                                                                                                                          #!ifdef WATCOM
+!ifdef CODEWARRIOR
+NWLIBPATH  = 
+LIBPATH386 =
+LIBPATH = 
+!else                                                                                                                          #!ifdef CODEWARRIOR
+!error Please define the tools base directory before proceeding
+!endif                                                                                                                         #!ifdef CODEWARRIOR
+!endif                                                                                                                         #!ifdef WATCOM
+
+!ifndef BASE_LIBRARIES
+!ifdef WATCOM
+BASE_LIBRARIES = Library plib3s.lib,math3s.lib,clib3s.lib
+!else
+!ifdef CODEWARRIOR
+BASE_LIBRARIES = 
+!endif                                                                                                                         #!ifdef CODEWARRIOR
+!endif                                                                                                                         #!ifdef WATCOM  
+!endif                                                                                                                         #!ifndef BASE_LIBRARIES
+
+COPYRIGHT = Copyright 2001 by Novell, Inc. All rights reserved.
+
+EXPORTS = Export @perl.imp
+
+#
+# Set these to wherever you want "nmake install" to put your
+# newly built perl.
+#
+INST_DRV       = c:
+INST_TOP       = $(INST_DRV)\perl
+
+INST_NW_DRV = i:
+INST_NW_VOL = sys:
+INST_NW_TOP1 = $(INST_NW_VOL)\perl
+INST_NW_TOP2 = $(INST_NW_DRV)\perl
+#INST_NW_VER = \5.6.1
+
+#
+# Comment this out if you DON'T want your perl installation to be versioned.
+# This means that the new installation will overwrite any files from the
+# old installation at the same INST_TOP location.  Leaving it enabled is
+# the safest route, as perl adds the extra version directory to all the
+# locations it installs files to.  If you disable it, an alternative
+# versioned installation can be obtained by setting INST_TOP above to a
+# path that includes an arbitrary version string.
+#
+INST_VER       = \5.7.1
+
+#
+# Comment this out if you DON'T want your perl installation to have
+# architecture specific components.  This means that architecture-
+# specific files will be installed along with the architecture-neutral
+# files.  Leaving it enabled is safer and more flexible, in case you
+# want to build multiple flavors of perl and install them together in
+# the same location.  Commenting it out gives you a simpler
+# installation that is easier to understand for beginners.
+#
+INST_ARCH      = \$(ARCHNAME)
+
+#
+# uncomment to enable multiple interpreters.  This is need for fork()
+# emulation.
+#
+USE_MULTI      = define
+
+#
+# Beginnings of interpreter cloning/threads; still very incomplete.
+# This should be enabled to get the fork() emulation.  This needs
+# USE_MULTI as well.
+#
+USE_ITHREADS   = define
+
+#
+# uncomment to enable the implicit "host" layer for all system calls
+# made by perl.  This needs USE_MULTI above.  This is also needed to
+# get fork().
+#
+USE_IMP_SYS    = define
+
+# uncomment this to enable the experimental PerlIO I/O subsystem
+# else USE_STDIO will be defined.
+#USE_PERLIO    = define
+#USE_STDIO = define
+
+#
+# WARNING! This option is deprecated and will eventually go away (enable
+# USE_ITHREADS instead).
+#
+# uncomment to enable threads-capabilities.  This is incompatible with
+# USE_ITHREADS, and is only here for people who may have come to rely
+# on the experimental Thread support that was in 5.005.
+#
+#USE_5005THREADS= define
+
+#
+# WARNING! This option is deprecated and will eventually go away (enable
+# USE_MULTI instead).
+#
+# uncomment next line if you want to use the PERL_OBJECT build option.
+# DO NOT ENABLE unless you have legacy code that relies on the C++
+# CPerlObj class that was available in 5.005.  This cannot be enabled
+# if you ask for USE_5005THREADS above.
+#
+#USE_OBJECT    = define
+
+# For now let this be here
+#
+#CRYPT_SRC     = fcrypt.c
+
+# For now let this be here
+#
+#CRYPT_LIB     = fcrypt.lib
+
+#
+# set this if you wish to use perl's malloc
+# WARNING: Turning this on/off WILL break binary compatibility with extensions
+# you may have compiled with/without it.  Be prepared to recompile all
+# extensions if you change the default.  Currently, this cannot be enabled
+# if you ask for USE_IMP_SYS above.
+#
+#PERL_MALLOC   = define
+
+#
+# set this to your email address (perl will guess a value from
+# from your loginname and your hostname, which may not be right)
+#
+#EMAIL         =
+
+##
+## Build configuration ends.
+##
+
+##################### CHANGE THESE ONLY IF YOU MUST #####################
+
+!IF "$(CRYPT_SRC)$(CRYPT_LIB)" == ""
+D_CRYPT                = undef
+!ELSE
+D_CRYPT                = define
+CRYPT_FLAG     = -DHAVE_DES_FCRYPT
+!ENDIF
+
+!IF "$(USE_OBJECT)" == "define"
+PERL_MALLOC    = undef
+USE_5005THREADS        = undef
+USE_MULTI      = undef
+USE_IMP_SYS    = define
+!ENDIF
+
+!IF "$(PERL_MALLOC)" == ""
+PERL_MALLOC    = undef
+!ENDIF
+
+!IF "$(USE_5005THREADS)" == ""
+USE_5005THREADS        = undef
+!ENDIF
+
+!IF "$(USE_5005THREADS)" == "define"
+USE_ITHREADS   = undef
+!ENDIF
+
+!IF "$(USE_IMP_SYS)" == "define"
+PERL_MALLOC    = undef
+!ENDIF
+
+!IF "$(USE_MULTI)" == ""
+USE_MULTI      = undef
+!ENDIF
+
+!IF "$(USE_OBJECT)" == ""
+USE_OBJECT     = undef
+!ENDIF
+
+!IF "$(USE_ITHREADS)" == ""
+USE_ITHREADS   = undef
+!ENDIF
+
+!IF "$(USE_IMP_SYS)" == ""
+USE_IMP_SYS    = undef
+!ENDIF
+
+!IF "$(USE_PERLCRT)" == ""
+USE_PERLCRT    = undef
+!ENDIF
+
+!IF "$(USE_IMP_SYS)$(USE_MULTI)$(USE_5005THREADS)$(USE_OBJECT)" == "defineundefundefundef"
+USE_MULTI      = define
+!ENDIF
+
+!IF "$(USE_ITHREADS)$(USE_MULTI)$(USE_OBJECT)" == "defineundefundef"
+USE_MULTI      = define
+USE_5005THREADS        = undef
+!ENDIF
+
+!IF "$(USE_MULTI)$(USE_5005THREADS)$(USE_OBJECT)" != "undefundefundef"
+BUILDOPT       = $(BUILDOPT) -DPERL_IMPLICIT_CONTEXT
+!ENDIF
+
+!IF "$(USE_IMP_SYS)" != "undef"
+BUILDOPT       = $(BUILDOPT) -DPERL_IMPLICIT_SYS
+!ENDIF
+
+!IF "$(PROCESSOR_ARCHITECTURE)" == ""
+PROCESSOR_ARCHITECTURE = x86
+!ENDIF
+
+!IF "$(USE_OBJECT)" == "define"
+ARCHNAME       = NetWare-$(PROCESSOR_ARCHITECTURE)-object
+!ELSE
+!IF "$(USE_5005THREADS)" == "define"
+ARCHNAME       = NetWare-$(PROCESSOR_ARCHITECTURE)-thread
+!ELSE
+!IF "$(USE_MULTI)" == "define"
+ARCHNAME       = NetWare-$(PROCESSOR_ARCHITECTURE)-multi
+!ELSE
+ARCHNAME       = NetWare-$(PROCESSOR_ARCHITECTURE)
+!ENDIF
+!ENDIF
+!ENDIF
+
+!IF "$(USE_MULTI)$(USE_5005THREADS)$(USE_OBJECT)" != "undefundefundef"
+ADD_BUILDOPT   = $(ADD_BUILDOPT) -DPERL_IMPLICIT_CONTEXT
+!ENDIF
+
+!IF "$(USE_IMP_SYS)" != "undef"
+ADD_BUILDOPT   = $(ADD_BUILDOPT) -DPERL_IMPLICIT_SYS
+!ENDIF
+
+!IF "$(USE_ITHREADS)" == "define"
+ARCHNAME       = $(ARCHNAME)-thread
+!ENDIF
+
+!IF "$(USE_PERLIO)" == "define"
+USE_STDIO              = undef
+ADD_BUILDOPT   = $(ADD_BUILDOPT) -DUSE_PERLIO
+ARCHNAME               = $(ARCHNAME)-perlio
+!ELSE
+#USE_STDIO     = define
+#ADD_BUILDOPT  = $(ADD_BUILDOPT) -DUSE_STDIO
+!ENDIF
+
+ARCHDIR                = ..\lib\$(ARCHNAME)
+COREDIR                = ..\lib\CORE
+AUTODIR                = ..\lib\auto
+LIBDIR         = ..\lib
+EXTDIR         = ..\ext
+PODDIR         = ..\pod
+EXTUTILSDIR    = $(LIBDIR)\ExtUtils
+
+#
+INST_SCRIPT    = $(INST_TOP)$(INST_VER)\bin
+INST_BIN       = $(INST_SCRIPT)$(INST_ARCH)
+INST_LIB       = $(INST_TOP)$(INST_VER)\lib
+INST_ARCHLIB   = $(INST_LIB)$(INST_ARCH)
+INST_COREDIR   = $(INST_ARCHLIB)\CORE
+INST_POD       = $(INST_LIB)\pod
+INST_HTML      = $(INST_POD)\html
+
+#
+# Options
+#
+
+!IF "$(USE_OBJECT)" == "define"
+OPTIMIZE       = $(OPTIMIZE) $(CXX_FLAG)
+BUILDOPT       = $(BUILDOPT) -DPERL_OBJECT
+!ENDIF
+
+OBJOUT_FLAG    = -Fo
+EXEOUT_FLAG    = -Fe
+
+
+#################### do not edit below this line #######################
+############# NO USER-SERVICEABLE PARTS BEYOND THIS POINT ##############
+
+o = .obj
+
+#
+# Rules
+# 
+
+.SUFFIXES : .c $(o) .nlm .lib .nlp
+
+
+#
+# various targets
+PERLIMPLIB     = ..\perl.lib
+
+MINIPERL       = ..\miniperl.exe
+CONFIGPM       = ..\lib\Config.pm
+MINIMOD                = ..\lib\ExtUtils\Miniperl.pm
+X2P                    = ..\x2p\a2p.nlm
+
+PL2BAT         = ..\win32\bin\pl2bat.pl
+
+UTILS          =                       \
+               ..\utils\h2ph           \
+               ..\utils\splain         \
+               ..\utils\dprofpp        \
+               ..\utils\perlbug        \
+               ..\utils\pl2pm          \
+               ..\utils\c2ph           \
+               ..\utils\h2xs           \
+               ..\utils\perldoc        \
+               ..\utils\perlcc         \
+               ..\pod\checkpods        \
+               ..\pod\pod2html         \
+               ..\pod\pod2latex        \
+               ..\pod\pod2man          \
+               ..\pod\pod2text         \
+               ..\pod\pod2usage        \
+               ..\pod\podchecker       \
+               ..\pod\podselect        \
+               ..\x2p\find2perl        \
+               ..\x2p\s2p              
+
+MAKE           = nmake -nologo
+
+XCOPY          = xcopy /f /r /i /d
+RCOPY          = xcopy /f /r /i /e /d
+NOOP           = @echo
+NULL           =
+
+#
+# filenames given to xsubpp must have forward slashes (since it puts
+# full pathnames in #line strings)
+XSUBPP         = ..\$(MINIPERL) -I..\..\lib ..\$(EXTUTILSDIR)\xsubpp \
+               -C++ -prototypes
+
+MICROCORE_SRC  =               \
+               ..\av.c         \
+               ..\deb.c        \
+               ..\doio.c       \
+               ..\doop.c       \
+               ..\dump.c       \
+               ..\globals.c    \
+               ..\gv.c         \
+               ..\hv.c         \
+               ..\mg.c         \
+               ..\op.c         \
+               ..\perl.c       \
+               ..\perlapi.c    \
+               ..\perly.c      \
+               ..\pp.c         \
+               ..\pp_ctl.c     \
+               ..\pp_hot.c     \
+               ..\pp_sys.c     \
+               ..\regcomp.c    \
+               ..\regexec.c    \
+               ..\run.c        \
+               ..\scope.c      \
+               ..\sv.c         \
+               ..\taint.c      \
+               ..\toke.c       \
+               ..\universal.c  \
+               ..\utf8.c       \
+               ..\util.c       \
+               ..\xsutils.c
+
+#EXTRACORE_SRC = $(EXTRACORE_SRC) perllib.c
+
+!IF "$(PERL_MALLOC)" == "define"
+EXTRACORE_SRC  = $(EXTRACORE_SRC) ..\malloc.c
+!ENDIF
+
+#!IF "$(USE_OBJECT)" != "define"
+#EXTRACORE_SRC = $(EXTRACORE_SRC) ..\perlio.c
+#!ENDIF
+
+!IF "$(CRYPT_SRC)" != ""
+NW_SRC = $(NW_SRC) .\$(CRYPT_SRC)
+!ENDIF
+
+DLL_SRC                = $(DYNALOADER).c
+
+X2P_SRC                =               \
+               ..\x2p\a2p.c    \
+               ..\x2p\hash.c   \
+               ..\x2p\str.c    \
+               ..\x2p\util.c   \
+               ..\x2p\walk.c
+
+CORE_NOCFG_H   =               \
+               ..\av.h         \
+               ..\cop.h        \
+               ..\cv.h         \
+               ..\dosish.h     \
+               ..\embed.h      \
+               ..\form.h       \
+               ..\gv.h         \
+               ..\handy.h      \
+               ..\hv.h         \
+               ..\iperlsys.h   \
+               ..\mg.h         \
+               ..\nostdio.h    \
+               ..\op.h         \
+               ..\opcode.h     \
+               ..\perl.h       \
+               ..\perlapi.h    \
+               ..\perlsdio.h   \
+               ..\perlsfio.h   \
+               ..\perly.h      \
+               ..\pp.h         \
+               ..\proto.h      \
+               ..\regexp.h     \
+               ..\scope.h      \
+               ..\sv.h         \
+               ..\thread.h     \
+               ..\unixish.h    \
+               ..\utf8.h       \
+               ..\util.h       \
+               ..\warnings.h   \
+               ..\XSUB.h       \
+               ..\EXTERN.h     \
+               ..\perlvars.h   \
+               ..\intrpvar.h   \
+               ..\thrdvar.h    \
+               
+CORE_H         = $(CORE_NOCFG_H) .\config.h
+
+DLL_OBJ                = $(DLL_SRC:.c=.obj)
+X2P_OBJ                = $(X2P_SRC:.c=.obj)
+
+DYNAMIC_EXT    = Socket IO Fcntl Opcode SDBM_File POSIX attrs Thread B re \
+               Data/Dumper Devel/Peek ByteLoader Devel/DProf File/Glob 
+               
+STATIC_EXT     = DynaLoader
+NONXS_EXT      = Errno
+
+DYNALOADER     = $(EXTDIR)\DynaLoader\DynaLoader
+SOCKET         = $(EXTDIR)\Socket\Socket
+FCNTL          = $(EXTDIR)\Fcntl\Fcntl
+OPCODE         = $(EXTDIR)\Opcode\Opcode
+SDBM_FILE      = $(EXTDIR)\SDBM_File\SDBM_File
+IO                     = $(EXTDIR)\IO\IO
+POSIX          = $(EXTDIR)\POSIX\POSIX
+ATTRS          = $(EXTDIR)\attrs\attrs
+THREAD         = $(EXTDIR)\Thread\Thread
+B                      = $(EXTDIR)\B\B
+RE                     = $(EXTDIR)\re\re
+DUMPER         = $(EXTDIR)\Data\Dumper\Dumper
+ERRNO          = $(EXTDIR)\Errno\Errno
+PEEK           = $(EXTDIR)\Devel\Peek\Peek
+BYTELOADER     = $(EXTDIR)\ByteLoader\ByteLoader
+DPROF          = $(EXTDIR)\Devel\DProf\DProf
+GLOB           = $(EXTDIR)\File\Glob\Glob
+
+EXTENSION_C    =               \
+               $(SOCKET).c     \
+               $(FCNTL).c      \
+               $(OPCODE).c     \
+               $(SDBM_FILE).c  \
+               $(IO).c         \
+               $(POSIX).c      \
+               $(ATTRS).c      \
+               $(THREAD).c     \
+               $(RE).c         \
+               $(DUMPER).c     \
+               $(PEEK).c       \
+               $(B).c          \
+               $(BYTELOADER).c \
+               $(DPROF).c      \
+               $(GLOB).c       
+
+POD2HTML       = $(PODDIR)\pod2html
+POD2MAN                = $(PODDIR)\pod2man
+POD2LATEX      = $(PODDIR)\pod2latex
+POD2TEXT       = $(PODDIR)\pod2text
+
+#
+# Top targets
+#
+
+all : .cleanoldfiles .\nwconfig.h $(CONFIGPM) $(NLM_NAME) $(EXTENSION_NLP) $(EXTENSION_NPM) $(TEST_NLMS) $(NETWARE_EXTNS)
+
+#------------------------------------------------------------
+
+..\config.sh : config.nw5 $(MINIPERL) config_sh.PL
+       $(MINIPERL) -I..\lib config_sh.PL $(NW_CFG_VARS) config.nw5 > ..\config.sh
+
+# this target is for when changes to the main config.sh happen
+# edit config.{b,v,g,w}c and make this target once for each supported
+# compiler (e.g. `dmake CCTYPE=BORLAND regen_config_h`)
+regen_config_h:
+       perl config_sh.PL $(NW_CFG_VARS) $(NW_CFGSH_TMPL) > ..\config.sh
+       cd ..
+       -del /f perl.exe
+       perl configpm
+       cd netware
+       -del /f $(NW_CFGH_TMPL)
+       -mkdir $(COREDIR)
+       -perl -I..\lib config_h.PL "INST_VER=$(INST_VER)"
+       rename config.h $(NW_CFGH_TMPL)
+
+$(CONFIGPM) : $(MINIPERL) ..\config.sh config_h.PL ..\minimod.pl
+       cd .. && miniperl configpm
+       if exist lib\* $(RCOPY) lib\*.* ..\lib\$(NULL)
+       $(XCOPY) ..\*.h $(COREDIR)\*.*
+       $(XCOPY) *.h $(COREDIR)\*.*
+       $(XCOPY) ..\ext\re\re.pm $(LIBDIR)\*.*
+       if exist include\* $(RCOPY) include $(COREDIR)\*.*
+       $(MINIPERL) -I..\lib config_h.PL "INST_VER=$(INST_VER)" \
+           || $(MAKE) /$(MAKEFLAGS) $(CONFIGPM)
+
+$(MINIPERL) : 
+       $(error)Please build $(MINIPERL) before continuing
+
+$(MINIMOD) : $(MINIPERL) ..\minimod.pl
+       cd .. && miniperl minimod.pl > lib\ExtUtils\Miniperl.pm
+
+..\x2p\a2p$(o) : ..\x2p\a2p.c
+       @echo $(MPKMESSAGE)...$(BLDMESG)...$@
+       @$(C_COMPILER) -I..\x2p $(NLM_INCLUDES) $(COMPLER_FLAGS) $(ADD_LOCDEFS) $(OBJOUT_FLAG)$@ $(ERROR_FLAG)$*.err ..\x2p\a2p.c
+
+..\x2p\hash$(o) : ..\x2p\hash.c
+       @echo $(MPKMESSAGE)...$(BLDMESG)...$@
+       @$(C_COMPILER) -I..\x2p  $(NLM_INCLUDES) $(COMPLER_FLAGS) $(ADD_LOCDEFS)  $(OBJOUT_FLAG)$@ $(ERROR_FLAG)$*.err ..\x2p\hash.c
+
+..\x2p\str$(o) : ..\x2p\str.c
+       @echo $(MPKMESSAGE)...$(BLDMESG)...$@
+       @$(C_COMPILER) -I..\x2p  $(NLM_INCLUDES) $(COMPLER_FLAGS) $(ADD_LOCDEFS) $(OBJOUT_FLAG)$@ $(ERROR_FLAG)$*.err ..\x2p\str.c
+
+..\x2p\util$(o) : ..\x2p\util.c
+       @echo $(MPKMESSAGE)...$(BLDMESG)...$@
+       @$(C_COMPILER) -I..\x2p  $(NLM_INCLUDES) $(COMPLER_FLAGS) $(ADD_LOCDEFS) $(OBJOUT_FLAG)$@ $(ERROR_FLAG)$*.err ..\x2p\util.c
+
+..\x2p\walk$(o) : ..\x2p\walk.c
+       @echo $(MPKMESSAGE)...$(BLDMESG)...$@
+       @$(C_COMPILER) -I..\x2p  $(NLM_INCLUDES) $(COMPLER_FLAGS) $(ADD_LOCDEFS) $(OBJOUT_FLAG)$@ $(ERROR_FLAG)$*.err ..\x2p\walk.c
+
+$(X2P) : $(MINIPERL) $(X2P_OBJ)
+       $(MINIPERL) ..\x2p\find2perl.PL
+       $(MINIPERL) ..\x2p\s2p.PL
+!ifdef USE_XDC
+       $(MPKTOOL) $(XDCFLAGS) $*.xdc
+!endif
+!ifdef WATCOM
+       @$(NLM_LINK) @<<$*.link
+ Form   Novell NLM 'Awk to Perl converter'
+ Name   $(X2P)
+  Option Quiet
+ Option Version = $(NLM_VERSION)
+ Option Copyright '$(COPYRIGHT)'
+ Option Caseexact
+ Option Map=$*.map, Verbose, screenname 'System Console'
+ Option Stack=32k
+ Option SYMFILE=$*.sym
+!ifdef USE_XDC
+ OPTION        XDCDATA=$*.xdc
+!endif
+ Option NoDefaultLibs
+ $(EXTRA_LINK_OPTION)
+!if "$(MAKE_TYPE)"=="Debug"
+   Debug novell
+   Debug codeview
+!endif
+LibPath $(LIBPATH)
+ $(BASE_LIBRARIES)
+ Module clib
+ $(BASE_IMPORT_FNS)
+ $(BASE_IMPORT_FILES)
+ $(ADD_IMPORT_FNS)
+Import @perl.imp
+ $(EXPORTS)
+ File   $(X2P_OBJ:.obj=,) .\$(BLDDIR)\clibstuf.obj
+<<KEEP
+!else
+!ifdef CODEWARRIOR     
+# Linker definitions and lining come here for CODEWARRIOR
+!endif
+!endif
+
+$(EXTDIR)\DynaLoader\dl_netware.xs: dl_netware.xs
+       copy dl_netware.xs $(EXTDIR)\DynaLoader\dl_netware.xs
+
+HEADERS :
+       @echo . . . . making stdio.h and string.h
+       @copy << stdio.h >\nul
+
+/*
+ * Copyright Â© 2001 Novell, Inc. All Rights Reserved.
+ *
+ * You may distribute under the terms of either the GNU General Public
+ * License or the Artistic License, as specified in the README file.
+ *
+ */
+
+/*
+ * FILENAME            :       stdio.h
+ * DESCRIPTION :       Generated header file, do not edit. See makefile.
+ *                  This header file causes the includer to use clibstuf.h
+ *                  The purpose of clibstuf is to make sure that Perl, cgi2perl and
+ *                  all the perl extension nlm's (*.NLP) use the Novell Netware CLIB versions
+ *                  of standard functions. This code loads up a whole bunch of function pointers
+ *                  to point at the standard CLIB functions.
+ * Author              :       HYAK
+ * Date                        :       January 2001.
+ *
+ */
+
+
+#ifndef __Stdio_H__
+#define __Stdio_H__
+
+
+#include "$(NLMSDKBASE)\INCLUDE\NLM\stdio.h"
+#include "clibsdio.h"
+
+
+#endif // __Stdio_H__
+
+<<
+       @copy stdio.h $(COREDIR)
+        
+       @copy << string.h >\nul
+
+/*
+ * Copyright Â© 2001 Novell, Inc. All Rights Reserved.
+ *
+ * You may distribute under the terms of either the GNU General Public
+ * License or the Artistic License, as specified in the README file.
+ *
+ */
+
+/*
+ * FILENAME            :       string.h
+ * DESCRIPTION :       Generated header file, do not edit. See makefile.
+ *                  This header file causes the includer to use clibstuf.h
+ *                  The purpose of clibstuf is to make sure that Perl, cgi2perl and
+ *                  all the perl extension nlm's (*.NLP) use the Novell Netware CLIB versions
+ *                  of standard functions. This code loads up a whole bunch of function pointers
+ *                  to point at the standard CLIB functions.
+ * Author              :       HYAK
+ * Date                        :       January 2001.
+ *
+ */
+
+
+#ifndef __String_H__
+#define __String_H__
+
+
+#include "$(NLMSDKBASE)\INCLUDE\NLM\string.h"
+#include "clibstr.h"
+
+
+#endif // __String_H__
+
+<<
+       @copy string.h $(COREDIR)
+
+
+$(NLM_NAME): MESSAGE HEADERS $(BLDDIR)\nul $(NLM_OBJ) $(NEWTARE_OBJ_DEP) $(PERL_IO_OBJ_DEP) $(PERL_LIB_OBJ_DEP) $(DLL_OBJ) .XDC $(PERLIMPLIB) $(EXT_MAIN_OBJ)
+       @echo======= Linking $@ at $(MAKEDIR)\$(BLDDIR) =======
+!ifdef WATCOM
+       @$(NLM_LINK) @<<$(BLDDIR)\$*.link
+ Form   Novell NLM '$(NLM_DESCRIPTION)'
+ Name   $(BUILT)
+ Option Quiet
+ Option Version = $(NLM_VERSION)
+ Option Copyright '$(COPYRIGHT)'
+ Option Caseexact
+ Option Map=$(BLDDIR)\$(NLM_NAME8).map, Verbose, screenname $(SCREEN)
+ Option Stack=1000
+!ifdef NLM_NAME8
+ Option SYMFILE=$(BLDDIR)\$(NLM_NAME8).sym
+!ifdef USE_XDC
+ OPTION        XDCDATA=$(BLDDIR)\$(NLM_NAME8).xdc
+!endif
+!else
+ Option SYMFILE=$(BLDDIR)\$(NLM_NAME).sym
+!ifdef USE_XDC
+ OPTION        XDCDATA=$(BLDDIR)\$(NLM_NAME).xdc
+!endif
+!endif
+ Option NoDefaultLibs
+ $(EXTRA_LINK_OPTION)
+!if "$(MAKE_TYPE)"=="Debug"
+   # Debug all
+   Debug novell
+   Debug codeview
+!endif
+LibPath $(LIBPATH)
+ $(BASE_LIBRARIES)
+ Module clib
+ $(BASE_IMPORT_FNS)
+ $(BASE_IMPORT_FILES)
+ $(ADD_IMPORT_FNS)
+Import @perl.imp
+ $(EXPORTS)
+ File   $(NEWTARE_OBJ_DEP:.obj=.obj,) $(NLM_OBJ:.obj=.obj,) $(PERL_IO_OBJ_DEP:.obj=.obj,) $(PERL_LIB_OBJ_DEP:.obj=.obj,) $(DLL_OBJ:.obj=.obj,)
+<<KEEP
+!else
+!ifdef CODEWARRIOR     
+# Linker definitions and lining come here for CODEWARRIOR
+!endif
+!endif
+       copy ..\win32\splittree.pl .. 
+       $(MINIPERL) -I..\lib ..\splittree.pl "../LIB" $(AUTODIR)
+
+
+!if "$(MAKE_TYPE)"=="Debug"
+!ifdef NLM_NAME8
+       .\bat\cvpack $(BLDDIR)\$(NLM_NAME8).sym
+!else
+       .\bat\cvpack $(BLDDIR)\$(NLM_NAME).sym
+!endif
+!endif
+
+       @echo======= Finished building $(BUILT).
+# Create the debug\release directory if not existing
+$(BLDDIR)\nul:
+       @echo . . . . mkdir $(BLDDIR)
+       @mkdir $(BLDDIR)
+
+MESSAGE: 
+       @echo======= $(MAKE_ACTION)ing $(NLM_NAME) at $(MAKEDIR)\$(BLDDIR) ======= 
+
+.XDC:
+!ifdef USE_XDC
+        @echo======= Creating XDC file
+!ifdef NLM_NAME8
+        $(MPKTOOL) $(XDCFLAGS) $(BLDDIR)\$(NLM_NAME8).xdc
+!else
+        $(MPKTOOL) $(XDCFLAGS) $(BLDDIR)\$(NLM_NAME).xdc
+!endif
+!endif
+
+$(PERLIMPLIB): perllib.def
+       $(NLM_LIB) -def:perllib.def -out:$(PERLIMPLIB)
+       $(XCOPY) $(PERLIMPLIB) $(COREDIR)
+
+perllib.def : $(MINIPERL) $(CONFIGPM) ..\global.sym ..\pp.sym ..\makedef.pl
+       $(MINIPERL) -w ..\makedef.pl PLATFORM=netware FILETYPE=def $(BS_CFLAGS) $(DEFINES) $(ADD_BUILDOPT) \
+           CCTYPE=$(CCTYPE) > perllib.def
+       $(MINIPERL) -w ..\makedef.pl PLATFORM=netware FILETYPE=imp $(BS_CFLAGS) $(DEFINES) $(ADD_BUILDOPT) \
+           CCTYPE=$(CCTYPE) > perl.imp
+
+$(DLL_OBJ) : $(DYNALOADER).c $(CORE_H) $(EXTDIR)\DynaLoader\dlutils.c
+       @echo $(MPKMESSAGE)...$(BLDMESG)...$@
+       @$(C_COMPILER) @<<$(BLDDIR)\$(*F).options 
+       $(NLM_INCLUDES) -I$(EXTDIR)\DynaLoader\ $(COMPLER_FLAGS) $(ADD_LOCDEFS) $(OBJOUT_FLAG)$@ $(ERROR_FLAG)$(BLDDIR)\$(*F).err $(EXTDIR)\DynaLoader\$(*F).c
+<<KEEP
+
+$(DYNALOADER).c : $(MINIPERL) $(EXTDIR)\DynaLoader\dl_netware.xs $(CONFIGPM)
+       if not exist $(AUTODIR) mkdir $(AUTODIR)
+       cd $(EXTDIR)\$(*B)
+       ..\$(MINIPERL) -I..\..\lib $(*B)_pm.PL
+       ..\$(MINIPERL) -I..\..\lib XSLoader_pm.PL
+       cd ..\..\netware
+       $(XCOPY) $(EXTDIR)\$(*B)\$(*B).pm $(LIBDIR)\$(NULL)
+       $(XCOPY) $(EXTDIR)\$(*B)\XSLoader.pm $(LIBDIR)\$(NULL)
+       cd $(EXTDIR)\$(*B)
+       $(XSUBPP) dl_netware.xs > $(*B).c
+       cd ..\..\netware
+
+$(PERL_LIB_OBJ_DEP) : $(NW_HOST_H_FILES) $(*F).c
+       @echo $(MPKMESSAGE)...$(BLDMESG)...$@
+       @$(CPP_COMPILER) @<<$(BLDDIR)\$(*F).options 
+       -I.. $(NLM_INCLUDES) $(COMPLER_FLAGS) $(ADD_LOCDEFS) $(OBJOUT_FLAG)$@ $(ERROR_FLAG)$*.err $(*F).c
+<<KEEP
+
+$(PERL_IO_OBJ_DEP) : ..\$(*F).c
+       @echo $(MPKMESSAGE) $(BLDMESG) $@
+       @$(C_COMPILER) @<<$(BLDDIR)\$(*F).options 
+       $(NLM_INCLUDES) $(COMPLER_FLAGS) $(ADD_LOCDEFS) $(OBJOUT_FLAG)$@ $(ERROR_FLAG)$*.err ..\$(*F).c
+<<KEEP
+
+$(NLM_OBJ)     : ..\$(*F).c
+       @echo $(MPKMESSAGE) $(BLDMESG) $@
+       @$(C_COMPILER) @<<$(BLDDIR)\$(*F).options 
+       $(NLM_INCLUDES) $(COMPLER_FLAGS) $(ADD_LOCDEFS) $(OBJOUT_FLAG)$@ $(ERROR_FLAG)$*.err ..\$(*F).c
+<<KEEP
+
+$(NEWTARE_OBJ_DEP) : $(NW_H_FILES) $(NW_HOST_H_FILES) $(*F).c
+       @echo $(MPKMESSAGE) $(BLDMESG) $@
+       @$(C_COMPILER) @<<$(BLDDIR)\$(*F).options 
+       $(NLM_INCLUDES) $(COMPLER_FLAGS) $(ADD_LOCDEFS) $(OBJOUT_FLAG)$@ $(ERROR_FLAG)$*.err $(*F).c
+<<KEEP
+
+$(EXT_MAIN_OBJ) : $(CLIB_H_FILES)
+       @echo $(MPKMESSAGE) $(BLDMESG) $@
+       @$(C_COMPILER) @<<$(BLDDIR)\$(*F).options
+       $(NLM_INCLUDES) $(COMPLER_FLAGS) $(ADD_LOCDEFS) $(OBJOUT_FLAG)$@ $(ERROR_FLAG)$*.err $(*F).c
+<<KEEP
+       $(NLM_LIB) $@ $(NLMIMPORTS)\prelude.obj -out:$*.lib
+       @copy $*.lib $(COREDIR)
+
+# Delete any files that might have got created during building miniperl.exe
+# config.sh will definitely be created
+# COREDIR might have got created
+.cleanoldfiles :
+       -del ..\config.sh
+       -del .\Main.obj
+       -del .\Main.lib
+       -rmdir /s /q $(AUTODIR)
+       -rmdir /s /q $(COREDIR)
+
+.\nwconfig.h : $(NW_CFGH_TMPL)
+       -del /f config.h
+       copy $(NW_CFGH_TMPL) config.h
+
+# REQUIRED WHEN WE INCLUDE CONFIGPM OR REGEN_CONFIG - sgp
+#..\nwconfig.sh : config.nw5 $(MINIPERL) config_sh.PL
+#      $(MINIPERL) -I..\lib config_sh.PL $(NW_CFG_VARS) config.nw5 > ..\config.sh
+#      @pause
+#      cd ..
+#      del config.sh
+#      rename nwconfig.sh config.sh
+#      cd netware
+
+config.nw5 : $(NW_CFGSH_TMPL)
+       copy $(NW_CFGSH_TMPL) config.nw5
+
+$(SOCKET_NLP): $(NLM_NAME) $(SOCKET).xs
+       cd $(EXTDIR)\$(*B)
+       ..\..\miniperl -I..\..\lib Makefile.PL INSTALLDIRS=perl
+       $(MAKE)
+       cd ..\..\netware
+
+$(FCNTL_NLP):
+       cd $(EXTDIR)\$(*B)
+       ..\..\miniperl -I..\..\lib Makefile.PL INSTALLDIRS=perl
+       $(MAKE)
+       cd ..\..\netware
+
+$(IO_NLP):
+       cd $(EXTDIR)\$(*B)
+       ..\..\miniperl -I..\..\lib Makefile.PL INSTALLDIRS=perl
+       $(MAKE)
+       cd ..\..\netware
+
+$(OPCODE_NLP):
+       cd $(EXTDIR)\$(*B)
+       ..\..\miniperl -I..\..\lib Makefile.PL INSTALLDIRS=perl
+       $(MAKE)
+       cd ..\..\netware
+
+$(B_NLP):
+       cd $(EXTDIR)\$(*B)
+       ..\..\miniperl -I..\..\lib Makefile.PL INSTALLDIRS=perl
+       $(MAKE)
+       cd ..\..\netware
+
+$(DUMPER_NLP):
+       cd $(EXTDIR)\Data\$(*B)
+       ..\..\..\miniperl -I..\..\..\lib Makefile.PL INSTALLDIRS=perl
+       $(MAKE)
+       cd ..\..\..\netware
+
+$(PEEK_NLP):
+       cd $(EXTDIR)\Devel\$(*B)
+       ..\..\..\miniperl -I..\..\..\lib Makefile.PL INSTALLDIRS=perl
+       $(MAKE)
+       cd ..\..\..\netware
+
+$(RE_NLP):
+       cd $(EXTDIR)\$(*B)
+       ..\..\miniperl -I..\..\lib Makefile.PL INSTALLDIRS=perl
+       $(MAKE)
+       cd ..\..\netware
+
+$(BYTELOADER_NLP):
+       cd $(EXTDIR)\$(*B)
+       ..\..\miniperl -I..\..\lib Makefile.PL INSTALLDIRS=perl
+       $(MAKE)
+       cd ..\..\netware
+
+$(DPROF_NLP):
+       cd $(EXTDIR)\Devel\$(*B)
+       ..\..\..\miniperl -I..\..\..\lib Makefile.PL INSTALLDIRS=perl
+       $(MAKE)
+       cd ..\..\..\netware
+
+$(GLOB_NLP):
+       cd $(EXTDIR)\File\$(*B)
+       ..\..\..\miniperl -I..\..\..\lib Makefile.PL INSTALLDIRS=perl
+       $(MAKE)
+       cd ..\..\..\netware
+
+$(POSIX_NLP):
+       cd $(EXTDIR)\$(*B)
+       ..\..\miniperl -I..\..\lib Makefile.PL INSTALLDIRS=perl
+       $(MAKE)
+       cd ..\..\netware
+
+$(THREAD_NLP):
+       cd $(EXTDIR)\$(*B)
+       ..\..\miniperl -I..\..\lib Makefile.PL INSTALLDIRS=perl
+       $(MAKE)
+       cd ..\..\netware
+
+$(ATTRS_NLP):
+       cd $(EXTDIR)\$(*B)
+       ..\..\miniperl -I..\..\lib Makefile.PL INSTALLDIRS=perl
+       $(MAKE)
+       cd ..\..\netware
+
+$(SDBM_FILE_NLP):
+       cd $(EXTDIR)\$(*B)
+       ..\..\miniperl -I..\..\lib Makefile.PL INSTALLDIRS=perl
+       $(MAKE)
+       cd ..\..\netware
+
+$(ERRNO_PM_NW):
+       cd $(EXTDIR)\$(*B)
+       ..\..\miniperl -I..\..\lib Makefile.PL INSTALLDIRS=perl
+       $(MAKE)
+       cd ..\..\netware
+
+$(ECHO_SRC_OBJ): $*.c
+       @echo $(MPKMESSAGE) $(BLDMESG) $@
+       @$(C_COMPILER) @<<$*.options 
+       $(NLM_INCLUDES) $(COMPLER_FLAGS) $(ADD_LOCDEFS) $(OBJOUT_FLAG)$@ $(ERROR_FLAG)$*.err $*.c
+<<KEEP
+
+$(ECHO_NLM): $(ECHO_SRC_OBJ)
+       @echo======= Linking $@ =======
+!ifdef USE_XDC
+       $(MPKTOOL) $(XDCFLAGS) $*.xdc
+!endif
+!ifdef WATCOM
+       @$(NLM_LINK) @<<$*.link
+ Form   Novell NLM 'DOS echo emulation for Perl Testing' Name $@ 
+ Option Quiet Option Version = $(NLM_VERSION) Option Copyright '$(COPYRIGHT)' Option Caseexact Option Map=$*.map, Verbose, screenname 'System Console' Option Stack=1000 Option SYMFILE=$*.sym  Option NoDefaultLibs
+!ifdef USE_XDC
+ OPTION        XDCDATA=$*.xdc
+!endif
+ $(EXTRA_LINK_OPTION)
+!if "$(MAKE_TYPE)"=="Debug"
+   Debug novell
+   Debug codeview
+!endif
+LibPath $(LIBPATH)
+ $(BASE_LIBRARIES) Module clib $(BASE_IMPORT_FNS) $(BASE_IMPORT_FILES) $(ADD_IMPORT_FNS)
+Import @perl.imp
+ $(EXPORTS)
+ File   $(ECHO_SRC_OBJ:.obj=.obj,) .\$(BLDDIR)\clibstuf.obj
+<<KEEP
+!else
+!ifdef CODEWARRIOR     
+# Linker definitions and lining come here for CODEWARRIOR
+!endif
+!endif
+       @echo======= Linking Complete =======
+
+$(TYPE_SRC_OBJ): $*.c
+       @echo $(MPKMESSAGE) $(BLDMESG) $@
+       @$(C_COMPILER) @<<$*.options 
+       $(NLM_INCLUDES) $(COMPLER_FLAGS) $(ADD_LOCDEFS) $(OBJOUT_FLAG)$@ $(ERROR_FLAG)$*.err $*.c
+<<KEEP
+
+$(TYPE_NLM): $(TYPE_SRC_OBJ)
+       @echo======= Linking $@ =======
+!ifdef USE_XDC
+       $(MPKTOOL) $(XDCFLAGS) $*.xdc
+!endif
+!ifdef WATCOM
+       @$(NLM_LINK) @<<$*.link
+ Form   Novell NLM 'DOS type emulation for Perl Testing' Name $@ 
+ Option Quiet Option Version = $(NLM_VERSION) Option Copyright '$(COPYRIGHT)' Option Caseexact Option Map=$*.map, Verbose, screenname 'System Console' Option Stack=1000 Option SYMFILE=$*.sym
+!ifdef USE_XDC
+ OPTION        XDCDATA=$*.xdc
+!endif
+ Option NoDefaultLibs
+ $(EXTRA_LINK_OPTION)
+!if "$(MAKE_TYPE)"=="Debug"
+   Debug novell
+   Debug codeview
+!endif
+LibPath $(LIBPATH)
+ $(BASE_LIBRARIES) Module clib $(BASE_IMPORT_FNS) $(BASE_IMPORT_FILES) $(ADD_IMPORT_FNS)
+Import @perl.imp
+ $(EXPORTS)
+ File   $(TYPE_SRC_OBJ:.obj=.obj,) .\$(BLDDIR)\clibstuf.obj
+<<KEEP
+!else
+!ifdef CODEWARRIOR     
+# Linker definitions and lining come here for CODEWARRIOR
+!endif
+!endif
+       @echo======= Linking Complete =======
+
+# Build NetWare specific extensions
+$(CGI2PERL_NLP):
+!if "$(NW_EXTNS)"=="yes"
+       cd $(*B)
+       ..\..\miniperl -I..\..\lib Makefile.PL INSTALLDIRS=perl
+       $(MAKE)
+       cd ..\..\netware
+!endif
+
+$(PERL2UCS_NLP):
+!if "$(NW_EXTNS)"=="yes"
+       cd $(EXTDIR)\$(*B)
+       ..\..\miniperl -I..\..\lib Makefile.PL INSTALLDIRS=perl
+       $(MAKE)
+       cd ..\..\netware
+!endif
+
+nwclean:
+       -rmdir /s /q $(REL_DIR) || rmdir /s $(REL_DIR)
+       -rmdir /s /q $(DEB_DIR) || rmdir /s $(DEB_DIR)
+       @if exist .\stdio.h del .\stdio.h
+       @if exist .\string.h del .\string.h
+       @if exist .\Main.obj del .\Main.obj
+       @if exist .\Main.lib del .\Main.lib
+       cd testnlm\echo
+       -del *.obj *.map *.link *.options *.nlm *.sym *.xdc *.err
+       cd ..\type
+       -del *.obj *.map *.link *.options *.nlm *.sym *.xdc *.err
+       cd ..\..\
+
+utils: $(BLDDIR)\$(NLM_NAME8).$(NLM_EXT) $(X2P)
+       cd ..\utils
+       $(MAKE) PERL=$(MINIPERL)
+       cd ..\pod
+       copy ..\README.amiga .\perlamiga.pod
+       copy ..\README.cygwin .\perlcygwin.pod
+       copy ..\README.dos .\perldos.pod
+       copy ..\README.hpux .\perlhpux.pod
+#      copy ..\README.machten .\perlmachten.pod
+       copy ..\README.os2 .\perlos2.pod
+       copy ..\vms\perlvms.pod .\perlvms.pod
+       copy ..\README.win32 .\perlwin32.pod
+       copy ..\README.netware .\perlnw5.pod
+       $(MAKE) -f ..\win32\pod.mak converters
+       cd ..\netware
+       $(MINIPERL) $(PL2BAT) $(UTILS)
+
+distclean: clean nwclean
+       -del /f $(PERLIMPLIB) ..\miniperl.lib $(MINIMOD)
+       -del /f *.def *.map
+       -del /f $(EXTENSION_C) $(DYNALOADER).c $(ERRNO).pm
+       -del /f $(EXTDIR)\DynaLoader\dl_netware.xs
+       -del /f $(LIBDIR)\.exists $(LIBDIR)\attrs.pm $(LIBDIR)\DynaLoader.pm
+       -del /f $(LIBDIR)\XSLoader.pm
+       -del /f $(LIBDIR)\Fcntl.pm $(LIBDIR)\IO.pm $(LIBDIR)\Opcode.pm
+       -del /f $(LIBDIR)\ops.pm $(LIBDIR)\Safe.pm $(LIBDIR)\Thread.pm
+       -del /f $(LIBDIR)\SDBM_File.pm $(LIBDIR)\Socket.pm $(LIBDIR)\POSIX.pm
+       -del /f $(LIBDIR)\B.pm $(LIBDIR)\O.pm $(LIBDIR)\re.pm
+       -del /f $(LIBDIR)\Data\Dumper.pm $(LIBDIR)\ByteLoader.pm
+       -del /f $(LIBDIR)\Devel\Peek.pm $(LIBDIR)\Devel\DProf.pm
+       -del /f $(LIBDIR)\File\Glob.pm
+       -rmdir /s /q $(LIBDIR)\IO || rmdir /s $(LIBDIR)\IO
+       -rmdir /s /q $(LIBDIR)\Thread || rmdir /s $(LIBDIR)\Thread
+       -rmdir /s /q $(LIBDIR)\B || rmdir /s $(LIBDIR)\B
+       -rmdir /s /q $(LIBDIR)\Data || rmdir /s $(LIBDIR)\Data
+       -del /f $(PODDIR)\*.html
+       -del /f $(PODDIR)\*.bat
+       cd ..\utils
+       -del /f h2ph splain perlbug pl2pm c2ph h2xs perldoc dprofpp
+       -del /f *.bat
+       cd ..\netware
+       cd ..\x2p
+       -del /f find2perl s2p
+       -del /f *.bat
+       -del *.obj *.map *.link *.xdc *.err
+       cd ..\netware
+       -del /f ..\config.sh ..\splittree.pl dlutils.c config.h.new
+       -del /f $(CONFIGPM)
+       -del /f bin\*.bat
+       cd $(EXTDIR)
+       -del /s *.lib *.def *.map *.pdb *.bs Makefile *$(o) pm_to_blib *.xdc *.err
+       cd ..\netware
+!if "$(NW_EXTNS)"=="yes"
+       cd cgi2perl
+       -del *.obj *.bs Makefile *$(o) *.c pm_to_blib *.xdc *.err
+       cd ..
+!endif
+       -rmdir /s /q $(AUTODIR) || rmdir /s $(AUTODIR)
+       -rmdir /s /q $(COREDIR) || rmdir /s $(COREDIR)
+       -del ..\config.sh
+
+installwin:
+       $(MINIPERL) -I..\lib ..\installperl
+
+install : utils installwin
+
+installnw:
+       $(MINIPERL) -I..\lib ..\installperl -netware
+
+nwinstall: utils installnw
+
+inst_lib : $(CONFIGPM)
+       copy ..\win32\splittree.pl .. 
+       $(MINIPERL) -I..\lib ..\splittree.pl "../LIB" $(AUTODIR)
+       $(RCOPY) ..\lib $(INST_LIB)\*.*
+
+clean : 
+       -@erase miniperlmain$(o)
+       -@erase /f config.h
+       -@erase $(DLL_OBJ)
+       -@erase ..\*$(o) ..\*.lib ..\*.exp *$(o) *.lib *.exp *.res
+       -@erase ..\t\*.exe ..\t\*.dll ..\t\*.bat
+       -@erase ..\x2p\*.nlm ..\x2p\*.bat
+
diff --git a/NetWare/NWTInfo.c b/NetWare/NWTInfo.c
new file mode 100644 (file)
index 0000000..4180fa7
--- /dev/null
@@ -0,0 +1,720 @@
+
+/*
+ * Copyright Â© 2001 Novell, Inc. All Rights Reserved.
+ *
+ * You may distribute under the terms of either the GNU General Public
+ * License or the Artistic License, as specified in the README file.
+ *
+ */
+
+/*
+ * FILENAME            :       NWTInfo.c
+ * DESCRIPTION :       Thread-local storage for Perl.
+ *                                     The thread's information is stored in a hashed table that is based on
+ *                                     the lowest 5 bits of the current thread ID.
+ * Author              :       SGP, HYAK
+ * Date                        :       January 2001.
+ *
+ */
+
+
+
+#include "win32ish.h"          // For "BOOL", "TRUE" and "FALSE"
+#include "nwtinfo.h"
+
+#ifdef MPK_ON
+       #include <mpktypes.h>   
+       #include <mpkapis.h>
+#else
+       #include <nwsemaph.h>
+#endif //MPK_ON
+
+// Number of entries in the hashtable
+//
+#define NUM_ENTRIES 32  /* 2^5 */
+
+
+// macro to calculate the hash index for a given Thread ID
+//
+#define INDEXOF(tid) ((tid) & 0x1f)
+
+
+// Semaphore to control access to global linked list
+//
+#ifdef MPK_ON
+       static SEMAPHORE g_tinfoSem = NULL;
+       static SEMAPHORE g_tCtxSem = NULL;
+#else
+       static LONG g_tinfoSem = 0L;
+       static LONG g_tCtxSem = 0L;
+#endif //MPK_ON
+
+// Hash table of thread information structures
+//
+ThreadInfo* g_ThreadInfo[NUM_ENTRIES];
+ThreadContext* g_ThreadCtx;
+
+
+
+/*============================================================================================
+
+ Function              :       fnTerminateThreadInfo
+
+ Description   :       This function undoes fnInitializeThreadInfo; call once per NLM instance.
+
+ Parameters    :       None.
+
+ Returns               :       Boolean.
+
+==============================================================================================*/
+
+BOOL fnTerminateThreadInfo(void)
+{
+       int index = 0;
+
+       if (g_tinfoSem)
+       {
+               #ifdef MPK_ON
+                       kSemaphoreWait(g_tinfoSem);
+               #else
+                       WaitOnLocalSemaphore(g_tinfoSem);
+               #endif  //MPK_ON
+               for (index = 0; index < NUM_ENTRIES; index++)
+               {
+                       if (g_ThreadInfo[index] != NULL)
+                       {
+                               #ifdef MPK_ON
+                                       kSemaphoreSignal(g_tinfoSem);
+                               #else
+                                       SignalLocalSemaphore(g_tinfoSem);
+                               #endif  //MPK_ON
+                               return FALSE;
+                       }
+               }
+               #ifdef MPK_ON
+                       kSemaphoreFree(g_tinfoSem);
+                       g_tinfoSem = NULL;
+               #else
+                       CloseLocalSemaphore(g_tinfoSem);
+                       g_tinfoSem = 0;
+               #endif  //MPK_ON
+       }
+
+       return TRUE;
+}
+
+
+/*============================================================================================
+
+ Function              :       fnInitializeThreadInfo
+
+ Description   :       Initializes the global ThreadInfo hashtable and semaphore.
+                                       Call once per NLM instance
+
+ Parameters    :       None.
+
+ Returns               :       Nothing.
+
+==============================================================================================*/
+
+void fnInitializeThreadInfo(void)
+{
+       int index = 0;
+
+       if (g_tinfoSem)
+               return;
+
+       #ifdef MPK_ON
+               g_tinfoSem = kSemaphoreAlloc((BYTE *)"threadInfo", 1);
+       #else
+               g_tinfoSem = OpenLocalSemaphore(1);
+       #endif  //MPK_ON
+       
+
+       for (index = 0; index < NUM_ENTRIES; index++)
+               g_ThreadInfo[index] = NULL;
+
+       return;
+}
+
+
+/*============================================================================================
+
+ Function              :       fnRegisterWithThreadTable
+
+ Description   :       This function registers/adds a new thread with the thread table.
+
+ Parameters    :       None.
+
+ Returns               :       Boolean.
+
+==============================================================================================*/
+
+BOOL fnRegisterWithThreadTable(void)
+{
+       ThreadInfo* tinfo = NULL;
+
+       #ifdef MPK_ON
+               tinfo = fnAddThreadInfo(labs((int)kCurrentThread()));
+       #else
+               tinfo = fnAddThreadInfo(GetThreadID());
+       #endif  //MPK_ON
+       
+       if (!tinfo)
+               return FALSE;
+       else
+               return TRUE;
+}
+
+
+/*============================================================================================
+
+ Function              :       fnUnregisterWithThreadTable
+
+ Description   :       This function unregisters/removes a thread from the thread table.
+
+ Parameters    :       None.
+
+ Returns               :       Boolean.
+
+==============================================================================================*/
+
+BOOL fnUnregisterWithThreadTable(void)
+{
+       #ifdef MPK_ON
+               return fnRemoveThreadInfo(labs((int)kCurrentThread()));
+       #else
+               return fnRemoveThreadInfo(GetThreadID());
+       #endif  //MPK_ON
+}
+
+
+/*============================================================================================
+
+ Function              :       fnAddThreadInfo
+
+ Description   :       Adds a new ThreadInfo for the requested thread.
+
+ Parameters    :       tid     (IN)    -       ID of the thread.
+
+ Returns               :       Pointer to the ThreadInfo Structure.
+
+==============================================================================================*/
+
+ThreadInfo* fnAddThreadInfo(int tid)
+{
+       ThreadInfo* tip = NULL;
+       int index = 0;
+
+       if (g_tinfoSem)
+       {
+               #ifdef MPK_ON
+                       kSemaphoreWait(g_tinfoSem);
+               #else
+                       WaitOnLocalSemaphore(g_tinfoSem);
+               #endif  //MPK_ON
+       }
+
+       // Add a new one to the beginning of the hash entry
+       //
+       tip = (ThreadInfo *) malloc(sizeof(ThreadInfo));
+       if (tip == NULL)
+       {  
+               if (g_tinfoSem)
+               {
+                       #ifdef MPK_ON
+                               kSemaphoreSignal(g_tinfoSem);
+                       #else
+                               SignalLocalSemaphore(g_tinfoSem);
+                       #endif  //MPK_ON
+               }
+               return NULL;
+       }
+       index = INDEXOF(tid);     // just take the bottom five bits
+       tip->next            =  g_ThreadInfo[index];
+       tip->tid             =  tid;
+       tip->m_dontTouchHashLists = FALSE;
+       tip->m_allocList = NULL;
+
+       g_ThreadInfo [index] =  tip;
+       if (g_tinfoSem)
+       {
+               #ifdef MPK_ON
+                       kSemaphoreSignal(g_tinfoSem);
+               #else
+                       SignalLocalSemaphore(g_tinfoSem);
+               #endif  //MPK_ON
+       }
+
+       return tip;
+}
+
+
+/*============================================================================================
+
+ Function              :       fnRemoveThreadInfo
+
+ Description   :       Frees the specified thread info structure and removes it from the
+                                       global linked list.
+
+ Parameters    :       tid     (IN)    -       ID of the thread.
+
+ Returns               :       Boolean.
+
+==============================================================================================*/
+
+BOOL fnRemoveThreadInfo(int tid)
+{
+       ThreadInfo* tip = NULL;
+       ThreadInfo* prevt = NULL;
+       int index = INDEXOF(tid);     // just take the bottom five bits
+
+       if (g_tinfoSem)
+       {
+               #ifdef MPK_ON
+                       kSemaphoreWait(g_tinfoSem);
+               #else
+                       WaitOnLocalSemaphore(g_tinfoSem);
+               #endif  //MPK_ON
+       }
+
+       for (tip = g_ThreadInfo[index]; tip != NULL; tip = tip->next)
+       {
+               if (tip->tid == tid)
+               {
+                       if (prevt == NULL)
+                               g_ThreadInfo[index] = tip->next;
+                       else
+                               prevt->next = tip->next;
+
+                       free(tip);
+                       tip=NULL;
+                       if (g_tinfoSem)
+                       {
+                               #ifdef MPK_ON
+                                       kSemaphoreSignal(g_tinfoSem);
+                               #else
+                                       SignalLocalSemaphore(g_tinfoSem);
+                               #endif  //MPK_ON
+                       }
+
+                       return TRUE;
+               }
+               prevt = tip;
+       }
+
+       if (g_tinfoSem)
+       {
+               #ifdef MPK_ON
+                       kSemaphoreSignal(g_tinfoSem);
+               #else
+                       SignalLocalSemaphore(g_tinfoSem);
+               #endif  //MPK_ON
+       }
+
+       return FALSE;       // entry not found
+}
+
+
+/*============================================================================================
+
+ Function              :       fnGetThreadInfo
+
+ Description   :       Returns the thread info for the given thread ID or NULL if not successful.
+
+ Parameters    :       tid     (IN)    -       ID of the thread.
+
+ Returns               :       Pointer to the ThreadInfo Structure.
+
+==============================================================================================*/
+
+ThreadInfo* fnGetThreadInfo(int tid)
+{
+       ThreadInfo*  tip;   
+       int index = INDEXOF(tid);     // just take the bottom five bits
+
+       if (g_tinfoSem) {
+               #ifdef MPK_ON
+                       kSemaphoreWait(g_tinfoSem);
+               #else
+                       WaitOnLocalSemaphore(g_tinfoSem);
+               #endif  //MPK_ON
+       }
+
+       // see if this is already in the table at the index'th offset
+       //
+       for (tip = g_ThreadInfo[index]; tip != NULL; tip = tip->next)
+       {
+               if (tip->tid == tid)
+               {
+                       if (g_tinfoSem)
+                       {
+                               #ifdef MPK_ON
+                                       kSemaphoreSignal(g_tinfoSem);
+                               #else
+                                       SignalLocalSemaphore(g_tinfoSem);
+                               #endif  //MPK_ON
+                       }
+                       return tip;
+               }
+       }
+
+       if (g_tinfoSem)
+       {
+               #ifdef MPK_ON
+                       kSemaphoreSignal(g_tinfoSem);
+               #else
+                       SignalLocalSemaphore(g_tinfoSem);
+               #endif  //MPK_ON
+       }
+
+       return NULL;
+}
+
+BOOL fnInsertHashListAddrs(void *addrs, BOOL dontTouchHashList)
+{
+       ThreadInfo*  tip;   
+       int index,tid;
+
+       if (g_tinfoSem) 
+       {
+               #ifdef MPK_ON
+                       kSemaphoreWait(g_tinfoSem);
+               #else
+                       WaitOnLocalSemaphore(g_tinfoSem);
+               #endif  //MPK_ON
+       }
+
+       #ifdef MPK_ON
+               tid=index = abs(kCurrentThread());
+       #else
+               tid=index = GetThreadID();
+       #endif  //MPK_ON
+
+       index = INDEXOF(index);     // just take the bottom five bits   
+
+       // see if this is already in the table at the index'th offset
+       //
+       for (tip = g_ThreadInfo[index]; tip != NULL; tip = tip->next)
+       {
+               if (tip->tid == tid)
+               {
+                       if (g_tinfoSem)
+                       {
+                               #ifdef MPK_ON
+                                       kSemaphoreSignal(g_tinfoSem);
+                               #else
+                                       SignalLocalSemaphore(g_tinfoSem);
+                               #endif  //MPK_ON
+                       }
+                       tip->m_allocList = addrs;
+                       tip->m_dontTouchHashLists = dontTouchHashList;
+                       return TRUE;
+               }
+       }
+
+       if (g_tinfoSem)
+       {
+               #ifdef MPK_ON
+                       kSemaphoreSignal(g_tinfoSem);
+               #else
+                       SignalLocalSemaphore(g_tinfoSem);
+               #endif  //MPK_ON
+       }
+
+       return FALSE;
+}
+
+BOOL fnGetHashListAddrs(void **addrs, BOOL *dontTouchHashList)
+{
+       ThreadInfo*  tip;   
+       int index,tid;   
+
+       if (g_tinfoSem) 
+       {
+               #ifdef MPK_ON
+                       kSemaphoreWait(g_tinfoSem);
+               #else
+                       WaitOnLocalSemaphore(g_tinfoSem);
+               #endif  //MPK_ON
+       }
+
+       #ifdef MPK_ON
+               tid=index = abs(kCurrentThread());
+       #else
+               tid=index = GetThreadID();
+       #endif  //MPK_ON
+
+       index = INDEXOF(index);     // just take the bottom five bits 
+
+       // see if this is already in the table at the index'th offset
+       //
+       for (tip = g_ThreadInfo[index]; tip != NULL; tip = tip->next)
+       {
+               if (tip->tid == tid)
+               {
+                       if (g_tinfoSem)
+                       {
+                               #ifdef MPK_ON
+                                       kSemaphoreSignal(g_tinfoSem);
+                               #else
+                                       SignalLocalSemaphore(g_tinfoSem);
+                               #endif  //MPK_ON
+                       }
+                       *addrs = tip->m_allocList;
+                       *dontTouchHashList = tip->m_dontTouchHashLists;
+                       return TRUE;
+               }
+       }
+
+       if (g_tinfoSem)
+       {
+               #ifdef MPK_ON
+                       kSemaphoreSignal(g_tinfoSem);
+               #else
+                       SignalLocalSemaphore(g_tinfoSem);
+               #endif  //MPK_ON
+       }
+
+       return FALSE;
+}
+
+
+/*============================================================================================
+
+ Function              :       fnInitializeThreadCtx
+
+ Description   :       Initialises the thread context.
+
+ Parameters    :       None.
+
+ Returns               :       Nothing.
+
+==============================================================================================*/
+
+long fnInitializeThreadCtx(void)
+{
+       int index = 0;
+       //long tid;
+
+       if (!g_tCtxSem) {
+               #ifdef MPK_ON
+                       g_tCtxSem = kSemaphoreAlloc((BYTE *)"threadCtx", 1);
+               #else
+                       g_tCtxSem = OpenLocalSemaphore(1);
+               #endif  //MPK_ON
+
+               g_ThreadCtx =NULL;
+       }
+
+       return 0l;
+}
+
+
+/*============================================================================================
+
+ Function              :       fnAddThreadCtx
+
+ Description   :       Add a new thread context.
+
+ Parameters    :       lTLSIndex       (IN)    -       Index
+                                       t       (IN)    -       void pointer.
+
+ Returns               :       Pointer to ThreadContext structure.
+
+==============================================================================================*/
+
+ThreadContext* fnAddThreadCtx(long lTLSIndex, void *t)
+{
+       ThreadContext* tip = NULL;
+       ThreadContext* temp = NULL;
+
+       if (g_tCtxSem)
+       {
+               #ifdef MPK_ON
+                       kSemaphoreWait(g_tCtxSem);
+               #else
+                       WaitOnLocalSemaphore(g_tCtxSem);
+               #endif  //MPK_ON
+       }
+
+       // add a new one to the beginning of the list
+       //
+       tip = (ThreadContext *) malloc(sizeof(ThreadContext));
+       if (tip == NULL)
+       {  
+               if (g_tCtxSem)
+               {
+                       #ifdef MPK_ON
+                               kSemaphoreSignal(g_tCtxSem);
+                       #else
+                               SignalLocalSemaphore(g_tCtxSem);
+                       #endif  //MPK_ON
+               }
+               return NULL;
+       }
+
+       #ifdef MPK_ON
+               lTLSIndex = labs(kCurrentThread());
+       #else
+               lTLSIndex = GetThreadID();
+       #endif  //MPK_ON
+
+       tip->next            =  NULL;
+       tip->tid             =  lTLSIndex;
+       tip->tInfo                       =  t;
+
+       if(g_ThreadCtx==NULL) {
+               g_ThreadCtx = tip;
+       } else {
+               int count=0;
+               //Traverse to the end
+               temp = g_ThreadCtx;
+               while(temp->next != NULL)
+               {
+                       temp = temp->next;
+                       count++;
+               }
+               temp->next = tip;
+       }
+
+       if (g_tCtxSem)
+       {
+               #ifdef MPK_ON
+                       kSemaphoreSignal(g_tCtxSem);
+               #else
+                       SignalLocalSemaphore(g_tCtxSem);
+               #endif  //MPK_ON
+       }
+       return tip;
+}
+
+
+/*============================================================================================
+
+ Function              :       fnRemoveThreadCtx
+
+ Description   :       Removes a thread context.
+
+ Parameters    :       lTLSIndex       (IN)    -       Index
+
+ Returns               :       Boolean.
+
+==============================================================================================*/
+
+BOOL fnRemoveThreadCtx(long lTLSIndex)
+{
+       ThreadContext* tip = NULL;
+       ThreadContext* prevt = NULL;
+
+       if (g_tCtxSem)
+       {
+               #ifdef MPK_ON
+                       kSemaphoreWait(g_tCtxSem);
+               #else
+                       WaitOnLocalSemaphore(g_tCtxSem);
+               #endif  //MPK_ON
+       }
+
+       #ifdef MPK_ON
+               lTLSIndex = labs(kCurrentThread());
+       #else
+               lTLSIndex = GetThreadID();
+       #endif  //MPK_ON
+
+       tip = g_ThreadCtx;
+       while(tip) {
+               if (tip->tid == lTLSIndex) {
+                       if (prevt == NULL)
+                               g_ThreadCtx = tip->next;
+                       else
+                               prevt->next = tip->next;
+
+                       free(tip);
+                       tip=NULL;
+                       if (g_tCtxSem)
+                       {
+                               #ifdef MPK_ON
+                                       kSemaphoreSignal(g_tCtxSem);
+                               #else
+                                       SignalLocalSemaphore(g_tCtxSem);
+                               #endif  //MPK_ON
+                       }
+                       return TRUE;
+               }
+               prevt = tip;
+               tip = tip->next;
+       }
+
+       if (g_tCtxSem)
+       {
+               #ifdef MPK_ON
+                       kSemaphoreSignal(g_tCtxSem);
+               #else
+                       SignalLocalSemaphore(g_tCtxSem);
+               #endif  //MPK_ON
+       }
+
+       return FALSE;       // entry not found
+}
+
+
+/*============================================================================================
+
+ Function              :       fnGetThreadCtx
+
+ Description   :       Get a thread context.
+
+ Parameters    :       lTLSIndex       (IN)    -       Index
+
+ Returns               :       Nothing.
+
+==============================================================================================*/
+
+void* fnGetThreadCtx(long lTLSIndex)
+{
+       ThreadContext*  tip;   
+
+       if (g_tCtxSem) 
+       {
+               #ifdef MPK_ON
+                       kSemaphoreWait(g_tCtxSem);
+               #else
+                       WaitOnLocalSemaphore(g_tCtxSem);
+               #endif  //MPK_ON
+       }
+
+       #ifdef MPK_ON
+               lTLSIndex = labs(kCurrentThread());
+       #else
+               lTLSIndex = GetThreadID();
+       #endif  //MPK_ON
+
+       tip = g_ThreadCtx;
+       while(tip) {
+               if (tip->tid == lTLSIndex) {
+                       if (g_tCtxSem)
+                       {
+                               #ifdef MPK_ON
+                                       kSemaphoreSignal(g_tCtxSem);
+                               #else
+                                       SignalLocalSemaphore(g_tCtxSem);
+                               #endif  //MPK_ON
+                       }
+                       return (tip->tInfo);
+               }
+               tip=tip->next;
+       }
+
+       if (g_tCtxSem)
+       {
+               #ifdef MPK_ON
+                       kSemaphoreSignal(g_tCtxSem);
+               #else
+                       SignalLocalSemaphore(g_tCtxSem);
+               #endif  //MPK_ON
+       }
+
+       return NULL;
+}
+
diff --git a/NetWare/NWUtil.c b/NetWare/NWUtil.c
new file mode 100644 (file)
index 0000000..9cc5b5c
--- /dev/null
@@ -0,0 +1,826 @@
+
+/*
+ * Copyright Â© 2001 Novell, Inc. All Rights Reserved.
+ *
+ * You may distribute under the terms of either the GNU General Public
+ * License or the Artistic License, as specified in the README file.
+ *
+ */
+
+/*
+ * FILENAME            :       NWUtil.c
+ * DESCRIPTION :       Utility functions for NetWare implementation of Perl.
+ * Author              :       HYAK
+ * Date                        :       Januray 2001.
+ *
+ */
+
+
+
+#include "stdio.h"
+#include "string.h"
+
+#include <nwdsdefs.h>          // For "MAX_DN_BYTES"
+#include <malloc.h>                    // For "malloc" and "free"
+#include <stdlib.h>                    // For "getenv"
+#include <ctype.h>                     // For "isspace"
+
+#include <process.h>
+#include <unistd.h>
+#include <errno.h>
+#include <nwerrno.h>
+
+#include <nwlocale.h>
+#include <nwadv.h>
+
+#include "nwutil.h"
+
+
+#define TRUE   1
+#define FALSE  0
+
+
+/**
+  Global variables used for better token parsing. When these were absent,
+  token parsing was not correct when there were more number of arguments passed.
+  These are used in fnCommandLineParser, fnSkipToken and fnScanToken to get/return
+  the correct and updated pointer to the command line string.
+**/
+char *s1 = NULL;       // Used in fnScanToken.
+char *s2 = NULL;       // Used in fnSkipToken.
+
+
+
+
+/*============================================================================================
+
+ Function              :       fnSkipWhite
+
+ Description   :       This function skips the white space characters in the given string and
+                                       returns the resultant value.
+
+ Parameters    :       s       (IN)    -       Input string.
+
+ Returns               :       String.
+
+==============================================================================================*/
+
+char *fnSkipWhite(char *s)
+{
+       while (isspace(*s))
+               s++;
+       return s;
+}
+
+
+
+/*============================================================================================
+
+ Function              :       fnNwGetEnvironmentStr
+
+ Description   :       This function returns the NetWare environment string if available,
+                                       otherwise returns the supplied default value
+
+ Parameters    :       name                    (IN)    -       To hold the NetWare environment value.
+                                       defaultvalue    (IN)    -       Default value.
+
+
+ Returns               :       String.
+
+==============================================================================================*/
+
+char *fnNwGetEnvironmentStr(char *name, char *defaultvalue)
+{
+       char* ret = getenv(name);
+       if (ret == NULL)
+               ret = defaultvalue;
+       return ret;
+}
+
+
+
+/*============================================================================================
+
+ Function              :       fnCommandLineParser
+
+ Description   :       This function parses the command line into argc/argv style of
+                                       Number of params and array of params.
+
+ Parameters    :       pclp            (IN)    -       CommandLine structure.
+                                       commandLine     (IN)    -       CommandLine String.
+                                       preserverQuotes (IN)    -       Indicates whether to preserve/copy the quotes or not.
+
+ Returns               :       Nothing.
+
+==============================================================================================*/
+
+void fnCommandLineParser(PCOMMANDLINEPARSER pclp, char * commandLine, BOOL preserveQuotes)
+{
+       char *buffer = NULL;
+
+       int index = 0;
+       int do_delete = 1;
+       int i=0, j=0, k=0;
+
+
+       // +1 makes room for the terminating NULL
+       buffer = (char *) malloc((strlen(commandLine) + 1) * sizeof(char));
+       if (buffer == NULL)
+       {
+               pclp->m_isValid = FALSE;
+               return;
+       }
+
+       if (preserveQuotes)
+       {
+               // No I/O redirection nor quote processing if preserveQuotes
+
+               char *s = NULL;
+               char *sSkippedToken = NULL;
+
+
+               strcpy(buffer, commandLine);
+               s = buffer;
+               s = fnSkipWhite(s);             // Skip white spaces.
+
+               s2 = s; // Update the global pointer.
+
+
+               pclp->sSkippedToken = (char *) malloc(MAX_DN_BYTES * sizeof(char));
+               if(pclp->sSkippedToken == NULL)
+               {
+                       pclp->m_isValid = FALSE;
+                       return;
+               }
+
+               while (*s && pclp->m_isValid)
+               {
+/****
+// Commented since only one time malloc and free is enough as is done outside this while loop.
+// It is not required to do them everytime the execution comes into this while loop.
+// Still retained here. Remove this  once things are proved to be working fine to a good confident level,
+
+                       if(pclp->sSkippedToken)
+                       {
+                               free(pclp->sSkippedToken);
+                               pclp->sSkippedToken = NULL;
+                       }
+
+                       if(pclp->sSkippedToken == NULL)
+                       {
+                               pclp->sSkippedToken = (char *) malloc(MAX_DN_BYTES * sizeof(char));
+                               if(pclp->sSkippedToken == NULL)
+                               {
+                                       pclp->m_isValid = FALSE;
+                                       return;
+                               }
+                       }
+****/
+
+                       // Empty the string.
+                       strncpy(pclp->sSkippedToken, "", (MAX_DN_BYTES * sizeof(char)));
+
+                       // s is advanced by fnSkipToken
+                       pclp->sSkippedToken = fnSkipToken(s, pclp->sSkippedToken);      // Collect the next command-line argument.
+
+                       s2 = fnSkipWhite(s2);   // s2 is already updated by fnSkipToken.
+                       s = s2;         // Update the local pointer too.
+
+                       fnAppendArgument(pclp, pclp->sSkippedToken);    // Append the argument into an array.
+               }
+
+               if(pclp->sSkippedToken)
+               {
+                       free(pclp->sSkippedToken);
+                       pclp->sSkippedToken = NULL;
+               }
+       }
+       else
+       {
+               char *s = NULL;
+
+               strcpy(buffer, commandLine);
+               s = buffer;
+               s = fnSkipWhite(s);
+
+               s1 = s; // Update the global pointer.
+
+               while (*s && pclp->m_isValid)
+               {
+                       // s is advanced by fnScanToken
+                       // Check for I/O redirection here, *outside* of
+                       // fnScanToken(), so that quote-protected angle
+                       // brackets do NOT cause redirection.
+                       if (*s == '<')
+                       {
+                               s = fnSkipWhite(s+1); // get stdin redirection
+
+                               if(pclp->m_redirInName)
+                               {
+                                       free(pclp->m_redirInName);
+                                       pclp->m_redirInName = NULL;
+                               }
+
+                               if(pclp->m_redirInName == NULL)
+                               {
+                                       pclp->m_redirInName = (char *) malloc(MAX_DN_BYTES * sizeof(char));
+                                       if(pclp->m_redirInName == NULL)
+                                       {
+                                               pclp->m_isValid = FALSE;
+                                               return;
+                                       }
+                               }
+
+                               // Collect the next command-line argument.
+                               pclp->m_redirInName = fnScanToken(s, pclp->m_redirInName);
+
+                               s1 = fnSkipWhite(s1);   // s1 is already updated by fnScanToken.
+                               s = s1;         // Update the local pointer too.
+                       }
+                       else if (*s == '>')
+                       {
+                               s = fnSkipWhite(s+1); //get stdout redirection
+
+                               if(pclp->m_redirOutName)
+                               {
+                                       free(pclp->m_redirOutName);
+                                       pclp->m_redirOutName = NULL;
+                               }
+
+                               if(pclp->m_redirOutName == NULL)
+                               {
+                                       pclp->m_redirOutName = (char *) malloc(MAX_DN_BYTES * sizeof(char));
+                                       if(pclp->m_redirOutName == NULL)
+                                       {
+                                               pclp->m_isValid = FALSE;
+                                               return;
+                                       }
+                               }
+
+                               // Collect the next command-line argument.
+                               pclp->m_redirOutName = fnScanToken(s, pclp->m_redirOutName);
+
+                               s1 = fnSkipWhite(s1);   // s1 is already updated by fnScanToken.
+                               s = s1;         // Update the local pointer too.
+                       }
+                       else if (*s == '2' && s[1] == '>')
+                       {
+                               s = fnSkipWhite(s+2); // get stderr redirection
+
+                               if(pclp->m_redirErrName)
+                               {
+                                       free(pclp->m_redirErrName);
+                                       pclp->m_redirErrName = NULL;
+                               }
+
+                               if(pclp->m_redirErrName == NULL)
+                               {
+                                       pclp->m_redirErrName = (char *) malloc(MAX_DN_BYTES * sizeof(char));
+                                       if(pclp->m_redirErrName == NULL)
+                                       {
+                                               pclp->m_isValid = FALSE;
+                                               return;
+                                       }
+                               }
+
+                               // Collect the next command-line argument.
+                               pclp->m_redirErrName = fnScanToken(s, pclp->m_redirErrName);
+
+                               s1 = fnSkipWhite(s1);   // s1 is already updated by fnScanToken.
+                               s = s1;         // Update the local pointer too.
+                       }
+                       else if (*s == '&' && s[1] == '>')
+                       {
+                               s = fnSkipWhite(s+2); // get stdout+stderr redirection
+
+                               if(pclp->m_redirBothName)
+                               {
+                                       free(pclp->m_redirBothName);
+                                       pclp->m_redirBothName = NULL;
+                               }
+
+                               if(pclp->m_redirBothName == NULL)
+                               {
+                                       pclp->m_redirBothName = (char *) malloc(MAX_DN_BYTES * sizeof(char));
+                                       if(pclp->m_redirBothName == NULL)
+                                       {
+                                               pclp->m_isValid = FALSE;
+                                               return;
+                                       }
+                               }
+
+                               // Collect the next command-line argument.
+                               pclp->m_redirBothName = fnScanToken(s, pclp->m_redirBothName);
+
+                               s1 = fnSkipWhite(s1);   // s1 is already updated by fnScanToken.
+                               s = s1;         // Update the local pointer too.
+                       }
+                       else
+                       {
+                               if(pclp->nextarg)
+                               {
+                                       free(pclp->nextarg);
+                                       pclp->nextarg = NULL;
+                               }
+
+                               if(pclp->nextarg == NULL)
+                               {
+                                       pclp->nextarg = (char *) malloc(MAX_DN_BYTES * sizeof(char));
+                                       if(pclp->nextarg == NULL)
+                                       {
+                                               pclp->m_isValid = FALSE;
+                                               return;
+                                       }
+                               }
+
+                               // Collect the next command-line argument.
+                               pclp->nextarg = fnScanToken(s, pclp->nextarg);
+
+                               s1 = fnSkipWhite(s1);   // s1 is already updated by fnScanToken.
+                               s = s1;         // Update the local pointer too.
+
+                               // Append the next command-line argument into an array.
+                               fnAppendArgument(pclp, pclp->nextarg);
+                       }
+               }
+       }
+
+
+       // The -{ option, the --noscreen option, the --autodestroy option, if present,
+       // are processed now and removed from the argument vector.
+       for(index=0; index < pclp->m_argc; )
+       {
+               // "-q" is replaced by "-{", because of clash with GetOpt - sgp - 7th Nov 2000
+               // Copied from NDK build - Jan 5th 2001
+               if (strncmp(pclp->m_argv[index], (char *)"-{", 2) == 0)
+               {
+                       // found a -q option; grab the semaphore number
+                       sscanf(pclp->m_argv[index], (char *)"-{%x", &pclp->m_qSemaphore);
+                       fnDeleteArgument(pclp, index);          // Delete the argument from the list.
+               }
+               else if (strcmp(pclp->m_argv[index], (char *)"--noscreen") == 0)
+               {
+                       // found a --noscreen option
+                       pclp->m_noScreen = 1;
+                       fnDeleteArgument(pclp, index);
+               }
+               else if (strcmp(pclp->m_argv[index], (char *)"--autodestroy") == 0)
+               {
+                       // found a --autodestroy option - create a screen but close automatically
+                       pclp->m_AutoDestroy = 1;
+                       fnDeleteArgument(pclp, index);
+               }
+               else
+                       index++;
+       }
+
+       // pclp->m_isValid is TRUE if there are more than 2 command line parameters  OR
+       // if there is only one command and if it is the comman PERL.
+       pclp->m_isValid = ((pclp->m_argc >= 2) || ((pclp->m_argc > 0) && (stricmp(pclp->m_argv[0], LOAD_COMMAND) != 0)));
+
+       if(buffer)
+       {
+               free(buffer);
+               buffer = NULL;
+       }
+
+       return;
+}
+
+
+
+/*============================================================================================
+
+ Function              :       fnAppendArgument
+
+ Description   :       This function appends the arguments into a list.
+
+ Parameters    :       pclp    (IN)    -       CommandLine structure.
+                                       new_arg (IN)    -       The new argument to be appended.
+
+ Returns               :       Nothing.
+
+==============================================================================================*/
+
+void fnAppendArgument(PCOMMANDLINEPARSER pclp, char *new_arg)
+{
+       char **new_argv = pclp->new_argv;
+
+       int new_argv_len = pclp->m_argv_len*2;
+       int i = 0, j = 0;
+
+
+       // Lengthen the argument vector if there's not room for another.
+       // Testing for 'm_argc+2' rather than 'm_argc+1' in the test guarantees 
+       // that there'll always be a NULL terminator at the end of argv.
+       if ((pclp->m_argc + 2) > pclp->m_argv_len)
+       {
+               new_argv = (char **) malloc(new_argv_len * sizeof(char*));      // get a longer arg-vector
+               if (new_argv == NULL)
+               {
+                       pclp->m_isValid = FALSE;
+                       return;
+               }
+               for(i=0; i<new_argv_len; i++)
+               {
+                       new_argv[i] = (char *) malloc(MAX_DN_BYTES * sizeof(char));
+                       if (new_argv[i] == NULL)
+                       {
+                               for(j=0; j<i; j++)
+                               {
+                                       if(new_argv[j])
+                                       {
+                                               free(new_argv[j]);
+                                               new_argv[j] = NULL;
+                                       }
+                               }
+                               if(new_argv)
+                               {
+                                       free(new_argv);
+                                       new_argv = NULL;
+                               }
+
+                               pclp->m_isValid = FALSE;
+                               return;
+                       }
+               }
+
+               for (i=0; i<pclp->m_argc; i++)
+                       strcpy(new_argv[i], pclp->m_argv[i]);  // copy old arg strings
+
+               for(i=0; i<(pclp->m_argv_len); i++)
+               {
+                       if(pclp->m_argv[i])
+                       {
+                               free(pclp->m_argv[i]);
+                               pclp->m_argv[i] = NULL;
+                       }
+               }
+               if (pclp->m_argv != NULL)
+               {
+                       free(pclp->m_argv);
+                       pclp->m_argv = NULL;
+               }
+
+
+               pclp->m_argv = new_argv;
+               pclp->m_argv_len = new_argv_len;
+
+       }
+
+       // Once m_argv is guaranteed long enough, appending the argument is a direct job.
+       strcpy(pclp->m_argv[pclp->m_argc], new_arg);    // Appended the new argument.
+       pclp->m_argc++;         // Increment the number of parameters appended.
+
+       // The char array is emptied for all elements upto the end so that there are no junk characters.
+       // If this is not done, then the issue is like this:
+       // - Simple perl command like "perl" on the system console works fine for the first time.
+       // - When it is given the second time, a new blank screen should come up which also
+       //   allows for editing. This was not consistently working well.
+       //   More so when the command was like, "perl   ", that is the name "perl"
+       //   followed by a few blank spaces. It used to give error in opening file and
+       //   would give some junk as the filename unable to open.
+       // Once the below fix was done, it is working fine.
+       for(i=pclp->m_argc; i<pclp->m_argv_len; i++)
+               strncpy(pclp->m_argv[i], "", (MAX_DN_BYTES * sizeof(char)));    // MAX_DN_BYTES is the size of pclp->m_argv[].
+
+
+       // Fix for empty command line double quote abend - perl <.pl> ""
+       if ((new_arg==NULL) || ((strlen(new_arg))<=0))
+       {
+               pclp->m_argc--;         // Decrement the number of parameters appended.
+               pclp->m_isValid = FALSE;
+               return;
+       }
+
+
+       return;
+}
+
+
+
+/*============================================================================================
+
+ Function              :       fnSkipToken
+
+ Description   :       This function collects the next command-line argument, breaking on
+                                       unquoted white space. The quote symbols are copied into the output.
+                                       White space has already been skipped.
+
+ Parameters    :       s       (IN)    -       Input string in which the token is skipped.
+                                       r       (IN)    -       The resultant return string.
+
+ Returns               :       String.
+
+==============================================================================================*/
+
+char *fnSkipToken(char *s, char *r)
+{
+       register char *t=NULL;
+       register char quote = '\0'; // NULL, single quote, or double quote
+       char ch = '\0';
+
+       for (t=s; t[0]; t++)
+       {
+               ch = t[0];
+               if (!quote)
+               {
+                       if (isspace(ch))                                // if unquoted whitespace...
+                       {
+                               break;                                          // ...end of token found
+                       }
+                       else if (ch=='"' || ch=='\'')   // if opening quote...
+                       {
+                               quote = ch;                                     // ...enter quote mode
+                       }
+               }
+               else
+               {
+                       if (ch=='\\' && t[1]==quote)    // if escaped quote...
+                       {
+                               t++;                                            // ...skip backslash
+                       }
+                       else if (ch==quote)                             // if close quote...
+                       {
+                               quote = 0;                                      // ...leave quote mode
+                       } 
+               }
+       }
+
+       r = fnStashString(s, r, t-s);  // get heap-allocated token string
+       t = fnSkipWhite(t);                // skip any trailing white space
+       s = t;                           // return updated source pointer
+
+       s2 = t;                           // return updated global source pointer
+
+       return r;                        // return heap-allocated token string
+}
+
+
+
+/*============================================================================================
+
+ Function              :       fnScanToken
+
+ Description   :       This function collects the next command-line argument, breaking on
+                                       unquoted white space or I/O redirection symbols. Quote symbols are not
+                                       copied into the output.
+                                       When called, any leading white space has already been skipped.
+
+ Parameters    :       x       (IN)    -       Input string in which the token is scanned.
+                                       r       (IN)    -       The resultant return string.
+
+ Returns               :       String.
+
+==============================================================================================*/
+
+char *fnScanToken(char *x, char *r)
+{
+       register char *s = x; // input string position
+       register char *t = x; // output string position
+       register char quote = '\0'; // either NULL, or single quote, or double quote
+       register char ch = '\0';
+       register char c = '\0';
+
+       while (*s)
+       {
+               ch = *s; // invariant: ch != 0
+               
+               // look to see if we've reached the end of the token
+               if (!quote)             // but don't look for token break if we're inside quotes
+               {
+                       if (isspace(ch))
+                               break;          // break on whitespace
+                       if (ch=='>')
+                               break;              // break on ">"  (redirect stdout)
+                       if (ch=='<')
+                               break;              // break on "<"  (redirect stdin)
+                       if (ch=='&' && x[1]=='>')
+                               break; // break on "&>" (redirect both stdout & stderr)
+               }
+               
+               // process the next source character
+               if (ch=='\\' && (c=s[1]) && (c=='\\'||c=='>'||c=='<'||c==quote))
+               {
+                       //-----------------if an escaped '\\', '>', '<', or quote...
+                       s++;            // ...skip over the backslash...
+                       *t++ = *s++;    // ...and copy the escaped character
+               }
+               else if (ch==quote)             // (won't match unless inside quotes because invariant ch!=0)
+               {
+                       //-----------------if close quote...
+                       s++;            // ...skip over the quote...
+                       quote=0;        // ...and leave quote mode
+               }
+               else if (!quote && (ch=='"' || ch=='\''))
+               {
+                       //-----------------if opening quote...
+                       quote = *s++;   // ...enter quote mode (remembering quote char, and skipping the quote)
+               }
+               else
+               {               //----------if normal character...
+                       *t++ = *s++;    // ...copy the character
+               }
+       }
+
+       // clean up return values
+       r = fnStashString(x, r, t-x);  // get heap-allocated token string
+       s = fnSkipWhite(s);                // skip any trailing white space
+       x = s;                           // return updated source pointer
+
+       s1 = s;                           // return updated global source pointer
+
+       return r;
+}
+
+
+
+/*============================================================================================
+
+ Function              :       fnStashString
+
+ Description   :       This function return the heap-allocated token string.
+
+ Parameters    :       s       (IN)    -       Input string from which the token is extracted.
+                                       buffer  (IN)    -       Return string.
+                                       length  (IN)    -       Length of the token to be extracted.
+
+ Returns               :       String.
+
+==============================================================================================*/
+
+char *fnStashString(char *s, char *buffer, int length)
+{
+       if (length <= 0)
+       {
+               // Copy "" instead of NULL since "" indicates that there is memory allocated having no/null value.
+               // NULL indicates that there is no memory allocated to it!
+               strcpy(buffer, "");
+       }
+       else
+       {
+               strncpy(buffer, s, length);
+               buffer[length] = '\0';
+       }
+
+       return buffer;
+}
+
+
+
+/*============================================================================================
+
+ Function              :       fnDeleteArgument
+
+ Description   :       This function deletes an argument (that was originally appended) from the list.
+
+ Parameters    :       pclp    (IN)    -       CommandLine structure.
+                                       index   (IN)    -       Index of the argument to be deleted.
+
+ Returns               :       Nothing.
+
+==============================================================================================*/
+
+void fnDeleteArgument(PCOMMANDLINEPARSER pclp, int index)
+{
+       int i = index;
+
+
+       // If index is greater than the no. of arguments, just return.
+       if (index >= pclp->m_argc)
+               return;
+
+       // Move all the arguments after the index one up.
+       while(i < (pclp->m_argv_len-1))
+       {
+               strcpy(pclp->m_argv[i], pclp->m_argv[i+1]);
+               i++;
+       }
+
+
+       // Delete the last one and free memory.
+       if ( pclp->m_argv[i] )
+       {
+               free(pclp->m_argv[i]);
+               pclp->m_argv[i] = NULL;
+       }
+
+
+       pclp->m_argc--;         // Decrement the number of arguments.
+       pclp->m_argv_len--;
+
+       return;
+}
+
+
+
+/*============================================================================================
+
+ Function              :       fnMy_MkTemp
+
+ Description   :       This is a standard ANSI C mktemp for NetWare
+
+ Parameters    :       templatestr     (IN)    -       Input temp filename.
+
+ Returns               :       String.
+
+==============================================================================================*/
+
+char* fnMy_MkTemp(char* templatestr)
+{
+       char* pXs=NULL;
+       char numbuf[50]={'\0'};
+       int count=0;
+       char* pPid=NULL;
+
+       char termchar = '\0';
+       char letter = 'a';
+
+
+       if (templatestr && (pXs = strstr(templatestr, (char *)"XXXXXX")))
+       {
+               // generate temp name
+               termchar = pXs[6];
+               ltoa(GetThreadID(), numbuf, 16);
+//             numbuf[sizeof(numbuf)-1] = '\0';
+               numbuf[strlen(numbuf)-1] = '\0';
+               // beware! thread IDs are 8 hex digits on NW 4.11 and only the
+               // lower digits seem to change, whereas on NW 5 they are in the
+               // range of < 1000 hex or 3 hex digits in length. So the following
+               // logic ensures we use the least significant portion of the number.
+               if (strlen(numbuf) > 5)
+                       pPid = &numbuf[strlen(numbuf)-5];
+               else
+                       pPid = numbuf;
+
+               letter = 'a';
+               do
+               {
+                       sprintf(pXs, (char *)"%c%05.5s", letter, pPid);
+                       pXs[6] = termchar;
+                       if (access(templatestr, 0) != 0)        // File does not exist
+                       {
+                               return templatestr;
+                       }
+                       letter++;
+               } while (letter <= 'z');
+
+               errno = ENOENT;
+               return NULL;
+       }
+       else
+       {
+               errno = EINVAL;
+               return NULL;
+       }
+}
+
+
+
+/*============================================================================================
+
+ Function              :       fnSystemCommand
+
+ Description   :       This function constructs a system command from the given
+                                       null-terminated argv array and runs the command on the system console.
+
+ Parameters    :       argv    (IN)    -       Array of input commands.
+                                       argc    (IN)    -       Number of input parameters.
+
+ Returns               :       Nothing.
+
+==============================================================================================*/
+
+void fnSystemCommand (char** argv, int argc)
+{
+       // calculate the size of a temp buffer needed
+       int k = 0;
+       int totalSize = 0;
+       int bytes = 0;
+       char* tempCmd = NULL;
+       char* tptr = NULL;
+
+
+       for(k=0; k<argc; k++)
+               totalSize += strlen(argv[k]) + 1;
+
+       tempCmd = (char *) malloc((totalSize+1) * sizeof(char));
+       if (!tempCmd)
+               return;
+       tptr = tempCmd;
+
+       for(k=0; k<argc; k++)
+               tptr += sprintf(tptr, (char *)"%s ", argv[k]);
+       *tptr = 0;
+
+       if (stricmp(argv[0], PERL_COMMAND_NAME) == 0)
+               fnInternalPerlLaunchHandler(tempCmd);   // Launch perl.
+       else
+               system(tempCmd);
+
+
+       free(tempCmd);
+       tempCmd = NULL;
+       return;
+}
+
diff --git a/NetWare/Nwmain.c b/NetWare/Nwmain.c
new file mode 100644 (file)
index 0000000..a01fa5e
--- /dev/null
@@ -0,0 +1,1422 @@
+
+/*
+ * Copyright Â© 2001 Novell, Inc. All Rights Reserved.
+ *
+ * You may distribute under the terms of either the GNU General Public
+ * License or the Artistic License, as specified in the README file.
+ *
+ */
+
+/*
+ * FILENAME            :       NWMain.c
+ * DESCRIPTION :       Main function, Commandline handlers and shutdown for NetWare implementation of Perl.
+ * Author              :       HYAK, SGP
+ * Date                        :       January 2001.
+ *
+ */
+
+
+
+#ifdef NLM
+#define N_PLAT_NLM
+#endif
+
+#undef BYTE
+#define BYTE char
+
+
+#include <nwadv.h>
+#include <signal.h>
+#include <nwdsdefs.h>
+
+#include "perl.h"
+#include "nwutil.h"
+#include "stdio.h"
+#include "clibstuf.h"
+
+#ifdef MPK_ON
+       #include <mpktypes.h>
+       #include <mpkapis.h>
+#endif //MPK_ON
+
+
+// Thread group ID for this NLM. Set only by main when the NLM is initially loaded,
+// so it should be okay for this to be global.
+//
+#ifdef MPK_ON
+       THREAD  gThreadHandle;
+#else
+       int gThreadGroupID = -1;
+#endif //MPK_ON
+
+
+// Global to kill all running scripts during NLM unload.
+//
+bool gKillAll = FALSE;
+
+
+// Global structure needed by OS to register command parser.
+// fnRegisterCommandLineHandler gets called only when the NLM is initially loaded,
+// so it should be okay for this structure to be a global.
+//
+static struct commandParserStructure gCmdParser = {0,0,0};
+
+
+// True if the command-line parsing procedure has been registered with the OS.
+// Altered only during initial NLM loading or unloading so it should be okay as a global.
+//
+BOOL gCmdProcInit = FALSE;
+
+
+// Array to hold the screen name for all new screens.
+//
+char sPerlScreenName[MAX_DN_BYTES * sizeof(char)] = {'\0'};
+
+
+// Structure to pass data when spawning new threadgroups to run scripts.
+//
+typedef struct tagScriptData
+{
+       char *m_commandLine;
+       BOOL m_fromConsole;
+}ScriptData;
+
+
+#define  CS_CMD_NOT_FOUND      -1              // Console command not found
+#define  CS_CMD_FOUND          0               // Console command found
+
+/**
+  The stack size is make 256k from the earlier 64k since complex scripts (charnames.t and complex.t)
+  were failing with the lower stack size. In fact, we tested with 128k and it also failed
+  for the complexity of the script used. In case the complexity of a script is increased,
+  then this might warrant an increase in the stack size. But instead of simply giving  a very large stack,
+  a trade off was required and we stopped at 256k!
+**/
+#define PERL_COMMAND_STACK_SIZE (256*1024L)    // Stack size of thread that runs a perl script from command line
+
+#define MAX_COMMAND_SIZE 512
+
+
+#define kMaxValueLen 1024      // Size of the Environment variable value limited/truncated to 1024 characters.
+#define kMaxVariableNameLen 256                // Size of the Environment variable name.
+
+
+typedef void (*PFUSEACCURATECASEFORPATHS) (int);
+typedef LONG (*PFGETFILESERVERMAJORVERSIONNUMBER) (void);
+typedef void (*PFUCSTERMINATE) ();             // For ucs terminate.
+typedef void (*PFUNAUGMENTASTERISK)(BOOL);             // For longfile support.
+typedef int (*PFFSETMODE) (FILE *, char *);
+
+
+// local function prototypes
+//
+void fnSigTermHandler(int sig);
+void fnRegisterCommandLineHandler(void);
+void fnLaunchPerl(void* context);
+void fnSetUpEnvBlock(char*** penv);
+void fnDestroyEnvBlock(char** env);
+int fnFpSetMode(FILE* fp, int mode, int *err);
+
+void fnGetPerlScreenName(char *sPerlScreenName);
+
+
+
+
+/*============================================================================================
+
+ Function              :       main
+
+ Description   :       Called when the NLM is first loaded. Registers the command-line handler
+                                                               and then terminates-stay-resident.
+
+ Parameters            :       argc    (IN)    -       No of  Input  strings.
+                                                               argv    (IN)    -       Array of  Input  strings.
+
+ Returns               :       Nothing.
+
+==============================================================================================*/
+
+void main(int argc, char *argv[]) 
+{
+       char sysCmdLine[MAX_COMMAND_SIZE] = {'\0'};
+       char cmdLineCopy[sizeof(PERL_COMMAND_NAME)+sizeof(sysCmdLine)+2] = {'\0'};
+
+       ScriptData* psdata = NULL;
+
+
+       // Keep this thread alive, since we use the thread group id of this thread to allocate memory on.
+       // When we unload the NLM, clib will tear the thread down.
+       //
+       #ifdef MPK_ON
+               gThreadHandle = kCurrentThread();
+       #else
+               gThreadGroupID = GetThreadGroupID ();
+       #endif  //MPK_ON
+
+       signal (SIGTERM, fnSigTermHandler);
+       fnInitGpfGlobals();             // For importing the CLIB calls in place of the Watcom calls
+       fnInitializeThreadInfo();
+
+
+//     Ensure that we have a "temp" directory
+       fnSetupNamespace();
+       if (access(DEFTEMP, 0) != 0)
+               mkdir(DEFTEMP);
+
+       // Create the file NUL if not present. This is done only once per NLM load.
+       // This is required for -e.
+       // Earlier verions were creating temporary files (in perl.c file) for -e.
+       // Now, the technique of creating temporary files are removed since they were
+       // fragile or insecure or slow. It now uses the memory by setting
+       // the BIT_BUCKET to "nul" on Win32, which is equivalent to /dev/nul of Unix.
+       // Since there is no equivalent of /dev/nul on NetWare, the work-around is that
+       // we create a file called "nul" and the BIT_BUCKET is set to "nul".
+       // This makes sure that -e works on NetWare too without the creation of temporary files
+       // in -e code in perl.c
+       {
+               char sNUL[MAX_DN_BYTES] = {'\0'};
+
+               strcpy(sNUL, DEFPERLROOT);
+               strcat(sNUL, "\\nul");
+               if (access((const char *)sNUL, 0) != 0)
+               {
+                       // The file, "nul" is not found and so create the file.
+                       FILE *fp = NULL;
+
+                       fp = fopen((const char *)sNUL, (const char *)"w");
+                       fclose(fp);
+               }
+       }
+
+       fnRegisterCommandLineHandler();         // Register the command line handler
+       SynchronizeStart();             // Restart the NLM startup process when using synchronization mode.
+
+       fnGetPerlScreenName(sPerlScreenName);   // Get the screen name. Done only once per NLM load.
+
+
+       // If the command line has two strings, then the first has to be "Perl" and the second is assumed
+       // to be a script to be run. If only one string (i.e., Perl) is input, then there is nothing to do!
+       //
+       if ((argc > 1) && getcmd(sysCmdLine))
+       {
+               strcpy(cmdLineCopy, PERL_COMMAND_NAME);
+               strcat(cmdLineCopy, (char *)" ");       // Space between the Perl Command and the input script name.
+               strcat(cmdLineCopy, sysCmdLine);        // The command line parameters built into 
+
+               // Create a safe copy of the command line and pass it to the
+               // new thread for parsing. The new thread will be responsible
+               // to delete it when it is finished with it.
+               //
+               psdata = (ScriptData *) malloc(sizeof(ScriptData));
+               if (psdata)
+               {
+                       psdata->m_commandLine = NULL;
+                       psdata->m_commandLine = (char *) malloc(MAX_DN_BYTES * sizeof(char));
+                       if(psdata->m_commandLine)
+                       {
+                               strcpy(psdata->m_commandLine, cmdLineCopy);
+                               psdata->m_fromConsole = TRUE;
+
+                               #ifdef MPK_ON
+//                                     kStartThread((char *)"ConsoleHandlerThread", fnLaunchPerl, NULL, PERL_COMMAND_STACK_SIZE, (void *)psdata);
+                                       // Establish a new thread within a new thread group.
+                                       BeginThreadGroup(fnLaunchPerl, NULL, PERL_COMMAND_STACK_SIZE, (void*)psdata);
+                               #else
+                                       // Start a new thread in its own thread group
+                                       BeginThreadGroup(fnLaunchPerl, NULL, PERL_COMMAND_STACK_SIZE, (void*)psdata);
+                               #endif  //MPK_ON
+                       }
+                       else
+                       {
+                               free(psdata);
+                               psdata = NULL;
+                               return;
+                       }
+               }
+               else
+                       return;
+       }
+
+
+       // Keep this thread alive, since we use the thread group id of this thread to allocate memory on.
+       // When we unload the NLM, clib will tear the thread down.
+       //
+       #ifdef MPK_ON
+               kSuspendThread(gThreadHandle);
+       #else
+               SuspendThread(GetThreadID());
+       #endif  //MPK_ON
+
+
+       return;
+}
+
+
+
+/*============================================================================================
+
+ Function              :       fnSigTermHandler
+
+ Description   :       Called when the NLM is unloaded; used to unregister the console command handler.
+
+ Parameters            :       sig             (IN)
+
+ Returns               :       Nothing.
+
+==============================================================================================*/
+
+void fnSigTermHandler(int sig)
+{
+       int k = 0;
+
+
+       #ifdef MPK_ON
+               kResumeThread(gThreadHandle);
+       #endif  //MPK_ON
+
+       // Unregister the command line handler.
+       //
+       if (gCmdProcInit)
+       {
+               UnRegisterConsoleCommand (&gCmdParser);
+               gCmdProcInit = FALSE;
+       }
+
+       // Free the global environ buffer
+       nw_freeenviron();
+
+       // Kill running scripts.
+       //
+       if (!fnTerminateThreadInfo())
+       {
+               ConsolePrintf("Terminating Perl scripts...\n");
+               gKillAll = TRUE;
+
+               // fnTerminateThreadInfo will be run for 5 threads. If more threads/scripts are run,
+               // then the NLM will unload without terminating the thread info and leaks more memory.
+               // If this number is increased to reduce memory leaks, then it will unnecessarily take more time
+               // to unload when there are a smaller no of threads. Since this is a rare case, the no is kept as 5.
+               //
+               while (!fnTerminateThreadInfo() && k < 5)
+               {
+                       sleep(1);
+                       k++;
+               }
+       }
+
+       // Delete the file, "nul" if present since the NLM is unloaded.
+       {
+               char sNUL[MAX_DN_BYTES] = {'\0'};
+
+               strcpy(sNUL, DEFPERLROOT);
+               strcat(sNUL, "\\nul");
+               if (access((const char *)sNUL, 0) == 0)
+               {
+                       // The file, "nul" is found and so delete it.
+                       unlink((const char *)sNUL);
+               }
+       }
+}
+
+
+
+/*============================================================================================
+
+ Function              :       fnCommandLineHandler
+
+ Description   :       Gets called by OS when someone enters an unknown command at the system console,
+                                       after this routine is registered by RegisterConsoleCommand.
+                                       For the valid command we just spawn     a thread with enough stack space
+                                       to actually run the script.
+
+ Parameters            :       screenID        (IN)    -       id for the screen.
+                                                               cmdLine         (IN)    -       Command line string.
+
+ Returns               :       Long.
+
+==============================================================================================*/
+
+LONG  fnCommandLineHandler (LONG screenID, BYTE * cmdLine)
+{
+       ScriptData* psdata=NULL;
+       int OsThrdGrpID = -1;
+       LONG retCode = CS_CMD_FOUND;
+       char* cptr = NULL;
+
+
+       #ifdef MPK_ON
+               // Initialisation for MPK_ON
+       #else
+               OsThrdGrpID = -1;
+       #endif  //MPK_ON
+
+
+       #ifdef MPK_ON
+               // For MPK_ON
+       #else
+               if (gThreadGroupID != -1)
+                       OsThrdGrpID = SetThreadGroupID (gThreadGroupID);
+       #endif  //MPK_ON
+
+
+       cptr = fnSkipWhite(cmdLine);    // Skip white spaces.
+       if ((strnicmp(cptr, PERL_COMMAND_NAME, strlen(PERL_COMMAND_NAME)) == 0) &&
+                ((cptr[strlen(PERL_COMMAND_NAME)] == ' ') ||
+                (cptr[strlen(PERL_COMMAND_NAME)] == '\t') ||
+                (cptr[strlen(PERL_COMMAND_NAME)] == '\0')))
+       {
+               // Create a safe copy of the command line and pass it to the new thread for parsing.
+               // The new thread will be responsible to delete it when it is finished with it.
+               //
+               psdata = (ScriptData *) malloc(sizeof(ScriptData));
+               if (psdata)
+               {
+                       psdata->m_commandLine = NULL;
+                       psdata->m_commandLine = (char *) malloc(MAX_DN_BYTES * sizeof(char));
+                       if(psdata->m_commandLine)
+                       {
+                               strcpy(psdata->m_commandLine, (char *)cmdLine);
+                               psdata->m_fromConsole = TRUE;
+
+                               #ifdef MPK_ON
+//                                     kStartThread((char *)"ConsoleHandlerThread", fnLaunchPerl, NULL, PERL_COMMAND_STACK_SIZE, (void *)psdata);
+                                       // Establish a new thread within a new thread group.
+                                       BeginThreadGroup(fnLaunchPerl, NULL, PERL_COMMAND_STACK_SIZE, (void*)psdata);
+                               #else
+                                       // Start a new thread in its own thread group
+                                       BeginThreadGroup(fnLaunchPerl, NULL, PERL_COMMAND_STACK_SIZE, (void*)psdata);
+                               #endif  //MPK_ON
+                       }
+                       else
+                       {
+                               free(psdata);
+                               psdata = NULL;
+                               retCode = CS_CMD_NOT_FOUND;
+                       }
+               }
+               else
+                       retCode = CS_CMD_NOT_FOUND;
+       }
+       else
+               retCode = CS_CMD_NOT_FOUND;
+
+
+       #ifdef MPK_ON
+               // For MPK_ON
+       #else
+               if (OsThrdGrpID != -1)
+                       SetThreadGroupID (OsThrdGrpID);
+       #endif  //MPK_ON
+
+
+       return retCode;
+}
+
+
+
+/*============================================================================================
+
+ Function              :       fnRegisterCommandLineHandler
+
+ Description   :       Registers the console command-line parsing function with the OS.
+
+ Parameters            :       None.
+
+ Returns               :       Nothing.
+
+==============================================================================================*/
+
+void fnRegisterCommandLineHandler(void)
+{
+       // Allocates resource tag for Console Command
+       if ((gCmdParser.RTag =
+               AllocateResourceTag (GetNLMHandle(), (char *)"Console Command", ConsoleCommandSignature)) != 0)
+       {
+               gCmdParser.parseRoutine = fnCommandLineHandler;         // Set the Console Command parsing routine.
+               RegisterConsoleCommand (&gCmdParser);           // Registers the Console Command parsing function
+               gCmdProcInit = TRUE;
+       }
+
+       return;
+}
+
+
+
+/*============================================================================================
+
+ Function              :       fnSetupNamespace
+
+ Description   :       Sets the name space of the current threadgroup to the long name space.
+
+ Parameters            :       None.
+
+ Returns               :       Nothing.
+
+==============================================================================================*/
+
+void fnSetupNamespace(void)
+{
+       SetCurrentNameSpace(NWOS2_NAME_SPACE);
+
+
+       //LATER: call SetTargetNameSpace(NWOS2_NAME_SPACE)? Currently, if
+       // I make this call, then CPerlExe::Rename fails in certain cases,
+       // and it isn't clear why. Looks like a CLIB bug...
+//     SetTargetNameSpace(NWOS2_NAME_SPACE); 
+
+       //Uncommented that above call, retaining the comment so that it will be easy 
+       //to revert back if there is any problem - sgp - 10th May 2000
+
+       //Commented again, since Perl debugger had some problems because of
+       //the above call - sgp - 20th June 2000
+
+       {
+               // if running on Moab, call UseAccurateCaseForPaths. This API
+               // does bad things on 4.11 so we call only for Moab.
+               PFGETFILESERVERMAJORVERSIONNUMBER pf_getfileservermajorversionnumber = NULL;
+               pf_getfileservermajorversionnumber = (PFGETFILESERVERMAJORVERSIONNUMBER) 
+               ImportSymbol(GetNLMHandle(), (char *)"GetFileServerMajorVersionNumber");
+               if (pf_getfileservermajorversionnumber && ((*pf_getfileservermajorversionnumber)() > 4))
+               {
+                       PFUSEACCURATECASEFORPATHS pf_useaccuratecaseforpaths = NULL;
+                       pf_useaccuratecaseforpaths = (PFUSEACCURATECASEFORPATHS) 
+                       ImportSymbol(GetNLMHandle(), (char *)"UseAccurateCaseForPaths");
+                       if (pf_useaccuratecaseforpaths)
+                               (*pf_useaccuratecaseforpaths)(TRUE);
+                       {
+                               PFUNAUGMENTASTERISK pf_unaugmentasterisk = NULL;
+                               pf_unaugmentasterisk = (PFUNAUGMENTASTERISK)
+                               ImportSymbol(GetNLMHandle(), (char *)"UnAugmentAsterisk");
+                               if (pf_unaugmentasterisk)
+                                       (*pf_unaugmentasterisk)(TRUE);
+                       }
+               }
+       }
+
+       return;
+}
+
+
+
+/*============================================================================================
+
+ Function              :       fnLaunchPerl
+
+ Description   :       Parse the command line into argc/argv style parameters and then run the script.
+
+ Parameters            :       context (IN)    -       void* that will be typecasted to ScriptDate structure.
+
+ Returns               :       Nothing.
+
+==============================================================================================*/
+
+void fnLaunchPerl(void* context)
+{
+       char* defaultDir = NULL;
+       char curdir[_MAX_PATH] = {'\0'};
+       ScriptData* psdata = (ScriptData *) context;
+
+       unsigned int moduleHandle = 0;
+       int currentThreadGroupID = -1;
+
+       #ifdef MPK_ON
+               kExitNetWare();
+       #endif  //MPK_ON
+
+       errno = 0;
+
+
+       if (psdata->m_fromConsole)
+       {
+               // get the default working directory name
+               //
+               defaultDir = fnNwGetEnvironmentStr("PERL_ROOT", DEFPERLROOT);
+       }
+       else
+               defaultDir = getcwd(curdir, sizeof(curdir)-1);
+
+       // set long name space
+       //
+       fnSetupNamespace();
+
+       // make the working directory the current directory if from console
+       //
+       if (psdata->m_fromConsole)
+               chdir(defaultDir);
+
+
+       // run the script
+       //
+       fnRunScript(psdata);
+
+
+       // May have to check this, I am blindly calling UCSTerminate, irrespective of
+       // whether it is initialized or not
+       // Copied from the previous Perl - sgp - 31st Oct 2000
+       moduleHandle = FindNLMHandle("UCSCORE.NLM");
+       if (moduleHandle)
+       {
+               PFUCSTERMINATE ucsterminate = (PFUCSTERMINATE)ImportSymbol(moduleHandle, "therealUCSTerminate");
+               if (ucsterminate!=NULL)
+                       (*ucsterminate)();
+       }
+
+
+       if (psdata->m_fromConsole)
+       {
+               // change thread groups for the call to free the memory
+               // allocated before the new thread group was started
+               #ifdef MPK_ON
+                       // For MPK_ON
+               #else
+                       if (gThreadGroupID != -1)
+                               currentThreadGroupID = SetThreadGroupID (gThreadGroupID);
+               #endif  //MPK_ON
+       }
+
+       // Free memory
+       if (psdata)
+       {
+               if(psdata->m_commandLine)
+               {
+                       free(psdata->m_commandLine);
+                       psdata->m_commandLine = NULL;
+               }
+
+               free(psdata);
+               psdata = NULL;
+               context = NULL;
+       }
+
+       #ifdef MPK_ON
+               // For MPK_ON
+       #else
+               if (currentThreadGroupID != -1)
+                       SetThreadGroupID (currentThreadGroupID);
+       #endif  //MPK_ON
+
+       #ifdef MPK_ON
+//             kExitThread(NULL);
+       #else
+               // just let the thread terminate by falling off the end of the
+               // function started by BeginThreadGroup
+//             ExitThread(EXIT_THREAD, 0);
+       #endif
+
+
+       return;
+}
+
+
+
+/*============================================================================================
+
+ Function              :       fnRunScript
+
+ Description   :       Parses and runs a perl script.
+
+ Parameters            :       psdata  (IN)    -       ScriptData structure.
+
+ Returns               :       Nothing.
+
+==============================================================================================*/
+
+void fnRunScript(ScriptData* psdata)
+{
+       char **av=NULL;
+       char **en=NULL;
+       int exitstatus = 1;
+       int i=0, j=0;
+       int *dummy = 0;
+
+       PCOMMANDLINEPARSER pclp = NULL;
+
+       // Set up the environment block. This will only work on
+       // on Moab; on 4.11 the environment block will be empty.
+       char** env = NULL;
+
+       BOOL use_system_console = TRUE;
+       BOOL newscreen = FALSE;
+       int newscreenhandle = 0;
+
+       // redirect stdin or stdout and run the script
+       FILE* redirOut = NULL;
+       FILE* redirIn = NULL;
+       FILE* redirErr = NULL;
+       FILE* stderr_fp = NULL;
+
+       int stdin_fd=-1, stdin_fd_dup=-1;
+       int stdout_fd=-1, stdout_fd_dup=-1;
+       int stderr_fd=-1, stderr_fd_dup=-1;
+
+
+
+       // Main callback instance
+       //
+       if (fnRegisterWithThreadTable() == FALSE)
+               return;
+
+
+       // parse the command line into argc/argv style:
+       // number of params and char array of params
+       //
+       pclp = (PCOMMANDLINEPARSER) malloc(sizeof(COMMANDLINEPARSER));
+       if (!pclp)
+       {
+               fnUnregisterWithThreadTable();
+               return;
+       }
+
+
+       // Initialise the variables
+       pclp->m_isValid = TRUE;
+       pclp->m_redirInName = NULL;
+       pclp->m_redirOutName = NULL;
+       pclp->m_redirErrName = NULL;
+       pclp->m_redirBothName = NULL;
+       pclp->nextarg = NULL;
+       pclp->sSkippedToken = NULL;
+       pclp->m_argv = NULL;
+       pclp->new_argv = NULL;
+
+       #ifdef MPK_ON
+               pclp->m_qSemaphore = NULL;
+       #else
+               pclp->m_qSemaphore = 0L;
+       #endif  //MPK_ON
+
+       pclp->m_noScreen = 0;
+       pclp->m_AutoDestroy = 0;
+       pclp->m_argc = 0;
+       pclp->m_argv_len = 1;
+
+
+       // Allocate memory
+       pclp->m_argv = (char **) malloc(pclp->m_argv_len * sizeof(char *));
+       if (pclp->m_argv == NULL)
+       {
+               free(pclp);
+               pclp = NULL;
+
+               fnUnregisterWithThreadTable();
+               return;
+       }
+
+       pclp->m_argv[0] = (char *) malloc(MAX_DN_BYTES * sizeof(char));
+       if (pclp->m_argv[0] == NULL)
+       {
+               free(pclp->m_argv);
+               pclp->m_argv=NULL;
+
+               free(pclp);
+               pclp = NULL;
+
+               fnUnregisterWithThreadTable();
+               return;
+       }
+
+
+       // Parse the command line
+       fnCommandLineParser(pclp, (char *)psdata->m_commandLine, FALSE);
+       if (!pclp->m_isValid)
+       {
+               if(pclp->m_argv)
+               {
+                       for(i=0; i<pclp->m_argv_len; i++)
+                       {
+                               if(pclp->m_argv[i] != NULL)
+                               {
+                                       free(pclp->m_argv[i]);
+                                       pclp->m_argv[i] = NULL;
+                               }
+                       }
+
+                       free(pclp->m_argv);
+                       pclp->m_argv = NULL;
+               }
+
+               if(pclp->nextarg)
+               {
+                       free(pclp->nextarg);
+                       pclp->nextarg = NULL;
+               }
+               if(pclp->sSkippedToken != NULL)
+               {
+                       free(pclp->sSkippedToken);
+                       pclp->sSkippedToken = NULL;
+               }
+
+               if(pclp->m_redirInName)
+               {
+                       free(pclp->m_redirInName);
+                       pclp->m_redirInName = NULL;
+               }
+               if(pclp->m_redirOutName)
+               {
+                       free(pclp->m_redirOutName);
+                       pclp->m_redirOutName = NULL;
+               }
+               if(pclp->m_redirErrName)
+               {
+                       free(pclp->m_redirErrName);
+                       pclp->m_redirErrName = NULL;
+               }
+               if(pclp->m_redirBothName)
+               {
+                       free(pclp->m_redirBothName);
+                       pclp->m_redirBothName = NULL;
+               }
+
+
+               // Signal a semaphore, if indicated by "-{" option, to indicate that
+               // the script has terminated and files are closed
+               //
+               if (pclp->m_qSemaphore != 0)
+               {
+                       #ifdef MPK_ON
+                               kSemaphoreSignal(pclp->m_qSemaphore);
+                       #else
+                               SignalLocalSemaphore(pclp->m_qSemaphore);
+                       #endif  //MPK_ON
+               }
+
+               free(pclp);
+               pclp = NULL;
+
+               fnUnregisterWithThreadTable();
+               return;
+       }
+
+
+       // Simulating a shell on NetWare can be difficult. If you don't
+       // create a new screen for the script to run in, you can output to
+       // the console but you can't get any input from the console. Therefore,
+       // every invocation of perl potentially needs its own screen unless
+       // you are running either "perl -h" or "perl -v" or you are redirecting
+       // stdin from a file.
+       //
+       // So we need to create a new screen and set that screen as the current
+       // screen when running any script launched from the console that is not
+       // "perl -h" or "perl -v" and is not redirecting stdin from a file.
+       //
+       // But it would be a little weird if we didn't create a new screen only
+       // in the case when redirecting stdin from a file; in only that case,
+       // stdout would be the console instead of a new screen.
+       //
+       // There is also the issue of standard err. In short, we might as well
+       // create a new screen no matter what is going on with redirection, just
+       // for the sake of consistency.
+       //
+       // In summary, we should a create a new screen and make that screen the
+       // current screen unless one of the following is true:
+       //  * The command is "perl -h"
+       //  * The command is "perl -v"
+       //  * The script was launched by another perl script. In this case,
+       //        the screen belonging to the parent perl script should probably be
+       //    the same screen for this process. And it will be if use BeginThread
+       //    instead of BeginThreadGroup when launching Perl from within a Perl
+       //    script.
+       //
+       // In those cases where we create a new screen we should probably also display
+       // that screen.
+       //
+
+       use_system_console = pclp->m_noScreen  ||
+                               ((pclp->m_argc == 2) && (strcmp(pclp->m_argv[1], (char *)"-h") == 0))  ||
+                               ((pclp->m_argc == 2) && (strcmp(pclp->m_argv[1], (char *)"-v") == 0));
+
+       newscreen = (!use_system_console) && psdata->m_fromConsole;
+
+       if (newscreen)
+       {
+               newscreenhandle = CreateScreen(sPerlScreenName, 0);
+               if (newscreenhandle)
+                       DisplayScreen(newscreenhandle);
+       }
+       else if (use_system_console)
+         CreateScreen((char *)"System Console", 0);
+
+
+       if (pclp->m_redirInName)
+       {
+               if ((stdin_fd = fileno(stdin)) != -1)
+               {
+                       stdin_fd_dup = dup(stdin_fd);
+                       if (stdin_fd_dup != -1)
+                       {
+                               redirIn = fdopen (stdin_fd_dup, (char const *)"r");
+                               if (redirIn)
+                                       stdin = freopen (pclp->m_redirInName, (char const *)"r", redirIn);
+                               if (!stdin)
+                               {
+                                       redirIn = NULL;
+                                       // undo the redirect, if possible
+                                       stdin = fdopen(stdin_fd, (char const *)"r");
+                               }
+                       }
+               }
+       }
+
+       /**
+       The below code stores the handle for the existing stdout to be used later and the existing stdout is closed.
+       stdout is then initialised to the new File pointer where the operations are done onto that.
+       Later (look below for the code), the saved stdout is restored back.
+       **/
+       if (pclp->m_redirOutName)
+       {
+               if ((stdout_fd = fileno(stdout)) != -1)         // Handle of the existing stdout.
+               {
+                       stdout_fd_dup = dup(stdout_fd);
+                       if (stdout_fd_dup != -1)
+                       {
+                               // Close the existing stdout.
+                               fflush(stdout);         // Write any unwritten data to the file.
+
+                               // New stdout
+                               redirOut = fdopen (stdout_fd_dup, (char const *)"w");
+                               if (redirOut)
+                                       stdout = freopen (pclp->m_redirOutName, (char const *)"w", redirOut);
+                               if (!stdout)
+                               {
+                                       redirOut = NULL;
+                                       // Undo the redirection.
+                                       stdout = fdopen(stdout_fd, (char const *)"w");
+                               }
+                               setbuf(stdout, NULL);   // Unbuffered file pointer.
+                       }
+               }
+       }
+
+       if (pclp->m_redirErrName)
+       {
+               if ((stderr_fd = fileno(stderr)) != -1)
+               {
+                       stderr_fd_dup = dup(stderr_fd);
+                       if (stderr_fd_dup != -1)
+                       {
+                               fflush(stderr);
+
+                               redirErr = fdopen (stderr_fd_dup, (char const *)"w");
+                               if (redirErr)
+                                       stderr = freopen (pclp->m_redirErrName, (char const *)"w", redirErr);
+                               if (!stderr)
+                               {
+                                       redirErr = NULL;
+                                       // undo the redirect, if possible
+                                       stderr = fdopen(stderr_fd, (char const *)"w");
+                               }
+                               setbuf(stderr, NULL);   // Unbuffered file pointer.
+                       }
+               }
+       }
+
+       if (pclp->m_redirBothName)
+       {
+               if ((stdout_fd = fileno(stdout)) != -1)
+               {
+                       stdout_fd_dup = dup(stdout_fd);
+                       if (stdout_fd_dup != -1)
+                       {
+                               fflush(stdout);
+
+                               redirOut = fdopen (stdout_fd_dup, (char const *)"w");
+                               if (redirOut)
+                                       stdout = freopen (pclp->m_redirBothName, (char const *)"w", redirOut);
+                               if (!stdout)
+                               {
+                                       redirOut = NULL;
+                                       // undo the redirect, if possible
+                                       stdout = fdopen(stdout_fd, (char const *)"w");
+                               }
+                               setbuf(stdout, NULL);   // Unbuffered file pointer.
+                       }
+               }
+               if ((stderr_fd = fileno(stderr)) != -1)
+               {
+               stderr_fp = stderr;
+                       stderr = stdout;
+               }
+       }
+
+
+       env = NULL;
+       fnSetUpEnvBlock(&env);  // Set up the ENV block
+
+       // Run the Perl script
+       exitstatus = RunPerl(pclp->m_argc, pclp->m_argv, env);
+
+
+       // clean up any redirection
+       //
+       if (pclp->m_redirInName && redirIn)
+       {
+               fclose(stdin);
+               stdin = fdopen(stdin_fd, (char const *)"r");            // Put back the old handle for stdin.
+       }
+
+       if (pclp->m_redirOutName && redirOut)
+       {
+               // Close the new stdout.
+               fflush(stdout);
+               fclose(stdout);
+
+               // Put back the old handle for stdout.
+               stdout = fdopen(stdout_fd, (char const *)"w");
+               setbuf(stdout, NULL);   // Unbuffered file pointer.
+       }
+
+       if (pclp->m_redirErrName && redirErr)
+       {
+               fflush(stderr);
+               fclose(stderr);
+
+               stderr = fdopen(stderr_fd, (char const *)"w");          // Put back the old handle for stderr.
+               setbuf(stderr, NULL);   // Unbuffered file pointer.
+       }
+
+       if (pclp->m_redirBothName && redirOut)
+       {
+               stderr = stderr_fp;
+
+               fflush(stdout);
+               fclose(stdout);
+
+               stdout = fdopen(stdout_fd, (char const *)"w");          // Put back the old handle for stdout.
+               setbuf(stdout, NULL);   // Unbuffered file pointer.
+       }
+
+
+       if (newscreen && newscreenhandle)
+       {
+               //added for --autodestroy switch
+               if(!pclp->m_AutoDestroy)
+               {
+                       if ((redirOut == NULL) && (redirIn == NULL) && (!gKillAll))
+                       {
+                               printf((char *)"\n\nPress any key to exit\n");
+                               getch();
+                       }
+               }
+               DestroyScreen(newscreenhandle);
+       }
+
+       // Set the mode for stdin and stdout
+       fnFpSetMode(stdin, O_TEXT, dummy);
+       fnFpSetMode(stdout, O_TEXT, dummy);
+
+       // Cleanup
+       if(pclp->m_argv)
+       {
+               for(i=0; i<pclp->m_argv_len; i++)
+               {
+                       if(pclp->m_argv[i] != NULL)
+                       {
+                               free(pclp->m_argv[i]);
+                               pclp->m_argv[i] = NULL;
+                       }
+               }
+
+               free(pclp->m_argv);
+               pclp->m_argv = NULL;
+       }
+
+       if(pclp->nextarg)
+       {
+               free(pclp->nextarg);
+               pclp->nextarg = NULL;
+       }
+       if(pclp->sSkippedToken != NULL)
+       {
+               free(pclp->sSkippedToken);
+               pclp->sSkippedToken = NULL;
+       }
+
+       if(pclp->m_redirInName)
+       {
+               free(pclp->m_redirInName);
+               pclp->m_redirInName = NULL;
+       }
+       if(pclp->m_redirOutName)
+       {
+               free(pclp->m_redirOutName);
+               pclp->m_redirOutName = NULL;
+       }
+       if(pclp->m_redirErrName)
+       {
+               free(pclp->m_redirErrName);
+               pclp->m_redirErrName = NULL;
+       }
+       if(pclp->m_redirBothName)
+       {
+               free(pclp->m_redirBothName);
+               pclp->m_redirBothName = NULL;
+       }
+
+
+       // Signal a semaphore, if indicated by -{ option, to indicate that
+       // the script has terminated and files are closed
+       //
+       if (pclp->m_qSemaphore != 0)
+       {
+               #ifdef MPK_ON
+                       kSemaphoreSignal(pclp->m_qSemaphore);
+               #else
+                       SignalLocalSemaphore(pclp->m_qSemaphore);
+               #endif  //MPK_ON
+       }
+
+       if(pclp)
+       {
+               free(pclp);
+               pclp = NULL;
+       }
+
+       if(env)
+               fnDestroyEnvBlock(env);
+       fnUnregisterWithThreadTable();
+       // Remove the thread context set during Perl_set_context
+       Remove_Thread_Ctx();
+
+
+       return;
+}
+
+
+
+/*============================================================================================
+
+ Function              :       fnSetUpEnvBlock
+
+ Description   :       Sets up the initial environment block.
+
+ Parameters            :       penv    (IN)    -       ENV variable as char***.
+
+ Returns               :       Nothing.
+
+==============================================================================================*/
+
+void fnSetUpEnvBlock(char*** penv)
+{
+       char** env = NULL;
+
+       int sequence = 0;
+       char var[kMaxVariableNameLen+1] = {'\0'};
+       char val[kMaxValueLen+1] = {'\0'};
+       char both[kMaxVariableNameLen + kMaxValueLen + 5] = {'\0'};
+       size_t len  = kMaxValueLen;
+       int totalcnt = 0;
+
+       while(scanenv( &sequence, var, &len, val ))
+       {
+               totalcnt++;
+               len  = kMaxValueLen;
+       }
+       // add one for null termination
+       totalcnt++;
+
+
+       env = (char **) malloc (totalcnt * sizeof(char *));
+       if (env)
+       {
+               int cnt = 0;
+               int i = 0;
+
+               sequence = 0;
+               len  = kMaxValueLen;
+
+               while( (cnt < (totalcnt-1)) && scanenv( &sequence, var, &len, val ) )
+               {
+                       val[len] = '\0';
+                       strcpy( both, var );
+                       strcat( both, (char *)"=" );
+                       strcat( both, val );
+
+                       env[cnt] = (char *) malloc((sizeof(both)+1) * sizeof(char));
+                       if (env[cnt])
+                       {
+                               strcpy(env[cnt], both);
+                               cnt++;
+                       }
+                       else
+                       {
+                               for(i=0; i<cnt; i++)
+                               {
+                                       if(env[i])
+                                       {
+                                               free(env[i]);
+                                               env[i] = NULL;
+                                       }
+                               }
+
+                               free(env);
+                               env = NULL;
+
+                               return;
+                       }
+
+                       len  = kMaxValueLen;
+               }
+
+               for(i=cnt; i<=(totalcnt-1); i++)
+                       env[i] = NULL;
+       }
+       else
+               return;
+
+       *penv = env;
+
+       return;
+}
+
+
+
+/*============================================================================================
+
+ Function              :       fnDestroyEnvBlock
+
+ Description   :       Frees resources used by the ENV block.
+
+ Parameters            :       env     (IN)    -       ENV variable as char**.
+
+ Returns               :       Nothing.
+
+==============================================================================================*/
+
+void fnDestroyEnvBlock(char** env)
+{
+       // It is assumed that this block is entered only if env is TRUE. So, the calling function
+       // must check for this condition before calling fnDestroyEnvBlock.
+       // If no check is made by the calling function, then the server abends.
+       int k = 0;
+       while (env[k] != NULL)
+       {
+               free(env[k]);
+               env[k] = NULL;
+               k++;
+       }
+
+       free(env);
+       env = NULL;
+
+       return;
+}
+
+
+
+/*============================================================================================
+
+ Function              :       fnFpSetMode
+
+ Description   :       Sets the mode for a file.
+
+ Parameters            :       fp      (IN)    -       FILE pointer for the input file.
+                                       mode    (IN)    -       Mode to be set
+                                       e       (OUT)   -       Error.
+
+ Returns               :       Integer which is the set value.
+
+==============================================================================================*/
+
+int fnFpSetMode(FILE* fp, int mode, int *err)
+{
+       int ret = -1;
+
+       PFFSETMODE pf_fsetmode;
+
+
+       if (mode == O_BINARY || mode == O_TEXT)
+       {
+               if (fp)
+               {
+                       errno = 0;
+                       // the setmode call is not implemented (correctly) on NetWare,
+                       // but the CLIB guys were kind enough to provide another
+                       // call, fsetmode, which does a similar thing. It only works
+                       // on Moab
+                       pf_fsetmode = (PFFSETMODE) ImportSymbol(GetNLMHandle(), (char *)"fsetmode");
+                       if (pf_fsetmode)
+                               ret = (*pf_fsetmode) (fp, ((mode == O_BINARY) ? "b" : "t"));
+                       else
+                       {
+                               // we are on 4.11 instead of Moab, so we just return an error
+                               errno = ESERVER;
+                               err = &errno;
+                       }
+                       if (errno)
+                               err = &errno;
+
+               }
+               else
+               {
+                       errno = EBADF;
+                       err = &errno;
+               }
+       }
+       else
+       {
+               errno = EINVAL;
+               err = &errno;
+       }
+
+
+       return ret;
+}
+
+
+
+/*============================================================================================
+
+ Function              :       fnInternalPerlLaunchHandler
+
+ Description   :       Gets called by perl to spawn a new instance of perl.
+
+ Parameters            :       cndLine (IN)    -       Command Line string.
+
+ Returns               :       Nothing.
+
+==============================================================================================*/
+
+void fnInternalPerlLaunchHandler(char* cmdLine)
+{
+       int currentThreadGroup = -1;
+
+       ScriptData* psdata=NULL;
+
+
+       // Create a safe copy of the command line and pass it to the
+       // new thread for parsing. The new thread will be responsible
+       // to delete it when it is finished with it.
+       psdata = (ScriptData *) malloc(sizeof(ScriptData));
+       if (psdata)
+       {
+               psdata->m_commandLine = NULL;
+               psdata->m_commandLine = (char *) malloc(MAX_DN_BYTES * sizeof(char));
+
+               if(psdata->m_commandLine)
+               {
+                       strcpy(psdata->m_commandLine, cmdLine);
+                       psdata->m_fromConsole = FALSE;
+
+                       #ifdef MPK_ON
+                               BeginThread(fnLaunchPerl, NULL, PERL_COMMAND_STACK_SIZE, (void*)psdata);
+                       #else
+                               // Start a new thread in its own thread group
+                               BeginThread(fnLaunchPerl, NULL, PERL_COMMAND_STACK_SIZE, (void*)psdata);
+                       #endif  //MPK_ON
+               }
+               else
+               {
+                       free(psdata);
+                       psdata = NULL;
+                       return;
+               }
+       }
+       else
+               return;
+
+       return;
+}
+
+
+
+/*============================================================================================
+
+ Function              :       fnGetPerlScreenName
+
+ Description   :       This function creates the Perl screen name.
+                                       Gets called from main only once when the Perl NLM loads.
+
+ Parameters            :       sPerlScreenName (OUT)   -       Resultant Perl screen name.
+
+ Returns               :       Nothing.
+
+==============================================================================================*/
+
+void fnGetPerlScreenName(char *sPerlScreenName)
+{
+       // HYAK:
+       // The logic for using 32 in the below array sizes is like this:
+       // The NetWare CLIB SDK documentation says that for base 2 conversion,
+       // this number must be minimum 8. Also, in the example of the documentation,
+       // 20 is used as the size and testing is done for bases from 2 upto 16.
+       // So, to simply chose a number above 20 and also keeping in mind not to reserve
+       // unnecessary big array sizes, I have chosen 32 !
+       // Less than that may also suffice.
+       char sPerlRevision[32 * sizeof(char)] = {'\0'};
+       char sPerlVersion[32 * sizeof(char)] = {'\0'};
+       char sPerlSubVersion[32 * sizeof(char)] = {'\0'};
+
+       // The defines for PERL_REVISION, PERL_VERSION, PERL_SUBVERSION are available in
+       // patchlevel.h  under root and gets included when  perl.h  is included.
+       // The number 10 below indicates base 10.
+       itoa(PERL_REVISION, sPerlRevision, 10);
+       itoa(PERL_VERSION, sPerlVersion, 10);
+       itoa(PERL_SUBVERSION, sPerlSubVersion, 10);
+
+       // Concatenate substrings to get a string like Perl5.6.1 which is used as the screen name.
+       sprintf(sPerlScreenName, "%s%s.%s.%s", PERL_COMMAND_NAME,
+                                                                       sPerlRevision, sPerlVersion, sPerlSubVersion);
+
+       return;
+}
+
+
+
+// Global variable to hold the environ information.
+// First time it is accessed, it will be created and initialized and 
+// next time onwards, the pointer will be returned.
+
+// Improvements - Dynamically read env everytime a request comes - Is this required?
+char** genviron = NULL;
+
+
+/*============================================================================================
+
+ Function              :       nw_getenviron
+
+ Description   :       Gets the environment information.
+
+ Parameters            :       None.
+
+ Returns               :       Nothing.
+
+==============================================================================================*/
+
+char ***
+nw_getenviron()
+{
+       if (genviron)
+               // This (and not the next line) is the correct operation since it matches with the return type.
+               // But it is leaking memory upto 11736 bytes!!  So it is commented.
+//             return (&genviron);
+               return genviron;
+       else
+               fnSetUpEnvBlock(&genviron);
+
+       return (&genviron);
+}
+
+
+
+/*============================================================================================
+
+ Function              :       nw_freeenviron
+
+ Description   :       Frees the environment information.
+
+ Parameters            :       None.
+
+ Returns               :       Nothing.
+
+==============================================================================================*/
+
+void
+nw_freeenviron()
+{
+       if (genviron)
+       {
+               fnDestroyEnvBlock(genviron);
+               genviron=NULL;
+       }
+}
+
diff --git a/NetWare/Nwpipe.c b/NetWare/Nwpipe.c
new file mode 100644 (file)
index 0000000..2da2b06
--- /dev/null
@@ -0,0 +1,704 @@
+
+/*
+ * Copyright Â© 2001 Novell, Inc. All Rights Reserved.
+ *
+ * You may distribute under the terms of either the GNU General Public
+ * License or the Artistic License, as specified in the README file.
+ *
+ */
+
+/*
+ * FILENAME            :       NWPipe.c
+ * DESCRIPTION :       Functions to implement pipes on NetWare.
+ * Author              :       HYAK
+ * Date                        :       January 2001.
+ *
+ */
+
+
+
+#include <nwadv.h>
+#include <nwdsdefs.h>
+
+#include "win32ish.h"
+#include "nwpipe.h"
+#include "nwplglob.h"
+
+
+// This was added since the compile failed saying "undefined P_WAIT"
+// when USE_ITHREADS was commented in the makefile
+#ifndef P_WAIT
+#define        P_WAIT          0
+#endif
+
+#ifndef P_NOWAIT
+#define        P_NOWAIT        1
+#endif
+
+
+
+
+/*============================================================================================
+
+ Function              :       fnPipeFileMakeArgv
+
+ Description   :       This function makes the argument array.
+
+ Parameters    :       ptpf    (IN)    -       Input structure.
+
+ Returns               :       Boolean.
+
+==============================================================================================*/
+
+BOOL fnPipeFileMakeArgv(PTEMPPIPEFILE ptpf)
+{
+       int i=0, j=0;
+       int dindex = 0;
+       int sindex = 0;
+
+       ptpf->m_argv_len = 0;
+
+
+       // Below 2 is added for the following reason:
+       //   - The first one is for an additional value that will be added through ptpf->m_redirect.
+       //   - The second one is for a NULL termination of the array.
+       //     This is required for spawnvp API that takes a NULL-terminated array as its 3rd parameter.
+       //     If the array is NOT NULL-terminated, then the server abends at the spawnvp call !!
+       ptpf->m_argv = (char **) malloc((ptpf->m_pipeCommand->m_argc + 2) * sizeof(char*));
+       if (ptpf->m_argv == NULL)
+               return FALSE;
+
+       // For memory allocation it is just +1 since the last one is only for NULL-termination
+       // and no memory is required to be allocated.
+       for(i=0; i<(ptpf->m_pipeCommand->m_argc + 1); i++)
+       {
+               ptpf->m_argv[i] = (char *) malloc(MAX_DN_BYTES * sizeof(char));
+               if (ptpf->m_argv[i] == NULL)
+               {
+                       for(j=0; j<i; j++)
+                       {
+                               if(ptpf->m_argv[j])
+                               {
+                                       free(ptpf->m_argv[j]);
+                                       ptpf->m_argv[j] = NULL;
+                               }
+                       }
+                       free(ptpf->m_argv);
+                       ptpf->m_argv = NULL;
+
+                       return FALSE;
+               }
+       }
+
+       // Copy over parsed items, removing "load" keyword if necessary.
+       sindex = ((stricmp(ptpf->m_pipeCommand->m_argv[0], LOAD_COMMAND) == 0) ? 1 : 0);
+       while (sindex < ptpf->m_pipeCommand->m_argc)
+       {
+               strcpy(ptpf->m_argv[dindex], ptpf->m_pipeCommand->m_argv[sindex]);
+               dindex++;
+               sindex++;
+       }
+
+       if (stricmp(ptpf->m_argv[0], PERL_COMMAND_NAME) == 0)   // If Perl is the first command.
+       {
+               ptpf->m_launchPerl = TRUE;
+
+               #ifdef MPK_ON
+                       ptpf->m_perlSynchSemaphore = kSemaphoreAlloc((BYTE *)"pipeSemaphore", 0);
+               #else
+                       ptpf->m_perlSynchSemaphore = OpenLocalSemaphore(0);
+               #endif  //MPK_ON
+       }
+       else if (stricmp(ptpf->m_argv[0], (char *)"perlglob") == 0)
+               ptpf->m_doPerlGlob = TRUE;
+
+
+       // Create last argument, which will redirect to or from the temp file
+       if (!ptpf->m_doPerlGlob || ptpf->m_mode)
+       {
+               if (!ptpf->m_mode)      // If read mode?
+               {
+                       if (ptpf->m_launchPerl)
+                               strcpy(ptpf->m_redirect, (char *)">");
+                       else
+                               strcpy(ptpf->m_redirect, (char *)"(CLIB_OPT)/>");
+               }
+               else
+               {
+                       if (ptpf->m_launchPerl)
+                               strcpy(ptpf->m_redirect, (char *)"<");
+                       else
+                               strcpy(ptpf->m_redirect, (char *)"(CLIB_OPT)/<");
+               }
+               strcat(ptpf->m_redirect, ptpf->m_fileName);
+
+               if (ptpf->m_launchPerl)
+               {
+                       char tbuf[15] = {'\0'};
+                       sprintf(tbuf, (char *)" -{%x", ptpf->m_perlSynchSemaphore);
+                       strcat(ptpf->m_redirect, tbuf);
+               }
+
+               strcpy(ptpf->m_argv[dindex], (char*) ptpf->m_redirect);
+               dindex++;
+       }
+
+       if (dindex < (ptpf->m_pipeCommand->m_argc + 1))
+       {
+               if(ptpf->m_argv[dindex])
+               {
+                       free(ptpf->m_argv[dindex]);
+                       ptpf->m_argv[dindex] = NULL;    // NULL termination - required for  spawnvp  call.
+               }
+       }
+
+       ptpf->m_argv_len = dindex;              // Length of the argv array  OR  number of argv string values.
+       ptpf->m_argv[ptpf->m_argv_len] = NULL;  // NULL termination - required for  spawnvp  call.
+
+
+       return TRUE;
+}
+
+
+/*============================================================================================
+
+ Function              :       fnPipeFileOpen
+
+ Description   :       This function opens the pipe file.
+
+ Parameters    :       ptpf    (IN)    -       Input structure.
+                                       command (IN)    -       Input command string.
+                                       mode    (IN)    -       Mode of opening.
+
+ Returns               :       File pointer.
+
+==============================================================================================*/
+
+FILE* fnPipeFileOpen(PTEMPPIPEFILE ptpf, char* command, char* mode)
+{
+       int i=0, j=0;
+
+       char tempName[_MAX_PATH] = {'\0'};
+
+
+       ptpf->m_fileName = (char *) malloc(_MAX_PATH * sizeof(char));
+       if(ptpf->m_fileName == NULL)
+               return NULL;
+
+       // The char array is emptied so that there is no junk characters.
+       strncpy(ptpf->m_fileName, "", (_MAX_PATH * sizeof(char)));
+       
+
+       // Save off stuff
+       //
+       if(strchr(mode,'r') != 0)
+               ptpf->m_mode = FALSE;   // Read mode
+       else if(strchr(mode,'w') != 0)
+               ptpf->m_mode = TRUE;    // Write mode
+       else
+       {
+               if(ptpf->m_fileName != NULL)
+               {
+//                     if (strlen(ptpf->m_fileName))
+                       if (ptpf->m_fileName)
+                               unlink(ptpf->m_fileName);
+
+                       free(ptpf->m_fileName);
+                       ptpf->m_fileName = NULL;
+               }
+
+               return NULL;
+       }
+
+
+       ptpf->m_pipeCommand = (PCOMMANDLINEPARSER) malloc(sizeof(COMMANDLINEPARSER));
+       if (!ptpf->m_pipeCommand)
+       {
+//             if (strlen(ptpf->m_fileName))
+               if (ptpf->m_fileName)
+                       unlink(ptpf->m_fileName);
+
+               free(ptpf->m_fileName);
+               ptpf->m_fileName = NULL;
+
+               return NULL;
+       }
+
+       // Initialise the variables
+       ptpf->m_pipeCommand->m_isValid = TRUE;
+
+/****
+// Commented since these are not being used.  Still retained here.
+// To be removed once things are proved to be working fine to a good confident level,
+
+       ptpf->m_pipeCommand->m_redirInName = NULL;
+       ptpf->m_pipeCommand->m_redirOutName = NULL;
+       ptpf->m_pipeCommand->m_redirErrName = NULL;
+       ptpf->m_pipeCommand->m_redirBothName = NULL;
+       ptpf->m_pipeCommand->nextarg = NULL;
+****/
+
+       ptpf->m_pipeCommand->sSkippedToken = NULL;
+       ptpf->m_pipeCommand->m_argv = NULL;
+       ptpf->m_pipeCommand->new_argv = NULL;
+
+       #ifdef MPK_ON
+               ptpf->m_pipeCommand->m_qSemaphore = NULL;
+       #else
+               ptpf->m_pipeCommand->m_qSemaphore = 0L;
+       #endif  //MPK_ON
+
+       ptpf->m_pipeCommand->m_noScreen = 0;
+       ptpf->m_pipeCommand->m_AutoDestroy = 0;
+       ptpf->m_pipeCommand->m_argc = 0;
+       ptpf->m_pipeCommand->m_argv_len = 1;
+
+
+       ptpf->m_pipeCommand->m_argv = (char **) malloc(ptpf->m_pipeCommand->m_argv_len * sizeof(char *));
+       if (ptpf->m_pipeCommand->m_argv == NULL)
+       {
+               free(ptpf->m_pipeCommand);
+               ptpf->m_pipeCommand = NULL;
+
+//             if (strlen(ptpf->m_fileName))
+               if (ptpf->m_fileName)
+                       unlink(ptpf->m_fileName);
+
+               free(ptpf->m_fileName);
+               ptpf->m_fileName = NULL;
+
+               return NULL;
+       }
+       ptpf->m_pipeCommand->m_argv[0] = (char *) malloc(MAX_DN_BYTES * sizeof(char));
+       if (ptpf->m_pipeCommand->m_argv[0] == NULL)
+       {
+               for(j=0; j<i; j++)
+               {
+                       if(ptpf->m_pipeCommand->m_argv[j])
+                       {
+                               free(ptpf->m_pipeCommand->m_argv[j]);
+                               ptpf->m_pipeCommand->m_argv[j]=NULL;
+                       }
+               }
+               free(ptpf->m_pipeCommand->m_argv);
+               ptpf->m_pipeCommand->m_argv=NULL;
+
+               free(ptpf->m_pipeCommand);
+               ptpf->m_pipeCommand = NULL;
+
+//             if (strlen(ptpf->m_fileName))
+               if (ptpf->m_fileName)
+                       unlink(ptpf->m_fileName);
+
+               free(ptpf->m_fileName);
+               ptpf->m_fileName = NULL;
+
+               return NULL;
+       }
+
+
+       ptpf->m_redirect = (char *) malloc(MAX_DN_BYTES * sizeof(char));
+       if (ptpf->m_redirect == NULL)
+       {
+               for(i=0; i<ptpf->m_pipeCommand->m_argv_len; i++)
+               {
+                       if(ptpf->m_pipeCommand->m_argv[i] != NULL)
+                       {
+                               free(ptpf->m_pipeCommand->m_argv[i]);
+                               ptpf->m_pipeCommand->m_argv[i] = NULL;
+                       }
+               }
+
+               free(ptpf->m_pipeCommand->m_argv);
+               ptpf->m_pipeCommand->m_argv = NULL;
+
+               free(ptpf->m_pipeCommand);
+               ptpf->m_pipeCommand = NULL;
+
+
+//             if (strlen(ptpf->m_fileName))
+               if (ptpf->m_fileName)
+                       unlink(ptpf->m_fileName);
+
+               free(ptpf->m_fileName);
+               ptpf->m_fileName = NULL;
+
+               return NULL;
+       }
+
+       // The char array is emptied.
+       // If it is not done so, then it could contain some junk values and the string length in that case
+       // will not be zero.  This causes erroneous results in  fnPipeFileMakeArgv()  function
+       // where  strlen(ptpf->m_redirect)  is used as a check for incrementing the parameter count and
+       // it will wrongly get incremented in such cases.
+       strncpy(ptpf->m_redirect, "", (MAX_DN_BYTES * sizeof(char)));
+
+       // Parse the parameters.
+       fnCommandLineParser(ptpf->m_pipeCommand, (char *)command, TRUE);
+       if (!ptpf->m_pipeCommand->m_isValid)
+       {
+               fnTempPipeFileReleaseMemory(ptpf);
+               return NULL;
+       }
+
+
+       // Create a temporary file name
+       //
+       strncpy ( tempName, fnNwGetEnvironmentStr((char *)"TEMP", DEFTEMP), (_MAX_PATH - 20) );
+       tempName[_MAX_PATH-20] = '\0';
+       strcat(tempName, (char *)"\\plXXXXXX.tmp");
+       if (!fnMy_MkTemp(tempName))
+       {
+               fnTempPipeFileReleaseMemory(ptpf);
+               return NULL;
+       }
+
+       // create a temporary place-holder file
+       fclose(fopen(tempName, (char *)"w"));
+       strcpy(ptpf->m_fileName, tempName);
+
+
+       // Make the argument array
+       if(!fnPipeFileMakeArgv(ptpf))
+       {
+               fnTempPipeFileReleaseMemory(ptpf);
+
+               // Release additional memory
+               if(ptpf->m_argv != NULL)
+               {
+                       for(i=0; i<ptpf->m_argv_len; i++)
+                       {
+                               if(ptpf->m_argv[i] != NULL)
+                               {
+                                       free(ptpf->m_argv[i]);
+                                       ptpf->m_argv[i] = NULL;
+                               }
+                       }
+
+                       free(ptpf->m_argv);
+                       ptpf->m_argv = NULL;
+               }
+
+               return NULL;
+       }
+
+
+       // Open the temp file in the appropriate way...
+       //
+       if (!ptpf->m_mode)      // If Read mode?
+       {
+               // we wish to spawn a command, intercept its output,
+               // and then get that output
+               //
+               if (!ptpf->m_argv[0])
+               {
+                       fnTempPipeFileReleaseMemory(ptpf);
+
+                       // Release additional memory
+                       if(ptpf->m_argv != NULL)
+                       {
+                               for(i=0; i<ptpf->m_argv_len; i++)
+                               {
+                                       if(ptpf->m_argv[i] != NULL)
+                                       {
+                                               free(ptpf->m_argv[i]);
+                                               ptpf->m_argv[i] = NULL;
+                                       }
+                               }
+
+                               free(ptpf->m_argv);
+                               ptpf->m_argv = NULL;
+                       }
+
+                       return NULL;
+               }
+
+               if (ptpf->m_launchPerl)
+                       fnPipeFileDoPerlLaunch(ptpf);
+               else
+                       if (ptpf->m_doPerlGlob)
+                               fnDoPerlGlob(ptpf->m_argv, ptpf->m_fileName);   // hack to do perl globbing
+               else
+                       spawnvp(P_WAIT, ptpf->m_argv[0], ptpf->m_argv);
+
+               ptpf->m_file = fopen (ptpf->m_fileName, (char *)"r");   // Get the Pipe file handle
+       }
+       else if (ptpf->m_mode)  // If Write mode?
+       {
+               // we wish to open the file for writing now and
+               // do the command later
+               //
+               ptpf->m_file = fopen(ptpf->m_fileName, (char *)"w");
+       }
+
+       fnTempPipeFileReleaseMemory(ptpf);
+
+       // Release additional memory
+       if(ptpf->m_argv != NULL)
+       {
+               for(i=0; i<(ptpf->m_argv_len); i++)
+               {
+                       if(ptpf->m_argv[i] != NULL)
+                       {
+                               free(ptpf->m_argv[i]);
+                               ptpf->m_argv[i] = NULL;
+                       }
+               }
+
+               free(ptpf->m_argv);
+               ptpf->m_argv = NULL;
+       }
+
+               
+       return ptpf->m_file;    // Return the Pipe file handle.
+}
+
+
+/*============================================================================================
+
+ Function              :       fnPipeFileClose
+
+ Description   :       This function closes the pipe file.
+
+ Parameters    :       ptpf    (IN)    -       Input structure.
+
+ Returns               :       Nothing.
+
+==============================================================================================*/
+
+void fnPipeFileClose(PTEMPPIPEFILE ptpf)
+{
+       int i = 0;
+
+       if (ptpf->m_mode)       // If Write mode?
+       {
+               // we wish to spawn a command using our temp file for
+               // its input
+               //
+               if(ptpf->m_file != NULL)
+               {
+                       fclose (ptpf->m_file);
+                       ptpf->m_file = NULL;
+               }
+
+               if (ptpf->m_launchPerl)
+                       fnPipeFileDoPerlLaunch(ptpf);
+               else if (ptpf->m_argv)
+                       spawnvp(P_WAIT, ptpf->m_argv[0], ptpf->m_argv);
+       }
+
+
+       // Close the temporary Pipe File, if opened
+       if (ptpf->m_file)
+       {
+               fclose(ptpf->m_file);
+               ptpf->m_file = NULL;
+       }
+       // Delete the temporary Pipe Filename if still valid and free the memory associated with the file name.
+       if(ptpf->m_fileName != NULL)
+       {
+//             if (strlen(ptpf->m_fileName))
+               if (ptpf->m_fileName)
+                       unlink(ptpf->m_fileName);
+
+               free(ptpf->m_fileName);
+               ptpf->m_fileName = NULL;
+       }
+
+/**
+       if(ptpf->m_argv != NULL)
+       {
+               for(i=0; i<(ptpf->m_argv_len); i++)
+               {
+                       if(ptpf->m_argv[i] != NULL)
+                       {
+                               free(ptpf->m_argv[i]);
+                               ptpf->m_argv[i] = NULL;
+                       }
+               }
+
+               free(ptpf->m_argv);
+               ptpf->m_argv = NULL;
+       }
+**/
+
+       if (ptpf->m_perlSynchSemaphore)
+       {
+               #ifdef MPK_ON
+                       kSemaphoreFree(ptpf->m_perlSynchSemaphore);
+               #else
+                       CloseLocalSemaphore(ptpf->m_perlSynchSemaphore);
+               #endif  //MPK_ON
+       }
+
+
+       return;
+}
+
+
+/*============================================================================================
+
+ Function              :       fnPipeFileDoPerlLaunch
+
+ Description   :       This function launches Perl.
+
+ Parameters    :       ptpf    (IN)    -       Input structure.
+
+ Returns               :       Nothing.
+
+==============================================================================================*/
+
+void fnPipeFileDoPerlLaunch(PTEMPPIPEFILE ptpf)
+{
+       char curdir[_MAX_PATH] = {'\0'};
+       char* pcwd = NULL;
+
+       int i=0;
+
+
+       // save off the current working directory to restore later
+       // this is just a hack! these problems of synchronization and
+       // restoring calling context need a much better solution!
+       pcwd = (char *)getcwd(curdir, sizeof(curdir)-1);
+       fnSystemCommand(ptpf->m_argv, ptpf->m_argv_len);
+       if (ptpf->m_perlSynchSemaphore)
+       {
+               #ifdef MPK_ON
+                       kSemaphoreWait(ptpf->m_perlSynchSemaphore);
+               #else
+                       WaitOnLocalSemaphore(ptpf->m_perlSynchSemaphore);
+               #endif  //MPK_ON
+       }
+
+       if (pcwd)
+               chdir(pcwd);
+
+       return;
+}
+
+
+/*============================================================================================
+
+ Function              :       fnTempPipeFile
+
+ Description   :       This function initialises the variables of the structure passed in.
+
+ Parameters    :       ptpf    (IN)    -       Input structure.
+
+ Returns               :       Nothing.
+
+==============================================================================================*/
+
+void fnTempPipeFile(PTEMPPIPEFILE ptpf)
+{
+       ptpf->m_fileName = NULL;
+
+       ptpf->m_mode = FALSE;   // Default mode = Read mode.
+       ptpf->m_file = NULL;
+       ptpf->m_pipeCommand = NULL;
+       ptpf->m_argv = NULL;
+
+       ptpf->m_redirect = NULL;
+
+       ptpf->m_launchPerl = FALSE;
+       ptpf->m_doPerlGlob = FALSE;
+
+       #ifdef MPK_ON
+               ptpf->m_perlSynchSemaphore = NULL;
+       #else
+               ptpf->m_perlSynchSemaphore = 0L;
+       #endif
+
+       ptpf->m_argv_len = 0;
+
+       return;
+}
+
+
+/*============================================================================================
+
+ Function              :       fnTempPipeFileReleaseMemory
+
+ Description   :       This function frees the memory allocated to various buffers.
+
+ Parameters    :       ptpf    (IN)    -       Input structure.
+
+ Returns               :       Nothing.
+
+==============================================================================================*/
+
+void fnTempPipeFileReleaseMemory(PTEMPPIPEFILE ptpf)
+{
+       int i=0;
+
+
+       if (ptpf->m_pipeCommand)
+       {
+               if(ptpf->m_pipeCommand->m_argv != NULL)
+               {
+                       for(i=0; i<ptpf->m_pipeCommand->m_argv_len; i++)
+                       {
+                               if(ptpf->m_pipeCommand->m_argv[i] != NULL)
+                               {
+                                       free(ptpf->m_pipeCommand->m_argv[i]);
+                                       ptpf->m_pipeCommand->m_argv[i] = NULL;
+                               }
+                       }
+
+                       free(ptpf->m_pipeCommand->m_argv);
+                       ptpf->m_pipeCommand->m_argv = NULL;
+               }
+
+               if(ptpf->m_pipeCommand->sSkippedToken != NULL)
+               {
+                       free(ptpf->m_pipeCommand->sSkippedToken);
+                       ptpf->m_pipeCommand->sSkippedToken = NULL;
+               }
+/****
+// Commented since these are not being used.  Still retained here.
+// To be removed once things are proved to be working fine to a good confident level,
+
+               if(ptpf->m_pipeCommand->nextarg)
+               {
+                       free(ptpf->m_pipeCommand->nextarg);
+                       ptpf->m_pipeCommand->nextarg = NULL;
+               }
+
+               if(ptpf->m_pipeCommand->m_redirInName)
+               {
+                       free(ptpf->m_pipeCommand->m_redirInName);
+                       ptpf->m_pipeCommand->m_redirInName = NULL;
+               }
+               if(ptpf->m_pipeCommand->m_redirOutName)
+               {
+                       free(ptpf->m_pipeCommand->m_redirOutName);
+                       ptpf->m_pipeCommand->m_redirOutName = NULL;
+               }
+               if(ptpf->m_pipeCommand->m_redirErrName)
+               {
+                       free(ptpf->m_pipeCommand->m_redirErrName);
+                       ptpf->m_pipeCommand->m_redirErrName = NULL;
+               }
+               if(ptpf->m_pipeCommand->m_redirBothName)
+               {
+                       free(ptpf->m_pipeCommand->m_redirBothName);
+                       ptpf->m_pipeCommand->m_redirBothName = NULL;
+               }
+****/
+
+               if(ptpf->m_pipeCommand != NULL)
+               {
+                       free(ptpf->m_pipeCommand);
+                       ptpf->m_pipeCommand = NULL;
+               }
+       }
+
+       if(ptpf->m_redirect != NULL)
+       {
+               free(ptpf->m_redirect);
+               ptpf->m_redirect = NULL;
+       }
+
+       return;
+}
+
diff --git a/NetWare/bat/BldNWExt.bat b/NetWare/bat/BldNWExt.bat
new file mode 100644 (file)
index 0000000..bdeddbb
--- /dev/null
@@ -0,0 +1,39 @@
+@echo off
+@rem AUTHOR: sgp
+@rem CREATED: Sat Apr 14 13:05:44 2001
+@rem LAST REVISED: Sat Apr 14 2001
+@rem Batch file to toggle b/n building and not building NetWare
+@rem specific extns - cgi2perl & perl2ucs.
+
+if "%1" == "" goto Usage
+
+if "%1" == "/now" goto now
+if "%1" == "on" goto yes
+if "%1" == "off" goto no
+if "%1" == "/?" goto usage
+if "%1" == "/h" goto usage
+goto dontknow
+
+:now
+if not "%NW_EXTNS%" == "yes" echo NW_EXTNS is removed, doesn't build NetWare specific extensions
+if "%NW_EXTNS%"  == "yes" echo NW_EXTNS is set, builds NetWare specific extensions
+goto exit
+
+:yes
+Set NW_EXTNS=yes
+echo ....NW_EXTNS is set, builds NetWare specific extensions
+goto exit
+
+:no
+Set NW_EXTNS=
+echo ....NW_EXTNS is removed, doesn't build NetWare specific extensions
+goto exit
+
+:dontknow
+goto Usage
+
+:Usage
+ @echo on
+ @echo "Usage: BldNWExt [on|off]"
+ @echo "Usage: BldNWExt /now" - To display current setting
+:exit
diff --git a/NetWare/bat/Buildtype.bat b/NetWare/bat/Buildtype.bat
new file mode 100644 (file)
index 0000000..9f39da7
--- /dev/null
@@ -0,0 +1,53 @@
+@echo off
+@rem AUTHOR: sgp
+@rem CREATED: 24th July 2000
+@rem LAST REVISED: 6th April 2001
+@rem Batch file to set debug/release build and toggle D2 flag for 
+@rem debugging in case of debug build.
+@rem This file calls ToggleD2.bat which switches b/n d2 & d1 flags
+
+if "%1" == "" goto Usage
+if "%1" == "/now" goto now
+if "%1" == "/?" goto usage
+if "%1" == "/h" goto usage
+
+if "%1" == "r" goto set_type_rel
+if "%1" == "R" goto set_type_rel
+
+if "%1" == "d" goto set_type_dbg
+if "%1" == "D" goto set_type_dbg
+
+Rem Invalid input, display help message
+goto Usage
+:set_type_rel
+set MAKE_TYPE=Release
+echo ....Build set to %MAKE_TYPE%
+goto set_d2_off
+
+:set_type_dbg
+set MAKE_TYPE=Debug
+echo ....Build set to %MAKE_TYPE%
+if "%2" == "" goto set_d2_off
+call ToggleD2 %2
+
+goto exit
+
+:set_d2_off
+call ToggleD2 off
+goto exit
+
+:now
+if "%MAKE_TYPE%" == "" echo MAKE_TYPE is not set, hence it defaults to Release build
+if not "%MAKE_TYPE%"  == "" echo Current build type is - %MAKE_TYPE%
+call ToggleD2 /now
+goto exit
+
+:Usage
+ @echo on
+ @echo "Usage: buildtype r/R|d/D [on/off]"  
+ @echo      on/off - Toggling D2 flag for debug build
+ @echo "Usage: buildtype /now"  - To display current setting
+ @echo Ex. buildtype d on
+
+:exit
diff --git a/NetWare/bat/MPKBuild.bat b/NetWare/bat/MPKBuild.bat
new file mode 100644 (file)
index 0000000..0740906
--- /dev/null
@@ -0,0 +1,64 @@
+@echo off
+@rem AUTHOR: sgp
+@rem CREATED: 22nd May 2000
+@rem LAST REVISED: 6th April 2001
+@rem Batch file to set MPK/Non-MPK builds and toggle XDC flag setting
+@rem This file calls ToggleXDC.bat
+
+if "%1" == "" goto Usage
+
+if "%1" == "/now" goto now
+if "%1" == "on" goto yes
+if "%1" == "off" goto no
+if "%1" == "/?" goto usage
+goto dontknow
+
+:now
+if "%USE_MPK%" == "" echo USE_MPK is removed, doesn't use MPK APIs
+if not "%USE_MPK%"  == "" echo USE_MPK is set, uses MPK APIs, MPKBASE set to %MPKBASE%
+call ToggleXDC %1
+goto exit
+
+:yes
+Set USE_MPK=1
+echo ....USE_MPK is set, uses MPK APIs
+if "%2" == "" goto setdef
+if "%2" == "default" goto setdef
+SET MPKBASE=%2
+:yescon1
+call ToggleXDC on %3 %4
+echo ....MPKBASE set to %MPKBASE%
+goto exit
+
+:no
+Set USE_MPK=
+SET MPKBASE=
+if not "%2" == "" goto xdc_u
+call ToggleXDC off
+:nocon1
+echo ....USE_MPK is removed. doesn't use MPK APIs
+goto exit
+
+:dontknow
+goto Usage
+
+:setdef
+SET MPKBASE=p:\apps\mpk
+goto yescon1
+
+:xdc_u
+call ToggleXDC on %2 %3
+goto nocon1
+
+:Usage
+ @echo on
+ @echo "Usage: MPKBuild [on][off] [[path][default]] [[flag1] [flag2]]"
+ @echo "Usage: MPKBuild /now"  - To display current setting
+ @echo Scenarios...
+ @echo ...Use MPK, path set to default and XDC set to -u     :MPKBuild on
+ @echo ...Use MPK, path set to default and XDC set to -u     :MPKBuild on default -n
+ @echo ...Use MPK, path set to "path" and XDC set to -n      :MPKBuild on "path" -n
+ @echo ...Use MPK, path set to default and XDC set to -n, -u :MPKBuild on default -n -u
+ @echo ...No MPK, No XDC                                     :MPKBuild off
+ @echo ...No MPK, Use XDC with -u flag                       :MPKBuild off -u
+:exit
diff --git a/NetWare/bat/SetNWBld.bat b/NetWare/bat/SetNWBld.bat
new file mode 100644 (file)
index 0000000..062c531
--- /dev/null
@@ -0,0 +1,62 @@
+@echo off
+@rem AUTHOR: sgp
+@rem CREATED: Thu 18th Jan 2001 09:18:08
+@rem LAST REVISED: 6th April 2001
+@rem Batch file to set the path to NetWare SDK, Watcom directories & MPK SDK
+@rem This file calls setnlmsdk.bat, setwatcom.bat & setmpksdk.bat
+
+REM If no parameters are passed, display usage
+if "%1" == "" goto Usage
+if "%1" == "/?" goto Usage
+if "%1" == "/h" goto Usage
+
+REM Display the current settings
+if "%1" == "/now" goto now
+
+REM If na is passed, don't set that parameter
+if "%1" == "na" goto skip_nlmsdk_msg
+:setnwsdk
+call setnlmsdk %1
+goto skip_nlmsdk_nomsg
+
+:skip_nlmsdk_msg
+@echo Retaining NLMSDKBASE=%NLMSDKBASE%
+:skip_nlmsdk_nomsg
+
+if "%2" == "" goto exit
+if "%2" == "na" goto skip_watcom_msg
+:setwatcom
+call setwatcom %2
+goto skip_watcom_nomsg
+
+:skip_watcom_msg
+@echo Retaining WATCOM=%WATCOM%
+:skip_watcom_nomsg
+
+if "%3" == "" goto exit
+if "%3" == "na" goto skip_mpksdk_msg
+:setmpk
+call setmpksdk %3
+goto skip_mpksdk_nomsg
+
+:skip_mpksdk_msg
+@echo Retaining MPKBASE=%MPKBASE%
+:skip_mpksdk_nomsg
+
+goto exit
+
+:now
+@echo NLMSDKBASE=%NLMSDKBASE%
+@echo WATCOM=%WATCOM%
+@echo MPKBASE=%MPKBASE%
+goto exit
+
+goto exit
+:Usage
+ @echo on
+ @echo "Usage: setnwbld <path to NetWare SDK> [<path to Watcom dir>] [<path to MPK SDK>]"
+ @echo "Usage: setnwbld /now" - To display current setting
+ @echo Pass na if you don't want to change a setting
+ @echo Ex. setnwbld d:\ndk\nwsdk na p:\mpk
+ @echo Ex. setnwbld d:\ndk\
+:exit
diff --git a/NetWare/bat/Setmpksdk.bat b/NetWare/bat/Setmpksdk.bat
new file mode 100644 (file)
index 0000000..3404fa4
--- /dev/null
@@ -0,0 +1,27 @@
+@echo off
+@rem AUTHOR: sgp
+@rem CREATED: 24th July 2000
+@rem LAST REVISED: 6th April 2001
+@rem Batch file to set the path to MPK SDK
+@rem This file is called from SetNWBld.bat. 
+
+if "%1" == "/now" goto now
+if "%1" == "" goto Usage
+if "%1" == "/?" goto usage
+if "%1" == "/h" goto usage
+
+SET MPKBASE=%1
+echo MPKBASE set to %1
+
+goto exit
+
+:now
+@echo MPKBASE=%MPKBASE%
+goto exit
+
+:Usage
+ @echo on
+ @echo "Usage: setmpksdk <path to MPK sdk>"
+ @echo "Usage: setmpksdk /now" - To display current setting
+ @echo Ex. setmpksdk p:\sw\mpk
+:exit
diff --git a/NetWare/bat/Setnlmsdk.bat b/NetWare/bat/Setnlmsdk.bat
new file mode 100644 (file)
index 0000000..82fcf8b
--- /dev/null
@@ -0,0 +1,28 @@
+@echo off
+@rem AUTHOR: sgp
+@rem CREATED: 24th July 2000
+@rem LAST REVISED: 6th April 2001
+@rem Batch file to set the path to NetWare SDK
+@rem This file is called from SetNWBld.bat. 
+
+if "%1" == "/now" goto now
+if "%1" == "" goto Usage
+if "%1" == "/?" goto usage
+if "%1" == "/h" goto usage
+
+set NLMSDKBASE=%1
+echo NLMSDKBASE set to %1
+
+goto exit
+
+:now
+@echo NLMSDKBASE=%NLMSDKBASE%
+goto exit
+
+:Usage
+ @echo on
+ @echo "Usage: setnlmsdk <path to NetWare sdk>"
+ @echo "Usage: setnlmsdk /now" - To display current setting
+ @echo Ex. setnlmsdk e:\sdkcd14\nwsdk
+:exit
+
diff --git a/NetWare/bat/Setwatcom.bat b/NetWare/bat/Setwatcom.bat
new file mode 100644 (file)
index 0000000..445ac67
--- /dev/null
@@ -0,0 +1,28 @@
+@echo off
+@rem AUTHOR: sgp
+@rem CREATED: 24th July 2000
+@rem LAST REVISED: 6th April 2001
+@rem Batch file to set the path to Watcom directories
+@rem This file is called from SetNWBld.bat. 
+
+if "%1" == "/now" goto now
+if "%1" == "" goto Usage
+if "%1" == "/?" goto usage
+if "%1" == "/h" goto usage
+
+set WATCOM=%1
+echo WATCOM set to %1
+
+goto exit
+
+:now
+@echo WATCOM=%WATCOM%
+goto exit
+
+:Usage
+ @echo on
+ @echo "Usage: setwatcom <path to Watcom>"
+ @echo "Usage: setwatcom /now" - To display current setting
+ @echo Ex. setwatcom d:\Watcom
+:exit
+
diff --git a/NetWare/bat/ToggleD2.bat b/NetWare/bat/ToggleD2.bat
new file mode 100644 (file)
index 0000000..d3f5d2c
--- /dev/null
@@ -0,0 +1,40 @@
+@echo off
+@rem AUTHOR: sgp
+@rem CREATED: 23rd August 1999
+@rem LAST REVISED: 6th April 2001
+@rem Batch file to toggle D2 flag for debugging in case of debug build 
+@rem and remove in case of release build.
+@rem This file is called from BuildType.bat
+
+if "%1" == "" goto Usage
+
+if "%1" == "/now" goto now
+if "%1" == "on" goto yes
+if "%1" == "off" goto no
+if "%1" == "/?" goto usage
+if "%1" == "/h" goto usage
+goto dontknow
+
+:now
+if "%USE_D2%" == "" echo USE_D2 is removed, uses /d1
+if not "%USE_D2%"  == "" echo USE_D2 is set, uses /d2
+goto exit
+
+:yes
+Set USE_D2=1
+echo ....USE_D2 is set, uses /d2
+goto exit
+
+:no
+Set USE_D2=
+echo ....USE_D2 is removed. uses /d1
+goto exit
+
+:dontknow
+goto Usage
+
+:Usage
+ @echo on
+ @echo "Usage: ToggleD2 [on|off]"
+ @echo "Usage: ToggleD2 /now" - To display current setting
+:exit
diff --git a/NetWare/bat/ToggleXDC.bat b/NetWare/bat/ToggleXDC.bat
new file mode 100644 (file)
index 0000000..eafe4ed
--- /dev/null
@@ -0,0 +1,43 @@
+@echo off
+@rem AUTHOR: sgp
+@rem CREATED: 2nd November 1999
+@rem LAST REVISED: 6th April 2001
+@rem Batch file to toggle XDC flag setting, to link with XDC or not
+@rem This file is called from MPKBuild.bat. 
+
+if "%1" == "" goto Usage
+
+if "%1" == "/now" goto now
+if "%1" == "on" goto yes
+if "%1" == "off" goto no
+if "%1" == "/?" goto usage
+goto dontknow
+
+:now
+if "%USE_XDC%" == "" echo USE_XDC is removed, doesn't link with XDCDATA
+if not "%USE_XDC%"  == "" echo USE_XDC is set, links with XDCDATA, XDCFLAGS = %XDCFLAGS%
+goto exit
+
+:yes
+Set USE_XDC=1
+echo ....USE_XDC is set, links with XDCDATA
+if "%2" == "" SET XDCFLAGS=-n
+if not "%2" == "" SET XDCFLAGS=%2
+if not "%3" == "" SET XDCFLAGS=%XDCFLAGS% %3
+echo ....XDCFLAGS set to %XDCFLAGS%
+goto exit
+
+:no
+Set USE_XDC=
+SET XDCFLAGS=
+echo ....USE_XDC is removed. doesn't link with XDCDATA
+goto exit
+
+:dontknow
+goto Usage
+
+:Usage
+ @echo on
+ @echo "Usage: ToggleXDC [on|off] [[flag1] [flag2]]"
+ @echo "Usage: ToggleD2 /now"  - To display current setting
+:exit
diff --git a/NetWare/config.wc b/NetWare/config.wc
new file mode 100644 (file)
index 0000000..8ed8699
--- /dev/null
@@ -0,0 +1,800 @@
+## Configured by: ~cf_email~
+## Target system: NetWare 
+Author='Guruprasad'
+CONFIGDOTSH='true'
+Date='$Date'
+Header=''
+Id='$Id'
+Locker=''
+Log='$Log'
+Mcc='Mcc'
+RCSfile='$RCSfile'
+Revision='$Revision'
+Source=''
+State=''
+_a='.lib'
+_exe='.exe'
+_nlm='.nlm'
+_nlp='.nlp'
+_o='.obj'
+afs='false'
+alignbytes='8'
+ansi2knr=''
+aphostname=''
+api_revision='~PERL_API_REVISION~'
+api_subversion='~PERL_API_SUBVERSION~'
+api_version='~PERL_API_VERSION~'
+api_versionstring='~PERL_API_REVISION~.~PERL_API_VERSION~.~PERL_API_SUBVERSION~'
+ar='lib386'
+archlib='~INST_TOP~~INST_VER~\lib~INST_ARCH~'
+archlibexp='~INST_TOP~~INST_VER~\lib~INST_ARCH~'
+archname64=''
+archname='NetWare'
+archobjs=''
+awk='awk'
+baserev='5'
+bash=''
+bin='~INST_TOP~~INST_VER~\bin~INST_ARCH~'
+bincompat5005='undef'
+binexp='~INST_TOP~~INST_VER~\bin~INST_ARCH~'
+bison=''
+byacc='byacc'
+byteorder='1234'
+c=''
+castflags='0'
+cat='type'
+cc='cl'
+cccdlflags=' '
+ccdlflags=' '
+ccflags='-MD -DNETWARE'
+ccsymbols=''
+cf_by='nobody'
+cf_email='nobody@no.where.net'
+cf_time=''
+charsize='1'
+chgrp=''
+chmod=''
+chown=''
+clocktype='clock_t'
+comm=''
+compress=''
+contains='grep'
+cp='copy'
+cpio=''
+cpp='cl -nologo -E'
+cpp_stuff='42'
+cppccsymbols=''
+cppflags='-DNETWARE'
+cpplast=''
+cppminus=''
+cpprun='cl -nologo -E'
+cppstdin='cl -nologo -E'
+cppsymbols=''
+crosscompile='undef'
+cryptlib=''
+csh='undef'
+d_Gconvert='sprintf((b),"%.*g",(n),(x))'
+d_PRIEldbl='undef'
+d_PRIFldbl='undef'
+d_PRIGldbl='undef'
+d_PRIX64='undef'
+d_PRId64='undef'
+d_PRIeldbl='undef'
+d_PRIfldbl='undef'
+d_PRIgldbl='undef'
+d_PRIi64='undef'
+d_PRIo64='undef'
+d_PRIu64='undef'
+d_PRIx64='undef'
+d_access='define'
+d_accessx='undef'
+d_alarm='undef'
+d_archlib='define'
+d_atolf='undef'
+d_atoll='undef'
+d_attribut='undef'
+d_bcmp='undef'
+d_bcopy='undef'
+d_bincompat5005='undef'
+d_bsd='define'
+d_bsdgetpgrp='undef'
+d_bsdsetpgrp='undef'
+d_bzero='undef'
+d_casti32='undef'
+d_castneg='define'
+d_charvspr='undef'
+d_chown='undef'
+d_chroot='undef'
+d_chsize='define'
+d_closedir='define'
+d_const='define'
+d_crypt='undef'
+d_csh='undef'
+d_cuserid='undef'
+d_dbl_dig='define'
+d_difftime='define'
+d_dirnamlen='undef'
+d_dlerror='define'
+d_dlopen='define'
+d_dlsymun='undef'
+d_dosuid='undef'
+d_drand48proto='undef'
+d_dup2='define'
+d_eaccess='undef'
+d_endgrent='undef'
+d_endhent='undef'
+d_endnent='undef'
+d_endpent='undef'
+d_endpwent='undef'
+d_endsent='undef'
+d_endspent='undef'
+d_eofnblk='define'
+d_eunice='undef'
+d_fchmod='undef'
+d_fchown='undef'
+d_fcntl='undef'
+d_fd_macros='define'
+d_fd_set='define'
+d_fds_bits='define'
+d_fgetpos='define'
+d_flexfnam='define'
+d_flock='define'
+d_fork='undef'
+d_fpathconf='undef'
+d_fpos64_t='undef'
+d_fs_data_s='undef'
+d_fseeko='undef'
+d_fsetpos='define'
+d_fstatfs='undef'
+d_fstatvfs='undef'
+d_ftello='undef'
+d_ftime='define'
+d_getcwd='undef'
+d_getfsstat='undef'
+d_getgrent='undef'
+d_getgrps='undef'
+d_gethbyaddr='define'
+d_gethbyname='define'
+d_gethent='undef'
+d_gethname='define'
+d_gethostprotos='define'
+d_getlogin='define'
+d_getmnt='undef'
+d_getmntent='undef'
+d_getnbyaddr='undef'
+d_getnbyname='undef'
+d_getnent='undef'
+d_getnetprotos='define'
+d_getpbyname='define'
+d_getpbynumber='define'
+d_getpent='undef'
+d_getpgid='undef'
+d_getpgrp2='undef'
+d_getpgrp='undef'
+d_getppid='undef'
+d_getprior='undef'
+d_getprotoprotos='define'
+d_getpwent='undef'
+d_getsbyname='define'
+d_getsbyport='define'
+d_getsent='undef'
+d_getservprotos='define'
+d_getspent='undef'
+d_getspnam='undef'
+d_gettimeod='undef'
+d_gnulibc='undef'
+d_grpasswd='undef'
+d_hasmntopt='undef'
+d_htonl='define'
+d_iconv='undef'
+d_index='undef'
+d_inetaton='undef'
+d_int64_t='undef'
+d_isascii='define'
+d_killpg='undef'
+d_lchown='undef'
+d_ldbl_dig='define'
+d_link='define'
+d_locconv='define'
+d_lockf='undef'
+d_longdbl='define'
+d_longlong='undef'
+d_lseekproto='define'
+d_lstat='undef'
+d_madvise='undef'
+d_mblen='define'
+d_mbstowcs='define'
+d_mbtowc='define'
+d_memchr='define'
+d_memcmp='define'
+d_memcpy='define'
+d_memmove='define'
+d_memset='define'
+d_mkdir='define'
+d_mkdtemp='undef'
+d_mkfifo='undef'
+d_mkstemp='undef'
+d_mkstemps='undef'
+d_mktime='define'
+d_mmap='undef'
+d_mprotect='undef'
+d_msg='undef'
+d_msg_ctrunc='undef'
+d_msg_dontroute='undef'
+d_msg_oob='undef'
+d_msg_peek='undef'
+d_msg_proxy='undef'
+d_msgctl='undef'
+d_msgget='undef'
+d_msgrcv='undef'
+d_msgsnd='undef'
+d_msync='undef'
+d_munmap='undef'
+d_mymalloc='undef'
+d_nice='undef'
+d_nv_preserves_uv='define'
+d_off64_t='undef'
+d_old_pthread_create_joinable='undef'
+d_oldpthreads='undef'
+d_oldsock='undef'
+d_open3='undef'
+d_pathconf='undef'
+d_pause='undef'
+d_phostname='undef'
+d_pipe='define'
+d_poll='undef'
+d_portable='define'
+d_pthread_yield='undef'
+d_pwage='undef'
+d_pwchange='undef'
+d_pwclass='undef'
+d_pwcomment='undef'
+d_pwexpire='undef'
+d_pwgecos='undef'
+d_pwpasswd='undef'
+d_pwquota='undef'
+d_qgcvt='undef'
+d_quad='undef'
+d_readdir='define'
+d_readlink='undef'
+d_rename='define'
+d_rewinddir='define'
+d_rmdir='define'
+d_safebcpy='undef'
+d_safemcpy='undef'
+d_sanemcmp='define'
+d_sched_yield='undef'
+d_scm_rights='undef'
+d_seekdir='define'
+d_select='define'
+d_sem='undef'
+d_semctl='undef'
+d_semctl_semid_ds='undef'
+d_semctl_semun='undef'
+d_semget='undef'
+d_semop='undef'
+d_setegid='undef'
+d_seteuid='undef'
+d_setgrent='undef'
+d_setgrps='undef'
+d_sethent='undef'
+d_setlinebuf='undef'
+d_setlocale='define'
+d_setnent='undef'
+d_setpent='undef'
+d_setpgid='undef'
+d_setpgrp2='undef'
+d_setpgrp='undef'
+d_setprior='undef'
+d_setpwent='undef'
+d_setregid='undef'
+d_setresgid='undef'
+d_setresuid='undef'
+d_setreuid='undef'
+d_setrgid='undef'
+d_setruid='undef'
+d_setsent='undef'
+d_setsid='undef'
+d_setspent='undef'
+d_setvbuf='define'
+d_sfio='undef'
+d_shm='undef'
+d_shmat='undef'
+d_shmatprototype='undef'
+d_shmctl='undef'
+d_shmdt='undef'
+d_shmget='undef'
+d_sigaction='undef'
+d_sigsetjmp='undef'
+d_socket='define'
+d_socklen_t='undef'
+d_sockpair='undef'
+d_sqrtl='undef'
+d_statblks='undef'
+d_statfs_f_flags='undef'
+d_statfs_s='undef'
+d_statvfs='undef'
+d_stdio_cnt_lval='undef'
+d_stdio_ptr_lval='undef'
+d_stdio_stream_array='undef'
+d_stdiobase='undef'
+d_stdstdio='undef'
+d_strchr='define'
+d_strcoll='define'
+d_strctcpy='define'
+d_strerrm='strerror(e)'
+d_strerror='define'
+d_strtod='define'
+d_strtol='define'
+d_strtold='undef'
+d_strtoll='undef'
+d_strtoul='define'
+d_strtoull='undef'
+d_strtouq='undef'
+d_strxfrm='define'
+d_suidsafe='undef'
+d_symlink='undef'
+d_syscall='undef'
+d_sysconf='undef'
+d_sysernlst=''
+d_syserrlst='define'
+d_system='define'
+d_tcgetpgrp='undef'
+d_tcsetpgrp='undef'
+d_telldir='define'
+d_telldirproto='define'
+d_time='define'
+d_times='undef'
+d_truncate='undef'
+d_tzname='define'
+d_umask='define'
+d_uname='define'
+d_union_semun='define'
+d_ustat='undef'
+d_vendorarch='undef'
+d_vendorbin='undef'
+d_vendorlib='undef'
+d_vfork='undef'
+d_void_closedir='undef'
+d_voidsig='define'
+d_voidtty=''
+d_volatile='define'
+d_vprintf='define'
+d_wait4='undef'
+d_waitpid='define'
+d_wcstombs='define'
+d_wctomb='define'
+d_xenix='undef'
+date='date'
+db_hashtype='int'
+db_prefixtype='int'
+defvoidused='15'
+def_perlroot='sys:\perl\scripts'
+def_temp='sys:\perl\temp'
+direntrytype='DIR'
+dlext='nlp'
+dlsrc='dl_netware.xs'
+doublesize='8'
+drand01='(rand()/(double)((unsigned)1<<RANDBITS))'
+dynamic_ext='Socket IO Fcntl Opcode SDBM_File attrs Thread'
+eagain='EAGAIN'
+ebcdic='undef'
+echo='echo'
+egrep='egrep'
+emacs=''
+eunicefix=':'
+exe_ext='.exe'
+expr='expr'
+extensions='~static_ext~ ~dynamic_ext~ ~nonxs_ext~'
+fflushNULL='define'
+fflushall='undef'
+find='find'
+firstmakefile='makefile'
+flex=''
+fpossize='4'
+fpostype='fpos_t'
+freetype='void'
+full_ar=''
+full_csh=''
+full_sed=''
+gccversion=''
+gidformat='"ld"'
+gidsign='-1'
+gidsize='4'
+gidtype='gid_t'
+glibpth='/usr/shlib  /lib/pa1.1 /usr/lib/large /lib /usr/lib /usr/lib/386 /lib/386 /lib/large /usr/lib/small /lib/small /usr/ccs/lib /usr/ucblib /usr/shlib '
+grep='grep'
+groupcat=''
+groupstype='gid_t'
+gzip='gzip'
+h_fcntl='false'
+h_sysfile='true'
+hint='recommended'
+hostcat='ypcat hosts'
+huge=''
+i16size='2'
+i16type='short'
+i32size='4'
+i32type='long'
+i64size='8'
+i64type='__int64'
+i8size='1'
+i8type='char'
+i_arpainet='define'
+i_bsdioctl=''
+i_db='undef'
+i_dbm='undef'
+i_dirent='define'
+i_dld='undef'
+i_dlfcn='define'
+i_fcntl='define'
+i_float='define'
+i_gdbm='undef'
+i_grp='undef'
+i_iconv='undef'
+i_ieeefp='undef'
+i_inttypes='undef'
+i_limits='define'
+i_locale='define'
+i_machcthr='undef'
+i_malloc='define'
+i_math='define'
+i_memory='undef'
+i_mntent='undef'
+i_ndbm='undef'
+i_netdb='define'
+i_neterrno='undef'
+i_netinettcp='undef'
+i_niin='define'
+i_poll='undef'
+i_pthread='undef'
+i_pwd='undef'
+i_rpcsvcdbm='define'
+i_sfio='undef'
+i_sgtty='undef'
+i_shadow='undef'
+i_socks='undef'
+i_stdarg='define'
+i_stddef='define'
+i_stdlib='define'
+i_string='define'
+i_sunmath='undef'
+i_sysaccess='undef'
+i_sysdir='undef'
+i_sysfile='undef'
+i_sysfilio='define'
+i_sysin='undef'
+i_sysioctl='undef'
+i_syslog='undef'
+i_sysmman='undef'
+i_sysmode='undef'
+i_sysmount='undef'
+i_sysndir='undef'
+i_sysparam='undef'
+i_sysresrc='undef'
+i_syssecrt='undef'
+i_sysselct='undef'
+i_syssockio='define'
+i_sysstatfs='undef'
+i_sysstatvfs='undef'
+i_sysstat='define'
+i_systime='undef'
+i_systimek='undef'
+i_systimes='undef'
+i_systypes='define'
+i_sysuio='undef'
+i_sysun='undef'
+i_sysutsname='define'
+i_sysvfs='undef'
+i_syswait='undef'
+i_termio='undef'
+i_termios='undef'
+i_time='define'
+i_unistd='undef'
+i_ustat='undef'
+i_utime='define'
+i_values='undef'
+i_varargs='undef'
+i_varhdr='varargs.h'
+i_vfork='undef'
+ignore_versioned_solibs=''
+inc_version_list=''
+inc_version_list_init='0'
+incpath=''
+inews=''
+installarchlib='~INST_TOP~~INST_VER~\lib~INST_ARCH~'
+installbin='~INST_TOP~~INST_VER~\bin~INST_ARCH~'
+installman1dir='~INST_TOP~~INST_VER~\man\man1'
+installman3dir='~INST_TOP~~INST_VER~\man\man3'
+installnwlib='~INST_NW_TOP2~~INST_NW_VER~\lib'
+installnwscripts='~INST_NW_TOP2~~INST_NW_VER~\scripts'
+installnwlcgi='~INST_NW_TOP2~~INST_NW_VER~\lcgi'
+installnwsystem='~INST_NW_TOP2~~INST_NW_VER~\system'
+installprefix='~INST_TOP~~INST_VER~'
+installprefixexp='~INST_TOP~~INST_VER~'
+installhtmldir='~INST_TOP~~INST_VER~\html'
+installhtmlhelpdir='~INST_TOP~~INST_VER~\htmlhelp'
+installprivlib='~INST_TOP~~INST_VER~\lib'
+installscript='~INST_TOP~~INST_VER~\bin'
+installsitearch='~INST_TOP~\site~INST_VER~\lib~INST_ARCH~'
+installsitebin='~INST_TOP~~INST_VER~\bin~INST_ARCH~'
+installsitelib='~INST_TOP~\site~INST_VER~\lib'
+installstyle='lib'
+installusrbinperl='undef'
+installvendorarch=''
+installvendorbin=''
+installvendorlib=''
+intsize='4'
+ivdformat='"ld"'
+ivsize='4'
+ivtype='long'
+known_extensions='~static_ext~ ~dynamic_ext~ ~nonxs_ext~'
+ksh=''
+large=''
+ld='link'
+lddlflags='-dll ~LINK_FLAGS~'
+ldflags='~LINK_FLAGS~'
+ldlibpthname=''
+less='less'
+lib_ext='.lib'
+libc=''
+libperl='perl.lib'
+libpth=''
+libs=''
+libsdirs=''
+libsfiles=''
+libsfound=''
+libspath=''
+libswanted='net socket inet nsl nm ndbm gdbm dbm db malloc dl dld ld sun m c cposix posix ndir dir crypt ucb bsd BSD PW x'
+line='line'
+lint=''
+lkflags=''
+ln=''
+lns='copy'
+locincpth='/usr/local/include /opt/local/include /usr/gnu/include /opt/gnu/include /usr/GNU/include /opt/GNU/include'
+loclibpth='/usr/local/lib /opt/local/lib /usr/gnu/lib /opt/gnu/lib /usr/GNU/lib /opt/GNU/lib'
+longdblsize='10'
+longlongsize='8'
+longsize='4'
+lp=''
+lpr=''
+ls='dir'
+lseeksize='4'
+lseektype='off_t'
+mail=''
+mailx=''
+make='nmake'
+make_set_make='#'
+mallocobj='malloc.o'
+mallocsrc='malloc.c'
+malloctype='void *'
+man1dir='~INST_TOP~~INST_VER~\man\man1'
+man1direxp='~INST_TOP~~INST_VER~\man\man1'
+man1ext='1'
+man3dir='~INST_TOP~~INST_VER~\man\man3'
+man3direxp='~INST_TOP~~INST_VER~\man\man3'
+man3ext='3'
+medium=''
+mips_type=''
+mkdir='mkdir'
+mmaptype='void *'
+models='none'
+modetype='mode_t'
+more='more /e'
+multiarch='undef'
+mv=''
+myarchname='MSWin32'
+mydomain=''
+myhostname=''
+myuname=''
+n='-n'
+netdb_hlen_type='int'
+netdb_host_type='char *'
+netdb_name_type='char *'
+netdb_net_type='long'
+nm=''
+nm_opt=''
+nm_so_opt=''
+nonxs_ext='Errno'
+nroff=''
+nvEUformat='"E"'
+nvFUformat='"F"'
+nvGUformat='"G"'
+nveformat='"e"'
+nvfformat='"f"'
+nvgformat='"g"'
+nvsize='8'
+nvtype='double'
+o_nonblock='O_NONBLOCK'
+obj_ext='.obj'
+old_pthread_create_joinable=''
+optimize='-O'
+orderlib='false'
+osname='NetWare'
+osvers='5.x'
+package='perl5'
+pager='more /e'
+passcat=''
+patchlevel='~PATCHLEVEL~'
+path_sep=';'
+perl5=''
+perl='perl'
+perladmin=''
+perlpath='~INST_TOP~~INST_VER~\bin~INST_ARCH~\perl.nlm'
+pg=''
+phostname='hostname'
+pidtype='int'
+plibpth=''
+pm_apiversion='5.005'
+pmake=''
+pr=''
+prefix='~INST_TOP~'
+prefixexp='~INST_DRV~'
+privlib='~INST_NW_TOP1~\lib'
+privlibexp='~INST_TOP~~INST_VER~\lib'
+prototype='define'
+ptrsize='4'
+quadkind='5'
+quadtype='__int64'
+randbits='15'
+randfunc='rand'
+randseedtype='unsigned'
+ranlib='rem'
+rd_nodata='-1'
+revision='5'
+rm='del'
+rmail=''
+runnm='true'
+sPRIEldbl='"E"'
+sPRIFldbl='"F"'
+sPRIGldbl='"G"'
+sPRIX64='"lX"'
+sPRId64='"ld"'
+sPRIeldbl='"e"'
+sPRIfldbl='"f"'
+sPRIgldbl='"g"'
+sPRIi64='"li"'
+sPRIo64='"lo"'
+sPRIu64='"lu"'
+sPRIx64='"lx"'
+sched_yield=''
+scriptdir='~INST_TOP~~INST_VER~\bin'
+scriptdirexp='~INST_TOP~~INST_VER~\bin'
+sed='sed'
+seedfunc='srand'
+selectminbits='32'
+selecttype='fd_set *'
+sendmail='blat'
+sh='cmd /x /c'
+shar=''
+sharpbang='#!'
+shmattype='void *'
+shortsize='2'
+shrpenv=''
+shsharp='true'
+sig_count='26'
+sig_name='ZERO NUM01 INT QUIT ILL NUM05 NUM06 NUM07 FPE KILL NUM10 SEGV NUM12 PIPE ALRM TERM NUM16 NUM17 NUM18 NUM19 CHLD BREAK ABRT STOP NUM24 CONT CLD'
+sig_name_init='"ZERO", "NUM01", "INT", "QUIT", "ILL", "NUM05", "NUM06", "NUM07", "FPE", "KILL", "NUM10", "SEGV", "NUM12", "PIPE", "ALRM", "TERM", "NUM16", "NUM17", "NUM18", "NUM19", "CHLD", "BREAK", "ABRT", "STOP", "NUM24", "CONT", "CLD", 0'
+sig_num='0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 20 0'
+sig_num_init='0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 20, 0'
+sig_size='27'
+signal_t='void'
+sitearch='~INST_TOP~\site~INST_VER~\lib~INST_ARCH~'
+sitearchexp='~INST_TOP~\site~INST_VER~\lib~INST_ARCH~'
+sitebin='~INST_TOP~\site~INST_VER~\bin~INST_ARCH~'
+sitebinexp='~INST_TOP~\site~INST_VER~\bin~INST_ARCH~'
+sitelib='~INST_TOP~\site~INST_VER~\lib'
+sitelib_stem=''
+sitelibexp='~INST_TOP~\site~INST_VER~\lib'
+siteprefix='~INST_TOP~\site~INST_VER~'
+siteprefixexp='~INST_TOP~\site~INST_VER~'
+sizesize='4'
+sizetype='size_t'
+sleep=''
+smail=''
+small=''
+so='dll'
+sockethdr=''
+socketlib=''
+socksizetype='int'
+sort='sort'
+spackage='Perl5'
+spitshell=''
+split=''
+src=''
+ssizetype='int'
+startperl='#!perl'
+startsh='#!/bin/sh'
+static_ext='DynaLoader'
+stdchar='char'
+stdio_base='((fp)->_base)'
+stdio_bufsiz='((fp)->_cnt + (fp)->_ptr - (fp)->_base)'
+stdio_cnt='((fp)->_cnt)'
+stdio_filbuf=''
+stdio_ptr='((fp)->_ptr)'
+stdio_stream_array=''
+strings='/usr/include/string.h'
+submit=''
+subversion='~SUBVERSION~'
+sysman='/usr/man/man1'
+tail=''
+tar=''
+tbl=''
+tee=''
+test=''
+timeincl='/usr/include/sys/time.h '
+timetype='time_t'
+touch='touch'
+tr=''
+trnl='\012'
+troff=''
+u16size='2'
+u16type='unsigned short'
+u32size='4'
+u32type='unsigned long'
+u64size='8'
+u64type='unsigned __int64'
+u8size='1'
+u8type='unsigned char'
+uidformat='"ld"'
+uidsign='-1'
+uidsize='4'
+uidtype='uid_t'
+uname='uname'
+uniq='uniq'
+uquadtype='unsigned __int64'
+use5005threads='undef'
+use64bitall='undef'
+use64bitint='undef'
+usedl='define'
+useithreads='define'
+uselargefiles='undef'
+uselongdouble='undef'
+usemorebits='undef'
+usemultiplicity='define'
+usemymalloc='n'
+usenm='false'
+useopcode='true'
+useperlio='undef'
+useposix='true'
+usesfio='false'
+useshrplib='yes'
+usesocks='undef'
+usethreads='undef'
+usevendorprefix='undef'
+usevfork='true'
+usrinc='/usr/include'
+uuname=''
+uvoformat='"lo"'
+uvsize='4'
+uvtype='unsigned long'
+uvuformat='"lu"'
+uvxformat='"lx"'
+vendorarch=''
+vendorarchexp=''
+vendorbin=''
+vendorbinexp=''
+vendorlib=''
+vendorlib_stem=''
+vendorlibexp=''
+vendorprefix=''
+vendorprefixexp=''
+version='~VERSION~'
+vi=''
+voidflags='15'
+xlibpth='/usr/lib/386 /lib/386'
+xs_apiversion='5.6.0'
+zcat=''
+zip='zip'
+PERL_REVISION='~PERL_REVISION~'
+PERL_SUBVERSION='~PERL_SUBVERSION~'
+PERL_VERSION='~PERL_VERSION~'
+PERL_API_REVISION='~PERL_API_REVISION~'
+PERL_API_SUBVERSION='~PERL_API_SUBVERSION~'
+PERL_API_VERSION='~PERL_API_VERSION~'
+PATCHLEVEL='~PERL_VERSION~'
+SUBVERSION='~PERL_SUBVERSION~'
+base_import=''
+nlm_version=''
+mpktool=''
+toolpath=''
diff --git a/NetWare/config_H.wc b/NetWare/config_H.wc
new file mode 100644 (file)
index 0000000..bea1761
--- /dev/null
@@ -0,0 +1,3331 @@
+/*
+ * This file was produced by running the config_h.SH script, which
+ * gets its values from undef, which is generally produced by
+ * running Configure.
+ *
+ * Feel free to modify any of this as the need arises.  Note, however,
+ * that running config_h.SH again will wipe out any changes you've made.
+ * For a more permanent change edit undef and rerun config_h.SH.
+ *
+ * $Id: Config_h.U,v 3.0.1.5 1997/02/28 14:57:43 ram Exp $
+ */
+
+/*
+ * Package name      : perl5
+ * Source directory  : 
+ * Configuration time: Wed Jun  6 09:31:53 2001
+ * Configured by     : Administrator
+ * Target system     : 
+ */
+
+#ifndef _config_h_
+#define _config_h_
+
+/* LOC_SED:
+ *     This symbol holds the complete pathname to the sed program.
+ */
+#define LOC_SED        ""      /**/
+
+/* HAS_ALARM:
+ *     This symbol, if defined, indicates that the alarm routine is
+ *     available.
+ */
+/*#define HAS_ALARM            /**/
+
+/* HASATTRIBUTE:
+ *     This symbol indicates the C compiler can check for function attributes,
+ *     such as printf formats. This is normally only supported by GNU cc.
+ */
+/*#define HASATTRIBUTE         /**/
+#ifndef HASATTRIBUTE
+#define __attribute__(_arg_)
+#endif
+
+/* HAS_BCMP:
+ *     This symbol is defined if the bcmp() routine is available to
+ *     compare blocks of memory.
+ */
+/*#define HAS_BCMP     /**/
+
+/* HAS_BCOPY:
+ *     This symbol is defined if the bcopy() routine is available to
+ *     copy blocks of memory.
+ */
+/*#define HAS_BCOPY    /**/
+
+/* HAS_BZERO:
+ *     This symbol is defined if the bzero() routine is available to
+ *     set a memory block to 0.
+ */
+/*#define HAS_BZERO    /**/
+
+/* HAS_CHOWN:
+ *     This symbol, if defined, indicates that the chown routine is
+ *     available.
+ */
+/*#define HAS_CHOWN            /**/
+
+/* HAS_CHROOT:
+ *     This symbol, if defined, indicates that the chroot routine is
+ *     available.
+ */
+/*#define HAS_CHROOT           /**/
+
+/* HAS_CHSIZE:
+ *     This symbol, if defined, indicates that the chsize routine is available
+ *     to truncate files.  You might need a -lx to get this routine.
+ */
+#define        HAS_CHSIZE              /**/
+
+/* HASCONST:
+ *     This symbol, if defined, indicates that this C compiler knows about
+ *     the const type. There is no need to actually test for that symbol
+ *     within your programs. The mere use of the "const" keyword will
+ *     trigger the necessary tests.
+ */
+#define HASCONST       /**/
+#ifndef HASCONST
+#define const
+#endif
+
+/* HAS_CRYPT:
+ *     This symbol, if defined, indicates that the crypt routine is available
+ *     to encrypt passwords and the like.
+ */
+/*#define HAS_CRYPT            /**/
+
+/* HAS_CUSERID:
+ *     This symbol, if defined, indicates that the cuserid routine is
+ *     available to get character login names.
+ */
+/*#define HAS_CUSERID          /**/
+
+/* HAS_DBL_DIG:
+ *     This symbol, if defined, indicates that this system's <float.h>
+ *     or <limits.h> defines the symbol DBL_DIG, which is the number
+ *     of significant digits in a double precision number.  If this
+ *     symbol is not defined, a guess of 15 is usually pretty good.
+ */
+#define HAS_DBL_DIG    /**/
+
+/* HAS_DIFFTIME:
+ *     This symbol, if defined, indicates that the difftime routine is
+ *     available.
+ */
+#define HAS_DIFFTIME           /**/
+
+/* HAS_DLERROR:
+ *     This symbol, if defined, indicates that the dlerror routine is
+ *     available to return a string describing the last error that
+ *     occurred from a call to dlopen(), dlclose() or dlsym().
+ */
+#define HAS_DLERROR    /**/
+
+/* SETUID_SCRIPTS_ARE_SECURE_NOW:
+ *     This symbol, if defined, indicates that the bug that prevents
+ *     setuid scripts from being secure is not present in this kernel.
+ */
+/* DOSUID:
+ *     This symbol, if defined, indicates that the C program should
+ *     check the script that it is executing for setuid/setgid bits, and
+ *     attempt to emulate setuid/setgid on systems that have disabled
+ *     setuid #! scripts because the kernel can't do it securely.
+ *     It is up to the package designer to make sure that this emulation
+ *     is done securely.  Among other things, it should do an fstat on
+ *     the script it just opened to make sure it really is a setuid/setgid
+ *     script, it should make sure the arguments passed correspond exactly
+ *     to the argument on the #! line, and it should not trust any
+ *     subprocesses to which it must pass the filename rather than the
+ *     file descriptor of the script to be executed.
+ */
+/*#define SETUID_SCRIPTS_ARE_SECURE_NOW        /**/
+/*#define DOSUID               /**/
+
+/* HAS_DUP2:
+ *     This symbol, if defined, indicates that the dup2 routine is
+ *     available to duplicate file descriptors.
+ */
+#define HAS_DUP2       /**/
+
+/* HAS_FCHMOD:
+ *     This symbol, if defined, indicates that the fchmod routine is available
+ *     to change mode of opened files.  If unavailable, use chmod().
+ */
+/*#define HAS_FCHMOD           /**/
+
+/* HAS_FCHOWN:
+ *     This symbol, if defined, indicates that the fchown routine is available
+ *     to change ownership of opened files.  If unavailable, use chown().
+ */
+/*#define HAS_FCHOWN           /**/
+
+/* HAS_FCNTL:
+ *     This symbol, if defined, indicates to the C program that
+ *     the fcntl() function exists.
+ */
+/*#define HAS_FCNTL            /**/
+
+/* HAS_FGETPOS:
+ *     This symbol, if defined, indicates that the fgetpos routine is
+ *     available to get the file position indicator, similar to ftell().
+ */
+#define HAS_FGETPOS    /**/
+
+/* HAS_FLOCK:
+ *     This symbol, if defined, indicates that the flock routine is
+ *     available to do file locking.
+ */
+#define HAS_FLOCK              /**/
+
+/* HAS_FORK:
+ *     This symbol, if defined, indicates that the fork routine is
+ *     available.
+ */
+/*#define HAS_FORK             /**/
+
+/* HAS_FSETPOS:
+ *     This symbol, if defined, indicates that the fsetpos routine is
+ *     available to set the file position indicator, similar to fseek().
+ */
+#define HAS_FSETPOS    /**/
+
+/* HAS_GETTIMEOFDAY:
+ *     This symbol, if defined, indicates that the gettimeofday() system
+ *     call is available for a sub-second accuracy clock. Usually, the file
+ *     <sys/resource.h> needs to be included (see I_SYS_RESOURCE).
+ *     The type "Timeval" should be used to refer to "struct timeval".
+ */
+/*#define HAS_GETTIMEOFDAY     /**/
+#ifdef HAS_GETTIMEOFDAY
+#define Timeval struct timeval /* Structure used by gettimeofday() */
+#endif
+
+/* HAS_GETGROUPS:
+ *     This symbol, if defined, indicates that the getgroups() routine is
+ *     available to get the list of process groups.  If unavailable, multiple
+ *     groups are probably not supported.
+ */
+/*#define HAS_GETGROUPS                /**/
+
+/* HAS_GETLOGIN:
+ *     This symbol, if defined, indicates that the getlogin routine is
+ *     available to get the login name.
+ */
+#define HAS_GETLOGIN           /**/
+
+/* HAS_GETPGID:
+ *     This symbol, if defined, indicates to the C program that 
+ *     the getpgid(pid) function is available to get the
+ *     process group id.
+ */
+/*#define HAS_GETPGID          /**/
+
+/* HAS_GETPGRP2:
+ *     This symbol, if defined, indicates that the getpgrp2() (as in DG/UX)
+ *     routine is available to get the current process group.
+ */
+/*#define HAS_GETPGRP2         /**/
+
+/* HAS_GETPPID:
+ *     This symbol, if defined, indicates that the getppid routine is
+ *     available to get the parent process ID.
+ */
+/*#define HAS_GETPPID          /**/
+
+/* HAS_GETPRIORITY:
+ *     This symbol, if defined, indicates that the getpriority routine is
+ *     available to get a process's priority.
+ */
+/*#define HAS_GETPRIORITY              /**/
+
+/* HAS_INET_ATON:
+ *     This symbol, if defined, indicates to the C program that the
+ *     inet_aton() function is available to parse IP address "dotted-quad"
+ *     strings.
+ */
+/*#define HAS_INET_ATON                /**/
+
+/* HAS_KILLPG:
+ *     This symbol, if defined, indicates that the killpg routine is available
+ *     to kill process groups.  If unavailable, you probably should use kill
+ *     with a negative process number.
+ */
+/*#define HAS_KILLPG   /**/
+
+/* HAS_LINK:
+ *     This symbol, if defined, indicates that the link routine is
+ *     available to create hard links.
+ */
+#define HAS_LINK       /**/
+
+/* HAS_LOCALECONV:
+ *     This symbol, if defined, indicates that the localeconv routine is
+ *     available for numeric and monetary formatting conventions.
+ */
+#define HAS_LOCALECONV /**/
+
+/* HAS_LOCKF:
+ *     This symbol, if defined, indicates that the lockf routine is
+ *     available to do file locking.
+ */
+/*#define HAS_LOCKF            /**/
+
+/* HAS_LSTAT:
+ *     This symbol, if defined, indicates that the lstat routine is
+ *     available to do file stats on symbolic links.
+ */
+/*#define HAS_LSTAT            /**/
+
+/* HAS_MBLEN:
+ *     This symbol, if defined, indicates that the mblen routine is available
+ *     to find the number of bytes in a multibye character.
+ */
+#define HAS_MBLEN              /**/
+
+/* HAS_MBSTOWCS:
+ *     This symbol, if defined, indicates that the mbstowcs routine is
+ *     available to covert a multibyte string into a wide character string.
+ */
+#define        HAS_MBSTOWCS            /**/
+
+/* HAS_MBTOWC:
+ *     This symbol, if defined, indicates that the mbtowc routine is available
+ *     to covert a multibyte to a wide character.
+ */
+#define HAS_MBTOWC             /**/
+
+/* HAS_MEMCMP:
+ *     This symbol, if defined, indicates that the memcmp routine is available
+ *     to compare blocks of memory.
+ */
+#define HAS_MEMCMP     /**/
+
+/* HAS_MEMCPY:
+ *     This symbol, if defined, indicates that the memcpy routine is available
+ *     to copy blocks of memory.
+ */
+#define HAS_MEMCPY     /**/
+
+/* HAS_MEMMOVE:
+ *     This symbol, if defined, indicates that the memmove routine is available
+ *     to copy potentially overlapping blocks of memory. This should be used
+ *     only when HAS_SAFE_BCOPY is not defined. If neither is there, roll your
+ *     own version.
+ */
+#define HAS_MEMMOVE    /**/
+
+/* HAS_MEMSET:
+ *     This symbol, if defined, indicates that the memset routine is available
+ *     to set blocks of memory.
+ */
+#define HAS_MEMSET     /**/
+
+/* HAS_MKDIR:
+ *     This symbol, if defined, indicates that the mkdir routine is available
+ *     to create directories.  Otherwise you should fork off a new process to
+ *     exec /bin/mkdir.
+ */
+#define HAS_MKDIR              /**/
+
+/* HAS_MKFIFO:
+ *     This symbol, if defined, indicates that the mkfifo routine is
+ *     available to create FIFOs. Otherwise, mknod should be able to
+ *     do it for you. However, if mkfifo is there, mknod might require
+ *     super-user privileges which mkfifo will not.
+ */
+/*#define HAS_MKFIFO           /**/
+
+/* HAS_MKTIME:
+ *     This symbol, if defined, indicates that the mktime routine is
+ *     available.
+ */
+#define HAS_MKTIME             /**/
+
+/* HAS_MSYNC:
+ *     This symbol, if defined, indicates that the msync system call is
+ *     available to synchronize a mapped file.
+ */
+/*#define HAS_MSYNC            /**/
+
+/* HAS_MUNMAP:
+ *     This symbol, if defined, indicates that the munmap system call is
+ *     available to unmap a region, usually mapped by mmap().
+ */
+/*#define HAS_MUNMAP           /**/
+
+/* HAS_NICE:
+ *     This symbol, if defined, indicates that the nice routine is
+ *     available.
+ */
+/*#define HAS_NICE             /**/
+
+/* HAS_PATHCONF:
+ *     This symbol, if defined, indicates that pathconf() is available
+ *     to determine file-system related limits and options associated
+ *     with a given filename.
+ */
+/* HAS_FPATHCONF:
+ *     This symbol, if defined, indicates that pathconf() is available
+ *     to determine file-system related limits and options associated
+ *     with a given open file descriptor.
+ */
+/*#define HAS_PATHCONF         /**/
+/*#define HAS_FPATHCONF                /**/
+
+/* HAS_PAUSE:
+ *     This symbol, if defined, indicates that the pause routine is
+ *     available to suspend a process until a signal is received.
+ */
+/*#define HAS_PAUSE            /**/
+
+/* HAS_PIPE:
+ *     This symbol, if defined, indicates that the pipe routine is
+ *     available to create an inter-process channel.
+ */
+#define HAS_PIPE               /**/
+
+/* HAS_POLL:
+ *     This symbol, if defined, indicates that the poll routine is
+ *     available to poll active file descriptors. You may safely
+ *     include <poll.h> when this symbol is defined.
+ */
+/*#define HAS_POLL             /**/
+
+/* HAS_READDIR:
+ *     This symbol, if defined, indicates that the readdir routine is
+ *     available to read directory entries. You may have to include
+ *     <dirent.h>. See I_DIRENT.
+ */
+#define HAS_READDIR            /**/
+
+/* HAS_SEEKDIR:
+ *     This symbol, if defined, indicates that the seekdir routine is
+ *     available. You may have to include <dirent.h>. See I_DIRENT.
+ */
+#define HAS_SEEKDIR            /**/
+
+/* HAS_TELLDIR:
+ *     This symbol, if defined, indicates that the telldir routine is
+ *     available. You may have to include <dirent.h>. See I_DIRENT.
+ */
+#define HAS_TELLDIR            /**/
+
+/* HAS_REWINDDIR:
+ *     This symbol, if defined, indicates that the rewinddir routine is
+ *     available. You may have to include <dirent.h>. See I_DIRENT.
+ */
+#define HAS_REWINDDIR          /**/
+
+/* HAS_READLINK:
+ *     This symbol, if defined, indicates that the readlink routine is
+ *     available to read the value of a symbolic link.
+ */
+/*#define HAS_READLINK         /**/
+
+/* HAS_RENAME:
+ *     This symbol, if defined, indicates that the rename routine is available
+ *     to rename files.  Otherwise you should do the unlink(), link(), unlink()
+ *     trick.
+ */
+#define HAS_RENAME     /**/
+
+/* HAS_RMDIR:
+ *     This symbol, if defined, indicates that the rmdir routine is
+ *     available to remove directories. Otherwise you should fork off a
+ *     new process to exec /bin/rmdir.
+ */
+#define HAS_RMDIR              /**/
+
+/* HAS_SELECT:
+ *     This symbol, if defined, indicates that the select routine is
+ *     available to select active file descriptors. If the timeout field
+ *     is used, <sys/time.h> may need to be included.
+ */
+#define HAS_SELECT     /**/
+
+/* HAS_SETEGID:
+ *     This symbol, if defined, indicates that the setegid routine is available
+ *     to change the effective gid of the current program.
+ */
+/*#define HAS_SETEGID          /**/
+
+/* HAS_SETEUID:
+ *     This symbol, if defined, indicates that the seteuid routine is available
+ *     to change the effective uid of the current program.
+ */
+/*#define HAS_SETEUID          /**/
+
+/* HAS_SETLINEBUF:
+ *     This symbol, if defined, indicates that the setlinebuf routine is
+ *     available to change stderr or stdout from block-buffered or unbuffered
+ *     to a line-buffered mode.
+ */
+/*#define HAS_SETLINEBUF               /**/
+
+/* HAS_SETLOCALE:
+ *     This symbol, if defined, indicates that the setlocale routine is
+ *     available to handle locale-specific ctype implementations.
+ */
+#define HAS_SETLOCALE  /**/
+
+/* HAS_SETPGID:
+ *     This symbol, if defined, indicates that the setpgid(pid, gpid)
+ *     routine is available to set process group ID.
+ */
+/*#define HAS_SETPGID  /**/
+
+/* HAS_SETPGRP2:
+ *     This symbol, if defined, indicates that the setpgrp2() (as in DG/UX)
+ *     routine is available to set the current process group.
+ */
+/*#define HAS_SETPGRP2         /**/
+
+/* HAS_SETPRIORITY:
+ *     This symbol, if defined, indicates that the setpriority routine is
+ *     available to set a process's priority.
+ */
+/*#define HAS_SETPRIORITY              /**/
+
+/* HAS_SETREGID:
+ *     This symbol, if defined, indicates that the setregid routine is
+ *     available to change the real and effective gid of the current
+ *     process.
+ */
+/* HAS_SETRESGID:
+ *     This symbol, if defined, indicates that the setresgid routine is
+ *     available to change the real, effective and saved gid of the current
+ *     process.
+ */
+/*#define HAS_SETREGID         /**/
+/*#define HAS_SETRESGID                /**/
+
+/* HAS_SETREUID:
+ *     This symbol, if defined, indicates that the setreuid routine is
+ *     available to change the real and effective uid of the current
+ *     process.
+ */
+/* HAS_SETRESUID:
+ *     This symbol, if defined, indicates that the setresuid routine is
+ *     available to change the real, effective and saved uid of the current
+ *     process.
+ */
+/*#define HAS_SETREUID         /**/
+/*#define HAS_SETRESUID                /**/
+
+/* HAS_SETRGID:
+ *     This symbol, if defined, indicates that the setrgid routine is available
+ *     to change the real gid of the current program.
+ */
+/*#define HAS_SETRGID          /**/
+
+/* HAS_SETRUID:
+ *     This symbol, if defined, indicates that the setruid routine is available
+ *     to change the real uid of the current program.
+ */
+/*#define HAS_SETRUID          /**/
+
+/* HAS_SETSID:
+ *     This symbol, if defined, indicates that the setsid routine is
+ *     available to set the process group ID.
+ */
+/*#define HAS_SETSID   /**/
+
+/* Shmat_t:
+ *     This symbol holds the return type of the shmat() system call.
+ *     Usually set to 'void *' or 'char *'.
+ */
+/* HAS_SHMAT_PROTOTYPE:
+ *     This symbol, if defined, indicates that the sys/shm.h includes
+ *     a prototype for shmat().  Otherwise, it is up to the program to
+ *     guess one.  Shmat_t shmat _((int, Shmat_t, int)) is a good guess,
+ *     but not always right so it should be emitted by the program only
+ *     when HAS_SHMAT_PROTOTYPE is not defined to avoid conflicting defs.
+ */
+#define Shmat_t void * /**/
+/*#define HAS_SHMAT_PROTOTYPE  /**/
+
+/* HAS_STRCHR:
+ *     This symbol is defined to indicate that the strchr()/strrchr()
+ *     functions are available for string searching. If not, try the
+ *     index()/rindex() pair.
+ */
+/* HAS_INDEX:
+ *     This symbol is defined to indicate that the index()/rindex()
+ *     functions are available for string searching.
+ */
+#define HAS_STRCHR     /**/
+/*#define HAS_INDEX    /**/
+
+/* HAS_STRCOLL:
+ *     This symbol, if defined, indicates that the strcoll routine is
+ *     available to compare strings using collating information.
+ */
+#define HAS_STRCOLL    /**/
+
+/* USE_STRUCT_COPY:
+ *     This symbol, if defined, indicates that this C compiler knows how
+ *     to copy structures.  If undefined, you'll need to use a block copy
+ *     routine of some sort instead.
+ */
+#define        USE_STRUCT_COPY /**/
+
+/* HAS_STRTOD:
+ *     This symbol, if defined, indicates that the strtod routine is
+ *     available to provide better numeric string conversion than atof().
+ */
+#define HAS_STRTOD     /**/
+
+/* HAS_STRTOL:
+ *     This symbol, if defined, indicates that the strtol routine is available
+ *     to provide better numeric string conversion than atoi() and friends.
+ */
+#define HAS_STRTOL     /**/
+
+/* HAS_STRXFRM:
+ *     This symbol, if defined, indicates that the strxfrm() routine is
+ *     available to transform strings.
+ */
+#define HAS_STRXFRM    /**/
+
+/* HAS_SYMLINK:
+ *     This symbol, if defined, indicates that the symlink routine is available
+ *     to create symbolic links.
+ */
+/*#define HAS_SYMLINK  /**/
+
+/* HAS_SYSCALL:
+ *     This symbol, if defined, indicates that the syscall routine is
+ *     available to call arbitrary system calls. If undefined, that's tough.
+ */
+/*#define HAS_SYSCALL  /**/
+
+/* HAS_SYSCONF:
+ *     This symbol, if defined, indicates that sysconf() is available
+ *     to determine system related limits and options.
+ */
+/*#define HAS_SYSCONF  /**/
+
+/* HAS_SYSTEM:
+ *     This symbol, if defined, indicates that the system routine is
+ *     available to issue a shell command.
+ */
+#define HAS_SYSTEM     /**/
+
+/* HAS_TCGETPGRP:
+ *     This symbol, if defined, indicates that the tcgetpgrp routine is
+ *     available to get foreground process group ID.
+ */
+/*#define HAS_TCGETPGRP                /**/
+
+/* HAS_TCSETPGRP:
+ *     This symbol, if defined, indicates that the tcsetpgrp routine is
+ *     available to set foreground process group ID.
+ */
+/*#define HAS_TCSETPGRP                /**/
+
+/* HAS_TRUNCATE:
+ *     This symbol, if defined, indicates that the truncate routine is
+ *     available to truncate files.
+ */
+/*#define HAS_TRUNCATE /**/
+
+/* HAS_TZNAME:
+ *     This symbol, if defined, indicates that the tzname[] array is
+ *     available to access timezone names.
+ */
+#define HAS_TZNAME             /**/
+
+/* HAS_UMASK:
+ *     This symbol, if defined, indicates that the umask routine is
+ *     available to set and get the value of the file creation mask.
+ */
+#define HAS_UMASK              /**/
+
+/* HAS_USLEEP:
+ *     This symbol, if defined, indicates that the usleep routine is
+ *     available to let the process sleep on a sub-second accuracy.
+ */
+/*#define HAS_USLEEP           /**/
+
+/* HASVOLATILE:
+ *     This symbol, if defined, indicates that this C compiler knows about
+ *     the volatile declaration.
+ */
+#define        HASVOLATILE     /**/
+#ifndef HASVOLATILE
+#define volatile
+#endif
+
+/* HAS_WAIT4:
+ *     This symbol, if defined, indicates that wait4() exists.
+ */
+/*#define HAS_WAIT4    /**/
+
+/* HAS_WAITPID:
+ *     This symbol, if defined, indicates that the waitpid routine is
+ *     available to wait for child process.
+ */
+#define HAS_WAITPID    /**/
+
+/* HAS_WCSTOMBS:
+ *     This symbol, if defined, indicates that the wcstombs routine is
+ *     available to convert wide character strings to multibyte strings.
+ */
+#define HAS_WCSTOMBS   /**/
+
+/* HAS_WCTOMB:
+ *     This symbol, if defined, indicates that the wctomb routine is available
+ *     to covert a wide character to a multibyte.
+ */
+#define HAS_WCTOMB             /**/
+
+/* I_ARPA_INET:
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <arpa/inet.h> to get inet_addr and friends declarations.
+ */
+#define        I_ARPA_INET             /**/
+
+/* I_DBM:
+ *     This symbol, if defined, indicates that <dbm.h> exists and should
+ *     be included.
+ */
+/* I_RPCSVC_DBM:
+ *     This symbol, if defined, indicates that <rpcsvc/dbm.h> exists and
+ *     should be included.
+ */
+/*#define I_DBM        /**/
+#define I_RPCSVC_DBM   /**/
+
+/* I_DIRENT:
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <dirent.h>. Using this symbol also triggers the definition
+ *     of the Direntry_t define which ends up being 'struct dirent' or
+ *     'struct direct' depending on the availability of <dirent.h>.
+ */
+/* DIRNAMLEN:
+ *     This symbol, if defined, indicates to the C program that the length
+ *     of directory entry names is provided by a d_namlen field.  Otherwise
+ *     you need to do strlen() on the d_name field.
+ */
+/* Direntry_t:
+ *     This symbol is set to 'struct direct' or 'struct dirent' depending on
+ *     whether dirent is available or not. You should use this pseudo type to
+ *     portably declare your directory entries.
+ */
+#define I_DIRENT               /**/
+/*#define DIRNAMLEN    /**/
+#define Direntry_t DIR
+
+/* I_DLFCN:
+ *     This symbol, if defined, indicates that <dlfcn.h> exists and should
+ *     be included.
+ */
+#define I_DLFCN                /**/
+
+/* I_FCNTL:
+ *     This manifest constant tells the C program to include <fcntl.h>.
+ */
+#define I_FCNTL        /**/
+
+/* I_FLOAT:
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <float.h> to get definition of symbols like DBL_MAX or
+ *     DBL_MIN, i.e. machine dependent floating point values.
+ */
+#define I_FLOAT                /**/
+
+/* I_LIMITS:
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <limits.h> to get definition of symbols like WORD_BIT or
+ *     LONG_MAX, i.e. machine dependant limitations.
+ */
+#define I_LIMITS               /**/
+
+/* I_LOCALE:
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <locale.h>.
+ */
+#define        I_LOCALE                /**/
+
+/* I_MATH:
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <math.h>.
+ */
+#define I_MATH         /**/
+
+/* I_MEMORY:
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <memory.h>.
+ */
+/*#define I_MEMORY             /**/
+
+/* I_NDBM:
+ *     This symbol, if defined, indicates that <ndbm.h> exists and should
+ *     be included.
+ */
+/*#define I_NDBM       /**/
+
+/* I_NET_ERRNO:
+ *     This symbol, if defined, indicates that <net/errno.h> exists and 
+ *     should be included.
+ */
+/*#define I_NET_ERRNO          /**/
+
+/* I_NETINET_IN:
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <netinet/in.h>. Otherwise, you may try <sys/in.h>.
+ */
+#define I_NETINET_IN   /**/
+
+/* I_SFIO:
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <sfio.h>.
+ */
+/*#define      I_SFIO          /**/
+
+/* I_STDDEF:
+ *     This symbol, if defined, indicates that <stddef.h> exists and should
+ *     be included.
+ */
+#define I_STDDEF       /**/
+
+/* I_STDLIB:
+ *     This symbol, if defined, indicates that <stdlib.h> exists and should
+ *     be included.
+ */
+#define I_STDLIB               /**/
+
+/* I_STRING:
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <string.h> (USG systems) instead of <strings.h> (BSD systems).
+ */
+#define I_STRING               /**/
+
+/* I_SYS_DIR:
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <sys/dir.h>.
+ */
+/*#define I_SYS_DIR            /**/
+
+/* I_SYS_FILE:
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <sys/file.h> to get definition of R_OK and friends.
+ */
+/*#define I_SYS_FILE           /**/
+
+/* I_SYS_IOCTL:
+ *     This symbol, if defined, indicates that <sys/ioctl.h> exists and should
+ *     be included. Otherwise, include <sgtty.h> or <termio.h>.
+ */
+/* I_SYS_SOCKIO:
+ *     This symbol, if defined, indicates the <sys/sockio.h> should be included
+ *     to get socket ioctl options, like SIOCATMARK.
+ */
+#define        I_SYS_IOCTL             /**/
+
+
+/* I_SYS_NDIR:
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <sys/ndir.h>.
+ */
+/*#define I_SYS_NDIR   /**/
+
+/* I_SYS_PARAM:
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <sys/param.h>.
+ */
+/*#define I_SYS_PARAM          /**/
+
+/* I_SYS_RESOURCE:
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <sys/resource.h>.
+ */
+/*#define I_SYS_RESOURCE               /**/
+
+/* I_SYS_SELECT:
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <sys/select.h> in order to get definition of struct timeval.
+ */
+/*#define I_SYS_SELECT /**/
+
+/* I_SYS_STAT:
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <sys/stat.h>.
+ */
+#define        I_SYS_STAT              /**/
+
+/* I_SYS_TIMES:
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <sys/times.h>.
+ */
+/*#define      I_SYS_TIMES             /**/
+
+/* I_SYS_TYPES:
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <sys/types.h>.
+ */
+#define        I_SYS_TYPES             /**/
+
+/* I_SYS_UN:
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <sys/un.h> to get UNIX domain socket definitions.
+ */
+/*#define I_SYS_UN             /**/
+
+/* I_SYS_WAIT:
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <sys/wait.h>.
+ */
+/*#define I_SYS_WAIT   /**/
+
+/* I_TERMIO:
+ *     This symbol, if defined, indicates that the program should include
+ *     <termio.h> rather than <sgtty.h>.  There are also differences in
+ *     the ioctl() calls that depend on the value of this symbol.
+ */
+/* I_TERMIOS:
+ *     This symbol, if defined, indicates that the program should include
+ *     the POSIX termios.h rather than sgtty.h or termio.h.
+ *     There are also differences in the ioctl() calls that depend on the
+ *     value of this symbol.
+ */
+/* I_SGTTY:
+ *     This symbol, if defined, indicates that the program should include
+ *     <sgtty.h> rather than <termio.h>.  There are also differences in
+ *     the ioctl() calls that depend on the value of this symbol.
+ */
+/*#define I_TERMIO             /**/
+/*#define I_TERMIOS            /**/
+/*#define I_SGTTY              /**/
+
+/* I_UNISTD:
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <unistd.h>.
+ */
+/*#define I_UNISTD             /**/
+
+/* I_UTIME:
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <utime.h>.
+ */
+#define I_UTIME                /**/
+
+/* I_VALUES:
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <values.h> to get definition of symbols like MINFLOAT or
+ *     MAXLONG, i.e. machine dependant limitations.  Probably, you
+ *     should use <limits.h> instead, if it is available.
+ */
+/*#define I_VALUES             /**/
+
+/* I_STDARG:
+ *     This symbol, if defined, indicates that <stdarg.h> exists and should
+ *     be included.
+ */
+/* I_VARARGS:
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <varargs.h>.
+ */
+#define I_STDARG               /**/
+/*#define I_VARARGS    /**/
+
+/* I_VFORK:
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include vfork.h.
+ */
+/*#define I_VFORK      /**/
+
+/* CAN_PROTOTYPE:
+ *     If defined, this macro indicates that the C compiler can handle
+ *     function prototypes.
+ */
+/* _:
+ *     This macro is used to declare function parameters for folks who want
+ *     to make declarations with prototypes using a different style than
+ *     the above macros.  Use double parentheses.  For example:
+ *
+ *             int main _((int argc, char *argv[]));
+ */
+#define        CAN_PROTOTYPE   /**/
+#ifdef CAN_PROTOTYPE
+#define        _(args) args
+#else
+#define        _(args) ()
+#endif
+
+/* SH_PATH:
+ *     This symbol contains the full pathname to the shell used on this
+ *     on this system to execute Bourne shell scripts.  Usually, this will be
+ *     /bin/sh, though it's possible that some systems will have /bin/ksh,
+ *     /bin/pdksh, /bin/ash, /bin/bash, or even something such as
+ *     D:/bin/sh.exe.
+ */
+#define SH_PATH "cmd /x /c"  /**/
+
+/* CROSSCOMPILE:
+ *     This symbol, if defined, signifies that we our
+ *     build process is a cross-compilation.
+ */
+/*#define CROSSCOMPILE         /**/
+
+/* INTSIZE:
+ *     This symbol contains the value of sizeof(int) so that the C
+ *     preprocessor can make decisions based on it.
+ */
+/* LONGSIZE:
+ *     This symbol contains the value of sizeof(long) so that the C
+ *     preprocessor can make decisions based on it.
+ */
+/* SHORTSIZE:
+ *     This symbol contains the value of sizeof(short) so that the C
+ *     preprocessor can make decisions based on it.
+ */
+#define INTSIZE 4              /**/
+#define LONGSIZE 4             /**/
+#define SHORTSIZE 2            /**/
+
+/* MULTIARCH:
+ *     This symbol, if defined, signifies that the build
+ *     process will produce some binary files that are going to be
+ *     used in a cross-platform environment.  This is the case for
+ *     example with the NeXT "fat" binaries that contain executables
+ *     for several CPUs.
+ */
+/*#define MULTIARCH            /**/
+
+/* HAS_QUAD:
+ *     This symbol, if defined, tells that there's a 64-bit integer type,
+ *     Quad_t, and its unsigned counterpar, Uquad_t. QUADKIND will be one
+ *     of QUAD_IS_INT, QUAD_IS_LONG, QUAD_IS_LONG_LONG, or QUAD_IS_INT64_T.
+ */
+/*#define HAS_QUAD     /**/
+#ifdef HAS_QUAD
+#   define Quad_t __int64      /**/
+#   define Uquad_t unsigned __int64    /**/
+#   define QUADKIND 5  /**/
+#   define QUAD_IS_INT 1
+#   define QUAD_IS_LONG        2
+#   define QUAD_IS_LONG_LONG   3
+#   define QUAD_IS_INT64_T     4
+#endif
+
+/* HAS_ACCESSX:
+ *     This symbol, if defined, indicates that the accessx routine is
+ *     available to do extended access checks.
+ */
+/*#define HAS_ACCESSX          /**/
+
+/* HAS_EACCESS:
+ *     This symbol, if defined, indicates that the eaccess routine is
+ *     available to do extended access checks.
+ */
+/*#define HAS_EACCESS          /**/
+
+/* I_SYS_ACCESS:
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <sys/access.h>.
+ */
+/*#define   I_SYS_ACCESS                /**/
+
+/* I_SYS_SECURITY:
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <sys/security.h>.
+ */
+/*#define   I_SYS_SECURITY     /**/
+
+/* OSNAME:
+ *     This symbol contains the name of the operating system, as determined
+ *     by Configure.  You shouldn't rely on it too much; the specific
+ *     feature tests from Configure are generally more reliable.
+ */
+#define OSNAME "NetWare"               /**/
+
+/* MEM_ALIGNBYTES:
+ *     This symbol contains the number of bytes required to align a
+ *     double, or a long double when applicable. Usual values are 2,
+ *     4 and 8. The default is eight, for safety.
+ */
+#if defined(CROSSCOMPILE) || defined(MULTIARCH)
+#  define MEM_ALIGNBYTES 8
+#else
+#define MEM_ALIGNBYTES 8
+#endif
+
+/* ARCHLIB:
+ *     This variable, if defined, holds the name of the directory in
+ *     which the user wants to put architecture-dependent public
+ *     library files for perl5.  It is most often a local directory
+ *     such as /usr/local/lib.  Programs using this variable must be
+ *     prepared to deal with filename expansion.  If ARCHLIB is the
+ *     same as PRIVLIB, it is not defined, since presumably the
+ *     program already searches PRIVLIB.
+ */
+/* ARCHLIB_EXP:
+ *     This symbol contains the ~name expanded version of ARCHLIB, to be used
+ *     in programs that are not prepared to deal with ~ expansion at run-time.
+ */
+#define ARCHLIB "c:\\perl\\5.7.1\\lib\\NetWare-x86-multi-thread"               /**/
+/*#define ARCHLIB_EXP ""       /**/
+
+/* ARCHNAME:
+ *     This symbol holds a string representing the architecture name.
+ *     It may be used to construct an architecture-dependant pathname
+ *     where library files may be held under a private library, for
+ *     instance.
+ */
+#define ARCHNAME "NetWare-x86-multi-thread"            /**/
+
+/* HAS_ATOLF:
+ *     This symbol, if defined, indicates that the atolf routine is
+ *     available to convert strings into long doubles.
+ */
+/*#define HAS_ATOLF            /**/
+
+/* HAS_ATOLL:
+ *     This symbol, if defined, indicates that the atoll routine is
+ *     available to convert strings into long longs.
+ */
+/*#define HAS_ATOLL            /**/
+
+/* BIN:
+ *     This symbol holds the path of the bin directory where the package will
+ *     be installed. Program must be prepared to deal with ~name substitution.
+ */
+/* BIN_EXP:
+ *     This symbol is the filename expanded version of the BIN symbol, for
+ *     programs that do not want to deal with that at run-time.
+ */
+#define BIN "c:\\perl\\5.7.1\\bin\\NetWare-x86-multi-thread"   /**/
+#define BIN_EXP "c:\\perl\\5.7.1\\bin\\NetWare-x86-multi-thread"       /**/
+
+/* PERL_BINCOMPAT_5005:
+ *     This symbol, if defined, indicates that this version of Perl should be
+ *     binary-compatible with Perl 5.005.  This is impossible for builds
+ *     that use features like threads and multiplicity it is always undef
+ *     for those versions.
+ */
+/*#define PERL_BINCOMPAT_5005                  /**/
+
+/* BYTEORDER:
+ *     This symbol holds the hexadecimal constant defined in byteorder,
+ *     i.e. 0x1234 or 0x4321, etc...
+ *     If the compiler supports cross-compiling or multiple-architecture
+ *     binaries (eg. on NeXT systems), use compiler-defined macros to
+ *     determine the byte order.
+ *     On NeXT 3.2 (and greater), you can build "Fat" Multiple Architecture
+ *     Binaries (MAB) on either big endian or little endian machines.
+ *     The endian-ness is available at compile-time.  This only matters
+ *     for perl, where the config.h can be generated and installed on 
+ *     one system, and used by a different architecture to build an
+ *     extension.  Older versions of NeXT that might not have
+ *     defined either *_ENDIAN__ were all on Motorola 680x0 series,
+ *     so the default case (for NeXT) is big endian to catch them. 
+ *     This might matter for NeXT 3.0.
+ */
+#if defined(CROSSCOMPILE) || defined(MULTIARCH)
+#  ifdef __LITTLE_ENDIAN__
+#    if LONGSIZE == 4
+#      define BYTEORDER 0x1234
+#    else
+#      if LONGSIZE == 8
+#        define BYTEORDER 0x12345678
+#      endif
+#    endif
+#  else
+#    ifdef __BIG_ENDIAN__
+#      if LONGSIZE == 4
+#        define BYTEORDER 0x4321
+#      else
+#        if LONGSIZE == 8
+#          define BYTEORDER 0x87654321
+#        endif
+#      endif
+#    endif
+#  endif
+#  if !defined(BYTEORDER) && (defined(NeXT) || defined(__NeXT__))
+#    define BYTEORDER 0x4321
+#  endif
+#else
+#define BYTEORDER 0x1234       /* large digits for MSB */
+#endif /* NeXT */
+
+/* CAT2:
+ *     This macro catenates 2 tokens together.
+ */
+/* STRINGIFY:
+ *     This macro surrounds its token with double quotes.
+ */
+#if 42 == 1
+#define CAT2(a,b)      a/**/b
+#define STRINGIFY(a)   "a"
+               /* If you can get stringification with catify, tell me how! */
+#endif
+#if 42 == 42
+#define PeRl_CaTiFy(a, b)      a ## b  
+#define PeRl_StGiFy(a) #a
+/* the additional level of indirection enables these macros to be
+ * used as arguments to other macros.  See K&R 2nd ed., page 231. */
+#define CAT2(a,b)      PeRl_CaTiFy(a,b)
+#define StGiFy(a)      PeRl_StGiFy(a)
+#define STRINGIFY(a)   PeRl_StGiFy(a)
+#endif
+#if 42 != 1 && 42 != 42
+#   include "Bletch: How does this C preprocessor catenate tokens?"
+#endif
+
+/* CPPSTDIN:
+ *     This symbol contains the first part of the string which will invoke
+ *     the C preprocessor on the standard input and produce to standard
+ *     output.  Typical value of "cc -E" or "/lib/cpp", but it can also
+ *     call a wrapper. See CPPRUN.
+ */
+/* CPPMINUS:
+ *     This symbol contains the second part of the string which will invoke
+ *     the C preprocessor on the standard input and produce to standard
+ *     output.  This symbol will have the value "-" if CPPSTDIN needs a minus
+ *     to specify standard input, otherwise the value is "".
+ */
+/* CPPRUN:
+ *     This symbol contains the string which will invoke a C preprocessor on
+ *     the standard input and produce to standard output. It needs to end
+ *     with CPPLAST, after all other preprocessor flags have been specified.
+ *     The main difference with CPPSTDIN is that this program will never be a
+ *     pointer to a shell wrapper, i.e. it will be empty if no preprocessor is
+ *     available directly to the user. Note that it may well be different from
+ *     the preprocessor used to compile the C program.
+ */
+/* CPPLAST:
+ *     This symbol is intended to be used along with CPPRUN in the same manner
+ *     symbol CPPMINUS is used with CPPSTDIN. It contains either "-" or "".
+ */
+#define CPPSTDIN "cl -nologo -E"
+#define CPPMINUS ""
+#define CPPRUN "cl -nologo -E"
+#define CPPLAST ""
+
+/* HAS__FWALK:
+ *     This symbol, if defined, indicates that the _fwalk system call is
+ *     available to apply a function to all the file handles.
+ */
+/*#define HAS__FWALK           /**/
+
+/* HAS_ACCESS:
+ *     This manifest constant lets the C program know that the access()
+ *     system call is available to check for accessibility using real UID/GID.
+ *     (always present on UNIX.)
+ */
+#define HAS_ACCESS             /**/
+
+/* CASTI32:
+ *     This symbol is defined if the C compiler can cast negative
+ *     or large floating point numbers to 32-bit ints.
+ */
+/*#define      CASTI32         /**/
+
+/* CASTNEGFLOAT:
+ *     This symbol is defined if the C compiler can cast negative
+ *     numbers to unsigned longs, ints and shorts.
+ */
+/* CASTFLAGS:
+ *     This symbol contains flags that say what difficulties the compiler
+ *     has casting odd floating values to unsigned long:
+ *             0 = ok
+ *             1 = couldn't cast < 0
+ *             2 = couldn't cast >= 0x80000000
+ *             4 = couldn't cast in argument expression list
+ */
+#define        CASTNEGFLOAT            /**/
+#define CASTFLAGS 0            /**/
+
+/* VOID_CLOSEDIR:
+ *     This symbol, if defined, indicates that the closedir() routine
+ *     does not return a value.
+ */
+/*#define VOID_CLOSEDIR                /**/
+
+/* HAS_STRUCT_CMSGHDR:
+ *     This symbol, if defined, indicates that the struct cmsghdr
+ *     is supported.
+ */
+/*#define HAS_STRUCT_CMSGHDR   /**/
+
+/* HAS_CSH:
+ *     This symbol, if defined, indicates that the C-shell exists.
+ */
+/* CSH:
+ *     This symbol, if defined, contains the full pathname of csh.
+ */
+/*#define HAS_CSH              /**/
+#ifdef HAS_CSH
+#define CSH "" /**/
+#endif
+
+/* DLSYM_NEEDS_UNDERSCORE:
+ *     This symbol, if defined, indicates that we need to prepend an
+ *     underscore to the symbol name before calling dlsym().  This only
+ *     makes sense if you *have* dlsym, which we will presume is the
+ *     case if you're using dl_dlopen.xs.
+ */
+/*#define      DLSYM_NEEDS_UNDERSCORE  /**/
+
+/* HAS_DRAND48_PROTO:
+ *     This symbol, if defined, indicates that the system provides
+ *     a prototype for the drand48() function.  Otherwise, it is up
+ *     to the program to supply one.  A good guess is
+ *             extern double drand48 _((void));
+ */
+/*#define      HAS_DRAND48_PROTO       /**/
+
+/* HAS_ENDGRENT:
+ *     This symbol, if defined, indicates that the getgrent routine is
+ *     available for finalizing sequential access of the group database.
+ */
+/*#define HAS_ENDGRENT         /**/
+
+/* HAS_ENDHOSTENT:
+ *     This symbol, if defined, indicates that the endhostent() routine is
+ *     available to close whatever was being used for host queries.
+ */
+/*#define HAS_ENDHOSTENT               /**/
+
+/* HAS_ENDNETENT:
+ *     This symbol, if defined, indicates that the endnetent() routine is
+ *     available to close whatever was being used for network queries.
+ */
+/*#define HAS_ENDNETENT                /**/
+
+/* HAS_ENDPROTOENT:
+ *     This symbol, if defined, indicates that the endprotoent() routine is
+ *     available to close whatever was being used for protocol queries.
+ */
+/*#define HAS_ENDPROTOENT              /**/
+
+/* HAS_ENDPWENT:
+ *     This symbol, if defined, indicates that the getgrent routine is
+ *     available for finalizing sequential access of the passwd database.
+ */
+/*#define HAS_ENDPWENT         /**/
+
+/* HAS_ENDSERVENT:
+ *     This symbol, if defined, indicates that the endservent() routine is
+ *     available to close whatever was being used for service queries.
+ */
+/*#define HAS_ENDSERVENT               /**/
+
+/* FCNTL_CAN_LOCK:
+ *     This symbol, if defined, indicates that fcntl() can be used
+ *     for file locking.  Normally on Unix systems this is defined.
+ *     It may be undefined on VMS.
+ */
+/*#define FCNTL_CAN_LOCK               /**/
+
+/* HAS_FD_SET:
+ *     This symbol, when defined, indicates presence of the fd_set typedef
+ *     in <sys/types.h>
+ */
+#define HAS_FD_SET     /**/
+
+/* FLEXFILENAMES:
+ *     This symbol, if defined, indicates that the system supports filenames
+ *     longer than 14 characters.
+ */
+#define        FLEXFILENAMES           /**/
+
+/* HAS_FPOS64_T:
+ *     This symbol will be defined if the C compiler supports fpos64_t.
+ */
+/*#define      HAS_FPOS64_T            /**/
+
+/* HAS_FREXPL:
+ *     This symbol, if defined, indicates that the frexpl routine is
+ *     available to break a long double floating-point number into
+ *     a normalized fraction and an integral power of 2.
+ */
+/*#define HAS_FREXPL           /**/
+
+/* HAS_STRUCT_FS_DATA:
+ *     This symbol, if defined, indicates that the struct fs_data
+ *     to do statfs() is supported.
+ */
+/*#define HAS_STRUCT_FS_DATA   /**/
+
+/* HAS_FSEEKO:
+ *     This symbol, if defined, indicates that the fseeko routine is
+ *     available to fseek beyond 32 bits (useful for ILP32 hosts).
+ */
+/*#define HAS_FSEEKO           /**/
+
+/* HAS_FSTATFS:
+ *     This symbol, if defined, indicates that the fstatfs routine is
+ *     available to stat filesystems by file descriptors.
+ */
+/*#define HAS_FSTATFS          /**/
+
+/* HAS_FSYNC:
+ *     This symbol, if defined, indicates that the fsync routine is
+ *     available to write a file's modified data and attributes to
+ *     permanent storage.
+ */
+/*#define HAS_FSYNC            /**/
+
+/* HAS_FTELLO:
+ *     This symbol, if defined, indicates that the ftello routine is
+ *     available to ftell beyond 32 bits (useful for ILP32 hosts).
+ */
+/*#define HAS_FTELLO           /**/
+
+/* Gconvert:
+ *     This preprocessor macro is defined to convert a floating point
+ *     number to a string without a trailing decimal point.  This
+ *     emulates the behavior of sprintf("%g"), but is sometimes much more
+ *     efficient.  If gconvert() is not available, but gcvt() drops the
+ *     trailing decimal point, then gcvt() is used.  If all else fails,
+ *     a macro using sprintf("%g") is used. Arguments for the Gconvert
+ *     macro are: value, number of digits, whether trailing zeros should
+ *     be retained, and the output buffer.
+ *     Possible values are:
+ *             d_Gconvert='gconvert((x),(n),(t),(b))'
+ *             d_Gconvert='gcvt((x),(n),(b))'
+ *             d_Gconvert='sprintf((b),"%.*g",(n),(x))'
+ *     The last two assume trailing zeros should not be kept.
+ */
+#define Gconvert(x,n,t,b) sprintf((b),"%.*g",(n),(x))
+
+/* HAS_GETCWD:
+ *     This symbol, if defined, indicates that the getcwd routine is
+ *     available to get the current working directory.
+ */
+/*#define HAS_GETCWD           /**/
+
+/* HAS_GETESPWNAM:
+ *     This symbol, if defined, indicates that the getespwnam system call is
+ *     available to retrieve enchanced (shadow) password entries by name.
+ */
+/*#define HAS_GETESPWNAM               /**/
+
+/* HAS_GETFSSTAT:
+ *     This symbol, if defined, indicates that the getfsstat routine is
+ *     available to stat filesystems in bulk.
+ */
+/*#define HAS_GETFSSTAT                /**/
+
+/* HAS_GETGRENT:
+ *     This symbol, if defined, indicates that the getgrent routine is
+ *     available for sequential access of the group database.
+ */
+/*#define HAS_GETGRENT         /**/
+
+/* HAS_GETHOSTBYADDR:
+ *     This symbol, if defined, indicates that the gethostbyaddr() routine is
+ *     available to look up hosts by their IP addresses.
+ */
+#define HAS_GETHOSTBYADDR              /**/
+
+/* HAS_GETHOSTBYNAME:
+ *     This symbol, if defined, indicates that the gethostbyname() routine is
+ *     available to look up host names in some data base or other.
+ */
+#define HAS_GETHOSTBYNAME              /**/
+
+/* HAS_GETHOSTENT:
+ *     This symbol, if defined, indicates that the gethostent() routine is
+ *     available to look up host names in some data base or another.
+ */
+/*#define HAS_GETHOSTENT               /**/
+
+/* HAS_GETHOSTNAME:
+ *     This symbol, if defined, indicates that the C program may use the
+ *     gethostname() routine to derive the host name.  See also HAS_UNAME
+ *     and PHOSTNAME.
+ */
+/* HAS_UNAME:
+ *     This symbol, if defined, indicates that the C program may use the
+ *     uname() routine to derive the host name.  See also HAS_GETHOSTNAME
+ *     and PHOSTNAME.
+ */
+/* PHOSTNAME:
+ *     This symbol, if defined, indicates the command to feed to the
+ *     popen() routine to derive the host name.  See also HAS_GETHOSTNAME
+ *     and HAS_UNAME.  Note that the command uses a fully qualified path,
+ *     so that it is safe even if used by a process with super-user
+ *     privileges.
+ */
+/* HAS_PHOSTNAME:
+ *     This symbol, if defined, indicates that the C program may use the
+ *     contents of PHOSTNAME as a command to feed to the popen() routine
+ *     to derive the host name.
+ */
+#define HAS_GETHOSTNAME        /**/
+#define HAS_UNAME              /**/
+/*#define HAS_PHOSTNAME        /**/
+#ifdef HAS_PHOSTNAME
+#define PHOSTNAME ""   /* How to get the host name */
+#endif
+
+/* HAS_GETHOST_PROTOS:
+ *     This symbol, if defined, indicates that <netdb.h> includes
+ *     prototypes for gethostent(), gethostbyname(), and
+ *     gethostbyaddr().  Otherwise, it is up to the program to guess
+ *     them.  See netdbtype.U for probing for various Netdb_xxx_t types.
+ */
+#define        HAS_GETHOST_PROTOS      /**/
+
+/* HAS_GETITIMER:
+ *     This symbol, if defined, indicates that the getitimer routine is
+ *     available to return interval timers.
+ */
+/*#define HAS_GETITIMER                /**/
+
+/* HAS_GETMNT:
+ *     This symbol, if defined, indicates that the getmnt routine is
+ *     available to get filesystem mount info by filename.
+ */
+/*#define HAS_GETMNT           /**/
+
+/* HAS_GETMNTENT:
+ *     This symbol, if defined, indicates that the getmntent routine is
+ *     available to iterate through mounted file systems to get their info.
+ */
+/*#define HAS_GETMNTENT                /**/
+
+/* HAS_GETNETBYADDR:
+ *     This symbol, if defined, indicates that the getnetbyaddr() routine is
+ *     available to look up networks by their IP addresses.
+ */
+/*#define HAS_GETNETBYADDR             /**/
+
+/* HAS_GETNETBYNAME:
+ *     This symbol, if defined, indicates that the getnetbyname() routine is
+ *     available to look up networks by their names.
+ */
+/*#define HAS_GETNETBYNAME             /**/
+
+/* HAS_GETNETENT:
+ *     This symbol, if defined, indicates that the getnetent() routine is
+ *     available to look up network names in some data base or another.
+ */
+/*#define HAS_GETNETENT                /**/
+
+/* HAS_GETNET_PROTOS:
+ *     This symbol, if defined, indicates that <netdb.h> includes
+ *     prototypes for getnetent(), getnetbyname(), and
+ *     getnetbyaddr().  Otherwise, it is up to the program to guess
+ *     them.  See netdbtype.U for probing for various Netdb_xxx_t types.
+ */
+#define        HAS_GETNET_PROTOS       /**/
+
+/* HAS_GETPAGESIZE:
+ *     This symbol, if defined, indicates that the getpagesize system call
+ *     is available to get system page size, which is the granularity of
+ *     many memory management calls.
+ */
+/*#define HAS_GETPAGESIZE              /**/
+
+/* HAS_GETPROTOENT:
+ *     This symbol, if defined, indicates that the getprotoent() routine is
+ *     available to look up protocols in some data base or another.
+ */
+/*#define HAS_GETPROTOENT              /**/
+
+/* HAS_GETPGRP:
+ *     This symbol, if defined, indicates that the getpgrp routine is
+ *     available to get the current process group.
+ */
+/* USE_BSD_GETPGRP:
+ *     This symbol, if defined, indicates that getpgrp needs one
+ *     arguments whereas USG one needs none.
+ */
+/*#define HAS_GETPGRP          /**/
+/*#define USE_BSD_GETPGRP      /**/
+
+/* HAS_GETPROTOBYNAME:
+ *     This symbol, if defined, indicates that the getprotobyname()
+ *     routine is available to look up protocols by their name.
+ */
+/* HAS_GETPROTOBYNUMBER:
+ *     This symbol, if defined, indicates that the getprotobynumber()
+ *     routine is available to look up protocols by their number.
+ */
+#define HAS_GETPROTOBYNAME             /**/
+#define HAS_GETPROTOBYNUMBER           /**/
+
+/* HAS_GETPROTO_PROTOS:
+ *     This symbol, if defined, indicates that <netdb.h> includes
+ *     prototypes for getprotoent(), getprotobyname(), and
+ *     getprotobyaddr().  Otherwise, it is up to the program to guess
+ *     them.  See netdbtype.U for probing for various Netdb_xxx_t types.
+ */
+#define        HAS_GETPROTO_PROTOS     /**/
+
+/* HAS_GETPRPWNAM:
+ *     This symbol, if defined, indicates that the getprpwnam system call is
+ *     available to retrieve protected (shadow) password entries by name.
+ */
+/*#define HAS_GETPRPWNAM               /**/
+
+/* HAS_GETPWENT:
+ *     This symbol, if defined, indicates that the getpwent routine is
+ *     available for sequential access of the passwd database.
+ *     If this is not available, the older getpw() function may be available.
+ */
+/*#define HAS_GETPWENT         /**/
+
+/* HAS_GETSERVENT:
+ *     This symbol, if defined, indicates that the getservent() routine is
+ *     available to look up network services in some data base or another.
+ */
+/*#define HAS_GETSERVENT               /**/
+
+/* HAS_GETSERV_PROTOS:
+ *     This symbol, if defined, indicates that <netdb.h> includes
+ *     prototypes for getservent(), getservbyname(), and
+ *     getservbyaddr().  Otherwise, it is up to the program to guess
+ *     them.  See netdbtype.U for probing for various Netdb_xxx_t types.
+ */
+#define        HAS_GETSERV_PROTOS      /**/
+
+/* HAS_GETSPNAM:
+ *     This symbol, if defined, indicates that the getspnam system call is
+ *     available to retrieve SysV shadow password entries by name.
+ */
+/*#define HAS_GETSPNAM         /**/
+
+/* HAS_GETSERVBYNAME:
+ *     This symbol, if defined, indicates that the getservbyname()
+ *     routine is available to look up services by their name.
+ */
+/* HAS_GETSERVBYPORT:
+ *     This symbol, if defined, indicates that the getservbyport()
+ *     routine is available to look up services by their port.
+ */
+#define HAS_GETSERVBYNAME              /**/
+#define HAS_GETSERVBYPORT              /**/
+
+/* HAS_GNULIBC:
+ *     This symbol, if defined, indicates to the C program that 
+ *     the GNU C library is being used.
+ */
+/*#define HAS_GNULIBC          /**/
+#if defined(HAS_GNULIBC) && !defined(_GNU_SOURCE)
+#   define _GNU_SOURCE
+#endif
+/* HAS_HASMNTOPT:
+ *     This symbol, if defined, indicates that the hasmntopt routine is
+ *     available to query the mount options of file systems.
+ */
+/*#define HAS_HASMNTOPT                /**/
+
+/* HAS_HTONL:
+ *     This symbol, if defined, indicates that the htonl() routine (and
+ *     friends htons() ntohl() ntohs()) are available to do network
+ *     order byte swapping.
+ */
+/* HAS_HTONS:
+ *     This symbol, if defined, indicates that the htons() routine (and
+ *     friends htonl() ntohl() ntohs()) are available to do network
+ *     order byte swapping.
+ */
+/* HAS_NTOHL:
+ *     This symbol, if defined, indicates that the ntohl() routine (and
+ *     friends htonl() htons() ntohs()) are available to do network
+ *     order byte swapping.
+ */
+/* HAS_NTOHS:
+ *     This symbol, if defined, indicates that the ntohs() routine (and
+ *     friends htonl() htons() ntohl()) are available to do network
+ *     order byte swapping.
+ */
+#define HAS_HTONL              /**/
+#define HAS_HTONS              /**/
+#define HAS_NTOHL              /**/
+#define HAS_NTOHS              /**/
+
+/* HAS_ICONV:
+ *     This symbol, if defined, indicates that the iconv routine is
+ *     available to do character set conversions.
+ */
+/*#define HAS_ICONV            /**/
+
+/* HAS_INT64_T:
+ *     This symbol will defined if the C compiler supports int64_t.
+ *     Usually the <inttypes.h> needs to be included, but sometimes
+ *     <sys/types.h> is enough.
+ */
+/*#define     HAS_INT64_T               /**/
+
+/* HAS_ISASCII:
+ *     This manifest constant lets the C program know that isascii 
+ *     is available.
+ */
+#define HAS_ISASCII            /**/
+
+/* HAS_ISNAN:
+ *     This symbol, if defined, indicates that the isnan routine is
+ *     available to check whether a double is a NaN.
+ */
+/*#define HAS_ISNAN            /**/
+
+/* HAS_ISNANL:
+ *     This symbol, if defined, indicates that the isnanl routine is
+ *     available to check whether a long double is a NaN.
+ */
+/*#define HAS_ISNANL           /**/
+
+/* HAS_LCHOWN:
+ *     This symbol, if defined, indicates that the lchown routine is
+ *     available to operate on a symbolic link (instead of following the
+ *     link).
+ */
+/*#define HAS_LCHOWN           /**/
+
+/* HAS_LDBL_DIG:
+ *     This symbol, if defined, indicates that this system's <float.h>
+ *     or <limits.h> defines the symbol LDBL_DIG, which is the number
+ *     of significant digits in a long double precision number. Unlike
+ *     for DBL_DIG, there's no good guess for LDBL_DIG if it is undefined.
+ */
+#define HAS_LDBL_DIG   /**/
+
+/* HAS_LONG_DOUBLE:
+ *     This symbol will be defined if the C compiler supports long
+ *     doubles.
+ */
+/* LONG_DOUBLESIZE:
+ *     This symbol contains the size of a long double, so that the 
+ *     C preprocessor can make decisions based on it.  It is only
+ *     defined if the system supports long doubles.
+ */
+#define HAS_LONG_DOUBLE                /**/
+#ifdef HAS_LONG_DOUBLE
+#define LONG_DOUBLESIZE 10             /**/
+#endif
+
+/* HAS_LONG_LONG:
+ *     This symbol will be defined if the C compiler supports long long.
+ */
+/* LONGLONGSIZE:
+ *     This symbol contains the size of a long long, so that the 
+ *     C preprocessor can make decisions based on it.  It is only
+ *     defined if the system supports long long.
+ */
+/*#define HAS_LONG_LONG                /**/
+#ifdef HAS_LONG_LONG
+#define LONGLONGSIZE 8         /**/
+#endif
+
+/* HAS_LSEEK_PROTO:
+ *     This symbol, if defined, indicates that the system provides
+ *     a prototype for the lseek() function.  Otherwise, it is up
+ *     to the program to supply one.  A good guess is
+ *             extern off_t lseek(int, off_t, int);
+ */
+#define        HAS_LSEEK_PROTO /**/
+
+/* HAS_MADVISE:
+ *     This symbol, if defined, indicates that the madvise system call is
+ *     available to map a file into memory.
+ */
+/*#define HAS_MADVISE          /**/
+
+/* HAS_MEMCHR:
+ *     This symbol, if defined, indicates that the memchr routine is available
+ *     to locate characters within a C string.
+ */
+#define HAS_MEMCHR     /**/
+
+/* HAS_MKDTEMP:
+ *     This symbol, if defined, indicates that the mkdtemp routine is
+ *     available to exclusively create a uniquely named temporary directory.
+ */
+/*#define HAS_MKDTEMP          /**/
+
+/* HAS_MKSTEMP:
+ *     This symbol, if defined, indicates that the mkstemp routine is
+ *     available to exclusively create and open a uniquely named
+ *     temporary file.
+ */
+/*#define HAS_MKSTEMP          /**/
+
+/* HAS_MKSTEMPS:
+ *     This symbol, if defined, indicates that the mkstemps routine is
+ *     available to excluslvely create and open a uniquely named
+ *     (with a suffix) temporary file.
+ */
+/*#define HAS_MKSTEMPS         /**/
+
+/* HAS_MMAP:
+ *     This symbol, if defined, indicates that the mmap system call is
+ *     available to map a file into memory.
+ */
+/* Mmap_t:
+ *     This symbol holds the return type of the mmap() system call
+ *     (and simultaneously the type of the first argument).
+ *     Usually set to 'void *' or 'cadd_t'.
+ */
+/*#define HAS_MMAP             /**/
+#define Mmap_t void *  /**/
+
+/* HAS_MODFL:
+ *     This symbol, if defined, indicates that the modfl routine is
+ *     available to split a long double x into a fractional part f and
+ *     an integer part i such that |f| < 1.0 and (f + i) = x.
+ */
+/*#define HAS_MODFL            /**/
+
+/* HAS_MPROTECT:
+ *     This symbol, if defined, indicates that the mprotect system call is
+ *     available to modify the access protection of a memory mapped file.
+ */
+/*#define HAS_MPROTECT         /**/
+
+/* HAS_MSG:
+ *     This symbol, if defined, indicates that the entire msg*(2) library is
+ *     supported (IPC mechanism based on message queues).
+ */
+/*#define HAS_MSG              /**/
+
+/* HAS_STRUCT_MSGHDR:
+ *     This symbol, if defined, indicates that the struct msghdr
+ *     is supported.
+ */
+/*#define HAS_STRUCT_MSGHDR    /**/
+
+/* HAS_OFF64_T:
+ *     This symbol will be defined if the C compiler supports off64_t.
+ */
+/*#define      HAS_OFF64_T             /**/
+
+/* HAS_OPEN3:
+ *     This manifest constant lets the C program know that the three
+ *     argument form of open(2) is available.
+ */
+/*#define HAS_OPEN3            /**/
+
+/* OLD_PTHREAD_CREATE_JOINABLE:
+ *     This symbol, if defined, indicates how to create pthread
+ *     in joinable (aka undetached) state.  NOTE: not defined
+ *     if pthread.h already has defined PTHREAD_CREATE_JOINABLE
+ *     (the new version of the constant).
+ *     If defined, known values are PTHREAD_CREATE_UNDETACHED
+ *     and __UNDETACHED.
+ */
+/*#define OLD_PTHREAD_CREATE_JOINABLE  /**/
+
+/* HAS_PTHREAD_YIELD:
+ *     This symbol, if defined, indicates that the pthread_yield 
+ *     routine is available to yield the execution of the current
+ *     thread.  sched_yield is preferable to pthread_yield.
+ */
+/* SCHED_YIELD:
+ *     This symbol defines the way to yield the execution of
+ *     the current thread.  Known ways are sched_yield,
+ *     pthread_yield, and pthread_yield with NULL.
+ */
+/* HAS_SCHED_YIELD:
+ *     This symbol, if defined, indicates that the sched_yield
+ *     routine is available to yield the execution of the current
+ *     thread.  sched_yield is preferable to pthread_yield.
+ */
+/*#define HAS_PTHREAD_YIELD    /**/
+#define SCHED_YIELD            /**/
+/*#define HAS_SCHED_YIELD      /**/
+
+/* HAS_READV:
+ *     This symbol, if defined, indicates that the readv routine is
+ *     available to do gather reads.  You will also need <sys/uio.h>
+ *     and there I_SYSUIO.
+ */
+/*#define HAS_READV            /**/
+
+/* HAS_RECVMSG:
+ *     This symbol, if defined, indicates that the recvmsg routine is
+ *     available to send structured socket messages.
+ */
+/*#define HAS_RECVMSG          /**/
+
+/* HAS_SAFE_BCOPY:
+ *     This symbol, if defined, indicates that the bcopy routine is available
+ *     to copy potentially overlapping memory blocks. Otherwise you should
+ *     probably use memmove() or memcpy(). If neither is defined, roll your
+ *     own version.
+ */
+/*#define HAS_SAFE_BCOPY       /**/
+
+/* HAS_SAFE_MEMCPY:
+ *     This symbol, if defined, indicates that the memcpy routine is available
+ *     to copy potentially overlapping memory blocks. Otherwise you should
+ *     probably use memmove() or memcpy(). If neither is defined, roll your
+ *     own version.
+ */
+/*#define HAS_SAFE_MEMCPY      /**/
+
+/* HAS_SANE_MEMCMP:
+ *     This symbol, if defined, indicates that the memcmp routine is available
+ *     and can be used to compare relative magnitudes of chars with their high
+ *     bits set.  If it is not defined, roll your own version.
+ */
+#define HAS_SANE_MEMCMP        /**/
+
+/* HAS_SBRK_PROTO:
+ *     This symbol, if defined, indicates that the system provides
+ *     a prototype for the sbrk() function.  Otherwise, it is up
+ *     to the program to supply one.  Good guesses are
+ *             extern void* sbrk _((int));
+ *             extern void* sbrk _((size_t));
+ */
+/*#define      HAS_SBRK_PROTO  /**/
+
+/* HAS_SEM:
+ *     This symbol, if defined, indicates that the entire sem*(2) library is
+ *     supported.
+ */
+/*#define HAS_SEM              /**/
+
+/* HAS_SENDMSG:
+ *     This symbol, if defined, indicates that the sendmsg routine is
+ *     available to send structured socket messages.
+ */
+/*#define HAS_SENDMSG          /**/
+
+/* HAS_SETGRENT:
+ *     This symbol, if defined, indicates that the setgrent routine is
+ *     available for initializing sequential access of the group database.
+ */
+/*#define HAS_SETGRENT         /**/
+
+/* HAS_SETGROUPS:
+ *     This symbol, if defined, indicates that the setgroups() routine is
+ *     available to set the list of process groups.  If unavailable, multiple
+ *     groups are probably not supported.
+ */
+/*#define HAS_SETGROUPS                /**/
+
+/* HAS_SETHOSTENT:
+ *     This symbol, if defined, indicates that the sethostent() routine is
+ *     available.
+ */
+/*#define HAS_SETHOSTENT               /**/
+
+/* HAS_SETITIMER:
+ *     This symbol, if defined, indicates that the setitimer routine is
+ *     available to set interval timers.
+ */
+/*#define HAS_SETITIMER                /**/
+
+/* HAS_SETNETENT:
+ *     This symbol, if defined, indicates that the setnetent() routine is
+ *     available.
+ */
+/*#define HAS_SETNETENT                /**/
+
+/* HAS_SETPROTOENT:
+ *     This symbol, if defined, indicates that the setprotoent() routine is
+ *     available.
+ */
+/*#define HAS_SETPROTOENT              /**/
+
+/* HAS_SETPGRP:
+ *     This symbol, if defined, indicates that the setpgrp routine is
+ *     available to set the current process group.
+ */
+/* USE_BSD_SETPGRP:
+ *     This symbol, if defined, indicates that setpgrp needs two
+ *     arguments whereas USG one needs none.  See also HAS_SETPGID
+ *     for a POSIX interface.
+ */
+/*#define HAS_SETPGRP          /**/
+/*#define USE_BSD_SETPGRP      /**/
+
+/* HAS_SETPROCTITLE:
+ *     This symbol, if defined, indicates that the setproctitle routine is
+ *     available to set process title.
+ */
+/*#define HAS_SETPROCTITLE             /**/
+
+/* HAS_SETPWENT:
+ *     This symbol, if defined, indicates that the setpwent routine is
+ *     available for initializing sequential access of the passwd database.
+ */
+/*#define HAS_SETPWENT         /**/
+
+/* HAS_SETSERVENT:
+ *     This symbol, if defined, indicates that the setservent() routine is
+ *     available.
+ */
+/*#define HAS_SETSERVENT               /**/
+
+/* HAS_SETVBUF:
+ *     This symbol, if defined, indicates that the setvbuf routine is
+ *     available to change buffering on an open stdio stream.
+ *     to a line-buffered mode.
+ */
+#define HAS_SETVBUF            /**/
+
+/* USE_SFIO:
+ *     This symbol, if defined, indicates that sfio should
+ *     be used.
+ */
+/*#define      USE_SFIO                /**/
+
+/* HAS_SHM:
+ *     This symbol, if defined, indicates that the entire shm*(2) library is
+ *     supported.
+ */
+/*#define HAS_SHM              /**/
+
+/* HAS_SIGACTION:
+ *     This symbol, if defined, indicates that Vr4's sigaction() routine
+ *     is available.
+ */
+/*#define HAS_SIGACTION        /**/
+
+/* HAS_SIGSETJMP:
+ *     This variable indicates to the C program that the sigsetjmp()
+ *     routine is available to save the calling process's registers
+ *     and stack environment for later use by siglongjmp(), and
+ *     to optionally save the process's signal mask.  See
+ *     Sigjmp_buf, Sigsetjmp, and Siglongjmp.
+ */
+/* Sigjmp_buf:
+ *     This is the buffer type to be used with Sigsetjmp and Siglongjmp.
+ */
+/* Sigsetjmp:
+ *     This macro is used in the same way as sigsetjmp(), but will invoke
+ *     traditional setjmp() if sigsetjmp isn't available.
+ *     See HAS_SIGSETJMP.
+ */
+/* Siglongjmp:
+ *     This macro is used in the same way as siglongjmp(), but will invoke
+ *     traditional longjmp() if siglongjmp isn't available.
+ *     See HAS_SIGSETJMP.
+ */
+/*#define HAS_SIGSETJMP        /**/
+#ifdef HAS_SIGSETJMP
+#define Sigjmp_buf sigjmp_buf
+#define Sigsetjmp(buf,save_mask) sigsetjmp((buf),(save_mask))
+#define Siglongjmp(buf,retval) siglongjmp((buf),(retval))
+#else
+#define Sigjmp_buf jmp_buf
+#define Sigsetjmp(buf,save_mask) setjmp((buf))
+#define Siglongjmp(buf,retval) longjmp((buf),(retval))
+#endif
+
+/* HAS_SOCKET:
+ *     This symbol, if defined, indicates that the BSD socket interface is
+ *     supported.
+ */
+/* HAS_SOCKETPAIR:
+ *     This symbol, if defined, indicates that the BSD socketpair() call is
+ *     supported.
+ */
+/* HAS_MSG_CTRUNC:
+ *     This symbol, if defined, indicates that the MSG_CTRUNC is supported.
+ *     Checking just with #ifdef might not be enough because this symbol
+ *     has been known to be an enum.
+ */
+/* HAS_MSG_DONTROUTE:
+ *     This symbol, if defined, indicates that the MSG_DONTROUTE is supported.
+ *     Checking just with #ifdef might not be enough because this symbol
+ *     has been known to be an enum.
+ */
+/* HAS_MSG_OOB:
+ *     This symbol, if defined, indicates that the MSG_OOB is supported.
+ *     Checking just with #ifdef might not be enough because this symbol
+ *     has been known to be an enum.
+ */
+/* HAS_MSG_PEEK:
+ *     This symbol, if defined, indicates that the MSG_PEEK is supported.
+ *     Checking just with #ifdef might not be enough because this symbol
+ *     has been known to be an enum.
+ */
+/* HAS_MSG_PROXY:
+ *     This symbol, if defined, indicates that the MSG_PROXY is supported.
+ *     Checking just with #ifdef might not be enough because this symbol
+ *     has been known to be an enum.
+ */
+/* HAS_SCM_RIGHTS:
+ *     This symbol, if defined, indicates that the SCM_RIGHTS is supported.
+ *     Checking just with #ifdef might not be enough because this symbol
+ *     has been known to be an enum.
+ */
+#define        HAS_SOCKET              /**/
+/*#define      HAS_SOCKETPAIR  /**/
+/*#define      HAS_MSG_CTRUNC  /**/
+/*#define      HAS_MSG_DONTROUTE       /**/
+/*#define      HAS_MSG_OOB     /**/
+/*#define      HAS_MSG_PEEK    /**/
+/*#define      HAS_MSG_PROXY   /**/
+/*#define      HAS_SCM_RIGHTS  /**/
+
+/* HAS_SOCKS5_INIT:
+ *     This symbol, if defined, indicates that the socks5_init routine is
+ *     available to initialize SOCKS 5.
+ */
+/*#define HAS_SOCKS5_INIT              /**/
+
+/* HAS_SQRTL:
+ *     This symbol, if defined, indicates that the sqrtl routine is
+ *     available to do long double square roots.
+ */
+/*#define HAS_SQRTL            /**/
+
+/* USE_STAT_BLOCKS:
+ *     This symbol is defined if this system has a stat structure declaring
+ *     st_blksize and st_blocks.
+ */
+#ifndef USE_STAT_BLOCKS
+/*#define USE_STAT_BLOCKS      /**/
+#endif
+
+/* HAS_STRUCT_STATFS_F_FLAGS:
+ *     This symbol, if defined, indicates that the struct statfs
+ *     does have the f_flags member containing the mount flags of
+ *     the filesystem containing the file.
+ *     This kind of struct statfs is coming from <sys/mount.h> (BSD 4.3),
+ *     not from <sys/statfs.h> (SYSV).  Older BSDs (like Ultrix) do not
+ *     have statfs() and struct statfs, they have ustat() and getmnt()
+ *     with struct ustat and struct fs_data.
+ */
+/*#define HAS_STRUCT_STATFS_F_FLAGS            /**/
+
+/* HAS_STRUCT_STATFS:
+ *     This symbol, if defined, indicates that the struct statfs
+ *     to do statfs() is supported.
+ */
+/*#define HAS_STRUCT_STATFS    /**/
+
+/* HAS_FSTATVFS:
+ *     This symbol, if defined, indicates that the fstatvfs routine is
+ *     available to stat filesystems by file descriptors.
+ */
+/*#define HAS_FSTATVFS         /**/
+
+/* USE_STDIO_PTR:
+ *     This symbol is defined if the _ptr and _cnt fields (or similar)
+ *     of the stdio FILE structure can be used to access the stdio buffer
+ *     for a file handle.  If this is defined, then the FILE_ptr(fp)
+ *     and FILE_cnt(fp) macros will also be defined and should be used
+ *     to access these fields.
+ */
+/* FILE_ptr:
+ *     This macro is used to access the _ptr field (or equivalent) of the
+ *     FILE structure pointed to by its argument. This macro will always be
+ *     defined if USE_STDIO_PTR is defined.
+ */
+/* STDIO_PTR_LVALUE:
+ *     This symbol is defined if the FILE_ptr macro can be used as an
+ *     lvalue.
+ */
+/* FILE_cnt:
+ *     This macro is used to access the _cnt field (or equivalent) of the
+ *     FILE structure pointed to by its argument. This macro will always be
+ *     defined if USE_STDIO_PTR is defined.
+ */
+/* STDIO_CNT_LVALUE:
+ *     This symbol is defined if the FILE_cnt macro can be used as an
+ *     lvalue.
+ */
+/* STDIO_PTR_LVAL_SETS_CNT:
+ *     This symbol is defined if using the FILE_ptr macro as an lvalue
+ *     to increase the pointer by n has the side effect of decreasing the
+ *     value of File_cnt(fp) by n.
+ */
+/* STDIO_PTR_LVAL_NOCHANGE_CNT:
+ *     This symbol is defined if using the FILE_ptr macro as an lvalue
+ *     to increase the pointer by n leaves File_cnt(fp) unchanged.
+ */
+/*#define USE_STDIO_PTR        /**/
+#ifdef USE_STDIO_PTR
+#define FILE_ptr(fp)   ((fp)->_ptr)
+/*#define STDIO_PTR_LVALUE             /**/
+#define FILE_cnt(fp)   ((fp)->_cnt)
+/*#define STDIO_CNT_LVALUE             /**/
+/*#define STDIO_PTR_LVAL_SETS_CNT      /**/
+/*#define STDIO_PTR_LVAL_NOCHANGE_CNT  /**/
+#endif
+
+/* USE_STDIO_BASE:
+ *     This symbol is defined if the _base field (or similar) of the
+ *     stdio FILE structure can be used to access the stdio buffer for
+ *     a file handle.  If this is defined, then the FILE_base(fp) macro
+ *     will also be defined and should be used to access this field.
+ *     Also, the FILE_bufsiz(fp) macro will be defined and should be used
+ *     to determine the number of bytes in the buffer.  USE_STDIO_BASE
+ *     will never be defined unless USE_STDIO_PTR is.
+ */
+/* FILE_base:
+ *     This macro is used to access the _base field (or equivalent) of the
+ *     FILE structure pointed to by its argument. This macro will always be
+ *     defined if USE_STDIO_BASE is defined.
+ */
+/* FILE_bufsiz:
+ *     This macro is used to determine the number of bytes in the I/O
+ *     buffer pointed to by _base field (or equivalent) of the FILE
+ *     structure pointed to its argument. This macro will always be defined
+ *     if USE_STDIO_BASE is defined.
+ */
+/*#define USE_STDIO_BASE       /**/
+#ifdef USE_STDIO_BASE
+#define FILE_base(fp)  ((fp)->_base)
+#define FILE_bufsiz(fp)        ((fp)->_cnt + (fp)->_ptr - (fp)->_base)
+#endif
+
+/* HAS_STRERROR:
+ *     This symbol, if defined, indicates that the strerror routine is
+ *     available to translate error numbers to strings. See the writeup
+ *     of Strerror() in this file before you try to define your own.
+ */
+/* HAS_SYS_ERRLIST:
+ *     This symbol, if defined, indicates that the sys_errlist array is
+ *     available to translate error numbers to strings. The extern int
+ *     sys_nerr gives the size of that table.
+ */
+/* Strerror:
+ *     This preprocessor symbol is defined as a macro if strerror() is
+ *     not available to translate error numbers to strings but sys_errlist[]
+ *     array is there.
+ */
+#define HAS_STRERROR           /**/
+#define HAS_SYS_ERRLIST        /**/
+#define Strerror(e) strerror(e)
+
+/* HAS_STRTOLD:
+ *     This symbol, if defined, indicates that the strtold routine is
+ *     available to convert strings to long doubles.
+ */
+/*#define HAS_STRTOLD          /**/
+
+/* HAS_STRTOLL:
+ *     This symbol, if defined, indicates that the strtoll routine is
+ *     available to convert strings to long longs.
+ */
+/*#define HAS_STRTOLL          /**/
+
+/* HAS_STRTOQ:
+ *     This symbol, if defined, indicates that the strtoq routine is
+ *     available to convert strings to long longs (quads).
+ */
+/*#define HAS_STRTOQ           /**/
+
+/* HAS_STRTOUL:
+ *     This symbol, if defined, indicates that the strtoul routine is
+ *     available to provide conversion of strings to unsigned long.
+ */
+#define HAS_STRTOUL    /**/
+
+/* HAS_STRTOULL:
+ *     This symbol, if defined, indicates that the strtoull routine is
+ *     available to convert strings to unsigned long longs.
+ */
+/*#define HAS_STRTOULL         /**/
+
+/* HAS_STRTOUQ:
+ *     This symbol, if defined, indicates that the strtouq routine is
+ *     available to convert strings to unsigned long longs (quads).
+ */
+/*#define HAS_STRTOUQ          /**/
+
+/* HAS_TELLDIR_PROTO:
+ *     This symbol, if defined, indicates that the system provides
+ *     a prototype for the telldir() function.  Otherwise, it is up
+ *     to the program to supply one.  A good guess is
+ *             extern long telldir _((DIR*));
+ */
+#define        HAS_TELLDIR_PROTO       /**/
+
+/* Time_t:
+ *     This symbol holds the type returned by time(). It can be long,
+ *     or time_t on BSD sites (in which case <sys/types.h> should be
+ *     included).
+ */
+#define Time_t time_t          /* Time type */
+
+/* HAS_TIMES:
+ *     This symbol, if defined, indicates that the times() routine exists.
+ *     Note that this became obsolete on some systems (SUNOS), which now
+ * use getrusage(). It may be necessary to include <sys/times.h>.
+ */
+/*#define HAS_TIMES            /**/
+
+/* HAS_UALARM:
+ *     This symbol, if defined, indicates that the ualarm routine is
+ *     available to do alarms with microsecond granularity.
+ */
+/*#define HAS_UALARM           /**/
+
+/* HAS_UNION_SEMUN:
+ *     This symbol, if defined, indicates that the union semun is
+ *     defined by including <sys/sem.h>.  If not, the user code
+ *     probably needs to define it as:
+ *     union semun {
+ *         int val;
+ *         struct semid_ds *buf;
+ *         unsigned short *array;
+ *     }
+ */
+/* USE_SEMCTL_SEMUN:
+ *     This symbol, if defined, indicates that union semun is
+ *     used for semctl IPC_STAT.
+ */
+/* USE_SEMCTL_SEMID_DS:
+ *     This symbol, if defined, indicates that struct semid_ds * is
+ *     used for semctl IPC_STAT.
+ */
+#define HAS_UNION_SEMUN        /**/
+/*#define USE_SEMCTL_SEMUN     /**/
+/*#define USE_SEMCTL_SEMID_DS  /**/
+
+/* HAS_USTAT:
+ *     This symbol, if defined, indicates that the ustat system call is
+ *     available to query file system statistics by dev_t.
+ */
+/*#define HAS_USTAT            /**/
+
+/* HAS_VFORK:
+ *     This symbol, if defined, indicates that vfork() exists.
+ */
+/*#define HAS_VFORK    /**/
+
+/* Signal_t:
+ *     This symbol's value is either "void" or "int", corresponding to the
+ *     appropriate return type of a signal handler.  Thus, you can declare
+ *     a signal handler using "Signal_t (*handler)()", and define the
+ *     handler using "Signal_t handler(sig)".
+ */
+#define Signal_t void  /* Signal handler's return type */
+
+/* HAS_VPRINTF:
+ *     This symbol, if defined, indicates that the vprintf routine is available
+ *     to printf with a pointer to an argument list.  If unavailable, you
+ *     may need to write your own, probably in terms of _doprnt().
+ */
+/* USE_CHAR_VSPRINTF:
+ *     This symbol is defined if this system has vsprintf() returning type
+ *     (char*).  The trend seems to be to declare it as "int vsprintf()".  It
+ *     is up to the package author to declare vsprintf correctly based on the
+ *     symbol.
+ */
+#define HAS_VPRINTF    /**/
+/*#define USE_CHAR_VSPRINTF    /**/
+
+/* HAS_WRITEV:
+ *     This symbol, if defined, indicates that the writev routine is
+ *     available to do scatter writes.
+ */
+/*#define HAS_WRITEV           /**/
+
+/* USE_DYNAMIC_LOADING:
+ *     This symbol, if defined, indicates that dynamic loading of
+ *     some sort is available.
+ */
+#define USE_DYNAMIC_LOADING            /**/
+
+/* DOUBLESIZE:
+ *     This symbol contains the size of a double, so that the C preprocessor
+ *     can make decisions based on it.
+ */
+#define DOUBLESIZE 8           /**/
+
+/* EBCDIC:
+ *     This symbol, if defined, indicates that this system uses
+ *     EBCDIC encoding.
+ */
+/*#define      EBCDIC          /**/
+
+/* FFLUSH_NULL:
+ *     This symbol, if defined, tells that fflush(NULL) does flush
+ *     all pending stdio output.
+ */
+/* FFLUSH_ALL:
+ *     This symbol, if defined, tells that to flush
+ *     all pending stdio output one must loop through all
+ *     the stdio file handles stored in an array and fflush them.
+ *     Note that if fflushNULL is defined, fflushall will not
+ *     even be probed for and will be left undefined.
+ */
+#define        FFLUSH_NULL             /**/
+/*#define      FFLUSH_ALL              /**/
+
+/* Fpos_t:
+ *     This symbol holds the type used to declare file positions in libc.
+ *     It can be fpos_t, long, uint, etc... It may be necessary to include
+ *     <sys/types.h> to get any typedef'ed information.
+ */
+#define Fpos_t fpos_t          /* File position type */
+
+/* Gid_t_f:
+ *     This symbol defines the format string used for printing a Gid_t.
+ */
+#define        Gid_t_f         "ld"            /**/
+
+/* Gid_t_sign:
+ *     This symbol holds the signedess of a Gid_t.
+ *     1 for unsigned, -1 for signed.
+ */
+#define Gid_t_sign     -1              /* GID sign */
+
+/* Gid_t_size:
+ *     This symbol holds the size of a Gid_t in bytes.
+ */
+#define Gid_t_size 4           /* GID size */
+
+/* Gid_t:
+ *     This symbol holds the return type of getgid() and the type of
+ *     argument to setrgid() and related functions.  Typically,
+ *     it is the type of group ids in the kernel. It can be int, ushort,
+ *     gid_t, etc... It may be necessary to include <sys/types.h> to get
+ *     any typedef'ed information.
+ */
+#define Gid_t gid_t            /* Type for getgid(), etc... */
+
+/* Groups_t:
+ *     This symbol holds the type used for the second argument to
+ *     getgroups() and setgroups().  Usually, this is the same as
+ *     gidtype (gid_t) , but sometimes it isn't.
+ *     It can be int, ushort, gid_t, etc... 
+ *     It may be necessary to include <sys/types.h> to get any 
+ *     typedef'ed information.  This is only required if you have
+ *     getgroups() or setgroups()..
+ */
+#if defined(HAS_GETGROUPS) || defined(HAS_SETGROUPS)
+#define Groups_t gid_t /* Type for 2nd arg to [sg]etgroups() */
+#endif
+
+/* DB_Prefix_t:
+ *     This symbol contains the type of the prefix structure element
+ *     in the <db.h> header file.  In older versions of DB, it was
+ *     int, while in newer ones it is u_int32_t.
+ */
+/* DB_Hash_t:
+ *     This symbol contains the type of the prefix structure element
+ *     in the <db.h> header file.  In older versions of DB, it was
+ *     int, while in newer ones it is size_t.
+ */
+#define DB_Hash_t      int             /**/
+#define DB_Prefix_t    int     /**/
+
+/* I_GRP:
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <grp.h>.
+ */
+/* GRPASSWD:
+ *     This symbol, if defined, indicates to the C program that struct group
+ *     in <grp.h> contains gr_passwd.
+ */
+/*#define I_GRP                /**/
+/*#define GRPASSWD     /**/
+
+/* I_ICONV:
+ *     This symbol, if defined, indicates that <iconv.h> exists and
+ *     should be included.
+ */
+/*#define      I_ICONV         /**/
+
+/* I_IEEEFP:
+ *     This symbol, if defined, indicates that <ieeefp.h> exists and
+ *     should be included.
+ */
+/*#define      I_IEEEFP                /**/
+
+/* I_INTTYPES:
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <inttypes.h>.
+ */
+/*#define   I_INTTYPES                /**/
+
+/* I_LIBUTIL:
+ *     This symbol, if defined, indicates that <libutil.h> exists and
+ *     should be included.
+ */
+/*#define      I_LIBUTIL               /**/
+
+/* I_MACH_CTHREADS:
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <mach/cthreads.h>.
+ */
+/*#define   I_MACH_CTHREADS    /**/
+
+/* I_MNTENT:
+ *     This symbol, if defined, indicates that <mntent.h> exists and
+ *     should be included.
+ */
+/*#define      I_MNTENT                /**/
+
+/* I_NETDB:
+ *     This symbol, if defined, indicates that <netdb.h> exists and
+ *     should be included.
+ */
+#define I_NETDB                /**/
+
+/* I_NETINET_TCP:
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <netinet/tcp.h>.
+ */
+/*#define   I_NETINET_TCP                /**/
+
+/* I_POLL:
+ *     This symbol, if defined, indicates that <poll.h> exists and
+ *     should be included.
+ */
+/*#define      I_POLL          /**/
+
+/* I_PROT:
+ *     This symbol, if defined, indicates that <prot.h> exists and
+ *     should be included.
+ */
+/*#define      I_PROT          /**/
+
+/* I_PTHREAD:
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <pthread.h>.
+ */
+/*#define   I_PTHREAD  /**/
+
+/* I_PWD:
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <pwd.h>.
+ */
+/* PWQUOTA:
+ *     This symbol, if defined, indicates to the C program that struct passwd
+ *     contains pw_quota.
+ */
+/* PWAGE:
+ *     This symbol, if defined, indicates to the C program that struct passwd
+ *     contains pw_age.
+ */
+/* PWCHANGE:
+ *     This symbol, if defined, indicates to the C program that struct passwd
+ *     contains pw_change.
+ */
+/* PWCLASS:
+ *     This symbol, if defined, indicates to the C program that struct passwd
+ *     contains pw_class.
+ */
+/* PWEXPIRE:
+ *     This symbol, if defined, indicates to the C program that struct passwd
+ *     contains pw_expire.
+ */
+/* PWCOMMENT:
+ *     This symbol, if defined, indicates to the C program that struct passwd
+ *     contains pw_comment.
+ */
+/* PWGECOS:
+ *     This symbol, if defined, indicates to the C program that struct passwd
+ *     contains pw_gecos.
+ */
+/* PWPASSWD:
+ *     This symbol, if defined, indicates to the C program that struct passwd
+ *     contains pw_passwd.
+ */
+/*#define I_PWD                /**/
+/*#define PWQUOTA      /**/
+/*#define PWAGE        /**/
+/*#define PWCHANGE     /**/
+/*#define PWCLASS      /**/
+/*#define PWEXPIRE     /**/
+/*#define PWCOMMENT    /**/
+/*#define PWGECOS      /**/
+/*#define PWPASSWD     /**/
+
+/* I_SHADOW:
+ *     This symbol, if defined, indicates that <shadow.h> exists and
+ *     should be included.
+ */
+/*#define      I_SHADOW                /**/
+
+/* I_SOCKS:
+ *     This symbol, if defined, indicates that <socks.h> exists and
+ *     should be included.
+ */
+/*#define      I_SOCKS         /**/
+
+/* I_SUNMATH:
+ *     This symbol, if defined, indicates that <sunmath.h> exists and
+ *     should be included.
+ */
+/*#define      I_SUNMATH               /**/
+
+/* I_SYSLOG:
+ *     This symbol, if defined, indicates that <syslog.h> exists and
+ *     should be included.
+ */
+/*#define      I_SYSLOG                /**/
+
+/* I_SYSMODE:
+ *     This symbol, if defined, indicates that <sys/mode.h> exists and
+ *     should be included.
+ */
+/*#define      I_SYSMODE               /**/
+
+/* I_SYS_MOUNT:
+ *     This symbol, if defined, indicates that <sys/mount.h> exists and
+ *     should be included.
+ */
+/*#define      I_SYS_MOUNT             /**/
+
+/* I_SYS_STATFS:
+ *     This symbol, if defined, indicates that <sys/statfs.h> exists.
+ */
+/*#define      I_SYS_STATFS            /**/
+
+/* I_SYS_STATVFS:
+ *     This symbol, if defined, indicates that <sys/statvfs.h> exists and
+ *     should be included.
+ */
+/*#define      I_SYS_STATVFS           /**/
+
+/* I_SYSUIO:
+ *     This symbol, if defined, indicates that <sys/uio.h> exists and
+ *     should be included.
+ */
+/*#define      I_SYSUIO                /**/
+
+/* I_SYSUTSNAME:
+ *     This symbol, if defined, indicates that <sys/utsname.h> exists and
+ *     should be included.
+ */
+#define        I_SYSUTSNAME            /**/
+
+/* I_SYS_VFS:
+ *     This symbol, if defined, indicates that <sys/vfs.h> exists and
+ *     should be included.
+ */
+/*#define      I_SYS_VFS               /**/
+
+/* I_TIME:
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <time.h>.
+ */
+/* I_SYS_TIME:
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <sys/time.h>.
+ */
+/* I_SYS_TIME_KERNEL:
+ *     This symbol, if defined, indicates to the C program that it should
+ *     include <sys/time.h> with KERNEL defined.
+ */
+#define I_TIME         /**/
+/*#define I_SYS_TIME           /**/
+/*#define I_SYS_TIME_KERNEL            /**/
+
+/* I_USTAT:
+ *     This symbol, if defined, indicates that <ustat.h> exists and
+ *     should be included.
+ */
+/*#define      I_USTAT         /**/
+
+/* PERL_INC_VERSION_LIST:
+ *     This variable specifies the list of subdirectories in over
+ *     which perl.c:incpush() and lib/lib.pm will automatically
+ *     search when adding directories to @INC, in a format suitable
+ *     for a C initialization string.  See the inc_version_list entry
+ *     in Porting/Glossary for more details.
+ */
+#define PERL_INC_VERSION_LIST 0                /**/
+
+/* INSTALL_USR_BIN_PERL:
+ *     This symbol, if defined, indicates that Perl is to be installed
+ *     also as /usr/bin/perl.
+ */
+/*#define INSTALL_USR_BIN_PERL /**/
+
+/* PERL_PRIfldbl:
+ *     This symbol, if defined, contains the string used by stdio to
+ *     format long doubles (format 'f') for output.
+ */
+/* PERL_PRIgldbl:
+ *     This symbol, if defined, contains the string used by stdio to
+ *     format long doubles (format 'g') for output.
+ */
+/* PERL_PRIeldbl:
+ *     This symbol, if defined, contains the string used by stdio to
+ *     format long doubles (format 'e') for output.
+ */
+/* PERL_SCNfldbl:
+ *     This symbol, if defined, contains the string used by stdio to
+ *     format long doubles (format 'f') for input.
+ */
+/*#define PERL_PRIfldbl        "f"     /**/
+/*#define PERL_PRIgldbl        "g"     /**/
+/*#define PERL_PRIeldbl        "e"     /**/
+/*#define PERL_SCNfldbl        undef   /**/
+
+/* Off_t:
+ *     This symbol holds the type used to declare offsets in the kernel.
+ *     It can be int, long, off_t, etc... It may be necessary to include
+ *     <sys/types.h> to get any typedef'ed information.
+ */
+/* LSEEKSIZE:
+ *     This symbol holds the number of bytes used by the Off_t.
+ */
+/* Off_t_size:
+ *     This symbol holds the number of bytes used by the Off_t.
+ */
+#define Off_t off_t            /* <offset> type */
+#define LSEEKSIZE 4            /* <offset> size */
+#define Off_t_size 4   /* <offset> size */
+
+/* Free_t:
+ *     This variable contains the return type of free().  It is usually
+ * void, but occasionally int.
+ */
+/* Malloc_t:
+ *     This symbol is the type of pointer returned by malloc and realloc.
+ */
+#define Malloc_t void *                        /**/
+#define Free_t void                    /**/
+
+/* MYMALLOC:
+ *     This symbol, if defined, indicates that we're using our own malloc.
+ */
+/*#define MYMALLOC                     /**/
+
+/* Mode_t:
+ *     This symbol holds the type used to declare file modes 
+ *     for systems calls.  It is usually mode_t, but may be
+ *     int or unsigned short.  It may be necessary to include <sys/types.h>
+ *     to get any typedef'ed information.
+ */
+#define Mode_t mode_t   /* file mode parameter for system calls */
+
+/* VAL_O_NONBLOCK:
+ *     This symbol is to be used during open() or fcntl(F_SETFL) to turn on
+ *     non-blocking I/O for the file descriptor. Note that there is no way
+ *     back, i.e. you cannot turn it blocking again this way. If you wish to
+ *     alternatively switch between blocking and non-blocking, use the
+ *     ioctl(FIOSNBIO) call instead, but that is not supported by all devices.
+ */
+/* VAL_EAGAIN:
+ *     This symbol holds the errno error code set by read() when no data was
+ *     present on the non-blocking file descriptor.
+ */
+/* RD_NODATA:
+ *     This symbol holds the return code from read() when no data is present
+ *     on the non-blocking file descriptor. Be careful! If EOF_NONBLOCK is
+ *     not defined, then you can't distinguish between no data and EOF by
+ *     issuing a read(). You'll have to find another way to tell for sure!
+ */
+/* EOF_NONBLOCK:
+ *     This symbol, if defined, indicates to the C program that a read() on
+ *     a non-blocking file descriptor will return 0 on EOF, and not the value
+ *     held in RD_NODATA (-1 usually, in that case!).
+ */
+#define VAL_O_NONBLOCK O_NONBLOCK
+#define VAL_EAGAIN EAGAIN
+#define RD_NODATA -1
+#define EOF_NONBLOCK
+
+/* NEED_VA_COPY:
+ *     This symbol, if defined, indicates that the system stores
+ *     the variable argument list datatype, va_list, in a format
+ *     that cannot be copied by simple assignment, so that some
+ *     other means must be used when copying is required.
+ *     As such systems vary in their provision (or non-provision)
+ *     of copying mechanisms, handy.h defines a platform-
+ *     independent macro, Perl_va_copy(src, dst), to do the job.
+ */
+/*#define      NEED_VA_COPY            /**/
+
+/* Netdb_host_t:
+ *     This symbol holds the type used for the 1st argument
+ *     to gethostbyaddr().
+ */
+/* Netdb_hlen_t:
+ *     This symbol holds the type used for the 2nd argument
+ *     to gethostbyaddr().
+ */
+/* Netdb_name_t:
+ *     This symbol holds the type used for the argument to
+ *     gethostbyname().
+ */
+/* Netdb_net_t:
+ *     This symbol holds the type used for the 1st argument to
+ *     getnetbyaddr().
+ */
+#define Netdb_host_t           char * /**/
+#define Netdb_hlen_t           int /**/
+#define Netdb_name_t           char * /**/
+#define Netdb_net_t            long /**/
+
+/* PERL_OTHERLIBDIRS:
+ *     This variable contains a colon-separated set of paths for the perl
+ *     binary to search for additional library files or modules.
+ *     These directories will be tacked to the end of @INC.
+ *     Perl will automatically search below each path for version-
+ *     and architecture-specific directories.  See PERL_INC_VERSION_LIST
+ *     for more details.
+ */
+/*#define PERL_OTHERLIBDIRS "undef"            /**/
+
+/* IVTYPE:
+ *     This symbol defines the C type used for Perl's IV.
+ */
+/* UVTYPE:
+ *     This symbol defines the C type used for Perl's UV.
+ */
+/* I8TYPE:
+ *     This symbol defines the C type used for Perl's I8.
+ */
+/* U8TYPE:
+ *     This symbol defines the C type used for Perl's U8.
+ */
+/* I16TYPE:
+ *     This symbol defines the C type used for Perl's I16.
+ */
+/* U16TYPE:
+ *     This symbol defines the C type used for Perl's U16.
+ */
+/* I32TYPE:
+ *     This symbol defines the C type used for Perl's I32.
+ */
+/* U32TYPE:
+ *     This symbol defines the C type used for Perl's U32.
+ */
+/* I64TYPE:
+ *     This symbol defines the C type used for Perl's I64.
+ */
+/* U64TYPE:
+ *     This symbol defines the C type used for Perl's U64.
+ */
+/* NVTYPE:
+ *     This symbol defines the C type used for Perl's NV.
+ */
+/* IVSIZE:
+ *     This symbol contains the sizeof(IV).
+ */
+/* UVSIZE:
+ *     This symbol contains the sizeof(UV).
+ */
+/* I8SIZE:
+ *     This symbol contains the sizeof(I8).
+ */
+/* U8SIZE:
+ *     This symbol contains the sizeof(U8).
+ */
+/* I16SIZE:
+ *     This symbol contains the sizeof(I16).
+ */
+/* U16SIZE:
+ *     This symbol contains the sizeof(U16).
+ */
+/* I32SIZE:
+ *     This symbol contains the sizeof(I32).
+ */
+/* U32SIZE:
+ *     This symbol contains the sizeof(U32).
+ */
+/* I64SIZE:
+ *     This symbol contains the sizeof(I64).
+ */
+/* U64SIZE:
+ *     This symbol contains the sizeof(U64).
+ */
+/* NVSIZE:
+ *     This symbol contains the sizeof(NV).
+ */
+/* NV_PRESERVES_UV:
+ *     This symbol, if defined, indicates that a variable of type NVTYPE
+ *     can preserve all the bits of a variable of type UVTYPE.
+ */
+/* NV_PRESERVES_UV_BITS:
+ *     This symbol contains the number of bits a variable of type NVTYPE
+ *     can preserve of a variable of type UVTYPE.
+ */
+#define        IVTYPE          long            /**/
+#define        UVTYPE          unsigned long           /**/
+#define        I8TYPE          char            /**/
+#define        U8TYPE          unsigned char           /**/
+#define        I16TYPE         short   /**/
+#define        U16TYPE         unsigned short  /**/
+#define        I32TYPE         long    /**/
+#define        U32TYPE         unsigned long   /**/
+#ifdef HAS_QUAD
+#define        I64TYPE         __int64 /**/
+#define        U64TYPE         unsigned __int64        /**/
+#endif
+#define        NVTYPE          double          /**/
+#define        IVSIZE          4               /**/
+#define        UVSIZE          4               /**/
+#define        I8SIZE          1               /**/
+#define        U8SIZE          1               /**/
+#define        I16SIZE         2       /**/
+#define        U16SIZE         2       /**/
+#define        I32SIZE         4       /**/
+#define        U32SIZE         4       /**/
+#ifdef HAS_QUAD
+#define        I64SIZE         8       /**/
+#define        U64SIZE         8       /**/
+#endif
+#define        NVSIZE          8               /**/
+#define        NV_PRESERVES_UV
+#define        NV_PRESERVES_UV_BITS    undef
+
+/* IVdf:
+ *     This symbol defines the format string used for printing a Perl IV
+ *     as a signed decimal integer.
+ */
+/* UVuf:
+ *     This symbol defines the format string used for printing a Perl UV
+ *     as an unsigned decimal integer.
+ */
+/* UVof:
+ *     This symbol defines the format string used for printing a Perl UV
+ *     as an unsigned octal integer.
+ */
+/* UVxf:
+ *     This symbol defines the format string used for printing a Perl UV
+ *     as an unsigned hexadecimal integer in lowercase abcdef.
+ */
+/* UVXf:
+ *     This symbol defines the format string used for printing a Perl UV
+ *     as an unsigned hexadecimal integer in uppercase ABCDEF.
+ */
+/* NVef:
+ *     This symbol defines the format string used for printing a Perl NV
+ *     using %e-ish floating point format.
+ */
+/* NVff:
+ *     This symbol defines the format string used for printing a Perl NV
+ *     using %f-ish floating point format.
+ */
+/* NVgf:
+ *     This symbol defines the format string used for printing a Perl NV
+ *     using %g-ish floating point format.
+ */
+#define        IVdf            "ld"            /**/
+#define        UVuf            "lu"            /**/
+#define        UVof            "lo"            /**/
+#define        UVxf            "lx"            /**/
+#define        UVXf            undef           /**/
+#define        NVef            "e"             /**/
+#define        NVff            "f"             /**/
+#define        NVgf            "g"             /**/
+
+/* Pid_t:
+ *     This symbol holds the type used to declare process ids in the kernel.
+ *     It can be int, uint, pid_t, etc... It may be necessary to include
+ *     <sys/types.h> to get any typedef'ed information.
+ */
+#define Pid_t int              /* PID type */
+
+/* PRIVLIB:
+ *     This symbol contains the name of the private library for this package.
+ *     The library is private in the sense that it needn't be in anyone's
+ *     execution path, but it should be accessible by the world.  The program
+ *     should be prepared to do ~ expansion.
+ */
+/* PRIVLIB_EXP:
+ *     This symbol contains the ~name expanded version of PRIVLIB, to be used
+ *     in programs that are not prepared to deal with ~ expansion at run-time.
+ */
+#define PRIVLIB "sys:\\perl\\lib"              /**/
+#define PRIVLIB_EXP (fnNwGetEnvironmentStr("PRIVLIB", PRIVLIB))        /**/
+
+/* PTRSIZE:
+ *     This symbol contains the size of a pointer, so that the C preprocessor
+ *     can make decisions based on it.  It will be sizeof(void *) if
+ *     the compiler supports (void *); otherwise it will be
+ *     sizeof(char *).
+ */
+#define PTRSIZE 4              /**/
+
+/* Drand01:
+ *     This macro is to be used to generate uniformly distributed
+ *     random numbers over the range [0., 1.[.  You may have to supply
+ *     an 'extern double drand48();' in your program since SunOS 4.1.3
+ *     doesn't provide you with anything relevant in it's headers.
+ *     See HAS_DRAND48_PROTO.
+ */
+/* Rand_seed_t:
+ *     This symbol defines the type of the argument of the
+ *     random seed function.
+ */
+/* seedDrand01:
+ *     This symbol defines the macro to be used in seeding the
+ *     random number generator (see Drand01).
+ */
+/* RANDBITS:
+ *     This symbol indicates how many bits are produced by the
+ *     function used to generate normalized random numbers.
+ *     Values include 15, 16, 31, and 48.
+ */
+#define Drand01()              (rand()/(double)((unsigned)1<<RANDBITS))                /**/
+#define Rand_seed_t            unsigned                /**/
+#define seedDrand01(x) srand((Rand_seed_t)x)   /**/
+#define RANDBITS               15              /**/
+
+/* SELECT_MIN_BITS:
+ *     This symbol holds the minimum number of bits operated by select.
+ *     That is, if you do select(n, ...), how many bits at least will be
+ *     cleared in the masks if some activity is detected.  Usually this
+ *     is either n or 32*ceil(n/32), especially many little-endians do
+ *     the latter.  This is only useful if you have select(), naturally.
+ */
+#define SELECT_MIN_BITS        32      /**/
+
+/* Select_fd_set_t:
+ *     This symbol holds the type used for the 2nd, 3rd, and 4th
+ *     arguments to select.  Usually, this is 'fd_set *', if HAS_FD_SET
+ *     is defined, and 'int *' otherwise.  This is only useful if you 
+ *     have select(), of course.
+ */
+#define Select_fd_set_t        fd_set *        /**/
+
+/* SIG_NAME:
+ *     This symbol contains a list of signal names in order of
+ *     signal number. This is intended
+ *     to be used as a static array initialization, like this:
+ *             char *sig_name[] = { SIG_NAME };
+ *     The signals in the list are separated with commas, and each signal
+ *     is surrounded by double quotes. There is no leading SIG in the signal
+ *     name, i.e. SIGQUIT is known as "QUIT".
+ *     Gaps in the signal numbers (up to NSIG) are filled in with NUMnn,
+ *     etc., where nn is the actual signal number (e.g. NUM37).
+ *     The signal number for sig_name[i] is stored in sig_num[i].
+ *     The last element is 0 to terminate the list with a NULL.  This
+ *     corresponds to the 0 at the end of the sig_num list.
+ */
+/* SIG_NUM:
+ *     This symbol contains a list of signal numbers, in the same order as the
+ *     SIG_NAME list. It is suitable for static array initialization, as in:
+ *             int sig_num[] = { SIG_NUM };
+ *     The signals in the list are separated with commas, and the indices
+ *     within that list and the SIG_NAME list match, so it's easy to compute
+ *     the signal name from a number or vice versa at the price of a small
+ *     dynamic linear lookup. 
+ *     Duplicates are allowed, but are moved to the end of the list.
+ *     The signal number corresponding to sig_name[i] is sig_number[i].
+ *     if (i < NSIG) then sig_number[i] == i.  
+ *     The last element is 0, corresponding to the 0 at the end of
+ *     the sig_name list.
+ */
+/* SIG_SIZE:
+ *     This variable contains the number of elements of the sig_name
+ *     and sig_num arrays, excluding the final NULL entry.
+ */
+#define SIG_NAME "ZERO", "NUM01", "INT", "QUIT", "ILL", "NUM05", "NUM06", "NUM07", "FPE", "KILL", "NUM10", "SEGV", "NUM12", "PIPE", "ALRM", "TERM", "NUM16", "NUM17", "NUM18", "NUM19", "CHLD", "BREAK", "ABRT", "STOP", "NUM24", "CONT", "CLD", 0             /**/
+#define SIG_NUM  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 20, 0           /**/
+#define SIG_SIZE 27                    /**/
+
+/* SITEARCH:
+ *     This symbol contains the name of the private library for this package.
+ *     The library is private in the sense that it needn't be in anyone's
+ *     execution path, but it should be accessible by the world.  The program
+ *     should be prepared to do ~ expansion.
+ *     The standard distribution will put nothing in this directory.
+ *     After perl has been installed, users may install their own local
+ *     architecture-dependent modules in this directory with
+ *             MakeMaker Makefile.PL
+ *     or equivalent.  See INSTALL for details.
+ */
+/* SITEARCH_EXP:
+ *     This symbol contains the ~name expanded version of SITEARCH, to be used
+ *     in programs that are not prepared to deal with ~ expansion at run-time.
+ */
+#define SITEARCH "c:\\perl\\site\\5.7.1\\lib\\NetWare-x86-multi-thread"                /**/
+/*#define SITEARCH_EXP ""      /**/
+
+/* SITELIB:
+ *     This symbol contains the name of the private library for this package.
+ *     The library is private in the sense that it needn't be in anyone's
+ *     execution path, but it should be accessible by the world.  The program
+ *     should be prepared to do ~ expansion.
+ *     The standard distribution will put nothing in this directory.
+ *     After perl has been installed, users may install their own local
+ *     architecture-independent modules in this directory with
+ *             MakeMaker Makefile.PL
+ *     or equivalent.  See INSTALL for details.
+ */
+/* SITELIB_EXP:
+ *     This symbol contains the ~name expanded version of SITELIB, to be used
+ *     in programs that are not prepared to deal with ~ expansion at run-time.
+ */
+/* SITELIB_STEM:
+ *     This define is SITELIB_EXP with any trailing version-specific component
+ *     removed.  The elements in inc_version_list (inc_version_list.U) can
+ *     be tacked onto this variable to generate a list of directories to search.
+ */
+#define SITELIB "c:\\perl\\site\\5.7.1\\lib"           /**/
+#define SITELIB_EXP (nw_get_sitelib("5.7.1"))  /**/
+#define SITELIB_STEM ""                /**/
+
+/* Size_t_size:
+ *     This symbol holds the size of a Size_t in bytes.
+ */
+#define Size_t_size 4          /**/
+
+/* Size_t:
+ *     This symbol holds the type used to declare length parameters
+ *     for string functions.  It is usually size_t, but may be
+ *     unsigned long, int, etc.  It may be necessary to include
+ *     <sys/types.h> to get any typedef'ed information.
+ */
+#define Size_t size_t   /* length paramater for string functions */
+
+/* Sock_size_t:
+ *     This symbol holds the type used for the size argument of
+ *     various socket calls (just the base type, not the pointer-to).
+ */
+#define Sock_size_t            int /**/
+
+/* SSize_t:
+ *     This symbol holds the type used by functions that return
+ *     a count of bytes or an error condition.  It must be a signed type.
+ *     It is usually ssize_t, but may be long or int, etc.
+ *     It may be necessary to include <sys/types.h> or <unistd.h>
+ *     to get any typedef'ed information.
+ *     We will pick a type such that sizeof(SSize_t) == sizeof(Size_t).
+ */
+#define SSize_t int     /* signed count of bytes */
+
+/* STARTPERL:
+ *     This variable contains the string to put in front of a perl
+ *     script to make sure (one hopes) that it runs with perl and not
+ *     some shell.
+ */
+#define STARTPERL "#!perl"             /**/
+
+/* STDCHAR:
+ *     This symbol is defined to be the type of char used in stdio.h.
+ *     It has the values "unsigned char" or "char".
+ */
+#define STDCHAR char   /**/
+
+/* HAS_STDIO_STREAM_ARRAY:
+ *     This symbol, if defined, tells that there is an array
+ *     holding the stdio streams.
+ */
+/* STDIO_STREAM_ARRAY:
+ *     This symbol tells the name of the array holding the stdio streams.
+ *     Usual values include _iob, __iob, and __sF.
+ */
+/*#define      HAS_STDIO_STREAM_ARRAY  /**/
+#define STDIO_STREAM_ARRAY     
+
+/* Uid_t_f:
+ *     This symbol defines the format string used for printing a Uid_t.
+ */
+#define        Uid_t_f         "ld"            /**/
+
+/* Uid_t_sign:
+ *     This symbol holds the signedess of a Uid_t.
+ *     1 for unsigned, -1 for signed.
+ */
+#define Uid_t_sign     -1              /* UID sign */
+
+/* Uid_t_size:
+ *     This symbol holds the size of a Uid_t in bytes.
+ */
+#define Uid_t_size 4           /* UID size */
+
+/* Uid_t:
+ *     This symbol holds the type used to declare user ids in the kernel.
+ *     It can be int, ushort, uid_t, etc... It may be necessary to include
+ *     <sys/types.h> to get any typedef'ed information.
+ */
+#define Uid_t uid_t            /* UID type */
+
+/* USE_64_BIT_INT:
+ *     This symbol, if defined, indicates that 64-bit integers should
+ *     be used when available.  If not defined, the native integers
+ *     will be employed (be they 32 or 64 bits).  The minimal possible
+ *     64-bitness is used, just enough to get 64-bit integers into Perl.
+ *     This may mean using for example "long longs", while your memory
+ *     may still be limited to 2 gigabytes.
+ */
+/* USE_64_BIT_ALL:
+ *     This symbol, if defined, indicates that 64-bit integers should
+ *     be used when available.  If not defined, the native integers
+ *     will be used (be they 32 or 64 bits).  The maximal possible
+ *     64-bitness is employed: LP64 or ILP64, meaning that you will
+ *     be able to use more than 2 gigabytes of memory.  This mode is
+ *     even more binary incompatible than USE_64_BIT_INT. You may not
+ *     be able to run the resulting executable in a 32-bit CPU at all or
+ *     you may need at least to reboot your OS to 64-bit mode.
+ */
+#ifndef USE_64_BIT_INT
+/*#define      USE_64_BIT_INT          /**/
+#endif
+
+#ifndef USE_64_BIT_ALL
+/*#define      USE_64_BIT_ALL          /**/
+#endif
+
+/* USE_LARGE_FILES:
+ *     This symbol, if defined, indicates that large file support
+ *     should be used when available.
+ */
+#ifndef USE_LARGE_FILES
+/*#define      USE_LARGE_FILES         /**/
+#endif
+
+/* USE_LONG_DOUBLE:
+ *     This symbol, if defined, indicates that long doubles should
+ *     be used when available.
+ */
+#ifndef USE_LONG_DOUBLE
+/*#define      USE_LONG_DOUBLE         /**/
+#endif
+
+/* USE_MORE_BITS:
+ *     This symbol, if defined, indicates that 64-bit interfaces and
+ *     long doubles should be used when available.
+ */
+#ifndef USE_MORE_BITS
+/*#define      USE_MORE_BITS           /**/
+#endif
+
+/* MULTIPLICITY:
+ *     This symbol, if defined, indicates that Perl should
+ *     be built to use multiplicity.
+ */
+#ifndef MULTIPLICITY
+#define        MULTIPLICITY            /**/
+#endif
+
+/* USE_PERLIO:
+ *     This symbol, if defined, indicates that the PerlIO abstraction should
+ *     be used throughout.  If not defined, stdio should be
+ *     used in a fully backward compatible manner.
+ */
+#ifndef USE_PERLIO
+/*#define      USE_PERLIO              /**/
+#endif
+
+/* USE_SOCKS:
+ *     This symbol, if defined, indicates that Perl should
+ *     be built to use socks.
+ */
+#ifndef USE_SOCKS
+/*#define      USE_SOCKS               /**/
+#endif
+
+/* USE_ITHREADS:
+ *     This symbol, if defined, indicates that Perl should be built to
+ *     use the interpreter-based threading implementation.
+ */
+/* USE_5005THREADS:
+ *     This symbol, if defined, indicates that Perl should be built to
+ *     use the 5.005-based threading implementation.
+ */
+/* OLD_PTHREADS_API:
+ *     This symbol, if defined, indicates that Perl should
+ *     be built to use the old draft POSIX threads API.
+ */
+/*#define      USE_5005THREADS         /**/
+#define        USE_ITHREADS            /**/
+#if defined(USE_5005THREADS) && !defined(USE_ITHREADS)
+#define                USE_THREADS             /* until src is revised*/
+#endif
+/*#define      OLD_PTHREADS_API                /**/
+
+/* PERL_VENDORARCH:
+ *     If defined, this symbol contains the name of a private library.
+ *     The library is private in the sense that it needn't be in anyone's
+ *     execution path, but it should be accessible by the world.
+ *     It may have a ~ on the front. 
+ *     The standard distribution will put nothing in this directory.
+ *     Vendors who distribute perl may wish to place their own
+ *     architecture-dependent modules and extensions in this directory with
+ *             MakeMaker Makefile.PL INSTALLDIRS=vendor 
+ *     or equivalent.  See INSTALL for details.
+ */
+/* PERL_VENDORARCH_EXP:
+ *     This symbol contains the ~name expanded version of PERL_VENDORARCH, to be used
+ *     in programs that are not prepared to deal with ~ expansion at run-time.
+ */
+/*#define PERL_VENDORARCH ""           /**/
+/*#define PERL_VENDORARCH_EXP ""               /**/
+
+/* PERL_VENDORLIB_EXP:
+ *     This symbol contains the ~name expanded version of VENDORLIB, to be used
+ *     in programs that are not prepared to deal with ~ expansion at run-time.
+ */
+/* PERL_VENDORLIB_STEM:
+ *     This define is PERL_VENDORLIB_EXP with any trailing version-specific component
+ *     removed.  The elements in inc_version_list (inc_version_list.U) can
+ *     be tacked onto this variable to generate a list of directories to search.
+ */
+/*#define PERL_VENDORLIB_EXP ""                /**/
+/*#define PERL_VENDORLIB_STEM ""               /**/
+
+/* VOIDFLAGS:
+ *     This symbol indicates how much support of the void type is given by this
+ *     compiler.  What various bits mean:
+ *
+ *         1 = supports declaration of void
+ *         2 = supports arrays of pointers to functions returning void
+ *         4 = supports comparisons between pointers to void functions and
+ *                 addresses of void functions
+ *         8 = suports declaration of generic void pointers
+ *
+ *     The package designer should define VOIDUSED to indicate the requirements
+ *     of the package.  This can be done either by #defining VOIDUSED before
+ *     including config.h, or by defining defvoidused in Myinit.U.  If the
+ *     latter approach is taken, only those flags will be tested.  If the
+ *     level of void support necessary is not present, defines void to int.
+ */
+#ifndef VOIDUSED
+#define VOIDUSED 15
+#endif
+#define VOIDFLAGS 15
+#if (VOIDFLAGS & VOIDUSED) != VOIDUSED
+#define void int               /* is void to be avoided? */
+#define M_VOID                 /* Xenix strikes again */
+#endif
+
+/* PERL_XS_APIVERSION:
+ *     This variable contains the version of the oldest perl binary
+ *     compatible with the present perl.  perl.c:incpush() and
+ *     lib/lib.pm will automatically search in c:\\perl\\site\\5.7.1\\lib\\NetWare-x86-multi-thread for older
+ *     directories across major versions back to xs_apiversion.
+ *     This is only useful if you have a perl library directory tree
+ *     structured like the default one.
+ *     See INSTALL for how this works.
+ *     The versioned site_perl directory was introduced in 5.005,
+ *     so that is the lowest possible value.
+ *     Since this can depend on compile time options (such as
+ *     bincompat) it is set by Configure.  Other non-default sources
+ *     of potential incompatibility, such as multiplicity, threads,
+ *     debugging, 64bits, sfio, etc., are not checked for currently,
+ *     though in principle we could go snooping around in old
+ *     Config.pm files.
+ */
+/* PERL_PM_APIVERSION:
+ *     This variable contains the version of the oldest perl
+ *     compatible with the present perl.  (That is, pure perl modules
+ *     written for pm_apiversion will still work for the current
+ *     version).  perl.c:incpush() and lib/lib.pm will automatically
+ *     search in c:\\perl\\site\\5.7.1\\lib for older directories across major versions
+ *     back to pm_apiversion.  This is only useful if you have a perl
+ *     library directory tree structured like the default one.  The
+ *     versioned site_perl library was introduced in 5.005, so that's
+ *     the default setting for this variable.  It's hard to imagine
+ *     it changing before Perl6.  It is included here for symmetry
+ *     with xs_apiveprsion -- the searching algorithms will
+ *     (presumably) be similar.
+ *     See the INSTALL file for how this works.
+ */
+#define PERL_XS_APIVERSION "5.6.0"
+#define PERL_PM_APIVERSION "5.005"
+
+/* HAS_SIGPROCMASK:
+ *     This symbol, if defined, indicates that the sigprocmask
+ *     system call is available to examine or change the signal mask
+ *     of the calling process.
+ */
+/*#define HAS_SIGPROCMASK              /**/
+
+/* HAS_SOCKATMARK:
+ *     This symbol, if defined, indicates that the sockatmark routine is
+ *     available to test whether a socket is at the out-of-band mark.
+ */
+/*#define HAS_SOCKATMARK               /**/
+
+/* U32_ALIGNMENT_REQUIRED:
+ *     This symbol, if defined, indicates that you must access
+ *     character data through U32-aligned pointers.
+ */
+/*#define U32_ALIGNMENT_REQUIRED       /**/
+
+#endif
diff --git a/NetWare/config_h.PL b/NetWare/config_h.PL
new file mode 100644 (file)
index 0000000..a7e5a09
--- /dev/null
@@ -0,0 +1,120 @@
+#
+use Config;
+use File::Compare qw(compare);
+use File::Copy qw(copy);
+my $OBJ   = 1 if $Config{'ccflags'} =~ /PERL_OBJECT/i;
+my $name = $0;
+$name =~ s#^(.*)\.PL$#../$1.SH#;
+my %opt;
+while (@ARGV && $ARGV[0] =~ /^([\w_]+)=(.*)$/)
+ {
+  $opt{$1}=$2;
+  shift(@ARGV);
+ }
+ $opt{CONFIG_H} ||= 'config.h';
+my $patchlevel = $opt{INST_VER};
+$patchlevel =~ s|^[\\/]||;
+$patchlevel =~ s|~VERSION~|$Config{version}|g;
+$patchlevel ||= $Config{version};
+$patchlevel = qq["$patchlevel"];
+
+open(SH,"<$name") || die "Cannot open $name:$!";
+while (<SH>)
+ {
+  last if /^sed/;
+ }
+($term,$file,$pat) = /^sed\s+<<(\S+)\s+>(\S+)\s+(.*)$/;
+$file =~ s/^\$(\w+)$/$opt{$1}/g;
+
+my $str = "sub munge\n{\n";
+
+while ($pat =~ s/-e\s+'([^']*)'\s*//)
+ {
+  my $e = $1;
+  $e =~ s/\\([\(\)])/$1/g;
+  $e =~ s/\\(\d)/\$$1/g; 
+  $str .= "$e;\n";
+ }
+$str .= "}\n";
+
+eval $str;
+
+die "$str:$@" if $@;
+
+open(H,">$file.new") || die "Cannot open $file.new:$!";
+binmode H;             # no CRs (which cause a spurious rebuild)
+while (<SH>)
+ {
+  last if /^$term$/o;
+  s/\$([\w_]+)/Config($1)/eg;
+  s/`([^\`]*)`/BackTick($1)/eg;
+  munge();
+  s/\\\$/\$/g;
+  s#/[ *\*]*\*/#/**/#;
+  if (/^\s*#define\s+(SITELIB|VENDORLIB)_EXP/)
+   {
+     $_ = "#define ". $1 . "_EXP (nw_get_". lc($1) . "($patchlevel))\t/**/\n";
+   }
+  # Added for NetWare and removed PRIVLIB from the above, the same thing might have
+  # to be done for other as well
+  elsif (/^\s*#define\s+(PRIVLIB)_EXP/)
+   {
+     $_ = "#define ". $1 . "_EXP (fnNwGetEnvironmentStr(\"PRIVLIB\", PRIVLIB))\t/**/\n";
+   }
+  # incpush() handles archlibs, so disable them
+  elsif (/^\s*#define\s+(ARCHLIB|SITEARCH|VENDORARCH)_EXP/)
+   {
+     $_ = "/*#define ". $1 . "_EXP \"\"\t/**/\n";
+   }
+  print H;
+ }
+close(H);
+close(SH);
+
+
+chmod(0666,"../lib/CORE/config.h");
+copy("$file.new","../lib/CORE/config.h") || die "Cannot copy:$!";
+chmod(0444,"../lib/CORE/config.h");
+
+if (!$OBJ && compare("$file.new",$file))
+ {
+  warn "$file has changed\n";
+  chmod(0666,$file);
+  unlink($file);
+  rename("$file.new",$file);
+  #chmod(0444,$file);
+  exit(1);
+ }
+else
+ {
+  unlink ("$file.new");
+  exit(0);
+ }
+
+sub Config
+{
+ my $var = shift;
+ my $val = $Config{$var};
+ $val = 'undef' unless defined $val;
+ $val =~ s/\\/\\\\/g;
+ return $val;
+}
+
+sub BackTick
+{
+ my $cmd = shift;
+ if ($cmd =~ /^echo\s+(.*?)\s*\|\s+sed\s+'(.*)'\s*$/)
+  {
+   local ($data,$pat) = ($1,$2);
+   $data =~ s/\s+/ /g;
+   eval "\$data =~ $pat";
+   return $data;
+  }
+ else
+  {
+   die "Cannot handle \`$cmd\`";
+  }
+ return $cmd;
+}
diff --git a/NetWare/config_sh.PL b/NetWare/config_sh.PL
new file mode 100644 (file)
index 0000000..0e1d351
--- /dev/null
@@ -0,0 +1,83 @@
+# take a semicolon separated path list and turn it into a quoted
+# list of paths that Text::Parsewords will grok
+sub mungepath {
+    my $p = shift;
+    # remove leading/trailing semis/spaces
+    $p =~ s/^[ ;]+//;
+    $p =~ s/[ ;]+$//;
+    $p =~ s/'/"/g;
+    my @p = map { $_ = "\"$_\"" if /\s/ and !/^".*"$/; $_ } split /;/, $p;
+    return join(' ', @p);
+}
+
+# generate an array of option strings from command-line args
+# or an option file
+#    -- added by BKS, 10-17-1999 to fix command-line overflow problems
+sub loadopts {
+    if ($ARGV[0] =~ /--cfgsh-option-file/) {
+       shift @ARGV;
+       my $optfile = shift @ARGV;
+       local (*F);
+       open OPTF, $optfile or die "Can't open $optfile: $!\n";
+       my @opts;
+       chomp(my $line = <OPTF>);
+       my @vars = split(/\t+~\t+/, $line);
+       for (@vars) {
+           push(@opts, $_) unless (/^\s*$/);
+       }
+       close OPTF;
+       return \@opts;
+    }
+    else {
+       return \@ARGV;
+    }
+}
+
+my %opt;
+my $optref = loadopts();
+while (@{$optref} && $optref->[0] =~ /^([\w_]+)=(.*)$/) {
+    $opt{$1}=$2;
+    shift(@{$optref});
+}
+
+my $pl_h = '../patchlevel.h';
+
+if (-e $pl_h) {
+    open PL, "<$pl_h" or die "Can't open $pl_h: $!";
+    while (<PL>) {
+       if (/^#\s*define\s+(PERL_\w+)\s+([\d.]+)/) {
+           $opt{$1} = $2;
+       }
+    }
+    close PL;
+}
+else {
+    die "Can't find $pl_h: $!";
+}
+$opt{VERSION} = "$opt{PERL_REVISION}.$opt{PERL_VERSION}.$opt{PERL_SUBVERSION}";
+$opt{INST_VER} =~ s|~VERSION~|$opt{VERSION}|g;
+
+$opt{'cf_by'} = $ENV{USERNAME} unless $opt{'cf_by'};
+$opt{'cf_email'} = $opt{'cf_by'} . '@' . (gethostbyname('localhost'))[0]
+       unless $opt{'cf_email'};
+$opt{'usemymalloc'} = 'y' if $opt{'d_mymalloc'} eq 'define';
+
+$opt{libpth} = mungepath($opt{libpth}) if exists $opt{libpth};
+$opt{incpath} = mungepath($opt{incpath}) if exists $opt{incpath};
+
+while (<>) {
+    s/~([\w_]+)~/$opt{$1}/g;
+    if (/^([\w_]+)=(.*)$/) {
+       my($k,$v) = ($1,$2);
+       # this depends on cf_time being empty in the template (or we'll
+       # get a loop)
+       if ($k eq 'cf_time') {
+           $_ = "$k='" . localtime(time) . "'\n" if $v =~ /^\s*'\s*'/;
+       }
+       elsif (exists $opt{$k}) {
+           $_ = "$k='$opt{$k}'\n";
+       }
+    }
+    print;
+}
+
diff --git a/NetWare/deb.h b/NetWare/deb.h
new file mode 100644 (file)
index 0000000..ece19c2
--- /dev/null
@@ -0,0 +1,47 @@
+
+/*
+ * Copyright Â© 2001 Novell, Inc. All Rights Reserved.
+ *
+ * You may distribute under the terms of either the GNU General Public
+ * License or the Artistic License, as specified in the README file.
+ *
+ */
+
+/*
+ * FILENAME            :       deb.h
+ * DESCRIPTION :       Defines Breakpoint macro.
+ * Author              :       SGP
+ * Date                        :       January 2001.
+ *
+ */
+
+
+
+#ifndef __Inc__deb___
+#define __Inc__deb___
+
+
+#include <nwconio.h>
+
+
+#if defined(DEBUGON) && !defined(USE_D2)
+       //debug build and d1 flag is used, so enable IDB
+       #define DBGMESG ConsolePrintf
+       #define IDB(x)                                  \
+                               ConsolePrintf(x);       \
+                               _asm {int 3}
+#else
+       #if defined(USE_D2)
+               //debug build and d2 flag is used, so disable IDB
+               #define DBGMESG ConsolePrintf
+               #define IDB ConsolePrintf
+       #else
+               //release build, so disable DBGMESG and IDB
+               #define DBGMESG 
+               #define IDB 
+       #endif  //if defined(USE_D2)
+#endif //if defined(DEBUGON) && !defined(USE_D2)
+
+
+#endif /*__Inc__deb___*/
+
diff --git a/NetWare/dl_netware.xs b/NetWare/dl_netware.xs
new file mode 100644 (file)
index 0000000..2f466ca
--- /dev/null
@@ -0,0 +1,194 @@
+/* dl_netware.xs
+ * 
+ * Platform:   NetWare 
+ * Author:     SGP
+ * Created:    21st July 2000
+ * Last Modified: 23rd Oct 2000
+ * Note: !!!Any modification to the xs file to be done to the one which is under netware directory!!!
+ * Modification History
+ * 23rd Oct - Failing to find nlms with long names fixed - sdbm_file
+ */
+
+/* 
+
+NetWare related modifications done on dl_win32.xs file created by Wei-Yuen Tan to get this file.
+
+*/
+
+
+#include <nwthread.h> 
+#include <nwerrno.h>
+
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+
+
+//function pointer for UCSInitialize
+typedef void (*PFUCSINITIALIZE) ();
+
+#ifdef PERL_OBJECT
+
+#endif  /* PERL_OBJECT */
+
+#include "dlutils.c"   /* SaveError() etc      */
+
+static void
+dl_private_init(pTHXo)
+{
+    (void)dl_generic_private_init(aTHXo);
+}
+
+
+MODULE = DynaLoader    PACKAGE = DynaLoader
+
+BOOT:
+    (void)dl_private_init(aTHXo);
+
+
+void *
+dl_load_file(filename,flags=0)
+    char *             filename
+    int                        flags
+    PREINIT:
+    CODE:
+  {
+       char* mod_name = filename;
+
+       //Names with more than 8 chars can't be found with FindNLMHandle
+       //8 - Name, 1 - Period, 3 - Extension, 1 - String terminator
+       char mod_name8[13]={'\0'};
+       char *p=NULL;
+       char *buffer=NULL;
+       int nNameLength=0;
+       unsigned int nlmHandle=0;
+
+       while (*mod_name) mod_name++;
+       
+       //Get the module name with extension to see if it is already loaded
+       while (mod_name > filename && mod_name[-1] != '/' && mod_name[-1] != '\\') mod_name--;
+
+    DLDEBUG(1,PerlIO_printf(Perl_debug_log,"dl_load_file(%s):\n", filename));
+
+       buffer = strdup(mod_name);
+       p = strtok (buffer, "."); 
+       if (p) {
+               nNameLength = (strlen(p)>8)?8:strlen(p);
+               memcpy(mod_name8,p,nNameLength);
+               *(mod_name8 + nNameLength) = '.';
+               *(mod_name8 + nNameLength+1) ='\0';
+               p = strtok (NULL, ".");
+               if (p){
+                       strcat(mod_name8,p);
+
+                       if ( (nlmHandle = FindNLMHandle(mod_name8)) == NULL )
+                       {
+                               //NLM/NLP not loaded, load it and get the handle
+                               if(spawnlp(P_NOWAIT, filename, filename, NULL)!=0)
+                               {
+                                       //failed to load the NLM/NLP, this unlikely
+                                       //If multiple scripts are executed for the first time before running any other
+                                       //ucs script, sometimes there used to be an abend.
+                                       switch(NetWareErrno)
+                                       {
+                                       case LOAD_CAN_NOT_LOAD_MULTIPLE_COPIES:
+                                               nlmHandle = FindNLMHandle(mod_name8);
+                                               break;
+                                       case LOAD_ALREADY_IN_PROGRESS:
+#ifdef MPK_ON
+                                                       kYieldThread();
+#else
+                                                       ThreadSwitch();
+#endif //MPK_ON
+                                               nlmHandle = FindNLMHandle(mod_name8);
+                                               break;
+                                       default:
+                                               nlmHandle = 0;
+                                       }
+                               }
+                               else
+                               {
+                                       nlmHandle = FindNLMHandle(mod_name8);
+                               }
+                       }
+                       //use UCSExt encountered-
+                       //initialize UCS, this has to be terminated when the script finishes execution
+                       //Is the script intending to use UCS Extensions?
+                       //This should be done once per script execution
+                       if (strcmp(mod_name,"Perl2UCS.nlp")==0)
+                       {
+                               unsigned int moduleHandle = 0;
+                               moduleHandle = FindNLMHandle("UCSCORE.NLM");
+                               if (moduleHandle)
+                               {
+                                       PFUCSINITIALIZE ucsinit = (PFUCSINITIALIZE)ImportSymbol(moduleHandle,"UCSInitialize");
+                                       if (ucsinit!=NULL)
+                                               (*ucsinit)();
+                               }
+                       }
+
+                       DLDEBUG(2,PerlIO_printf(Perl_debug_log," libref=%x\n", nlmHandle));
+                       ST(0) = sv_newmortal() ;
+                       if (nlmHandle == NULL)
+                       //SaveError(aTHXo_ "load_file:%s",
+                       //        OS_Error_String(aTHXo)) ;
+                       ConsolePrintf("load_file error :  %s\n", mod_name8);
+                       else
+                       sv_setiv( ST(0), (IV)nlmHandle);
+               }
+       }
+       free(buffer);
+
+       
+  }
+
+void *
+dl_find_symbol(libhandle, symbolname)
+    void *     libhandle
+    char *     symbolname
+    CODE:
+    DLDEBUG(2,PerlIO_printf(Perl_debug_log,"dl_find_symbol(handle=%x, symbol=%s)\n",
+                     libhandle, symbolname));
+
+       //import the symbol that the dynaloader is asking for.
+       RETVAL = (void *)ImportSymbol((int)libhandle, symbolname);
+
+    DLDEBUG(2,PerlIO_printf(Perl_debug_log,"  symbolref = %x\n", RETVAL));
+    ST(0) = sv_newmortal() ;
+    if (RETVAL == NULL)
+       //SaveError(aTHXo_ "find_symbol:%s",
+       //        OS_Error_String(aTHXo)) ;
+       ConsolePrintf("find_symbol error \n");
+    else
+       sv_setiv( ST(0), (IV)RETVAL);
+
+void
+dl_undef_symbols()
+    PPCODE:
+
+
+# These functions should not need changing on any platform:
+
+void
+dl_install_xsub(perl_name, symref, filename="$Package")
+    char *             perl_name
+    void *             symref 
+    char *             filename
+    CODE:
+    DLDEBUG(2,PerlIO_printf(Perl_debug_log,"dl_install_xsub(name=%s, symref=%x)\n",
+                     perl_name, symref));
+    ST(0) = sv_2mortal(newRV((SV*)newXS(perl_name,
+                                       (void(*)(pTHXo_ CV *))symref,
+                                       filename)));
+
+
+char *
+dl_error()
+    CODE:
+    RETVAL = LastError ;
+    OUTPUT:
+    RETVAL
+
+# end.
+
+
diff --git a/NetWare/intdef.h b/NetWare/intdef.h
new file mode 100644 (file)
index 0000000..ca84746
--- /dev/null
@@ -0,0 +1,86 @@
+
+/*
+ * Copyright Â© 2001 Novell, Inc. All Rights Reserved.
+ *
+ * You may distribute under the terms of either the GNU General Public
+ * License or the Artistic License, as specified in the README file.
+ *
+ */
+
+/*
+ * FILENAME            :       intdef.h
+ * DESCRIPTION :       ANSI functions hash defined to equivalent Netware functions.
+ * Author              :       SGP
+ * Date                        :       July 1999.
+ *
+ */
+
+
+
+#ifndef __INTDEF__
+#define __INTDEF__
+
+
+#include <nwlocale.h>
+#include "..\utility\utility.h"
+
+
+//ANSI functions define to equivalent NetWare internationalization functions
+
+#define setlocale      NWLsetlocale
+#define localeconv     NWLlocaleconv
+#define        strncoll        NWstrncoll
+#define strftime       NWLstrftime
+
+#define atoi           NWLatoi
+#define itoa        NWitoa
+#define utoa        NWutoa
+#define ultoa       NWultoa
+#define ltoa        NWltoa
+
+#define isalnum                NWLisalnum
+#define        isalpha         NWLisalpha
+#define isdigit                NWLisdigit
+
+#define strlen         NWLmbslen
+#define mblen          NWLmblen
+
+//#define strcpy(x,y) NWLstrbcpy(x,y,NWstrlen(y)+1)
+#define strcpy(x,y)     \
+       NWstrncpy(x,y,NWstrlen(y)); \
+       x[NWstrlen(y)] ='\0';
+#define strncpy(x,y,z)     NWLstrbcpy(x,y,(z + 1))
+#define strcat(x,y)             NWLstrbcpy((x + NWstrlen(x)), y, (NWstrlen(y) +1))
+#define strncmp(s1,s2,l) NWgstrncmp(s1,s2,l)
+#define strnicmp(s1,s2,l) NWgstrnicmp(s1,s2,l)
+
+#define toupper(s1)  NWCharUpr(s1)
+#define wsprintf        NWsprintf
+
+#define strncat(x,y,l)   \
+                       NWsprintf("oops!!! Not yet defined for NWI18N, define in intdef.h, still using strncat\n");     \
+                       strncat(x,y,l);
+
+#define strdup(s1)   \
+                       NWsprintf("oops!!! Not yet defined for NWI18N, define in intdef.h, still using strdup\n");      \
+                       strdup(s1);
+
+#define strlist   \
+                       NWsprintf("oops!!! Not yet defined for NWI18N, define in intdef.h, still using strlist\n");     \
+                       strlist;
+
+#define strlwr(s1)   \
+                       NWsprintf("oops!!! Not yet defined for NWI18N, define in intdef.h, still using strlwr\n");      \
+                       strlwr(s1);
+
+#define strnset(s1,l1,l2)   \
+                       NWsprintf("oops!!! Not yet defined for NWI18N, define in intdef.h, still using strnset\n");     \
+                       strnset(s1,l1,l2);
+
+#define strset(s1,l1)   \
+                       NWsprintf("oops!!! Not yet defined for NWI18N, define in intdef.h, still using strset\n");      \
+                       strset(s1,l1);
+
+
+#endif // __INTDEF__
+
diff --git a/NetWare/interface.c b/NetWare/interface.c
new file mode 100644 (file)
index 0000000..3525dcc
--- /dev/null
@@ -0,0 +1,196 @@
+
+/*
+ * Copyright Â© 2001 Novell, Inc. All Rights Reserved.
+ *
+ * You may distribute under the terms of either the GNU General Public
+ * License or the Artistic License, as specified in the README file.
+ *
+ */
+
+/*
+ * FILENAME            :       interface.c
+ * DESCRIPTION :       Perl parsing and running functions.
+ * Author              :       SGP
+ * Date                        :       January 2001.
+ *
+ */
+
+
+
+#include "interface.h"
+
+
+static void xs_init(pTHX);
+
+EXTERN_C int RunPerl(int argc, char **argv, char **env);
+EXTERN_C void Perl_nw5_init(int *argcp, char ***argvp);
+EXTERN_C void boot_DynaLoader (pTHXo_ CV* cv);
+
+
+ClsPerlHost::ClsPerlHost()
+{
+
+}
+
+ClsPerlHost::~ClsPerlHost()
+{
+
+}
+
+ClsPerlHost::VersionNumber()
+{
+       return 0;
+}
+
+int
+ClsPerlHost::PerlCreate(PerlInterpreter *my_perl)
+{
+/*     if (!(my_perl = perl_alloc()))          // Allocate memory for Perl.
+               return (1);*/
+    perl_construct(my_perl);
+
+       return 1;
+}
+
+int
+ClsPerlHost::PerlParse(PerlInterpreter *my_perl, int argc, char** argv, char** env)
+{
+       return(perl_parse(my_perl, xs_init, argc, argv, env));          // Parse the command line.
+}
+
+int
+ClsPerlHost::PerlRun(PerlInterpreter *my_perl)
+{
+       return(perl_run(my_perl));      // Run Perl.
+}
+
+void
+ClsPerlHost::PerlDestroy(PerlInterpreter *my_perl)
+{
+       perl_destruct(my_perl);         // Destructor for Perl.
+       perl_free(my_perl);                     // Free the memory allocated for Perl.
+
+}
+
+/*============================================================================================
+
+ Function              :       xs_init
+
+ Description   :       
+
+ Parameters    :       pTHX    (IN)    -       
+
+ Returns               :       Nothing.
+
+==============================================================================================*/
+
+static void xs_init(pTHX)
+{
+       char *file = __FILE__;
+
+       dXSUB_SYS;
+       newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
+}
+
+
+EXTERN_C
+int RunPerl(int argc, char **argv, char **env)
+{
+       int exitstatus = 0;
+       ClsPerlHost nlm;
+
+       PerlInterpreter *my_perl = NULL;                // defined in Perl.h
+       PerlInterpreter *new_perl = NULL;               // defined in Perl.h
+
+       #ifdef PERL_GLOBAL_STRUCT
+               #define PERLVAR(var,type)
+               #define PERLVARA(var,type)
+               #define PERLVARI(var,type,init) PL_Vars.var = init;
+               #define PERLVARIC(var,type,init) PL_Vars.var = init;
+
+               #include "perlvars.h"
+
+               #undef PERLVAR
+               #undef PERLVARA
+               #undef PERLVARI
+               #undef PERLVARIC
+       #endif
+
+       PERL_SYS_INIT(&argc, &argv);
+
+       if (!(my_perl = perl_alloc()))          // Allocate memory for Perl.
+               return (1);
+
+       if(nlm.PerlCreate(my_perl))
+       {
+               PL_perl_destruct_level = 0;
+
+               exitstatus = nlm.PerlParse(my_perl, argc, argv, env);
+               if(exitstatus == 0)
+               {
+                       #if defined(TOP_CLONE) && defined(USE_ITHREADS)         // XXXXXX testing
+                               #  ifdef PERL_OBJECT
+                                       CPerlHost *h = new CPerlHost();
+                                       new_perl = perl_clone_using(my_perl, 1,
+                                                                               h->m_pHostperlMem,
+                                                                               h->m_pHostperlMemShared,
+                                                                               h->m_pHostperlMemParse,
+                                                                               h->m_pHostperlEnv,
+                                                                               h->m_pHostperlStdIO,
+                                                                               h->m_pHostperlLIO,
+                                                                               h->m_pHostperlDir,
+                                                                               h->m_pHostperlSock,
+                                                                               h->m_pHostperlProc
+                                                                               );
+                                       CPerlObj *pPerl = (CPerlObj*)new_perl;
+                               #  else
+                                       new_perl = perl_clone(my_perl, 1);
+                               #  endif
+
+                               exitstatus = perl_run(new_perl);        // Run Perl.
+                               PERL_SET_THX(my_perl);
+                       #else
+                               exitstatus = nlm.PerlRun(my_perl);
+                       #endif
+               }
+               nlm.PerlDestroy(my_perl);
+       }
+
+       #ifdef USE_ITHREADS
+               if (new_perl)
+               {
+                       PERL_SET_THX(new_perl);
+                       nlm.PerlDestroy(new_perl);
+               }
+       #endif
+
+       PERL_SYS_TERM();
+       return exitstatus;
+}
+
+
+// FUNCTION: AllocStdPerl
+//
+// DESCRIPTION:
+//     Allocates a standard perl handler that other perl handlers
+//     may delegate to. You should call FreeStdPerl to free this
+//     instance when you are done with it.
+//
+IPerlHost* AllocStdPerl()
+{
+       return new ClsPerlHost();
+}
+
+
+// FUNCTION: FreeStdPerl
+//
+// DESCRIPTION:
+//     Frees an instance of a standard perl handler allocated by
+//     AllocStdPerl.
+//
+void FreeStdPerl(IPerlHost* pPerlHost)
+{
+       delete (ClsPerlHost*) pPerlHost;
+}
+
+
diff --git a/NetWare/interface.h b/NetWare/interface.h
new file mode 100644 (file)
index 0000000..f574166
--- /dev/null
@@ -0,0 +1,44 @@
+
+/*
+ * Copyright Â© 2001 Novell, Inc. All Rights Reserved.
+ *
+ * You may distribute under the terms of either the GNU General Public
+ * License or the Artistic License, as specified in the README file.
+ *
+ */
+
+/*
+ * FILENAME            :       interface.c
+ * DESCRIPTION :       Perl parsing and running functions.
+ * Author              :       SGP
+ * Date                        :       January 2001.
+ *
+ */
+
+
+
+#ifndef __Interface_H__
+#define __Interface_H__
+
+
+#include "iperlhost.h"
+
+
+class ClsPerlHost :    public IPerlHost
+{
+public:
+       ClsPerlHost(void);
+       virtual ~ClsPerlHost(void);
+
+       int VersionNumber();
+
+       int PerlCreate(PerlInterpreter *my_perl);
+       int PerlParse(PerlInterpreter *my_perl, int argc, char** argv, char** env);
+       int PerlRun(PerlInterpreter *my_perl);
+       void PerlDestroy(PerlInterpreter *my_perl);
+
+};
+
+
+#endif // __Interface_H__
+
diff --git a/NetWare/iperlhost.h b/NetWare/iperlhost.h
new file mode 100644 (file)
index 0000000..e07a14f
--- /dev/null
@@ -0,0 +1,45 @@
+
+/*
+ * Copyright Â© 2001 Novell, Inc. All Rights Reserved.
+ *
+ * You may distribute under the terms of either the GNU General Public
+ * License or the Artistic License, as specified in the README file.
+ *
+ */
+
+/*
+ * FILENAME            :       iperlhost.h
+ * DESCRIPTION :       IPerlHost class file.
+ * Author              :       SGP
+ * Date                        :       January 2001.
+ *
+ */
+
+
+
+#ifndef __iPerlHost_H__
+#define __iPerlHost_H__
+
+
+#include "EXTERN.h"
+#include "perl.h"
+
+
+class IPerlHost
+{
+public:
+       virtual int VersionNumber() = 0;
+
+       virtual int PerlCreate(PerlInterpreter *my_perl) = 0;
+       virtual int PerlParse(PerlInterpreter *my_perl,int argc, char** argv, char** env) = 0;
+       virtual int PerlRun(PerlInterpreter *my_perl) = 0;
+       virtual void PerlDestroy(PerlInterpreter *my_perl) = 0;
+
+};
+
+extern "C" IPerlHost* AllocStdPerl();
+extern "C" void FreeStdPerl(IPerlHost* pPerlHost);
+
+
+#endif // __iPerlHost_H__
+
diff --git a/NetWare/netware.h b/NetWare/netware.h
new file mode 100644 (file)
index 0000000..bd1a4c2
--- /dev/null
@@ -0,0 +1,87 @@
+
+/*
+ * Copyright Â© 2001 Novell, Inc. All Rights Reserved.
+ *
+ * You may distribute under the terms of either the GNU General Public
+ * License or the Artistic License, as specified in the README file.
+ *
+ */
+
+/*
+ * FILENAME            :       netware.h
+ * DESCRIPTION :       Include for NetWare stuff.
+ *                  This is based on the win32.h file of Win32 port.
+ * Author              :       SGP
+ * Date                        :       January 2001.
+ *
+ */
+
+
+
+#ifndef  _INC_NW_PERL5
+#define  _INC_NW_PERL5
+
+#include <dirent.h>
+#include "stdio.h"
+
+// to get the internal debugger break for functions that are not yet handled
+#include "deb.h"
+
+#ifndef EXT
+#include "EXTERN.h"
+#endif
+
+//structure that will be used by times routine.
+struct tms {
+       long    tms_utime;
+       long    tms_stime;
+       long    tms_cutime;
+       long    tms_cstime;
+};
+
+#define PERL_GET_CONTEXT_DEFINED
+#define ENV_IS_CASELESS
+
+#undef   init_os_extras
+#define  init_os_extras Perl_init_os_extras
+
+#define HAVE_INTERP_INTERN
+struct interp_intern {
+    void *     internal_host;
+};
+
+/*
+ * handle socket stuff, assuming socket is always available
+ */
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netdb.h>
+
+//This is clashing with a definition in perly.h, hence
+//undefine, may have to redefine if need be - CHKSGP
+#undef WORD
+
+#ifndef SOCKET
+typedef u_int           SOCKET;
+#endif
+
+#define nw_internal_host               (PL_sys_intern.internal_host)
+
+EXTERN_C void  Perl_nw5_init(int *argcp, char ***argvp);
+
+/*
+ * This provides a layer of functions and macros to ensure extensions will
+ * get to use the same RTL functions as the core.
+ */
+#include "nw5iop.h"
+
+// Below is called in Run.c file when a perl script executes/runs.
+#ifdef MPK_ON
+       #define PERL_ASYNC_CHECK() kYieldThread();
+#else
+       #define PERL_ASYNC_CHECK() ThreadSwitch();
+#endif
+
+
+#endif /* _INC_NW_PERL5 */
+
diff --git a/NetWare/nw5.c b/NetWare/nw5.c
new file mode 100644 (file)
index 0000000..e32fdb6
--- /dev/null
@@ -0,0 +1,896 @@
+
+/*
+ * Copyright Â© 2001 Novell, Inc. All Rights Reserved.
+ *
+ * You may distribute under the terms of either the GNU General Public
+ * License or the Artistic License, as specified in the README file.
+ *
+ */
+
+/*
+ * FILENAME            :       nw5.c
+ * DESCRIPTION :       Definitions for the redefined functions for NetWare.
+ * Author              :       SGP, HYAK
+ * Date                        :       January 2001.
+ *
+ */
+
+
+
+#include <perl.h>      // For dTHXo, etc.
+#include "nwpipe.h"
+
+
+// This was added since the compile failed saying "undefined P_WAIT"
+// when USE_ITHREADS was commented in the makefile
+#ifndef P_WAIT
+#define        P_WAIT          0
+#endif
+
+#ifndef P_NOWAIT
+#define        P_NOWAIT        1
+#endif
+
+// The array is used to store pointer to the memory allocated to the TempPipeFile structure everytime
+// a call to the function, nw_Popen. If a simple variable is used, everytime the memory is allocated before
+// the previously allocated memory is freed, the pointer will get overwritten and the previous memory allocations
+// are lost! Only the most recent one will get freed when calls are made to nw_Pclose.
+// By using the array and the iPopenCount to index the array, all memory are freed!
+
+// The size of the array indicates the limit on the no of times the nw_Popen function can be called (and
+// memory allocted) from within a script through backtick operators!
+// This is arbitrarily set to MAX_PIPE_RECURSION=256 which indicates there can be 256 nested backtick operators possible!
+PTEMPPIPEFILE ptpf1[MAX_PIPE_RECURSION] = {'\0'};
+int iPopenCount = 0;
+FILE* File1[MAX_PIPE_RECURSION] = {'\0'};
+
+
+/**
+General:
+
+In this code, wherever there is a  FILE *, the error condition is checked; and only if the FILE * is TRUE,
+then the corresponding operation is done. Otherwise the error value is returned.
+This is done because the file operations like "open" in the Perl code returns the FILE *,
+returning a valid value if the file is found or NULL when the particular file is not found.
+Now, if the return value is NULL, then an operation say "fgets", "fopen" etc. using this this NULL value
+for FILE * will abend the server. If the check is made then an operation on a non existing file
+does not abend the server.
+**/
+
+void
+nw_abort(void)
+{
+       abort();        // Terminate the NLM application abnormally.
+       return;
+}
+
+int
+nw_access(const char *path, int mode) 
+{
+    return access(path, mode);
+}
+
+int
+nw_chmod(const char *path, int mode)
+{
+    return chmod(path, mode);
+}
+
+void
+nw_clearerr(FILE *pf)
+{
+       if(pf)
+           clearerr(pf);
+}
+
+int
+nw_close(int fd)
+{
+    return close(fd);
+}
+
+nw_closedir(DIR *dirp)
+{
+       return (closedir(dirp));
+}
+
+void
+nw_setbuf(FILE *pf, char *buf)
+{
+       if(pf)
+           setbuf(pf, buf);
+}
+
+int
+nw_setmode(FILE *fp, int mode)
+{
+       int *dummy = 0;
+       return(fnFpSetMode(fp, mode, dummy));
+}
+
+int
+nw_setvbuf(FILE *pf, char *buf, int type, size_t size)
+{
+       if(pf)
+           return setvbuf(pf, buf, type, size);
+       else
+           return -1;
+}
+
+
+unsigned int
+nw_sleep(unsigned int t)
+{
+       delay(t*1000);  // Put the thread to sleep for 't' seconds.  Initially 't' is passed in milliseconds.
+    return 0;
+}
+
+int
+nw_spawnvp(int mode, char *cmdname, char **argv)
+{
+       // There is no pass-around environment on NetWare so we throw that
+       // argument away for now.
+
+       //  The function "spawnvp" does not work in all situations. Loading
+       // edit.nlm seems to work, for example, but the name of the file
+       // to edit does not appear to get passed correctly. Another problem
+       // is that on Netware, P_WAIT does not really work reliably. It only
+       // works with NLMs built to use CLIB (according to Nile Thayne).
+       // NLMs such as EDIT that are written directly to the system have no
+       // way of running synchronously from another process. The whole
+       // architecture on NetWare seems pretty busted, so we just support it
+       // as best we can.
+       //
+       // The spawnvp function only launches NLMs, it will not execute a command;
+       // the NetWare "system" function is used for that purpose. Unfortunately, "system"
+       // always returns success whether the command is successful or not or even
+       // if the command was not found! To avoid ambiguity--you can have both an
+       // NLM named "perl" and a system command named "perl"--we need to
+       // force perl scripts to carry the word "load" when loading an NLM. This
+       // might be clearer anyway.
+
+       int ret = 0;
+       int argc = 0;
+
+
+       if (stricmp(cmdname, LOAD_COMMAND) == 0)
+       {
+               if (argv[1] != NULL)
+                       ret = spawnvp(mode, argv[1], &argv[1]);
+       }
+       else
+       {
+               int i=0;
+               while (argv[i] != '\0')
+                       i++;
+               argc = i;
+
+               fnSystemCommand(argv, argc);
+       }
+
+       return ret;
+}
+
+int
+nw_execv(char *cmdname, char **argv)
+{
+       return spawnvp(P_WAIT, cmdname, (char **)argv);
+}
+
+
+int
+nw_execvp(char *cmdname, char **argv)
+{
+       return nw_spawnvp(P_WAIT, cmdname, (char **)argv);
+}
+
+int
+nw_stat(const char *path, struct stat *sbuf)
+{
+       return (stat(path, sbuf));
+}
+
+FILE *
+nw_stderr(void)
+{
+       return (stderr);
+}
+
+FILE *
+nw_stdin(void)
+{
+       return (stdin);
+}
+
+FILE *
+nw_stdout()
+{
+       return (stdout);
+}
+
+long
+nw_telldir(DIR *dirp)
+{
+       dTHXo;
+       Perl_croak(aTHX_ "telldir function is not implemented");
+       return 0l;
+}
+
+int
+nw_times(struct tms *timebuf)
+{
+       clock_t now = clock();
+
+       timebuf->tms_utime = now;
+       timebuf->tms_stime = 0;
+       timebuf->tms_cutime = 0;
+       timebuf->tms_cstime = 0;
+
+       return 0;
+}
+
+FILE*
+nw_tmpfile(void)
+{
+    return tmpfile();
+}
+
+int
+nw_uname(struct utsname *name)
+{
+       return(uname(name));
+}
+
+int
+nw_ungetc(int c, FILE *pf)
+{
+       if(pf)
+           return ungetc(c, pf);
+       else
+           return -1;
+}
+
+int
+nw_unlink(const char *filename)
+{
+       return(unlink(filename));
+}
+
+int
+nw_utime(const char *filename, struct utimbuf *times)
+{
+        return(utime(filename, times));
+}
+
+int
+nw_vfprintf(FILE *fp, const char *format, va_list args)
+{
+       if(fp)
+           return (vfprintf(fp, format, args));
+       else
+           return -1;
+}
+
+int
+nw_wait(int *status)
+{
+    return 0;  
+}
+
+int
+nw_waitpid(int pid, int *status, int flags)
+{
+    return 0;  
+}
+
+int
+nw_write(int fd, const void *buf, unsigned int cnt)
+{
+    return write(fd, buf, cnt);
+}
+
+char *
+nw_crypt(const char *txt, const char *salt)
+{
+        dTHXo;
+
+#ifdef HAVE_DES_FCRYPT
+    dTHR;
+    return des_fcrypt(txt, salt, w32_crypt_buffer);
+#else
+    Perl_croak(aTHX_ "The crypt() function is unimplemented due to excessive paranoia.");
+    return Nullch;
+#endif
+}
+
+int
+nw_dup(int fd)
+{
+    return dup(fd);
+}
+
+int
+nw_dup2(int fd1,int fd2)
+{
+       return dup2(fd1,fd2);
+}
+
+void*
+nw_dynaload(const char* filename)
+{
+       return NULL;
+}
+
+int
+nw_fclose(FILE *pf)
+{
+       if(pf)
+           return (fclose(pf));
+       else
+           return -1;
+}
+
+FILE *
+nw_fdopen(int handle, const char *mode)
+{
+       return(fdopen(handle, mode));
+}
+
+int
+nw_feof(FILE *fp)
+{
+       if(fp)
+           return (feof(fp));
+       else
+           return -1;
+}
+
+int
+nw_ferror(FILE *fp)
+{
+       if(fp)
+           return (ferror(fp));
+       else
+           return -1;
+}
+
+
+int
+nw_fflush(FILE *pf)
+{
+       if(pf)
+           return fflush(pf);
+       else
+           return -1;
+}
+
+int
+nw_fgetpos(FILE *pf, fpos_t *p)
+{
+       if(pf)
+           return fgetpos(pf, p);
+       else
+           return -1;
+}
+
+char*
+nw_fgets(char *s, int n, FILE *pf)
+{
+       if(pf)
+           return(fgets(s, n, pf));
+       else
+           return NULL;
+}
+
+int
+nw_fileno(FILE *pf)
+{
+       if(pf)
+           return fileno(pf);
+       else
+           return -1;
+}
+
+int
+nw_flock(int fd, int oper)
+{
+       return 0;
+}
+
+
+FILE *
+nw_fopen(const char *filename, const char *mode)
+{
+       return (fopen(filename, mode));
+}
+
+int
+nw_fputc(int c, FILE *pf)
+{
+       if(pf)
+           return fputc(c,pf);
+       else
+           return -1;
+}
+
+int
+nw_fputs(const char *s, FILE *pf)
+{
+       if(pf)
+           return fputs(s, pf);
+       else
+           return -1;
+}
+
+size_t
+nw_fread(void *buf, size_t size, size_t count, FILE *fp)
+{
+       if(fp)
+           return fread(buf, size, count, fp);
+       else
+           return -1;
+}
+
+FILE *
+nw_freopen(const char *path, const char *mode, FILE *stream)
+{
+       if(stream)
+           return freopen(path, mode, stream);
+       else
+           return NULL;
+}
+
+int
+nw_fseek(FILE *pf, long offset, int origin)
+{
+       if(pf)
+           return (fseek(pf, offset, origin));
+       else
+           return -1;
+}
+
+int
+nw_fsetpos(FILE *pf, const fpos_t *p)
+{
+       if(pf)
+           return fsetpos(pf, p);
+       else
+           return -1;
+}
+
+long
+nw_ftell(FILE *pf)
+{
+       if(pf)
+           return ftell(pf);
+       else
+           return -1;
+}
+
+size_t
+nw_fwrite(const void *buf, size_t size, size_t count, FILE *fp)
+{
+       if(fp)
+           return fwrite(buf, size, count, fp);
+       else
+           return -1;
+}
+
+long
+nw_get_osfhandle(int fd)
+{
+       return 0l;
+}
+
+int
+nw_getc(FILE *pf)
+{
+       if(pf)
+           return getc(pf);
+       else
+           return -1;
+}
+
+int
+nw_putc(int c, FILE *pf)
+{
+       if(pf)
+           return putc(c,pf);
+       else
+           return -1;
+}
+
+int
+nw_fgetc(FILE *pf)
+{
+       if(pf)
+           return fgetc(pf);
+       else
+           return -1;
+}
+
+int
+nw_getpid(void)
+{
+       return GetThreadGroupID();
+}
+
+int
+nw_kill(int pid, int sig)
+{
+       return 0;
+}
+
+int
+nw_link(const char *oldname, const char *newname)
+{
+       return 0;
+}
+
+long
+nw_lseek(int fd, long offset, int origin)
+{
+    return lseek(fd, offset, origin);
+}
+
+int
+nw_chdir(const char *dir)
+{
+    return chdir(dir);
+}
+
+int
+nw_rmdir(const char *dir)
+{
+    return rmdir(dir);
+}
+
+DIR *
+nw_opendir(char *filename)
+{
+       char    *buff = NULL;
+       int             len = 0;
+       DIR             *ret = NULL;
+       
+       len = strlen(filename);
+       buff = malloc(len + 5);
+       if (buff) {
+               strcpy(buff, filename);
+               if (buff[len-1]=='/' || buff[len-1]=='\\') {
+                       buff[--len] = 0;
+               }
+               strcpy(buff+len, "/*.*");
+               ret = opendir(buff);
+               free (buff);
+               buff = NULL;
+               return ret;
+       } else {
+               return NULL;
+       }
+}
+
+int
+nw_open(const char *path, int flag, ...)
+{
+       va_list ap;
+       int pmode = -1;
+
+       va_start(ap, flag);
+    pmode = va_arg(ap, int);
+    va_end(ap);
+
+       if (stricmp(path, "/dev/null")==0)
+       path = "NUL";
+
+       return open(path, flag, pmode);
+}
+
+int
+nw_open_osfhandle(long handle, int flags)
+{
+       return 0;
+}
+
+unsigned long
+nw_os_id(void)
+{
+       return 0l;
+}
+
+int nw_Pipe(int* a, int* e)
+{
+       int ret = 0;
+
+       errno = 0;
+       ret = pipe(a);
+       if(errno)
+               e = &errno;
+
+       return ret;
+}
+
+FILE* nw_Popen(char* command, char* mode, int* e)
+{
+       int i = -1;
+
+       FILE* ret = NULL;
+       PTEMPPIPEFILE ptpf = NULL;
+
+       // this callback is supposed to call _popen, which spawns an
+       // asynchronous command and opens a pipe to it. The returned
+       // file handle can be read or written to; if read, it represents
+       // stdout of the called process and will return EOF when the
+       // called process finishes. If written to, it represents stdin
+       // of the called process. Naturally _popen is not available on
+       // NetWare so we must do some fancy stuff to simulate it. We will
+       // redirect to and from temp files; this has the side effect
+       // of having to run the process synchronously rather than
+       // asynchronously. This means that you will only be able to do
+       // this with CLIB NLMs built to run on the calling thread.
+
+       errno = 0;
+
+       ptpf1[iPopenCount] = (PTEMPPIPEFILE) malloc(sizeof(TEMPPIPEFILE));
+       if (!ptpf1[iPopenCount])
+               return NULL;
+
+       ptpf = ptpf1[iPopenCount];
+       iPopenCount ++;
+       if(iPopenCount > MAX_PIPE_RECURSION)
+               iPopenCount = MAX_PIPE_RECURSION;       // Limit to the max no of pipes to be open recursively.
+
+       fnTempPipeFile(ptpf);
+       ret = fnPipeFileOpen((PTEMPPIPEFILE) ptpf, (char *) command, (char *) mode);
+       if (ret)
+               File1[iPopenCount-1] = ret;     // Store the obtained Pipe file handle.
+       else
+       {       // Pipe file not obtained. So free the allocated memory.
+               if(ptpf1[iPopenCount-1])
+               {
+                       free(ptpf1[iPopenCount-1]);
+                       ptpf1[iPopenCount-1] = NULL;
+                       ptpf = NULL;
+                       iPopenCount --;
+               }
+       }
+
+       if (errno)
+               e = &errno;
+
+       return ret;
+}
+
+int nw_Pclose(FILE* file, int* e)
+{
+       int i=0, j=0;
+
+       errno = 0;
+
+       if(file)
+       {
+               if(iPopenCount > 0)
+               {
+                       for (i=0; i<iPopenCount; i++)
+                       {
+                               if(File1[i] == file)
+                               {
+                                       // Delete the memory allocated corresponding to the file handle passed-in and
+                                       // also close the file corresponding to the file handle passed-in!
+                                       if(ptpf1[i])
+                                       {
+                                               fnPipeFileClose(ptpf1[i]);
+
+                                               free(ptpf1[i]);
+                                               ptpf1[i] = NULL;
+                                       }
+
+                                       fclose(File1[i]);
+                                       File1[i] = NULL;
+
+                                       break;
+                               }
+                       }
+
+                       // Rearrange the file pointer array
+                       for(j=i; j<(iPopenCount-1); j++)
+                       {
+                               File1[j] = File1[j+1];
+                               ptpf1[j] = ptpf1[j+1];
+                       }
+                       iPopenCount--;
+               }
+       }
+       else
+           return -1;
+
+       if (errno)
+               e = &errno;
+
+       return 0;
+}
+
+
+int
+nw_vprintf(const char *format, va_list args)
+{
+    return (vprintf(format, args));
+}
+
+int
+nw_printf(const char *format, ...)
+{
+       
+       va_list marker;
+    va_start(marker, format);     /* Initialize variable arguments. */
+
+    return (vprintf(format, marker));
+}
+
+int
+nw_read(int fd, void *buf, unsigned int cnt)
+{
+       return read(fd, buf, cnt);
+}
+
+struct direct *
+nw_readdir(DIR *dirp)
+{
+       DIR* ret=NULL;
+
+       ret = readdir(dirp);
+       if(ret)
+               return((struct direct *)ret);
+       return NULL;
+}
+
+int
+nw_rename(const char *oname, const char *newname)
+{
+       return(rename(oname,newname));
+}
+
+void
+nw_rewinddir(DIR *dirp)
+{
+       dTHXo;
+       Perl_croak(aTHX_ "rewinddir function is not implemented");
+}
+
+void
+nw_rewind(FILE *pf)
+{
+       if(pf)
+           rewind(pf);
+}
+
+void
+nw_seekdir(DIR *dirp, long loc)
+{
+       dTHXo;
+       Perl_croak(aTHX_ "seekdir function is not implemented");
+}
+
+int *
+nw_errno(void)
+{
+    return (&errno);
+}
+
+char ***
+nw_environ(void)
+{
+       return ((char ***)nw_getenviron());
+}
+
+char *
+nw_strerror(int e)
+{
+       return (strerror(e));
+}
+
+int
+nw_isatty(int fd)
+{
+       return(isatty(fd));
+}
+
+char *
+nw_mktemp(char *Template)
+{
+       return (fnMy_MkTemp(Template));
+}
+
+int
+nw_chsize(int handle, long size)
+{
+       return(chsize(handle,size));
+}
+
+#ifdef HAVE_INTERP_INTERN
+void
+sys_intern_init(pTHX)
+{
+
+}
+
+void
+sys_intern_clear(pTHX)
+{
+
+}
+
+void
+sys_intern_dup(pTHX_ struct interp_intern *src, struct interp_intern *dst)
+{
+
+}
+#endif /* HAVE_INTERP_INTERN */
+
+void
+Perl_init_os_extras(void)
+{
+    
+}
+
+void
+Perl_nw5_init(int *argcp, char ***argvp)
+{
+    MALLOC_INIT;
+}
+
+// Some more functions:
+
+char *
+nw_get_sitelib(const char *pl)
+{
+    return (NULL);
+}
+
+int
+execv(char *cmdname, char **argv)
+{
+       // This feature needs to be implemented.
+       // _asm is commented out since it goes into the internal debugger.
+//     _asm {int 3};
+       return(0);
+}
+
+int
+execvp(char *cmdname, char **argv)
+{
+       // This feature needs to be implemented.
+       // _asm is commented out since it goes into the internal debugger.
+//     _asm {int 3};
+       return(0);
+}
+
+int
+do_aspawn(void *vreally, void **vmark, void **vsp)
+{
+       // This feature needs to be implemented.
+       // _asm is commented out since it goes into the internal debugger.
+//     _asm {int 3};
+       return(0);
+}
+
+int
+do_spawn2(char *cmd, int exectype)
+{
+       // This feature needs to be implemented.
+       // _asm is commented out since it goes into the internal debugger.
+//     _asm {int 3};
+       return(0);
+}
+
+int
+do_spawn(char *cmd)
+{
+    return do_spawn2(cmd, 2);
+}
+
+int
+fork(void)
+{
+       return 0;
+}
+
diff --git a/NetWare/nw5iop.h b/NetWare/nw5iop.h
new file mode 100644 (file)
index 0000000..27cd0a1
--- /dev/null
@@ -0,0 +1,213 @@
+
+/*
+ * Copyright Â© 2001 Novell, Inc. All Rights Reserved.
+ *
+ * You may distribute under the terms of either the GNU General Public
+ * License or the Artistic License, as specified in the README file.
+ *
+ */
+
+/*
+ * FILENAME            :       nw5iop.h
+ * DESCRIPTION :       Redefined functions for NetWare.
+ * Author              :       SGP, HYAK
+ * Date                        :       January 2001.
+ *
+ */
+
+
+
+#ifndef NW5IOP_H
+#define NW5IOP_H
+
+
+#ifndef START_EXTERN_C
+#ifdef __cplusplus
+#  define START_EXTERN_C extern "C" {
+#  define END_EXTERN_C }
+#  define EXTERN_C extern "C"
+#else
+#  define START_EXTERN_C 
+#  define END_EXTERN_C 
+#  define EXTERN_C
+#endif
+#endif
+
+#if defined(_MSC_VER) || defined(__MINGW32__)
+#  include <sys/utime.h>
+#else
+#  include <utime.h>
+#endif
+
+/*
+ * defines for flock emulation
+ */
+#define LOCK_SH 1
+#define LOCK_EX 2
+#define LOCK_NB 4
+#define LOCK_UN 8
+
+
+/*
+ * Make this as close to original stdio as possible.
+ */
+
+/*
+ * function prototypes for our own win32io layer
+ */
+/********CHKSGP ****/
+//making DLLExport as nothing
+#define DllExport      
+/*******************/
+
+START_EXTERN_C
+
+int *  nw_errno(void);
+char ***       nw_environ(void);
+
+FILE*  nw_stdin(void);
+FILE*  nw_stdout(void);
+FILE*  nw_stderr(void);
+int            nw_ferror(FILE *fp);
+int            nw_feof(FILE *fp);
+
+char*  nw_strerror(int e);
+
+int            nw_fprintf(FILE *pf, const char *format, ...);
+int            nw_printf(const char *format, ...);
+int            nw_vfprintf(FILE *pf, const char *format, va_list arg);
+int            nw_vprintf(const char *format, va_list arg);
+
+size_t nw_fread(void *buf, size_t size, size_t count, FILE *pf);
+size_t nw_fwrite(const void *buf, size_t size, size_t count, FILE *pf);
+FILE*  nw_fopen(const char *path, const char *mode);
+FILE*  nw_fdopen(int fh, const char *mode);
+FILE*  nw_freopen(const char *path, const char *mode, FILE *pf);
+int            nw_fclose(FILE *pf);
+
+int            nw_fputs(const char *s,FILE *pf);
+int            nw_fputc(int c,FILE *pf);
+int            nw_ungetc(int c,FILE *pf);
+int            nw_getc(FILE *pf);
+int            nw_fileno(FILE *pf);
+void   nw_clearerr(FILE *pf);
+int            nw_fflush(FILE *pf);
+long   nw_ftell(FILE *pf);
+int            nw_fseek(FILE *pf,long offset,int origin);
+int            nw_fgetpos(FILE *pf,fpos_t *p);
+int            nw_fsetpos(FILE *pf,const fpos_t *p);
+void   nw_rewind(FILE *pf);
+FILE*  nw_tmpfile(void);
+
+void   nw_abort(void);
+
+int    nw_stat(const char *name,struct stat *sbufptr);
+
+FILE* nw_Popen(char* command, char* mode, int* e);
+int nw_Pclose(FILE* file, int* e);
+int nw_Pipe(int* a, int* e);
+
+int            nw_rename( const char *oname, const char *newname);
+//int          nw_setmode( int fd, int mode);
+int            nw_setmode( FILE *fp, int mode);
+long   nw_lseek( int fd, long offset, int origin);
+int            nw_dup( int fd);
+int            nw_dup2(int h1, int h2);
+int            nw_open(const char *path, int oflag,...);
+int            nw_close(int fd);
+int            nw_read(int fd, void *buf, unsigned int cnt);
+int            nw_write(int fd, const void *buf, unsigned int cnt);
+
+int nw_spawnvp(int mode, char *cmdname, char **argv);
+
+int            nw_rmdir(const char *dir);
+int            nw_chdir(const char *dir);
+int            nw_flock(int fd, int oper);
+
+int nw_execv(char *cmdname, char **argv);
+int nw_execvp(char *cmdname, char **argv);
+
+void   nw_setbuf(FILE *pf, char *buf);
+int            nw_setvbuf(FILE *pf, char *buf, int type, size_t size);
+char*  nw_fgets(char *s, int n, FILE *pf);
+
+int            nw_fgetc(FILE *pf);
+
+int            nw_putc(int c, FILE *pf);
+
+int            nw_open_osfhandle(long handle, int flags);
+long   nw_get_osfhandle(int fd);
+
+DIR*   nw_opendir(char *filename);
+struct direct* nw_readdir(DIR *dirp);
+long nw_telldir(DIR *dirp);
+void nw_seekdir(DIR *dirp, long loc);
+void nw_rewinddir(DIR *dirp);
+int            nw_closedir(DIR *dirp);
+
+unsigned int   nw_sleep(unsigned int);
+int            nw_times(struct tms *timebuf);
+
+int            nw_stat(const char *path, struct stat *buf);
+int nw_link(const char *oldname, const char *newname);
+int            nw_unlink(const char *f);
+int            nw_utime(const char *f, struct utimbuf *t);
+DllExport  int         nw_uname(struct utsname *n);
+
+int            nw_wait(int *status);
+
+int nw_waitpid(int pid, int *status, int flags);
+int nw_kill(int pid, int sig);
+
+unsigned long  nw_os_id(void);
+void*  nw_dynaload(const char*filename);
+
+int            nw_access(const char *path, int mode);
+int            nw_chmod(const char *path, int mode);
+int            nw_getpid(void);
+
+char * nw_crypt(const char *txt, const char *salt);
+
+int nw_isatty(int fd);
+char* nw_mktemp(char *Template);
+int nw_chsize(int handle, long size);
+END_EXTERN_C
+
+
+/*
+ * the following six(6) is #define in stdio.h
+ */
+#ifndef WIN32IO_IS_STDIO
+#undef environ
+#undef feof
+#undef pipe
+#undef pause
+#undef sleep
+#undef times
+#undef alarm
+#undef ioctl
+#undef unlink
+#undef utime
+#undef uname
+#undef wait
+
+#ifdef __BORLANDC__
+#undef ungetc
+#undef getc
+#undef putc
+#undef getchar
+#undef putchar
+#undef fileno
+#endif
+
+#define environ                                (*nw_environ())
+
+
+#if !defined(MYMALLOC) || !defined(PERL_CORE)
+
+#endif
+
+
+#endif /* WIN32IO_IS_STDIO */
+#endif /* NW5IOP_H */
+
diff --git a/NetWare/nw5sck.c b/NetWare/nw5sck.c
new file mode 100644 (file)
index 0000000..8985f0c
--- /dev/null
@@ -0,0 +1,332 @@
+
+/*
+ * Copyright Â© 2001 Novell, Inc. All Rights Reserved.
+ *
+ * You may distribute under the terms of either the GNU General Public
+ * License or the Artistic License, as specified in the README file.
+ *
+ */
+
+/*
+ * FILENAME            :       nw5sck.c
+ * DESCRIPTION :       Socket related functions.
+ * Author              :       SGP
+ * Date                        :       January 2001.
+ *
+ */
+
+
+
+#include "EXTERN.h"
+#include "perl.h"
+
+#if defined(PERL_OBJECT)
+#define NO_XSLOCKS
+#include "XSUB.h"
+#endif
+
+#include "nw5iop.h"
+#include "nw5sck.h"
+#include <fcntl.h>
+#include <sys/stat.h>
+
+static struct servent* nw_savecopyservent(struct servent*d,
+                                             struct servent*s,
+                                             const char *proto);
+
+
+u_long
+nw_htonl(u_long hostlong)
+{
+    return htonl(hostlong);
+}
+
+u_short
+nw_htons(u_short hostshort)
+{
+    return htons(hostshort);
+}
+
+u_long
+nw_ntohl(u_long netlong)
+{
+    return ntohl(netlong);
+}
+
+u_short
+nw_ntohs(u_short netshort)
+{
+    return ntohs(netshort);
+}
+
+SOCKET
+nw_accept(SOCKET s, struct sockaddr *addr, int *addrlen)
+{
+       return ((SOCKET)(accept(s, addr, addrlen)));
+}
+
+int
+nw_bind(SOCKET s, const struct sockaddr *addr, int addrlen)
+{
+       return ((int)bind(s, (struct sockaddr *)addr, addrlen));
+
+}
+
+int
+nw_connect(SOCKET s, const struct sockaddr *addr, int addrlen)
+{
+       return((int)connect(s, (struct sockaddr *)addr, addrlen));
+}
+
+void
+nw_endhostent() 
+{
+       endhostent();
+}
+
+void
+nw_endnetent()
+{
+       endnetent();
+}
+
+void
+nw_endprotoent()
+{
+       endprotoent();
+}
+
+void
+nw_endservent()
+{
+       endservent();
+}
+
+struct hostent *
+nw_gethostent()
+{
+       return(gethostent());
+}
+
+struct netent *
+nw_getnetent(void) 
+{
+    return ((struct netent *) getnetent());
+}
+
+struct protoent *
+nw_getprotoent(void) 
+{
+    return ((struct protoent *) getprotoent());
+}
+
+struct hostent *
+nw_gethostbyname(const char *name)
+{
+       return(gethostbyname((char*)name));
+}
+
+int
+nw_gethostname(char *name, int len)
+{
+    return(gethostname(name, len));
+}
+
+struct hostent *
+nw_gethostbyaddr(const char *addr, int len, int type)
+{
+       return(gethostbyaddr((char*)addr, len, type));
+}
+
+struct netent *
+nw_getnetbyaddr(long net, int type) 
+{
+       return(getnetbyaddr(net,type));
+}
+
+struct netent *
+nw_getnetbyname(char *name) 
+{
+    return (struct netent *)getnetbyname(name);
+}
+
+int
+nw_getpeername(SOCKET s, struct sockaddr *addr, int *addrlen)
+{
+       return((int)getpeername(s, addr, addrlen));
+}
+
+struct protoent *
+nw_getprotobyname(const char *name)
+{
+       return ((struct protoent *)getprotobyname((char*)name));
+}
+
+struct protoent *
+nw_getprotobynumber(int num)
+{
+       return ((struct protoent *)getprotobynumber(num));
+}
+
+struct servent *
+nw_getservbyname(const char *name, const char *proto)
+{
+       dTHXo; 
+    struct servent *r;
+
+    r = getservbyname((char*)name, (char*)proto);
+    if (r) {
+               /*r = nw_savecopyservent(&nw_servent, r, proto);*/
+    }
+    return r;
+}
+
+
+struct servent *
+nw_getservbyport(int port, const char *proto)
+{
+    dTHXo; 
+    struct servent *r;
+
+    r = getservbyport(port, (char*)proto);
+    if (r) {
+               //r = nw_savecopyservent(&nw_servent, r, proto);
+    }
+    return r;
+}
+
+struct servent *
+nw_getservent(void) 
+{
+    return (struct servent *) getservent();
+}
+
+void
+nw_sethostent(int stayopen)
+{
+       sethostent(stayopen);
+}
+
+void
+nw_setnetent(int stayopen)
+{
+       setnetent(stayopen);
+}
+
+void
+nw_setprotoent(int stayopen)
+{
+       setprotoent(stayopen);
+}
+
+void
+nw_setservent(int stayopen)
+{
+       setservent(stayopen);
+}
+
+int
+nw_getsockname(SOCKET s, struct sockaddr *addr, int *addrlen)
+{
+       return getsockname(s, addr, addrlen);
+}
+
+int
+nw_getsockopt(SOCKET s, int level, int optname, char *optval, int *optlen)
+{
+       return ((int)getsockopt(s, level, optname, optval, optlen));
+}
+
+unsigned long
+nw_inet_addr(const char *cp)
+{
+    return inet_addr((char*)cp);
+}
+
+static struct servent*
+nw_savecopyservent(struct servent*d, struct servent*s, const char *proto)
+{
+    d->s_name = s->s_name;
+    d->s_aliases = s->s_aliases;
+    d->s_port = s->s_port;
+#ifndef __BORLANDC__   /* Buggy on Win95 and WinNT-with-Borland-WSOCK */
+    if (/*!IsWin95() && */s->s_proto && strlen(s->s_proto))
+       d->s_proto = s->s_proto;
+    else
+#endif
+    if (proto && strlen(proto))
+       d->s_proto = (char *)proto;
+    else
+       d->s_proto = "tcp";
+   
+    return d;
+}
+
+SOCKET
+nw_socket(int af, int type, int protocol)
+{
+    SOCKET s;
+
+#ifndef USE_SOCKETS_AS_HANDLES
+    s = socket(af, type, protocol);
+#else
+    //StartSockets();
+    if((s = socket(af, type, protocol)) == INVALID_SOCKET)
+       //errno = WSAGetLastError();
+    else
+       s = s;
+#endif /* USE_SOCKETS_AS_HANDLES */
+
+    return s;
+}
+
+int
+nw_listen(SOCKET s, int backlog)
+{
+    return(listen(s, backlog));
+}
+
+int
+nw_send(SOCKET s, const char *buf, int len, int flags)
+{
+       return(send(s,(char*)buf,len,flags));
+}
+
+int
+nw_recv(SOCKET s, char *buf, int len, int flags)
+{
+       return (recv(s, buf, len, flags));
+}
+
+int
+nw_sendto(SOCKET s, const char *buf, int len, int flags,
+            const struct sockaddr *to, int tolen)
+{
+    return(sendto(s, (char*)buf, len, flags, (struct sockaddr *)to, tolen));
+}
+
+int
+nw_recvfrom(SOCKET s, char *buf, int len, int flags, struct sockaddr *from, int *fromlen)
+{
+    int r;
+    int frombufsize = *fromlen;
+
+    r = recvfrom(s, buf, len, flags, from, fromlen);
+       //Not sure if the is required - chksgp
+    if (r && frombufsize == *fromlen)
+       (void)nw_getpeername(s, from, fromlen);
+    return r;
+}
+
+int
+nw_select(int nfds, fd_set* rd, fd_set* wr, fd_set* ex, const struct timeval* timeout)
+{
+       return(select(nfds, rd, wr, ex, (struct timeval*)timeout));
+}
+
+int
+nw_shutdown(SOCKET s, int how)
+{
+    return (shutdown(s, how));
+}
+
diff --git a/NetWare/nw5sck.h b/NetWare/nw5sck.h
new file mode 100644 (file)
index 0000000..1b0bc51
--- /dev/null
@@ -0,0 +1,129 @@
+
+/*
+ * Copyright Â© 2001 Novell, Inc. All Rights Reserved.
+ *
+ * You may distribute under the terms of either the GNU General Public
+ * License or the Artistic License, as specified in the README file.
+ *
+ */
+
+/*
+ * FILENAME            :       nw5sck.h
+ * DESCRIPTION :       Socket related functions.
+ * Author              :       SGP
+ * Date                        :       January 2001.
+ *
+ */
+
+
+
+#ifndef  _INC_NW_SOCKET
+#define  _INC_NW_SOCKET
+
+
+#include <sys/socket.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef u_int           SOCKET;
+
+struct nwsockent local_context;
+
+# undef gethostbyname
+# undef gethostbyaddr
+
+# undef endhostent
+# undef endnetent
+# undef endprotoent
+# undef endservent
+# undef gethostent
+# undef getprotoent
+# undef getnetbyaddr
+# undef getnetbyname
+# undef gethostbyaddr
+# undef getprotobyname
+# undef getprotobyname
+# undef getservbyname
+# undef getservbyport
+# undef getservent
+# undef sethostent
+# undef setnetent
+# undef setprotoent
+# undef setservent
+
+# define gethostbyname(name)   NetDBgethostbyname(&local_context,name)
+# define gethostbyaddr(a,l,t)  NetDBgethostbyaddr(&local_context,a,l,t)
+
+# define endhostent()          NetDBendhostent(&local_context)
+# define endnetent()           NWendnetent(&local_context)
+# define endprotoent()         NWendprotoent(&local_context)
+# define endservent()          NWendservent(&local_context)
+# define gethostent()          NetDBgethostent(&local_context,NULL)
+# define getprotoent()         NWgetprotoent(&local_context)
+# define gethostbyaddr(a,l,t)  NetDBgethostbyaddr(&local_context,a,l,t)
+# define getnetbyaddr(net,typ) NWgetnetbyaddr(&local_context,net,typ)
+# define getnetbyname(name)    NWgetnetbyname(&local_context,name)
+# define getprotobyname(name)  NWgetprotobyname(&local_context,name)
+# define getprotobyname(name)  NWgetprotobyname(&local_context,name)
+# define getservbyname(n,p)    NWgetservbyname(&local_context,n,p)
+# define getservbyport(n,p)    NWgetservbyport(&local_context,n,p)
+# define getservent()          NWgetservent(&local_context)
+# define sethostent()          NWsethostent(&local_context, stayopen)
+# define setnetent()           NWsetnetent(&local_context, stayopen)
+# define setprotoent()         NWsetprotoent(&local_context, stayopen)
+# define setservent()          NWsetservent(&local_context, stayopen)
+
+u_long nw_htonl(u_long hostlong);
+u_short nw_htons(u_short hostshort);
+u_long nw_ntohl(u_long netlong);
+u_short nw_ntohs(u_short netshort);
+
+SOCKET nw_accept(SOCKET s, struct sockaddr *addr, int *addrlen);
+int nw_bind(SOCKET s, const struct sockaddr *addr, int addrlen);
+int nw_connect(SOCKET s, const struct sockaddr *addr, int addrlen);
+
+struct hostent * nw_gethostbyname(const char * name);
+struct hostent * nw_gethostbyaddr(const char *addr, int len, int type);
+int nw_gethostname(char *name, int len);
+struct netent * nw_getnetbyaddr(long net, int type);
+struct netent *nw_getnetbyname(char *name);
+int nw_getpeername(SOCKET s, struct sockaddr *addr, int *addrlen);
+struct protoent * nw_getprotobyname(const char *name);
+struct protoent * nw_getprotobynumber(int num);
+struct servent * nw_getservbyname(const char *name, const char *proto);
+struct servent * nw_getservbyport(int port, const char *proto);
+struct servent * nw_getservent(void);
+void nw_sethostent(int stayopen);
+void nw_setnetent(int stayopen);
+void nw_setprotoent(int stayopen);
+void nw_setservent(int stayopen);
+
+int nw_getsockname(SOCKET s, struct sockaddr *addr, int *addrlen);
+int nw_getsockopt(SOCKET s, int level, int optname, char *optval, int *optlen);
+
+unsigned long nw_inet_addr(const char *cp);
+
+void nw_endhostent();
+void nw_endnetent();
+void nw_endprotoent();
+void nw_endservent();
+struct hostent *nw_gethostent();
+struct netent *nw_getnetent();
+struct protoent * nw_getprotoent();
+
+SOCKET nw_socket(int af, int type, int protocol);
+int nw_listen(SOCKET s, int backlog);
+int nw_send(SOCKET s, const char *buf, int len, int flags);
+int nw_recv(SOCKET s, char *buf, int len, int flags);
+int nw_sendto(SOCKET s, const char *buf, int len, int flags,const struct sockaddr *to, int tolen);
+int nw_recvfrom(SOCKET s, char *buf, int len, int flags, struct sockaddr *from, int *fromlen);
+int nw_select(int nfds, fd_set* rd, fd_set* wr, fd_set* ex, const struct timeval* timeout);
+int nw_shutdown(SOCKET s, int how);
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif // _INC_NW_SOCKET
+
diff --git a/NetWare/nw5thread.c b/NetWare/nw5thread.c
new file mode 100644 (file)
index 0000000..5cfa180
--- /dev/null
@@ -0,0 +1,86 @@
+
+/*
+ * Copyright Â© 2001 Novell, Inc. All Rights Reserved.
+ *
+ * You may distribute under the terms of either the GNU General Public
+ * License or the Artistic License, as specified in the README file.
+ *
+ */
+
+/*
+ * FILENAME            :       nw5thread.c
+ * DESCRIPTION :       Thread related functions.
+ * Author              :       SGP
+ * Date                        :       January 2001.
+ *
+ */
+
+
+
+#include "EXTERN.h"
+#include "perl.h"
+
+#if defined(PERL_OBJECT)
+#define NO_XSLOCKS
+extern CPerlObj* pPerl;
+#include "XSUB.h"
+#endif
+
+//For Thread Local Storage
+#include "win32ish.h"          // For "BOOL", "TRUE" and "FALSE"
+#include "nwtinfo.h"
+
+#ifdef USE_DECLSPEC_THREAD
+__declspec(thread) void *PL_current_context = NULL;
+#endif
+
+
+void
+Perl_set_context(void *t)
+{
+#if defined(USE_THREADS) || defined(USE_ITHREADS)
+#  ifdef USE_DECLSPEC_THREAD
+    Perl_current_context = t;
+#  else
+       fnAddThreadCtx(PL_thr_key, t);
+#  endif
+#endif
+}
+
+
+void *
+Perl_get_context(void)
+{
+#if defined(USE_THREADS) || defined(USE_ITHREADS)
+#  ifdef USE_DECLSPEC_THREAD
+    return Perl_current_context;
+#  else
+       return(fnGetThreadCtx(PL_thr_key));
+#  endif
+#else
+    return NULL;
+#endif
+}
+
+
+//To Remove the Thread Context stored during Perl_set_context
+BOOL
+Remove_Thread_Ctx(void)
+{
+#if defined(USE_THREADS) || defined(USE_ITHREADS)
+#  ifdef USE_DECLSPEC_THREAD
+       return TRUE;
+#  else
+       return(fnRemoveThreadCtx(PL_thr_key));
+#  endif
+#  else
+       return TRUE;
+#endif
+}
+
+
+//PL_thr_key - Not very sure if this is global or per thread.  When multiple scripts
+//run simultaneously on NetWare, this will give problems.  Hence in nwtinfo.c, the 
+//current thread id is used as the TLS index & PL_thr_key is not used.  
+//This has to be checked???? - sgp
+
diff --git a/NetWare/nw5thread.h b/NetWare/nw5thread.h
new file mode 100644 (file)
index 0000000..895338c
--- /dev/null
@@ -0,0 +1,176 @@
+
+/*
+ * Copyright Â© 2001 Novell, Inc. All Rights Reserved.
+ *
+ * You may distribute under the terms of either the GNU General Public
+ * License or the Artistic License, as specified in the README file.
+ *
+ */
+
+/*
+ * FILENAME            :       nw5thread.h
+ * DESCRIPTION :       Thread related functions.
+ * Author              :       SGP
+ * Date                        :       January 2001.
+ *
+ */
+
+
+
+#ifndef _NW5THREAD_H
+#define _NW5THREAD_H
+
+
+#include <nwthread.h>
+
+#include "netware.h"
+
+typedef long perl_key;
+
+#if (defined (USE_ITHREADS) || defined (USE_THREADS)) && defined(MPK_ON)
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+       #include <mpktypes.h>
+       #include <mpkapis.h>
+       #define kSUCCESS        (0)
+       #define ERROR_INVALID_MUTEX  (0x1010)
+
+#ifdef __cplusplus
+}
+#endif
+#undef WORD
+//On NetWare, since the NLM will be resident, only once the MUTEX_INIT gets called and
+//this will be freed when the script terminates.  But when a new script is executed,
+//then MUTEX_LOCK will fail since it is already freed.  Even if this problem is fixed
+//by not freeing the mutex when script terminates but when the NLM unloads, there will
+//still be problems when multiple scripts are running simultaneously in a multi-processor
+//machine - sgp
+typedef MUTEX perl_mutex;
+#  define MUTEX_INIT(m) \
+    STMT_START {                                               \
+       /*if ((*(m) = kMutexAlloc("NetWarePerlMutex")) == NULL) */\
+           /*Perl_croak_nocontext("panic: MUTEX_ALLOC");               */\
+       /*ConsolePrintf("Mutex Init %d\n",*(m));        */\
+    } STMT_END
+
+#  define MUTEX_LOCK(m) \
+    STMT_START {                                               \
+       /*ConsolePrintf("Mutex lock %d\n",*(m));        */\
+       /*if (kMutexLock(*(m)) == ERROR_INVALID_MUTEX)  */\
+           /*Perl_croak_nocontext("panic: MUTEX_LOCK");                */\
+    } STMT_END
+
+#  define MUTEX_UNLOCK(m) \
+    STMT_START {                                               \
+       /*ConsolePrintf("Mutex unlock %d\n",*(m));      */\
+       /*if (kMutexUnlock(*(m)) != kSUCCESS)                           \
+           Perl_croak_nocontext("panic: MUTEX_UNLOCK");        */\
+    } STMT_END
+
+#  define MUTEX_DESTROY(m) \
+    STMT_START {                                               \
+       /*ConsolePrintf("Mutex Destroy %d\n",*(m));     */\
+       /*if (kMutexWaitCount(*(m)) == 0 )      */\
+       /*{     */\
+               /*PERL_SET_INTERP(NULL); *//*newly added CHKSGP???*/    \
+               /*if (kMutexFree(*(m)) != kSUCCESS)                     */      \
+                       /*Perl_croak_nocontext("panic: MUTEX_FREE");    */\
+       /*}     */\
+    } STMT_END
+
+#else
+typedef unsigned long perl_mutex;
+#  define MUTEX_INIT(m)
+#  define MUTEX_LOCK(m)
+#  define MUTEX_UNLOCK(m)
+#  define MUTEX_DESTROY(m)
+#endif
+
+/* These macros assume that the mutex associated with the condition
+ * will always be held before COND_{SIGNAL,BROADCAST,WAIT,DESTROY},
+ * so there's no separate mutex protecting access to (c)->waiters
+ */
+//For now let us just see when this happens -sgp.
+#define COND_INIT(c) \
+    STMT_START {                                               \
+       ConsolePrintf("In COND_INIT\n");        \
+    } STMT_END
+
+/*     (c)->waiters = 0;                                       \
+       (c)->sem = OpenLocalSemaphore (0);      \
+       if ((c)->sem == NULL)                                   \
+           Perl_croak_nocontext("panic: COND_INIT (%ld)",errno);       \*/
+
+#define COND_SIGNAL(c) \
+    STMT_START {                                               \
+       ConsolePrintf("In COND_SIGNAL\n");      \
+    } STMT_END
+/*if ((c)->waiters > 0 &&                                      \
+           SignalLocalSemaphore((c)->sem) != 0)                \
+           Perl_croak_nocontext("panic: COND_SIGNAL (%ld)",errno);     \*/
+
+#define COND_BROADCAST(c) \
+    STMT_START {                                               \
+       ConsolePrintf("In COND_BROADCAST\n");   \       
+    } STMT_END
+
+       /*if ((c)->waiters > 0 ) {                                      \
+               int count;      \
+               for(count=0; count<(c)->waiters; count++) {     \
+                       if(SignalLocalSemaphore((c)->sem) != 0) \
+                               Perl_croak_nocontext("panic: COND_BROADCAST (%ld)",GetLastError());\
+               }       \
+       }       \*/
+#define COND_WAIT(c, m) \
+    STMT_START {                                               \
+       ConsolePrintf("In COND_WAIT\n");        \       
+    } STMT_END
+
+
+#define COND_DESTROY(c) \
+    STMT_START {                                               \
+       ConsolePrintf("In COND_DESTROY\n");     \       
+    } STMT_END
+
+/*             (c)->waiters = 0;                                       \
+       if (CloseLocalSemaphore((c)->sem) != 0)                         \
+           Perl_croak_nocontext("panic: COND_DESTROY (%ld)",errno);    \*/
+
+#if 0
+#define DETACH(t) \
+    STMT_START {                                               \
+       if (CloseHandle((t)->self) == 0) {                      \
+           MUTEX_UNLOCK(&(t)->mutex);                          \
+           Perl_croak_nocontext("panic: DETACH");              \
+       }                                                       \
+    } STMT_END
+#endif //#if 0
+
+//Following has to be defined CHKSGP
+#if defined(PERLDLL) && defined(USE_DECLSPEC_THREAD) && (!defined(__BORLANDC__) || defined(_DLL))
+extern __declspec(thread) void *PL_current_context;
+#define PERL_SET_CONTEXT(t)            (PL_current_context = t)
+#define PERL_GET_CONTEXT               PL_current_context
+#else
+#define PERL_GET_CONTEXT               Perl_get_context()
+#define PERL_SET_CONTEXT(t)            Perl_set_context(t)
+#endif
+
+//Check the following, will be used in Thread extension - CHKSGP
+#define THREAD_RET_TYPE        unsigned __stdcall
+#define THREAD_RET_CAST(p)     ((unsigned)(p))
+
+#define INIT_THREADS           NOOP
+
+//Ideally this should have been PL_thr_key = fnInitializeThreadCtx();
+//See the comment at the end of file nw5thread.c as to why PL_thr_key is not assigned - sgp
+#define ALLOC_THREAD_KEY \
+    STMT_START {                                                       \
+       fnInitializeThreadCtx();                        \
+    } STMT_END
+
+
+#endif /* _NW5THREAD_H */
+
diff --git a/NetWare/nwperlsys.c b/NetWare/nwperlsys.c
new file mode 100644 (file)
index 0000000..b440629
--- /dev/null
@@ -0,0 +1,1308 @@
+/*
+ * Copyright Â© 2001 Novell, Inc. All Rights Reserved.
+ *
+ * You may distribute under the terms of either the GNU General Public
+ * License or the Artistic License, as specified in the README file.
+ *
+ */
+
+/*
+ * FILENAME            :       nwperlsys.c
+ * DESCRIPTION :       Contains the platform specific functions calls
+ *                  
+ * Author              :       SGP
+ * Date Created :      June 12th 2001.
+ * Date Modified:
+ */
+
+#include "EXTERN.h"
+#include "perl.h"
+
+
+#ifdef PERL_OBJECT
+#define NO_XSLOCKS
+#endif
+
+//CHKSGP
+//Including this is giving premature end-of-file error during compilation
+//#include "XSUB.h"
+
+#ifdef PERL_IMPLICIT_SYS
+
+#include "nw5iop.h"
+#include <fcntl.h>
+
+
+#include "win32ish.h"
+
+START_EXTERN_C
+extern int do_spawn2(char *cmd, int exectype);
+extern int do_aspawn(void *vreally, void **vmark, void **vsp);
+extern void Perl_init_os_extras(void);
+extern BOOL fnInsertHashListAddrs(void *addrs, BOOL dontTouchHashList);
+extern BOOL fnGetHashListAddrs(void *addrs, BOOL *dontTouchHashList);
+END_EXTERN_C
+
+//Includes iperlsys.h and function definitions
+#include "nwperlsys.h"
+
+/* IPerlStdio  - Stdio functions - Begin ================================================*/
+
+FILE*
+PerlStdIOStdin(struct IPerlStdIO* piPerl)
+{
+    return nw_stdin();
+}
+
+FILE*
+PerlStdIOStdout(struct IPerlStdIO* piPerl)
+{
+    return nw_stdout();
+}
+
+FILE*
+PerlStdIOStderr(struct IPerlStdIO* piPerl)
+{
+    return nw_stderr();
+}
+
+FILE*
+PerlStdIOOpen(struct IPerlStdIO* piPerl, const char *path, const char *mode)
+{
+    return nw_fopen(path, mode);
+}
+
+int
+PerlStdIOClose(struct IPerlStdIO* piPerl, FILE* pf)
+{
+    return nw_fclose(pf);
+}
+
+int
+PerlStdIOEof(struct IPerlStdIO* piPerl, FILE* pf)
+{
+    return nw_feof(pf);
+}
+
+int
+PerlStdIOError(struct IPerlStdIO* piPerl, FILE* pf)
+{
+    return nw_ferror(pf);
+}
+
+void
+PerlStdIOClearerr(struct IPerlStdIO* piPerl, FILE* pf)
+{
+    nw_clearerr(pf);
+}
+
+int
+PerlStdIOGetc(struct IPerlStdIO* piPerl, FILE* pf)
+{
+    return nw_getc(pf);
+}
+
+char*
+PerlStdIOGetBase(struct IPerlStdIO* piPerl, FILE* pf)
+{
+#ifdef FILE_base
+    FILE *f = pf;
+    return FILE_base(f);
+#else
+    return Nullch;
+#endif
+}
+
+int
+PerlStdIOGetBufsiz(struct IPerlStdIO* piPerl, FILE* pf)
+{
+#ifdef FILE_bufsiz
+    FILE *f = pf;
+    return FILE_bufsiz(f);
+#else
+    return (-1);
+#endif
+}
+
+int
+PerlStdIOGetCnt(struct IPerlStdIO* piPerl, FILE* pf)
+{
+#ifdef USE_STDIO_PTR
+    FILE *f = pf;
+    return FILE_cnt(f);
+#else
+    return (-1);
+#endif
+}
+
+char*
+PerlStdIOGetPtr(struct IPerlStdIO* piPerl, FILE* pf)
+{
+#ifdef USE_STDIO_PTR
+    FILE *f = pf;
+    return FILE_ptr(f);
+#else
+    return Nullch;
+#endif
+}
+
+char*
+PerlStdIOGets(struct IPerlStdIO* piPerl, FILE* pf, char* s, int n)
+{
+    return nw_fgets(s, n, pf);
+}
+
+int
+PerlStdIOPutc(struct IPerlStdIO* piPerl, FILE* pf, int c)
+{
+    return nw_fputc(c, pf);
+}
+
+int
+PerlStdIOPuts(struct IPerlStdIO* piPerl, FILE* pf, const char *s)
+{
+    return nw_fputs(s, pf);
+}
+
+int
+PerlStdIOFlush(struct IPerlStdIO* piPerl, FILE* pf)
+{
+    return nw_fflush(pf);
+}
+
+int
+PerlStdIOUngetc(struct IPerlStdIO* piPerl, int c, FILE* pf)
+{
+    return nw_ungetc(c, pf);
+}
+
+int
+PerlStdIOFileno(struct IPerlStdIO* piPerl, FILE* pf)
+{
+    return nw_fileno(pf);
+}
+
+FILE*
+PerlStdIOFdopen(struct IPerlStdIO* piPerl, int fd, const char *mode)
+{
+    return nw_fdopen(fd, mode);
+}
+
+FILE*
+PerlStdIOReopen(struct IPerlStdIO* piPerl, const char*path, const char*mode, FILE* pf)
+{
+    return nw_freopen(path, mode, pf);
+}
+
+SSize_t
+PerlStdIORead(struct IPerlStdIO* piPerl, void *buffer, Size_t size, Size_t count, FILE* pf)
+{
+    return nw_fread(buffer, size, count, pf);
+}
+
+SSize_t
+PerlStdIOWrite(struct IPerlStdIO* piPerl, const void *buffer, Size_t size, Size_t count, FILE* pf)
+{
+    return nw_fwrite(buffer, size, count, pf);
+}
+
+void
+PerlStdIOSetBuf(struct IPerlStdIO* piPerl, FILE* pf, char* buffer)
+{
+    nw_setbuf(pf, buffer);
+}
+
+int
+PerlStdIOSetVBuf(struct IPerlStdIO* piPerl, FILE* pf, char* buffer, int type, Size_t size)
+{
+    return nw_setvbuf(pf, buffer, type, size);
+}
+
+void
+PerlStdIOSetCnt(struct IPerlStdIO* piPerl, FILE* pf, int n)
+{
+#ifdef STDIO_CNT_LVALUE
+    FILE *f = pf;
+    FILE_cnt(f) = n;
+#endif
+}
+
+void
+PerlStdIOSetPtr(struct IPerlStdIO* piPerl, FILE* pf, char * ptr)
+{
+#ifdef STDIO_PTR_LVALUE
+    FILE *f = pf;
+    FILE_ptr(f) = ptr;
+#endif
+}
+
+void
+PerlStdIOSetlinebuf(struct IPerlStdIO* piPerl, FILE* pf)
+{
+    nw_setvbuf(pf, NULL, _IOLBF, 0);
+}
+
+int
+PerlStdIOPrintf(struct IPerlStdIO* piPerl, FILE* pf, const char *format,...)
+{
+    va_list(arglist);
+    va_start(arglist, format);
+    return nw_vfprintf(pf, format, arglist);
+}
+
+int
+PerlStdIOVprintf(struct IPerlStdIO* piPerl, FILE* pf, const char *format, va_list arglist)
+{
+    return nw_vfprintf(pf, format, arglist);
+}
+
+long
+PerlStdIOTell(struct IPerlStdIO* piPerl, FILE* pf)
+{
+    return nw_ftell(pf);
+}
+
+int
+PerlStdIOSeek(struct IPerlStdIO* piPerl, FILE* pf, off_t offset, int origin)
+{
+    return nw_fseek(pf, offset, origin);
+}
+
+void
+PerlStdIORewind(struct IPerlStdIO* piPerl, FILE* pf)
+{
+    nw_rewind(pf);
+}
+
+FILE*
+PerlStdIOTmpfile(struct IPerlStdIO* piPerl)
+{
+    return nw_tmpfile();
+}
+
+int
+PerlStdIOGetpos(struct IPerlStdIO* piPerl, FILE* pf, Fpos_t *p)
+{
+    return nw_fgetpos(pf, p);
+}
+
+int
+PerlStdIOSetpos(struct IPerlStdIO* piPerl, FILE* pf, const Fpos_t *p)
+{
+    return nw_fsetpos(pf, p);
+}
+
+void
+PerlStdIOInit(struct IPerlStdIO* piPerl)
+{
+}
+
+void
+PerlStdIOInitOSExtras(struct IPerlStdIO* piPerl)
+{
+    Perl_init_os_extras();
+}
+
+
+int
+PerlStdIOOpenOSfhandle(struct IPerlStdIO* piPerl, long osfhandle, int flags)
+{
+    return nw_open_osfhandle(osfhandle, flags);
+}
+
+int
+PerlStdIOGetOSfhandle(struct IPerlStdIO* piPerl, int filenum)
+{
+    return nw_get_osfhandle(filenum);
+}
+
+FILE*
+PerlStdIOFdupopen(struct IPerlStdIO* piPerl, FILE* pf)
+{
+    FILE* pfdup=NULL;
+    fpos_t pos=0;
+    char mode[3]={'\0'};
+    int fileno = nw_dup(nw_fileno(pf));
+
+    /* open the file in the same mode */
+    if(((FILE*)pf)->_flag & _IOREAD) {
+       mode[0] = 'r';
+       mode[1] = 0;
+    }
+    else if(((FILE*)pf)->_flag & _IOWRT) {
+       mode[0] = 'a';
+       mode[1] = 0;
+    }
+    else if(((FILE*)pf)->_flag & _IORW) {
+       mode[0] = 'r';
+       mode[1] = '+';
+       mode[2] = 0;
+    }
+
+    /* it appears that the binmode is attached to the 
+     * file descriptor so binmode files will be handled
+     * correctly
+     */
+    pfdup = nw_fdopen(fileno, mode);
+
+    /* move the file pointer to the same position */
+    if (!fgetpos(pf, &pos)) {
+       fsetpos(pfdup, &pos);
+    }
+    return pfdup;
+}
+
+/* IPerlStdio  - Stdio functions - End   ================================================*/
+
+/* IPerlDir    - Directory Manipulation functions - Begin ===================================*/
+
+int
+PerlDirMakedir(struct IPerlDir* piPerl, const char *dirname, int mode)
+{
+       return mkdir(dirname);
+}
+
+int
+PerlDirChdir(struct IPerlDir* piPerl, const char *dirname)
+{
+       return nw_chdir(dirname);
+}
+
+int
+PerlDirRmdir(struct IPerlDir* piPerl, const char *dirname)
+{
+       return nw_rmdir(dirname);
+}
+
+int
+PerlDirClose(struct IPerlDir* piPerl, DIR *dirp)
+{
+       return nw_closedir(dirp);
+}
+
+DIR*
+PerlDirOpen(struct IPerlDir* piPerl, char *filename)
+{
+       return nw_opendir(filename);
+}
+
+struct direct *
+PerlDirRead(struct IPerlDir* piPerl, DIR *dirp)
+{
+       return nw_readdir(dirp);
+}
+
+void
+PerlDirRewind(struct IPerlDir* piPerl, DIR *dirp)
+{
+    nw_rewinddir(dirp);
+}
+
+void
+PerlDirSeek(struct IPerlDir* piPerl, DIR *dirp, long loc)
+{
+    nw_seekdir(dirp, loc);
+}
+
+long
+PerlDirTell(struct IPerlDir* piPerl, DIR *dirp)
+{
+    return nw_telldir(dirp);
+}
+
+/* IPerlDir    - Directory Manipulation functions - End   ===================================*/
+
+/* IPerlEnv    - Environment related functions - Begin ======================================*/
+
+char*
+PerlEnvGetenv(struct IPerlEnv* piPerl, const char *varname)
+{
+       return(getenv(varname));
+};
+
+int
+PerlEnvPutenv(struct IPerlEnv* piPerl, const char *envstring)
+{
+       return(putenv(envstring));
+};
+
+char*
+PerlEnvGetenv_len(struct IPerlEnv* piPerl, const char* varname, unsigned long* len)
+{
+       *len = 0; 
+       char *e = getenv(varname);
+       if (e)
+           *len = strlen(e);
+       return e;
+}
+
+int
+PerlEnvUname(struct IPerlEnv* piPerl, struct utsname *name)
+{
+    return nw_uname(name);
+}
+
+void
+PerlEnvClearenv(struct IPerlEnv* piPerl)
+{
+       
+}
+
+/* IPerlEnv    - Environment related functions - End   ======================================*/
+
+/* IPerlLIO    - Low-level IO functions - Begin =============================================*/
+
+int
+PerlLIOAccess(struct IPerlLIO* piPerl, const char *path, int mode)
+{
+    return nw_access(path, mode);
+}
+
+int
+PerlLIOChmod(struct IPerlLIO* piPerl, const char *filename, int pmode)
+{
+    return nw_chmod(filename, pmode);
+}
+
+int
+PerlLIOChown(struct IPerlLIO* piPerl, const char *filename, uid_t owner, gid_t group)
+{
+       dTHXo;
+    Perl_croak(aTHX_ "chown not implemented!\n");
+       return 0;
+}
+
+int
+PerlLIOChsize(struct IPerlLIO* piPerl, int handle, long size)
+{
+       return (nw_chsize(handle,size));
+}
+
+int
+PerlLIOClose(struct IPerlLIO* piPerl, int handle)
+{
+    return nw_close(handle);
+}
+
+int
+PerlLIODup(struct IPerlLIO* piPerl, int handle)
+{
+    return nw_dup(handle);
+}
+
+int
+PerlLIODup2(struct IPerlLIO* piPerl, int handle1, int handle2)
+{
+    return nw_dup2(handle1, handle2);
+}
+
+int
+PerlLIOFlock(struct IPerlLIO* piPerl, int fd, int oper)
+{
+       //On NetWare simulate flock by locking a range on the file
+    return nw_flock(fd, oper);
+}
+
+int
+PerlLIOFileStat(struct IPerlLIO* piPerl, int handle, struct stat *buffer)
+{
+    return fstat(handle, buffer);
+}
+
+int
+PerlLIOIOCtl(struct IPerlLIO* piPerl, int i, unsigned int u, char *data)
+{
+       return 0;
+}
+
+int
+PerlLIOIsatty(struct IPerlLIO* piPerl, int fd)
+{
+    return nw_isatty(fd);
+}
+
+int
+PerlLIOLink(struct IPerlLIO* piPerl, const char*oldname, const char *newname)
+{
+    return nw_link(oldname, newname);
+}
+
+long
+PerlLIOLseek(struct IPerlLIO* piPerl, int handle, long offset, int origin)
+{
+    return nw_lseek(handle, offset, origin);
+}
+
+int
+PerlLIOLstat(struct IPerlLIO* piPerl, const char *path, struct stat *buffer)
+{
+    return nw_stat(path, buffer);
+}
+
+char*
+PerlLIOMktemp(struct IPerlLIO* piPerl, char *Template)
+{
+       return(nw_mktemp(Template));
+}
+
+int
+PerlLIOOpen(struct IPerlLIO* piPerl, const char *filename, int oflag)
+{
+    return nw_open(filename, oflag);
+}
+
+int
+PerlLIOOpen3(struct IPerlLIO* piPerl, const char *filename, int oflag, int pmode)
+{
+    return nw_open(filename, oflag, pmode);
+}
+
+int
+PerlLIORead(struct IPerlLIO* piPerl, int handle, void *buffer, unsigned int count)
+{
+    return nw_read(handle, buffer, count);
+}
+
+int
+PerlLIORename(struct IPerlLIO* piPerl, const char *OldFileName, const char *newname)
+{
+    return nw_rename(OldFileName, newname);
+}
+
+int
+PerlLIOSetmode(struct IPerlLIO* piPerl, FILE *fp, int mode)
+{
+    return nw_setmode(fp, mode);
+}
+
+int
+PerlLIONameStat(struct IPerlLIO* piPerl, const char *path, struct stat *buffer)
+{
+    return nw_stat(path, buffer);
+}
+
+char*
+PerlLIOTmpnam(struct IPerlLIO* piPerl, char *string)
+{
+    return tmpnam(string);
+}
+
+int
+PerlLIOUmask(struct IPerlLIO* piPerl, int pmode)
+{
+    return umask(pmode);
+}
+
+int
+PerlLIOUnlink(struct IPerlLIO* piPerl, const char *filename)
+{
+    return nw_unlink(filename);
+}
+
+int
+PerlLIOUtime(struct IPerlLIO* piPerl, char *filename, struct utimbuf *times)
+{
+    return nw_utime(filename, times);
+}
+
+int
+PerlLIOWrite(struct IPerlLIO* piPerl, int handle, const void *buffer, unsigned int count)
+{
+    return nw_write(handle, buffer, count);
+}
+
+/* IPerlLIO    - Low-level IO functions - End   =============================================*/
+
+/* IPerlMem - Memory management functions - Begin ========================================*/
+
+void*
+PerlMemMalloc(struct IPerlMem* piPerl, size_t size)
+{
+       void *ptr = NULL;
+       ptr = malloc(size);
+       if (ptr) {
+               void **listptr;
+               BOOL m_dontTouchHashLists;
+               if(fnGetHashListAddrs(&listptr,&m_dontTouchHashLists)) {
+                       if (listptr) {
+                               WCValHashTable<void*>* m_allocList= (WCValHashTable<void*>*)listptr;
+                               (WCValHashTable<void*>*)m_allocList->insert(ptr);
+                       }
+               }
+       }
+       return(ptr);
+}
+
+void*
+PerlMemRealloc(struct IPerlMem* piPerl, void* ptr, size_t size)
+{
+       void *newptr = NULL;
+       WCValHashTable<void*>* m_allocList;
+
+       newptr = realloc(ptr, size);
+
+       if (ptr)
+       {
+               void **listptr;
+               BOOL m_dontTouchHashLists;
+               if(fnGetHashListAddrs(&listptr,&m_dontTouchHashLists)) {
+                       m_allocList= (WCValHashTable<void*>*)listptr;
+                       (WCValHashTable<void*>*)m_allocList->remove(ptr);
+               }
+       }
+       if (newptr)
+       {
+               if (m_allocList)
+                       (WCValHashTable<void*>*)m_allocList->insert(newptr);
+       }
+
+       return(newptr);
+}
+
+void
+PerlMemFree(struct IPerlMem* piPerl, void* ptr)
+{
+       BOOL m_dontTouchHashLists;
+       WCValHashTable<void*>* m_allocList;
+
+       void **listptr;
+       if(fnGetHashListAddrs(&listptr,&m_dontTouchHashLists)) {
+               m_allocList= (WCValHashTable<void*>*)listptr;
+               // Final clean up, free all the nodes from the hash list
+               if (m_dontTouchHashLists)
+               {
+                       if(ptr)
+                       {
+                               free(ptr);
+                               ptr = NULL;
+                       }
+               }
+               else
+               {
+                       if(ptr && m_allocList)
+                       {
+                               if ((WCValHashTable<void*>*)m_allocList->remove(ptr))
+                               {
+                                       free(ptr);
+                                       ptr = NULL;
+                               }
+                               else
+                               {
+                                       // If it comes here, that means that the memory pointer is not contained in the hash list.
+                                       // But no need to free now, since if is deleted here, it will result in an abend!!
+                                       // If the memory is still there, it will be cleaned during final cleanup anyway.
+                               }
+                       }
+               }
+       }
+       return;
+}
+
+void*
+PerlMemCalloc(struct IPerlMem* piPerl, size_t num, size_t size)
+{
+       void *ptr = NULL;
+
+       ptr = calloc(num, size);
+       if (ptr) {
+               void **listptr;
+               BOOL m_dontTouchHashLists;
+               if(fnGetHashListAddrs(&listptr,&m_dontTouchHashLists)) {
+                       if (listptr) {
+                               WCValHashTable<void*>* m_allocList= (WCValHashTable<void*>*)listptr;
+                               (WCValHashTable<void*>*)m_allocList->insert(ptr);
+                       }
+               }
+       }
+       return(ptr);
+}
+
+/* IPerlMem - Memory management functions - End   ========================================*/
+
+/* IPerlProc - Process control functions - Begin =========================================*/
+
+#define EXECF_EXEC 1
+#define EXECF_SPAWN 2
+
+void
+PerlProcAbort(struct IPerlProc* piPerl)
+{
+    nw_abort();
+}
+
+char *
+PerlProcCrypt(struct IPerlProc* piPerl, const char* clear, const char* salt)
+{
+    return nw_crypt(clear, salt);
+}
+
+void
+PerlProcExit(struct IPerlProc* piPerl, int status)
+{
+//    exit(status);
+       dTHX;
+       dJMPENV;
+       JMPENV_JUMP(2);
+}
+
+void
+PerlProc_Exit(struct IPerlProc* piPerl, int status)
+{
+//    _exit(status);
+       dTHX;
+       dJMPENV;
+       JMPENV_JUMP(2);
+}
+
+int
+PerlProcExecl(struct IPerlProc* piPerl, const char *cmdname, const char *arg0, const char *arg1, const char *arg2, const char *arg3)
+{
+       dTHXo;
+    Perl_croak(aTHX_ "execl not implemented!\n");
+       return 0;
+}
+
+int
+PerlProcExecv(struct IPerlProc* piPerl, const char *cmdname, const char *const *argv)
+{
+    return nw_execvp((char *)cmdname, (char **)argv);
+}
+
+int
+PerlProcExecvp(struct IPerlProc* piPerl, const char *cmdname, const char *const *argv)
+{
+    return nw_execvp((char *)cmdname, (char **)argv);
+}
+
+uid_t
+PerlProcGetuid(struct IPerlProc* piPerl)
+{
+       return 0;
+}
+
+uid_t
+PerlProcGeteuid(struct IPerlProc* piPerl)
+{
+       return 0;
+}
+
+gid_t
+PerlProcGetgid(struct IPerlProc* piPerl)
+{
+       return 0;
+}
+
+gid_t
+PerlProcGetegid(struct IPerlProc* piPerl)
+{
+       return 0;
+}
+
+char *
+PerlProcGetlogin(struct IPerlProc* piPerl)
+{
+       return NULL;
+}
+
+int
+PerlProcKill(struct IPerlProc* piPerl, int pid, int sig)
+{
+    return nw_kill(pid, sig);
+}
+
+int
+PerlProcKillpg(struct IPerlProc* piPerl, int pid, int sig)
+{
+    dTHXo;
+    Perl_croak(aTHX_ "killpg not implemented!\n");
+    return 0;
+}
+
+int
+PerlProcPauseProc(struct IPerlProc* piPerl)
+{
+    return nw_sleep((32767L << 16) + 32767);
+}
+
+PerlIO*
+PerlProcPopen(struct IPerlProc* piPerl, const char *command, const char *mode)
+{
+    dTHXo;
+    PERL_FLUSHALL_FOR_CHILD;
+
+       return (PerlIO*)nw_Popen((char *)command, (char *)mode, (int *)errno);
+}
+
+int
+PerlProcPclose(struct IPerlProc* piPerl, PerlIO *stream)
+{
+    return nw_Pclose((FILE*)stream, (int *)errno);
+}
+
+int
+PerlProcPipe(struct IPerlProc* piPerl, int *phandles)
+{
+    return nw_Pipe((int *)phandles, (int *)errno);
+}
+
+int
+PerlProcSetuid(struct IPerlProc* piPerl, uid_t u)
+{
+       return 0;
+}
+
+int
+PerlProcSetgid(struct IPerlProc* piPerl, gid_t g)
+{
+       return 0;
+}
+
+int
+PerlProcSleep(struct IPerlProc* piPerl, unsigned int s)
+{
+    return nw_sleep(s);
+}
+
+int
+PerlProcTimes(struct IPerlProc* piPerl, struct tms *timebuf)
+{
+    return nw_times(timebuf);
+}
+
+int
+PerlProcWait(struct IPerlProc* piPerl, int *status)
+{
+    return nw_wait(status);
+}
+
+int
+PerlProcWaitpid(struct IPerlProc* piPerl, int pid, int *status, int flags)
+{
+    return nw_waitpid(pid, status, flags);
+}
+
+Sighandler_t
+PerlProcSignal(struct IPerlProc* piPerl, int sig, Sighandler_t subcode)
+{
+    return 0;
+}
+
+int
+PerlProcFork(struct IPerlProc* piPerl)
+{
+       return 0;
+}
+
+int
+PerlProcGetpid(struct IPerlProc* piPerl)
+{
+    return nw_getpid();
+}
+
+/*BOOL
+PerlProcDoCmd(struct IPerlProc* piPerl, char *cmd)
+{
+    do_spawn2(cmd, EXECF_EXEC);
+    return FALSE;
+}*/
+
+int
+PerlProcSpawn(struct IPerlProc* piPerl, char* cmds)
+{
+    return do_spawn2(cmds, EXECF_SPAWN);
+}
+
+int
+PerlProcSpawnvp(struct IPerlProc* piPerl, int mode, const char *cmdname, const char *const *argv)
+{
+    return nw_spawnvp(mode, (char *)cmdname, (char **)argv);
+}
+
+int
+PerlProcASpawn(struct IPerlProc* piPerl, void *vreally, void **vmark, void **vsp)
+{
+    return do_aspawn(vreally, vmark, vsp);
+}
+
+/* IPerlProc - Process control functions - End   =========================================*/
+
+/* IPerlSock - Socket functions - Begin ==================================================*/
+
+u_long
+PerlSockHtonl(struct IPerlSock* piPerl, u_long hostlong)
+{
+       return(nw_htonl(hostlong));
+}
+
+u_short
+PerlSockHtons(struct IPerlSock* piPerl, u_short hostshort)
+{
+       return(nw_htons(hostshort));
+}
+
+u_long
+PerlSockNtohl(struct IPerlSock* piPerl, u_long netlong)
+{
+       return nw_ntohl(netlong);
+}
+
+u_short
+PerlSockNtohs(struct IPerlSock* piPerl, u_short netshort)
+{
+       return nw_ntohs(netshort);
+}
+
+SOCKET PerlSockAccept(struct IPerlSock* piPerl, SOCKET s, struct sockaddr* addr, int* addrlen)
+{
+       return nw_accept(s, addr, addrlen);
+}
+
+int
+PerlSockBind(struct IPerlSock* piPerl, SOCKET s, const struct sockaddr* name, int namelen)
+{
+       return nw_bind(s, name, namelen);
+}
+
+int
+PerlSockConnect(struct IPerlSock* piPerl, SOCKET s, const struct sockaddr* name, int namelen)
+{
+       return nw_connect(s, name, namelen);
+}
+
+void
+PerlSockEndhostent(struct IPerlSock* piPerl)
+{
+    nw_endhostent();
+}
+
+void
+PerlSockEndnetent(struct IPerlSock* piPerl)
+{
+    nw_endnetent();
+}
+
+void
+PerlSockEndprotoent(struct IPerlSock* piPerl)
+{
+    nw_endprotoent();
+}
+
+void
+PerlSockEndservent(struct IPerlSock* piPerl)
+{
+    nw_endservent();
+}
+
+struct hostent*
+PerlSockGethostbyaddr(struct IPerlSock* piPerl, const char* addr, int len, int type)
+{
+       return(nw_gethostbyaddr(addr,len,type));
+}
+
+struct hostent*
+PerlSockGethostbyname(struct IPerlSock* piPerl, const char* name)
+{
+    return nw_gethostbyname(name);
+}
+
+struct hostent*
+PerlSockGethostent(struct IPerlSock* piPerl)
+{
+       return(nw_gethostent());
+}
+
+int
+PerlSockGethostname(struct IPerlSock* piPerl, char* name, int namelen)
+{
+       return nw_gethostname(name,namelen);
+}
+
+struct netent *
+PerlSockGetnetbyaddr(struct IPerlSock* piPerl, long net, int type)
+{
+    return nw_getnetbyaddr(net, type);
+}
+
+struct netent *
+PerlSockGetnetbyname(struct IPerlSock* piPerl, const char *name)
+{
+    return nw_getnetbyname((char*)name);
+}
+
+struct netent *
+PerlSockGetnetent(struct IPerlSock* piPerl)
+{
+    return nw_getnetent();
+}
+
+int PerlSockGetpeername(struct IPerlSock* piPerl, SOCKET s, struct sockaddr* name, int* namelen)
+{
+    return nw_getpeername(s, name, namelen);
+}
+
+struct protoent*
+PerlSockGetprotobyname(struct IPerlSock* piPerl, const char* name)
+{
+    return nw_getprotobyname(name);
+}
+
+struct protoent*
+PerlSockGetprotobynumber(struct IPerlSock* piPerl, int number)
+{
+    return nw_getprotobynumber(number);
+}
+
+struct protoent*
+PerlSockGetprotoent(struct IPerlSock* piPerl)
+{
+    return nw_getprotoent();
+}
+
+struct servent*
+PerlSockGetservbyname(struct IPerlSock* piPerl, const char* name, const char* proto)
+{
+    return nw_getservbyname((char*)name, (char*)proto);
+}
+
+struct servent*
+PerlSockGetservbyport(struct IPerlSock* piPerl, int port, const char* proto)
+{
+       return nw_getservbyport(port, proto);
+}
+
+struct servent*
+PerlSockGetservent(struct IPerlSock* piPerl)
+{
+       return nw_getservent();
+}
+
+int
+PerlSockGetsockname(struct IPerlSock* piPerl, SOCKET s, struct sockaddr* name, int* namelen)
+{
+       return nw_getsockname(s, name, namelen);
+}
+
+int
+PerlSockGetsockopt(struct IPerlSock* piPerl, SOCKET s, int level, int optname, char* optval, int* optlen)
+{
+       return nw_getsockopt(s, level, optname, optval, optlen);
+}
+
+unsigned long
+PerlSockInetAddr(struct IPerlSock* piPerl, const char* cp)
+{
+       return(nw_inet_addr(cp));
+}
+
+char*
+PerlSockInetNtoa(struct IPerlSock* piPerl, struct in_addr in)
+{
+       return NULL;
+}
+
+int
+PerlSockListen(struct IPerlSock* piPerl, SOCKET s, int backlog)
+{
+       return (nw_listen(s, backlog));
+}
+
+int
+PerlSockRecv(struct IPerlSock* piPerl, SOCKET s, char* buffer, int len, int flags)
+{
+       return (nw_recv(s, buffer, len, flags));
+}
+
+int
+PerlSockRecvfrom(struct IPerlSock* piPerl, SOCKET s, char* buffer, int len, int flags, struct sockaddr* from, int* fromlen)
+{
+       return nw_recvfrom(s, buffer, len, flags, from, fromlen);
+}
+
+int
+PerlSockSelect(struct IPerlSock* piPerl, int nfds, char* readfds, char* writefds, char* exceptfds, const struct timeval* timeout)
+{
+       return nw_select(nfds, (fd_set*) readfds, (fd_set*) writefds, (fd_set*) exceptfds, timeout);
+}
+
+int
+PerlSockSend(struct IPerlSock* piPerl, SOCKET s, const char* buffer, int len, int flags)
+{
+       return (nw_send(s, buffer, len, flags));
+}
+
+int
+PerlSockSendto(struct IPerlSock* piPerl, SOCKET s, const char* buffer, int len, int flags, const struct sockaddr* to, int tolen)
+{
+       return(nw_sendto(s, buffer, len, flags, to, tolen));
+}
+
+void
+PerlSockSethostent(struct IPerlSock* piPerl, int stayopen)
+{
+       nw_sethostent(stayopen);
+}
+
+void
+PerlSockSetnetent(struct IPerlSock* piPerl, int stayopen)
+{
+       nw_setnetent(stayopen);
+}
+
+void
+PerlSockSetprotoent(struct IPerlSock* piPerl, int stayopen)
+{
+       nw_setprotoent(stayopen);
+}
+
+void
+PerlSockSetservent(struct IPerlSock* piPerl, int stayopen)
+{
+       nw_setservent(stayopen);
+}
+
+int
+PerlSockSetsockopt(struct IPerlSock* piPerl, SOCKET s, int level, int optname, const char* optval, int optlen)
+{
+       dTHXo;
+    Perl_croak(aTHX_ "setsockopt not implemented!\n");
+       return 0;
+}
+
+int
+PerlSockShutdown(struct IPerlSock* piPerl, SOCKET s, int how)
+{
+       return nw_shutdown(s, how);
+}
+
+SOCKET
+PerlSockSocket(struct IPerlSock* piPerl, int af, int type, int protocol)
+{
+       return nw_socket(af, type, protocol);
+}
+
+int
+PerlSockSocketpair(struct IPerlSock* piPerl, int domain, int type, int protocol, int* fds)
+{
+    dTHXo;
+    Perl_croak(aTHX_ "socketpair not implemented!\n");
+    return 0;
+}
+
+int
+PerlSockIoctlsocket(struct IPerlSock* piPerl, SOCKET s, long cmd, u_long *argp)
+{
+       dTHXo;
+    Perl_croak(aTHX_ "ioctlsocket not implemented!\n");
+       return 0;
+}
+
+/* IPerlSock - Socket functions - End ==================================================*/
+
+/*============================================================================================
+
+ Function              :       fnFreeMemEntry
+
+ Description   :       Called for each outstanding memory allocation at the end of a script run.
+                                       Frees the outstanding allocations
+
+ Parameters    :       ptr     (IN).
+                                       context (IN)
+
+ Returns               :       Nothing.
+
+==============================================================================================*/
+
+void fnFreeMemEntry(void* ptr, void* context)
+{
+       if(ptr)
+       {
+               PerlMemFree(NULL, ptr);
+       }
+}
+/*============================================================================================
+
+ Function              :       fnAllocListHash
+
+ Description   :       Hashing function for hash table of memory allocations.
+
+ Parameters    :       invalue (IN).
+
+ Returns               :       unsigned.
+
+==============================================================================================*/
+
+unsigned fnAllocListHash(void* const& invalue)
+{
+    return (((unsigned) invalue & 0x0000ff00) >> 8);
+}
+
+/*============================================================================================
+
+ Function              :       perl_alloc
+
+ Description   :       creates a Perl interpreter variable and initializes
+
+ Parameters    :       none
+
+ Returns               :       Pointer to Perl interpreter
+
+==============================================================================================*/
+
+EXTERN_C PerlInterpreter*
+perl_alloc(void)
+{
+    PerlInterpreter* my_perl = NULL;
+
+       WCValHashTable<void*>*  m_allocList;
+       m_allocList = new WCValHashTable<void*> (fnAllocListHash, 256);
+       fnInsertHashListAddrs(m_allocList, FALSE);
+
+       my_perl = perl_alloc_using(&perlMem,
+                                  NULL,
+                                  NULL,
+                                  &perlEnv,
+                                  &perlStdIO,
+                                  &perlLIO,
+                                  &perlDir,
+                                  &perlSock,
+                                  &perlProc);
+       if (my_perl) {
+#ifdef PERL_OBJECT
+           CPerlObj* pPerl = (CPerlObj*)my_perl;
+#endif
+               //w32_internal_host = m_allocList;
+       }
+    return my_perl;
+}
+
+/*============================================================================================
+
+ Function              :       nw5_delete_internal_host
+
+ Description   :       Deletes the alloc_list pointer
+
+ Parameters    :       alloc_list pointer
+
+ Returns               :       none
+
+==============================================================================================*/
+
+EXTERN_C void
+nw5_delete_internal_host(void *h)
+{
+       WCValHashTable<void*>*  m_allocList;
+       void **listptr;
+       BOOL m_dontTouchHashLists;
+       if (fnGetHashListAddrs(&listptr,&m_dontTouchHashLists)) {
+               m_allocList = (WCValHashTable<void*>*)listptr;
+               fnInsertHashListAddrs(m_allocList, TRUE);
+               if (m_allocList)
+               {
+                       m_allocList->forAll(fnFreeMemEntry, NULL);
+                       fnInsertHashListAddrs(NULL, FALSE);
+                       delete m_allocList;
+               }
+       }
+}
+
+#endif /* PERL_IMPLICIT_SYS */
diff --git a/NetWare/nwperlsys.h b/NetWare/nwperlsys.h
new file mode 100644 (file)
index 0000000..b8c9790
--- /dev/null
@@ -0,0 +1,422 @@
+/*
+ * Copyright Â© 2001 Novell, Inc. All Rights Reserved.
+ *
+ * You may distribute under the terms of either the GNU General Public
+ * License or the Artistic License, as specified in the README file.
+ *
+ */
+
+/*
+ * FILENAME            :       nwperlsys.h
+ * DESCRIPTION :       Derives from iperlsys.h and define the platform specific function
+ * Author              :       SGP
+ * Date        Created :       June 12th 2001.
+ * Date Modified:
+ */
+
+#ifndef ___NWPerlSys_H___
+#define ___NWPerlSys_H___
+
+
+#include "iperlsys.h"
+
+//Socket related calls
+#include "nw5sck.h"
+
+//Store the Watcom hash list
+#include "nwtinfo.h"
+
+//Watcom hash list
+#include <wchash.h>
+
+/* IPerlMem - Memory management - Begin ==================================================*/
+
+void* PerlMemMalloc(struct IPerlMem* piPerl, size_t size);
+void* PerlMemRealloc(struct IPerlMem* piPerl, void* ptr, size_t size);
+void  PerlMemFree(struct IPerlMem* piPerl, void* ptr);
+void* PerlMemCalloc(struct IPerlMem* piPerl, size_t num, size_t size);
+
+struct IPerlMem perlMem =
+{
+    PerlMemMalloc,
+    PerlMemRealloc,
+    PerlMemFree,
+    PerlMemCalloc,
+};
+
+/* IPerlMem - Memory management - End   ==================================================*/
+
+/* IPerlDir    - Directory Manipulation - Begin =============================================*/
+
+int PerlDirMakedir(struct IPerlDir* piPerl, const char *dirname, int mode);
+int PerlDirChdir(struct IPerlDir* piPerl, const char *dirname);
+int PerlDirRmdir(struct IPerlDir* piPerl, const char *dirname);
+int PerlDirClose(struct IPerlDir* piPerl, DIR *dirp);
+DIR* PerlDirOpen(struct IPerlDir* piPerl, char *filename);
+struct direct * PerlDirRead(struct IPerlDir* piPerl, DIR *dirp);
+void PerlDirRewind(struct IPerlDir* piPerl, DIR *dirp);
+void PerlDirSeek(struct IPerlDir* piPerl, DIR *dirp, long loc);
+long PerlDirTell(struct IPerlDir* piPerl, DIR *dirp);
+
+struct IPerlDir perlDir =
+{
+       PerlDirMakedir,
+    PerlDirChdir,
+    PerlDirRmdir,
+    PerlDirClose,
+    PerlDirOpen,
+    PerlDirRead,
+    PerlDirRewind,
+    PerlDirSeek,
+    PerlDirTell,
+};
+
+/* IPerlDir    - Directory Manipulation - End   =============================================*/
+
+/* IPerlEnv    - Environment related functions - Begin ======================================*/
+
+char* PerlEnvGetenv(struct IPerlEnv* piPerl, const char *varname);
+int PerlEnvPutenv(struct IPerlEnv* piPerl, const char *envstring);
+char* PerlEnvGetenv_len(struct IPerlEnv* piPerl, const char* varname, unsigned long* len);
+int PerlEnvUname(struct IPerlEnv* piPerl, struct utsname *name);
+void PerlEnvClearenv(struct IPerlEnv* piPerl);
+
+//Uncomment the following prototypes and the function names in the structure below
+//whenever it is implemented.
+//The function definition to be put in nwperlsys.c
+
+/*void* PerlEnvGetChildenv(struct IPerlEnv* piPerl);
+void PerlEnvFreeChildenv(struct IPerlEnv* piPerl, void* childEnv);
+char* PerlEnvGetChilddir(struct IPerlEnv* piPerl);
+void PerlEnvFreeChilddir(struct IPerlEnv* piPerl, char* childDir);*/
+
+struct IPerlEnv perlEnv = 
+{
+       PerlEnvGetenv,
+       PerlEnvPutenv,
+    PerlEnvGetenv_len,
+    PerlEnvUname,
+    PerlEnvClearenv,
+/*    PerlEnvGetChildenv,
+    PerlEnvFreeChildenv,
+    PerlEnvGetChilddir,
+    PerlEnvFreeChilddir,*/
+};
+
+/* IPerlEnv    - Environment related functions - Begin ======================================*/
+
+/* IPerlStdio  - Stdio functions - Begin ================================================*/
+
+FILE* PerlStdIOStdin(struct IPerlStdIO* piPerl);
+FILE* PerlStdIOStdout(struct IPerlStdIO* piPerl);
+FILE* PerlStdIOStderr(struct IPerlStdIO* piPerl);
+FILE* PerlStdIOOpen(struct IPerlStdIO* piPerl, const char *path, const char *mode);
+int PerlStdIOClose(struct IPerlStdIO* piPerl, FILE* pf);
+int PerlStdIOEof(struct IPerlStdIO* piPerl, FILE* pf);
+int PerlStdIOError(struct IPerlStdIO* piPerl, FILE* pf);
+void PerlStdIOClearerr(struct IPerlStdIO* piPerl, FILE* pf);
+int PerlStdIOGetc(struct IPerlStdIO* piPerl, FILE* pf);
+char* PerlStdIOGetBase(struct IPerlStdIO* piPerl, FILE* pf);
+int PerlStdIOGetBufsiz(struct IPerlStdIO* piPerl, FILE* pf);
+int PerlStdIOGetCnt(struct IPerlStdIO* piPerl, FILE* pf);
+char* PerlStdIOGetPtr(struct IPerlStdIO* piPerl, FILE* pf);
+char* PerlStdIOGets(struct IPerlStdIO* piPerl, FILE* pf, char* s, int n);
+int PerlStdIOPutc(struct IPerlStdIO* piPerl, FILE* pf, int c);
+int PerlStdIOPuts(struct IPerlStdIO* piPerl, FILE* pf, const char *s);
+int PerlStdIOFlush(struct IPerlStdIO* piPerl, FILE* pf);
+int PerlStdIOUngetc(struct IPerlStdIO* piPerl, int c, FILE* pf);
+int PerlStdIOFileno(struct IPerlStdIO* piPerl, FILE* pf);
+FILE* PerlStdIOFdopen(struct IPerlStdIO* piPerl, int fd, const char *mode);
+FILE* PerlStdIOReopen(struct IPerlStdIO* piPerl, const char*path, const char*mode, FILE* pf);
+SSize_t PerlStdIORead(struct IPerlStdIO* piPerl, void *buffer, Size_t size, Size_t count, FILE* pf);
+SSize_t PerlStdIOWrite(struct IPerlStdIO* piPerl, const void *buffer, Size_t size, Size_t count, FILE* pf);
+void PerlStdIOSetBuf(struct IPerlStdIO* piPerl, FILE* pf, char* buffer);
+int PerlStdIOSetVBuf(struct IPerlStdIO* piPerl, FILE* pf, char* buffer, int type, Size_t size);
+void PerlStdIOSetCnt(struct IPerlStdIO* piPerl, FILE* pf, int n);
+void PerlStdIOSetPtr(struct IPerlStdIO* piPerl, FILE* pf, char * ptr);
+void PerlStdIOSetlinebuf(struct IPerlStdIO* piPerl, FILE* pf);
+int PerlStdIOPrintf(struct IPerlStdIO* piPerl, FILE* pf, const char *format,...);
+int PerlStdIOVprintf(struct IPerlStdIO* piPerl, FILE* pf, const char *format, va_list arglist);
+long PerlStdIOTell(struct IPerlStdIO* piPerl, FILE* pf);
+int PerlStdIOSeek(struct IPerlStdIO* piPerl, FILE* pf, off_t offset, int origin);
+void PerlStdIORewind(struct IPerlStdIO* piPerl, FILE* pf);
+FILE* PerlStdIOTmpfile(struct IPerlStdIO* piPerl);
+int PerlStdIOGetpos(struct IPerlStdIO* piPerl, FILE* pf, Fpos_t *p);
+int PerlStdIOSetpos(struct IPerlStdIO* piPerl, FILE* pf, const Fpos_t *p);
+void PerlStdIOInit(struct IPerlStdIO* piPerl);
+void PerlStdIOInitOSExtras(struct IPerlStdIO* piPerl);
+int PerlStdIOOpenOSfhandle(struct IPerlStdIO* piPerl, long osfhandle, int flags);
+int PerlStdIOGetOSfhandle(struct IPerlStdIO* piPerl, int filenum);
+FILE* PerlStdIOFdupopen(struct IPerlStdIO* piPerl, FILE* pf);
+
+struct IPerlStdIO perlStdIO =
+{
+       PerlStdIOStdin,
+    PerlStdIOStdout,
+    PerlStdIOStderr,
+    PerlStdIOOpen,
+    PerlStdIOClose,
+    PerlStdIOEof,
+    PerlStdIOError,
+    PerlStdIOClearerr,
+    PerlStdIOGetc,
+    PerlStdIOGetBase,
+    PerlStdIOGetBufsiz,
+    PerlStdIOGetCnt,
+    PerlStdIOGetPtr,
+    PerlStdIOGets,
+    PerlStdIOPutc,
+    PerlStdIOPuts,
+    PerlStdIOFlush,
+    PerlStdIOUngetc,
+    PerlStdIOFileno,
+    PerlStdIOFdopen,
+    PerlStdIOReopen,
+    PerlStdIORead,
+    PerlStdIOWrite,
+    PerlStdIOSetBuf,
+    PerlStdIOSetVBuf,
+    PerlStdIOSetCnt,
+    PerlStdIOSetPtr,
+    PerlStdIOSetlinebuf,
+    PerlStdIOPrintf,
+    PerlStdIOVprintf,
+    PerlStdIOTell,
+    PerlStdIOSeek,
+    PerlStdIORewind,
+    PerlStdIOTmpfile,
+    PerlStdIOGetpos,
+    PerlStdIOSetpos,
+    PerlStdIOInit,
+    PerlStdIOInitOSExtras,
+    PerlStdIOFdupopen,
+};
+
+/* IPerlStdio  - Stdio functions - End   ================================================*/
+
+/* IPerlLIO    - Low-level IO functions - Begin =============================================*/
+
+int PerlLIOAccess(struct IPerlLIO* piPerl, const char *path, int mode);
+int PerlLIOChmod(struct IPerlLIO* piPerl, const char *filename, int pmode);
+int PerlLIOChown(struct IPerlLIO* piPerl, const char *filename, uid_t owner, gid_t group);
+int PerlLIOChsize(struct IPerlLIO* piPerl, int handle, long size);
+int PerlLIOClose(struct IPerlLIO* piPerl, int handle);
+int PerlLIODup(struct IPerlLIO* piPerl, int handle);
+int PerlLIODup2(struct IPerlLIO* piPerl, int handle1, int handle2);
+int PerlLIOFlock(struct IPerlLIO* piPerl, int fd, int oper);
+int PerlLIOFileStat(struct IPerlLIO* piPerl, int handle, struct stat *buffer);
+int PerlLIOIOCtl(struct IPerlLIO* piPerl, int i, unsigned int u, char *data);
+int PerlLIOIsatty(struct IPerlLIO* piPerl, int fd);
+int PerlLIOLink(struct IPerlLIO* piPerl, const char*oldname, const char *newname);
+long PerlLIOLseek(struct IPerlLIO* piPerl, int handle, long offset, int origin);
+int PerlLIOLstat(struct IPerlLIO* piPerl, const char *path, struct stat *buffer);
+char* PerlLIOMktemp(struct IPerlLIO* piPerl, char *Template);
+int PerlLIOOpen(struct IPerlLIO* piPerl, const char *filename, int oflag);
+int PerlLIOOpen3(struct IPerlLIO* piPerl, const char *filename, int oflag, int pmode);
+int PerlLIORead(struct IPerlLIO* piPerl, int handle, void *buffer, unsigned int count);
+int PerlLIORename(struct IPerlLIO* piPerl, const char *OldFileName, const char *newname);
+int PerlLIOSetmode(struct IPerlLIO* piPerl, FILE *fp, int mode);
+int PerlLIONameStat(struct IPerlLIO* piPerl, const char *path, struct stat *buffer);
+char* PerlLIOTmpnam(struct IPerlLIO* piPerl, char *string);
+int PerlLIOUmask(struct IPerlLIO* piPerl, int pmode);
+int PerlLIOUnlink(struct IPerlLIO* piPerl, const char *filename);
+int PerlLIOUtime(struct IPerlLIO* piPerl, char *filename, struct utimbuf *times);
+int PerlLIOWrite(struct IPerlLIO* piPerl, int handle, const void *buffer, unsigned int count);
+
+struct IPerlLIO perlLIO =
+{
+       PerlLIOAccess,
+    PerlLIOChmod,
+    PerlLIOChown,
+    PerlLIOChsize,
+    PerlLIOClose,
+    PerlLIODup,
+    PerlLIODup2,
+    PerlLIOFlock,
+    PerlLIOFileStat,
+    PerlLIOIOCtl,
+    PerlLIOIsatty,
+    PerlLIOLink,
+    PerlLIOLseek,
+    PerlLIOLstat,
+    PerlLIOMktemp,
+    PerlLIOOpen,
+    PerlLIOOpen3,
+    PerlLIORead,
+    PerlLIORename,
+    PerlLIOSetmode,
+    PerlLIONameStat,
+    PerlLIOTmpnam,
+    PerlLIOUmask,
+    PerlLIOUnlink,
+    PerlLIOUtime,
+    PerlLIOWrite,    
+};
+
+/* IPerlLIO    - Low-level IO functions - End ==============================================*/
+
+/* IPerlProc - Process control functions - Begin =========================================*/
+
+void PerlProcAbort(struct IPerlProc* piPerl);
+char * PerlProcCrypt(struct IPerlProc* piPerl, const char* clear, const char* salt);
+void PerlProcExit(struct IPerlProc* piPerl, int status);
+void PerlProc_Exit(struct IPerlProc* piPerl, int status);
+int PerlProcExecl(struct IPerlProc* piPerl, const char *cmdname, const char *arg0, const char *arg1, const char *arg2, const char *arg3);
+int PerlProcExecv(struct IPerlProc* piPerl, const char *cmdname, const char *const *argv);
+int PerlProcExecvp(struct IPerlProc* piPerl, const char *cmdname, const char *const *argv);
+uid_t PerlProcGetuid(struct IPerlProc* piPerl);
+uid_t PerlProcGeteuid(struct IPerlProc* piPerl);
+gid_t PerlProcGetgid(struct IPerlProc* piPerl);
+gid_t PerlProcGetegid(struct IPerlProc* piPerl);
+char * PerlProcGetlogin(struct IPerlProc* piPerl);
+int PerlProcKill(struct IPerlProc* piPerl, int pid, int sig);
+int PerlProcKillpg(struct IPerlProc* piPerl, int pid, int sig);
+int PerlProcPauseProc(struct IPerlProc* piPerl);
+PerlIO* PerlProcPopen(struct IPerlProc* piPerl, const char *command, const char *mode);
+int PerlProcPclose(struct IPerlProc* piPerl, PerlIO *stream);
+int PerlProcPipe(struct IPerlProc* piPerl, int *phandles);
+int PerlProcSetuid(struct IPerlProc* piPerl, uid_t u);
+int PerlProcSetgid(struct IPerlProc* piPerl, gid_t g);
+int PerlProcSleep(struct IPerlProc* piPerl, unsigned int s);
+int PerlProcTimes(struct IPerlProc* piPerl, struct tms *timebuf);
+int PerlProcWait(struct IPerlProc* piPerl, int *status);
+int PerlProcWaitpid(struct IPerlProc* piPerl, int pid, int *status, int flags);
+Sighandler_t PerlProcSignal(struct IPerlProc* piPerl, int sig, Sighandler_t subcode);
+int PerlProcFork(struct IPerlProc* piPerl);
+int PerlProcGetpid(struct IPerlProc* piPerl);
+int PerlProcSpawn(struct IPerlProc* piPerl, char* cmds);
+int PerlProcSpawnvp(struct IPerlProc* piPerl, int mode, const char *cmdname, const char *const *argv);
+int PerlProcASpawn(struct IPerlProc* piPerl, void *vreally, void **vmark, void **vsp);
+
+struct IPerlProc perlProc =
+{
+    PerlProcAbort,
+    PerlProcCrypt,
+    PerlProcExit,
+    PerlProc_Exit,
+    PerlProcExecl,
+    PerlProcExecv,
+    PerlProcExecvp,
+    PerlProcGetuid,
+    PerlProcGeteuid,
+    PerlProcGetgid,
+    PerlProcGetegid,
+    PerlProcGetlogin,
+    PerlProcKill,
+    PerlProcKillpg,
+    PerlProcPauseProc,
+    PerlProcPopen,
+    PerlProcPclose,
+    PerlProcPipe,
+    PerlProcSetuid,
+    PerlProcSetgid,
+    PerlProcSleep,
+    PerlProcTimes,
+    PerlProcWait,
+    PerlProcWaitpid,
+    PerlProcSignal,
+    PerlProcFork,
+    PerlProcGetpid,
+    //PerlProcLastHost;
+    //PerlProcPopenList;
+};
+
+/* IPerlProc - Process control functions - End   =========================================*/
+
+/* IPerlSock - Socket functions - Begin ==================================================*/
+
+u_long PerlSockHtonl(struct IPerlSock* piPerl, u_long hostlong);
+u_short PerlSockHtons(struct IPerlSock* piPerl, u_short hostshort);
+u_long PerlSockNtohl(struct IPerlSock* piPerl, u_long netlong);
+u_short PerlSockNtohs(struct IPerlSock* piPerl, u_short netshort);
+SOCKET PerlSockAccept(struct IPerlSock* piPerl, SOCKET s, struct sockaddr* addr, int* addrlen);
+int PerlSockBind(struct IPerlSock* piPerl, SOCKET s, const struct sockaddr* name, int namelen);
+int PerlSockConnect(struct IPerlSock* piPerl, SOCKET s, const struct sockaddr* name, int namelen);
+void PerlSockEndhostent(struct IPerlSock* piPerl);
+void PerlSockEndnetent(struct IPerlSock* piPerl);
+void PerlSockEndprotoent(struct IPerlSock* piPerl);
+void PerlSockEndservent(struct IPerlSock* piPerl);
+struct hostent* PerlSockGethostbyaddr(struct IPerlSock* piPerl, const char* addr, int len, int type);
+struct hostent* PerlSockGethostbyname(struct IPerlSock* piPerl, const char* name);
+struct hostent* PerlSockGethostent(struct IPerlSock* piPerl);
+int PerlSockGethostname(struct IPerlSock* piPerl, char* name, int namelen);
+struct netent * PerlSockGetnetbyaddr(struct IPerlSock* piPerl, long net, int type);
+struct netent * PerlSockGetnetbyname(struct IPerlSock* piPerl, const char *name);
+struct netent * PerlSockGetnetent(struct IPerlSock* piPerl);
+int PerlSockGetpeername(struct IPerlSock* piPerl, SOCKET s, struct sockaddr* name, int* namelen);
+struct protoent* PerlSockGetprotobyname(struct IPerlSock* piPerl, const char* name);
+struct protoent* PerlSockGetprotobynumber(struct IPerlSock* piPerl, int number);
+struct protoent* PerlSockGetprotoent(struct IPerlSock* piPerl);
+struct servent* PerlSockGetservbyname(struct IPerlSock* piPerl, const char* name, const char* proto);
+struct servent* PerlSockGetservbyport(struct IPerlSock* piPerl, int port, const char* proto);
+struct servent* PerlSockGetservent(struct IPerlSock* piPerl);
+int PerlSockGetsockname(struct IPerlSock* piPerl, SOCKET s, struct sockaddr* name, int* namelen);
+int PerlSockGetsockopt(struct IPerlSock* piPerl, SOCKET s, int level, int optname, char* optval, int* optlen);
+unsigned long PerlSockInetAddr(struct IPerlSock* piPerl, const char* cp);
+char* PerlSockInetNtoa(struct IPerlSock* piPerl, struct in_addr in);
+int PerlSockListen(struct IPerlSock* piPerl, SOCKET s, int backlog);
+int PerlSockRecv(struct IPerlSock* piPerl, SOCKET s, char* buffer, int len, int flags);
+int PerlSockRecvfrom(struct IPerlSock* piPerl, SOCKET s, char* buffer, int len, int flags, struct sockaddr* from, int* fromlen);
+int PerlSockSelect(struct IPerlSock* piPerl, int nfds, char* readfds, char* writefds, char* exceptfds, const struct timeval* timeout);
+int PerlSockSend(struct IPerlSock* piPerl, SOCKET s, const char* buffer, int len, int flags);
+int PerlSockSendto(struct IPerlSock* piPerl, SOCKET s, const char* buffer, int len, int flags, const struct sockaddr* to, int tolen);
+void PerlSockSethostent(struct IPerlSock* piPerl, int stayopen);
+void PerlSockSetnetent(struct IPerlSock* piPerl, int stayopen);
+void PerlSockSetprotoent(struct IPerlSock* piPerl, int stayopen);
+void PerlSockSetservent(struct IPerlSock* piPerl, int stayopen);
+int PerlSockSetsockopt(struct IPerlSock* piPerl, SOCKET s, int level, int optname, const char* optval, int optlen);
+int PerlSockShutdown(struct IPerlSock* piPerl, SOCKET s, int how);
+SOCKET PerlSockSocket(struct IPerlSock* piPerl, int af, int type, int protocol);
+int PerlSockSocketpair(struct IPerlSock* piPerl, int domain, int type, int protocol, int* fds);
+int PerlSockIoctlsocket(struct IPerlSock* piPerl, SOCKET s, long cmd, u_long *argp);
+
+struct IPerlSock  perlSock =
+{
+       PerlSockHtonl,
+    PerlSockHtons,
+    PerlSockNtohl,
+    PerlSockNtohs,
+    PerlSockAccept,
+    PerlSockBind,
+    PerlSockConnect,
+    PerlSockEndhostent,
+    PerlSockEndnetent,
+    PerlSockEndprotoent,
+    PerlSockEndservent,
+    PerlSockGethostname,
+    PerlSockGetpeername,
+    PerlSockGethostbyaddr,
+    PerlSockGethostbyname,
+    PerlSockGethostent,
+    PerlSockGetnetbyaddr,
+    PerlSockGetnetbyname,
+    PerlSockGetnetent,
+    PerlSockGetprotobyname,
+    PerlSockGetprotobynumber,
+    PerlSockGetprotoent,
+    PerlSockGetservbyname,
+    PerlSockGetservbyport,
+    PerlSockGetservent,
+    PerlSockGetsockname,
+    PerlSockGetsockopt,
+    PerlSockInetAddr,
+       PerlSockInetNtoa,
+       PerlSockListen,
+    PerlSockRecv,
+    PerlSockRecvfrom,
+    PerlSockSelect,
+    PerlSockSend,
+    PerlSockSendto,
+    PerlSockSethostent,
+    PerlSockSetnetent,
+    PerlSockSetprotoent,
+    PerlSockSetservent,
+    PerlSockSetsockopt,
+    PerlSockShutdown,
+       PerlSockSocket,
+    PerlSockSocketpair,
+};
+
+/* IPerlSock - Socket functions - End ====================================================*/
+
+#endif /* ___NWPerlSys_H___ */
diff --git a/NetWare/nwpipe.h b/NetWare/nwpipe.h
new file mode 100644 (file)
index 0000000..4e9354a
--- /dev/null
@@ -0,0 +1,62 @@
+
+/*
+ * Copyright Â© 2001 Novell, Inc. All Rights Reserved.
+ *
+ * You may distribute under the terms of either the GNU General Public
+ * License or the Artistic License, as specified in the README file.
+ *
+ */
+
+/*
+ * FILENAME            :       NWPipe.h
+ * DESCRIPTION :       Functions to implement pipes on NetWare.
+ * Author              :       HYAK
+ * Date                        :       January 2001.
+ *
+ */
+
+
+
+#ifndef __NWPipe_H__
+#define __NWPipe_H__
+
+
+#include "stdio.h"
+#include "nwutil.h"
+
+#define MAX_PIPE_RECURSION 256
+
+
+typedef struct tagTempPipeFile
+{
+       BOOL    m_mode;         //  FALSE - Read mode  ;  TRUE - Write mode
+       BOOL    m_launchPerl;
+       BOOL    m_doPerlGlob;
+
+       int             m_argv_len;
+
+       char *  m_fileName;
+       char**  m_argv;
+       char *  m_redirect;
+
+       #ifdef MPK_ON
+               SEMAPHORE       m_perlSynchSemaphore;
+       #else
+               long            m_perlSynchSemaphore;
+       #endif
+
+       FILE*   m_file;
+       PCOMMANDLINEPARSER      m_pipeCommand;
+
+} TEMPPIPEFILE, *PTEMPPIPEFILE;
+
+
+void fnPipeFileClose(PTEMPPIPEFILE ptpf);
+void fnPipeFileDoPerlLaunch(PTEMPPIPEFILE ptpf);
+BOOL fnPipeFileMakeArgv(PTEMPPIPEFILE ptpf);
+FILE* fnPipeFileOpen(PTEMPPIPEFILE ptpf, char* command, char* mode);
+void fnTempPipeFileReleaseMemory(PTEMPPIPEFILE ptpf);
+
+
+#endif // __NWPipe_H__
+
diff --git a/NetWare/nwplglob.c b/NetWare/nwplglob.c
new file mode 100644 (file)
index 0000000..c7a2104
--- /dev/null
@@ -0,0 +1,90 @@
+
+/*
+ * Copyright Â© 2001 Novell, Inc. All Rights Reserved.
+ *
+ * You may distribute under the terms of either the GNU General Public
+ * License or the Artistic License, as specified in the README file.
+ *
+ */
+
+/*
+ * FILENAME            :       nwplglob.c
+ * DESCRIPTION :       Perl globbing support for NetWare. Other platforms have usually lauched
+ *                  a separate executable for this in order to take advantage of their
+ *                  shell's capability for generating a list of files from a given
+ *                  wildcard file spec. On NetWare, we don't have that luxury.
+ *                  So we just hack the support into pipe open support (which we also had to hack).
+ * Author              :       HYAK
+ * Date                        :       January 2001.
+ *
+ */
+
+
+
+#include <nwtypes.h>
+#include "stdio.h"
+#include <dirent.h>
+
+#include "win32ish.h"
+#include "nwplglob.h"
+
+
+
+/*============================================================================================
+
+ Function              :       fnDoPerlGlob
+
+ Description   :       Perl globbing support: Takes an array of wildcard descriptors
+                    and produces from it a list of files that the wildcards expand into.
+                                       The list of files is written to the temporary file named by fileName.
+
+ Parameters    :       argv (IN)       -       Input argument vector.
+                    fileName (IN)      -       Input file name for storing globed file names.
+
+ Returns               :       Nothing.
+
+==============================================================================================*/
+
+void fnDoPerlGlob(char** argv, char* fileName)
+{
+       FILE * redirOut = NULL;
+
+       if (*argv)
+               argv++;
+       if (*argv == NULL)
+               return;
+
+       redirOut = fopen((const char *)fileName, (const char *)"w");
+       if (!redirOut)
+               return;
+
+       do
+       {
+               DIR* dir = NULL;
+               DIR* fil = NULL;
+               char* pattern = NULL;
+
+               pattern = *argv++;
+
+               dir = opendir((const char *)pattern);
+               if (!dir)
+                       continue;
+
+               /* find the last separator in pattern, NetWare has three: /\: */
+               while (fil = readdir(dir))
+               {
+                       // The below displays the files separated by tab character.
+                       // Also, it displays only the file names and not directories.
+                       // If any other format is desired, it needs to be done here.
+                       fprintf(redirOut, "%s\t", fil->d_name);
+               }
+
+               closedir(dir);
+
+       } while (*argv);
+
+       fclose(redirOut);
+
+       return;
+}
+
diff --git a/NetWare/nwplglob.h b/NetWare/nwplglob.h
new file mode 100644 (file)
index 0000000..1c9d9e4
--- /dev/null
@@ -0,0 +1,27 @@
+
+/*
+ * Copyright Â© 2001 Novell, Inc. All Rights Reserved.
+ *
+ * You may distribute under the terms of either the GNU General Public
+ * License or the Artistic License, as specified in the README file.
+ *
+ */
+
+/*
+ * FILENAME            :       nwplglob.h
+ * DESCRIPTION :       Perl globbing support for NetWare.
+ * Author              :       HYAK
+ * Date                        :       January 2001.
+ *
+ */
+
+
+#ifndef __NWplGlob_H__
+#define __NWplGlob_H__
+
+
+void fnDoPerlGlob(char** argv, char* fileName);
+
+
+#endif // __NWplGlob_H__
+
diff --git a/NetWare/nwtinfo.h b/NetWare/nwtinfo.h
new file mode 100644 (file)
index 0000000..6930e05
--- /dev/null
@@ -0,0 +1,64 @@
+
+/*
+ * Copyright Â© 2001 Novell, Inc. All Rights Reserved.
+ *
+ * You may distribute under the terms of either the GNU General Public
+ * License or the Artistic License, as specified in the README file.
+ *
+ */
+
+/*
+ * FILENAME            :       NWTInfo.h
+ * DESCRIPTION :       Thread-local storage for Perl.
+ * Author              :       SGP, HYAK
+ * Date                        :       January 2001.
+ *
+ */
+
+
+
+#ifndef __NWTInfo_H__
+#define __NWTInfo_H__
+
+
+#include "win32ish.h"          // For "BOOL", "TRUE" and "FALSE"
+
+typedef struct tagThreadInfo
+{
+       int tid;
+       struct tagThreadInfo *next;
+       BOOL    m_dontTouchHashLists;
+       void*   m_allocList;
+}ThreadInfo;
+
+
+void fnInitializeThreadInfo(void);
+BOOL fnTerminateThreadInfo(void);
+BOOL fnRegisterWithThreadTable(void);
+BOOL fnUnregisterWithThreadTable(void);
+
+ThreadInfo* fnAddThreadInfo(int tid);
+BOOL fnRemoveThreadInfo(int tid);
+ThreadInfo* fnGetThreadInfo(int tid);
+
+//For storing and retrieving Watcom Hash list address
+BOOL fnInsertHashListAddrs(void *addrs, BOOL dontTouchHashList);
+BOOL fnGetHashListAddrs(void **addrs, BOOL *dontTouchHashList);
+
+//New TLS to set and get the thread contex - may be redundant,
+//or see if the above portion can be removed once this works properly
+typedef struct tagThreadCtx
+{
+       long tid;
+       void *tInfo;
+       struct tagThreadCtx *next;
+}ThreadContext;
+
+
+long fnInitializeThreadCtx(void);
+ThreadContext* fnAddThreadCtx(long lTLSIndex, void *t);
+BOOL fnRemoveThreadCtx(long lTLSIndex);
+void* fnGetThreadCtx(long lTLSIndex);
+
+#endif // __NWTInfo_H__
+
diff --git a/NetWare/nwutil.h b/NetWare/nwutil.h
new file mode 100644 (file)
index 0000000..a2e35ec
--- /dev/null
@@ -0,0 +1,99 @@
+
+/*
+ * Copyright Â© 2001 Novell, Inc. All Rights Reserved.
+ *
+ * You may distribute under the terms of either the GNU General Public
+ * License or the Artistic License, as specified in the README file.
+ *
+ */
+
+/*
+ * FILENAME            :       NWUtil.h
+ * DESCRIPTION :       Utility functions for NetWare implementation of Perl.
+ * Author              :       HYAK, SGP
+ * Date                        :       January 2001.
+ *
+ */
+
+
+
+#ifndef __NWUtil_H__
+#define __NWUtil_H__
+
+
+#include "stdio.h"
+#include <stdlib.h>
+#include "win32ish.h"          // For "BOOL", "TRUE" and "FALSE"
+
+
+#ifdef MPK_ON
+       #include <mpktypes.h>   
+       #include <mpkapis.h>
+#else
+       #include <nwsemaph.h>
+#endif //MPK_ON
+
+
+// Name of console command to invoke perl
+#define PERL_COMMAND_NAME "perl"
+
+// Name of console command to load an NLM
+#define LOAD_COMMAND "load"
+
+
+typedef struct tagCommandLineParser
+{
+       BOOL    m_noScreen;
+       BOOL    m_AutoDestroy;
+       BOOL    m_isValid;
+
+       int         m_argc;
+       int     m_argv_len;
+       
+       #ifdef MPK_ON
+               SEMAPHORE       m_qSemaphore;
+       #else
+               long        m_qSemaphore;
+       #endif
+
+       char*   m_redirInName;
+       char*   m_redirOutName;
+       char*   m_redirErrName;
+       char*   m_redirBothName;
+       char*   nextarg;
+       char*   sSkippedToken;
+
+       char**  m_argv;
+       char**  new_argv;
+
+}COMMANDLINEPARSER, *PCOMMANDLINEPARSER;
+
+
+
+char* fnSkipWhite(char* cptr);
+char* fnNwGetEnvironmentStr(char *name, char *defaultvalue);
+char* fnSkipToken(char *s, char *r);
+char* fnScanToken(char* x, char *r);
+char* fnStashString(char *s, char *r, int length);
+void fnAppendArgument(PCOMMANDLINEPARSER pclp, char * new_arg);
+void fnDeleteArgument(PCOMMANDLINEPARSER pclp, int index);
+void fnCommandLineParser(PCOMMANDLINEPARSER pclp, char * commandLine, BOOL preserveQuotes);
+void fnSystemCommand (char** argv, int argc);
+void fnInternalPerlLaunchHandler(char* cmdLine);
+char* fnMy_MkTemp(char* templatestr);
+
+
+/* DEFPERLROOT:
+ *  This symbol contains the name of the starting default directory to search
+ *  for scripts to run.
+ */
+#define DEFPERLROOT "sys:\\perl\\scripts"
+
+/* DEFTEMP:
+ *  This symbol contains the name of the default temp files directory.
+ */
+#define DEFTEMP "sys:\\perl\\temp"
+
+
+#endif // __NWUtil_H__
+
diff --git a/NetWare/t/NWModify.pl b/NetWare/t/NWModify.pl
new file mode 100644 (file)
index 0000000..12521d7
--- /dev/null
@@ -0,0 +1,132 @@
+
+
+print "\nModifying the '.t' files...\n\n";
+
+use File::Basename;
+use File::Copy;
+
+## Change the below line to the directory you want to process
+$DirName = "/perl/scripts/t";
+
+$FilesTotal = 0;
+$FilesRead = 0;
+$FilesModified = 0;
+
+opendir(DIR, $DirName) or die "Unable to open the directory, $DirName  for reading.\n";
+@Dirs = readdir(DIR);
+
+foreach $DirItem(@Dirs)
+{
+       $DirItem = $DirName."/".$DirItem;
+       push @DirNames, $DirItem;       # All items under  $DirName  directory is copied into an array.
+}
+
+foreach $FileName(@DirNames)
+{
+       if(-d $FileName)
+       {       # If an item is a directory, then open it further.
+
+               opendir(SUBDIR, $FileName) or die "Unable to open the directory, $FileName  for reading.\n";
+               @SubDirs = readdir(SUBDIR);
+               close(SUBDIR);
+
+               foreach $SubFileName(@SubDirs)
+               {
+                       if(-f $SubFileName)
+                       {
+                               &Process_File($SubFileName);    # If file, process it.
+                       }
+                       else
+                       {
+                               $SubFileName = $FileName."/".$SubFileName;
+                               push @DirNames, $SubFileName;   # If sub-directory, push it into the array.
+                       }
+               }
+       }
+       else
+       {
+               if(-f $FileName)
+               {
+                       &Process_File($FileName);       # If file, process it.
+               }
+       }
+}
+
+close(DIR);
+
+print "\n\n\nTotal number of files present = $FilesTotal\n";
+print "Total number of '.t' files read = $FilesRead\n";
+print "Total number of '.t' files modified = $FilesModified\n\n";
+
+
+
+
+# Process the file.
+sub Process_File
+{
+       local($FileToProcess) = @_;             # File name.
+       local($Modified) = 0;
+
+
+       if(!(-w $FileToProcess)) {
+               # If the file is a read-only file, then change its mode to read-write.
+               chmod(0777, $FileToProcess);
+       }
+
+
+       $base = basename($FileToProcess);       # Get the base name
+       $dir = dirname($FileToProcess);         # Get the directory name
+       ($base, $dir, $ext) = fileparse($FileToProcess, '\..*');        # Get the extension of the file passed.
+
+       ## If the value of $FileToProcess is '/perl/scripts/t/pragma/warnings.t', then
+               ## $dir = '/perl/scripts/t/pragma/'
+               ## $base = 'warnings'
+               ## $ext = '.t'
+
+
+       # Do the processing only if the file has '.t' extension.
+       if($ext eq '.t') {
+
+               open(FH, "+< $FileToProcess") or die "Unable to open the file,  $FileToProcess  for reading and writing.\n";
+               @ARRAY = <FH>;  # Get the contents of the file into an array.
+
+               flock(FH, LOCK_EX);             # Lock the file for safety purposes.
+               foreach $Line(@ARRAY)   # Get each line of the file.
+               {
+                       if($Line =~ m/\@INC = /)
+                       {       # If the line contains the string (@INC = ), then replace it
+
+                               # Replace "@INC = " with "unshift @INC, "
+                               $Line =~ s/\@INC = /unshift \@INC, /;
+
+                               $Modified = 1;
+                       }
+
+                       if($Line =~ m/push \@INC, /)
+                       {       # If the line contains the string (push @INC, ), then replace it
+
+                               # Replace "push @INC, " with "unshift @INC, "
+                               $Line =~ s/push \@INC, /unshift \@INC, /;
+
+                               $Modified = 1;
+                       }
+               }
+
+               seek(FH, 0, 0);         # Seek to the beginning.
+               print FH @ARRAY;        # Write the changed array into the file.
+               flock(FH, LOCK_UN);     # unlock the file.
+               close FH;                       # close the file.
+
+               $FilesRead++;   # One more file read.
+
+               if($Modified) {
+                       print "Modified the file,  $FileToProcess\n";
+                       $Modified = 0;
+
+                       $FilesModified++;       # One more file modified.
+               }
+       }
+
+       $FilesTotal++;  # One more file present.
+}
+
diff --git a/NetWare/t/NWScripts.pl b/NetWare/t/NWScripts.pl
new file mode 100644 (file)
index 0000000..36ca8ec
--- /dev/null
@@ -0,0 +1,158 @@
+
+
+print "\nGenerating automated scripts for NetWare...\n\n\n";
+
+
+use File::Basename;
+use File::Copy;
+
+chdir '/perl/scripts/';
+$DirName = "t";
+
+
+# These scripts have problems (either abend or hang) as of now (11 May 2001).
+# So, they are commented out in the corresponding auto scripts, io.pl and lib.pl
+@ScriptsNotUsed = ("t/io/argv.t", "t/io/openpid.t", "t/lib/filehand.t");
+
+
+print "Generating  t/auto.pl ...\n\n\n";
+
+open(FHWA, "> t/auto.pl") or die "Unable to open the file,  t/auto.pl  for writing.\n";
+seek(FHWA, 0 ,0);
+flock(FHWA, LOCK_EX);          # Lock the file for safety purposes.
+
+$version = sprintf("%vd",$^V);
+print FHWA "\n\nprint \"Automated Unit Testing of Perl$version\\n\\n\\n\"\;\n\n\n";
+
+
+opendir(DIR, $DirName) or die "Unable to open the directory, $DirName  for reading.\n";
+@Dirs = readdir(DIR);
+
+foreach $DirItem(@Dirs)
+{
+       $DirItem = $DirName."/".$DirItem;
+       push @DirNames, $DirItem;       # All items under  $DirName  directory is copied into an array.
+}
+
+foreach $FileName(@DirNames)
+{
+       if(-d $FileName)
+       {       # If an item is a directory, then open it further.
+
+               opendir(SUBDIR, $FileName) or die "Unable to open the directory, $FileName  for reading.\n";
+               @SubDirs = readdir(SUBDIR);
+               close(SUBDIR);
+
+
+               $base = basename($FileName);    # Get the base name
+               $dir = dirname($FileName);              # Get the directory name
+               ($base, $dir, $ext) = fileparse($FileName, '\..*');     # Get the extension of the file passed.
+
+               # Intemediary automated script like base.pl, lib.pl, cmd.pl etc.
+               $IntAutoScript = "t/".$base.".pl";
+
+
+               # Write into auto.pl
+               print FHWA "print \`perl $IntAutoScript\`\;\n";
+               print FHWA "print \"\\n\\n\\n\"\;\n\n";
+
+               
+               print "Generating  $IntAutoScript...\n";
+               # Write into the intermediary auto script.
+               open(FHW, "> $IntAutoScript") or die "Unable to open the file,  $IntAutoScript  for writing.\n";
+               seek(FHW, 0 ,0);
+               flock(FHW, LOCK_EX);            # Lock the file for safety purposes.
+
+               print FHW "\n\nprint \"Testing  $base  directory:\\n\\n\\n\"\;\n\n\n";
+
+
+               foreach $SubFileName(@SubDirs)
+               {
+                       if(-d $SubFileName)
+                       {
+                               $SubFileName = $FileName."/".$SubFileName;
+                               push @DirNames, $SubFileName;   # If sub-directory, push it into the array.
+                       }
+                       else
+                       {
+                               $SubFileName = $FileName."/".$SubFileName;
+                               &Process_File($SubFileName);    # If file, process it.
+                       }
+               }
+
+               # Write into the intermediary auto script.
+               print FHW "\nprint \"Testing of  $base  directory done!\\n\\n\"\;\n\n";
+
+               flock(FHW, LOCK_UN);    # unlock the file.
+               close FHW;                      # close the file.
+               print "$IntAutoScript Done!\n\n";
+       }
+}
+
+close(DIR);
+
+
+# Write into  auto.pl
+print FHWA "\nprint \"Automated Unit Testing of Perl$version  done!\\n\\n\"\;\n\n";
+
+flock(FHWA, LOCK_UN);  # unlock the file.
+close FHWA;                    # close the file.
+
+print "\nt/auto.pl Done!\n\n";
+
+
+print "\nGeneration of automated scripts for NetWare  DONE!\n";
+
+
+
+# Process the file.
+sub Process_File
+{
+       local($FileToProcess) = @_;             # File name.
+       local($Script) = 0;
+       local($HeadCut) = 0;
+
+
+       $base1 = basename($FileToProcess);      # Get the base name
+       $dir1 = dirname($FileToProcess);                # Get the directory name
+       ($base1, $dir1, $ext1) = fileparse($FileToProcess, '\..*');     # Get the extension of the file passed.
+
+       ## If the value of $FileToProcess is '/perl/scripts/t/pragma/warnings.t', then
+               ## $dir1 = '/perl/scripts/t/pragma/'
+               ## $base1 = 'warnings'
+               ## $ext1 = '.t'
+
+
+       # Do the processing only if the file has '.t' extension.
+       if($ext1 eq '.t')
+       {
+               foreach $Script(@ScriptsNotUsed)
+               {
+                       if($Script eq $FileToProcess)
+                       {
+                               $HeadCut = 1;
+                       }
+               }
+
+               if($HeadCut)
+               {
+                       # Write into the intermediary auto script.
+                       print FHW "=head\n";
+               }
+
+               # Write into the intermediary auto script.
+               print FHW "print \"Testing  $base1"."$ext1:\\n\\n\"\;\n";
+               print FHW "print \`perl $FileToProcess\`\;\n";  # Write the changed array into the file.
+               print FHW "print \"\\n\\n\\n\"\;\n";
+
+               if($HeadCut)
+               {
+                       # Write into the intermediary auto script.
+                       print FHW "=cut\n";
+               }
+
+               $HeadCut = 0;
+               print FHW "\n";
+       }
+}
+
diff --git a/NetWare/t/Readme.txt b/NetWare/t/Readme.txt
new file mode 100644 (file)
index 0000000..148fa2d
--- /dev/null
@@ -0,0 +1,58 @@
+
+
+               Automated Testing of Perl5.6.1 Interpreter for NetWare.
+
+
+
+A set of Standard Unit Test Scripts to test all the functionalities of Perl 5.6.1 Interpreter are available along with the CPAN download. They are all located under 't' folder. These include sub-folders under 't' folder: 'base', 'cmd', 'comp', 'io', lib', 'op', 'pod', 'pragma', 'run'. Each of these sub-folders contain few test scripts ('.t' files) under them.
+
+Executing these test scripts on NetWare can be automated as per the following:
+
+1. Automated scripts, 'base.pl', 'cmd.pl', 'comp.pl', 'io.pl', 'lib.pl', 'op.pl', 'pod.pl', 'pragma.pl', 'run.pl' can be generated that are used to execute all the test scripts ('.t' files) under the corresponding folder.
+For example, 'base.pl' tests all the test scripts under 'sys:\perl\scripts\t\base' folder, 'comp.pl' test all scripts under 'sys:\perl\scripts\t\comp' folder and so on.
+
+2. An automated script, 'auto.pl' can also be generated that executes all the above mentioned '.pl' automated scripts, thus executing all the '.t' scripts.
+
+There is a script 'NWScripts.pl' available under the 'NetWare\t' folder of the CPAN download. This is written to generate these automated scripts when executed on a NetWare server. It generates the automated scripts, 'base.pl', 'cmd.pl', 'comp.pl', 'io.pl', 'lib.pl', 'op.pl', 'pod.pl', 'pragma.pl', 'run.pl' and also 'auto.pl' by including all the corresponding '.t' scripts in them. For example, all the scripts that are under 't\base' folder will be entered in 'base.pl' and so on. 'auto.pl will include all these '.pl' scripts like 'base.pl', 'comp.pl' etc.
+
+
+The following steps elicits the procedure for executing the automated scripts:
+
+1. Copy the 't' folder from the CPAN download to 'sys:\perl\scripts' folder on the NetWare server.
+
+2. Copy all the files from 'NetWare\t' folder of the CPAN download into 'sys:\perl\scripts\t' folder.
+
+3. Execute the command  "perl t\NWModify.pl" on the console command prompt. This script replaces 
+     "@INC = " with "unshift @INC, "  and
+     "push @INC, " with "unshift @INC, "
+   from all the scripts under 'sys:\perl\scripts\t' folder.
+
+This is done to include the correct path for libraries into the scripts when executed on NetWare. If this is not done, some of the scripts will not get executed since they cannot locate the corresponding libraries.
+
+4. Execute the command  "perl t\NWScripts.pl" on the console command prompt to generate the automated scripts mentioned above under the 'sys:\perl\scripts\t' folder.
+   (See above for details).
+
+5. Execute 'auto.pl' script using the server console command, "perl t\auto.pl" to run all the standard test scripts. If you want the results to be redirected into a file, say 'auto.txt', then the console command is:  "perl t\auto.pl > auto.txt"
+
+6. If you want to execute certain set of scripts, then run the corresponding '.pl' file. For example, if you want to execute only the 'lib' scripts, then execute 'run.pl' through the server console command, "perl t\run.pl'. To redirect the results into a file, the console command could be, "perl t\run.pl > run.txt".
+
+
+Known Issues:
+
+The following scripts are commented out in the corresponding autoscript:
+
+1. 'openpid.t' in 'sys:\perl\scripts\t\io.pl' script
+   Reason:
+     This either hangs or abends the server when executing through auto scripts.
+     When run individually, the script execution goes through fine.
+
+2. 'argv.t' in 'sys:\perl\scripts\t\io.pl' script
+   Reason:
+     This either hangs or abends the server when executing through auto scripts.
+     When run individually, the script execution goes through fine.
+
+3. 'filehand.t' in 'sys:\perl\scripts\t\lib.pl' script
+   Reason:
+     This hangs in the last test case where it uses FileHandle::Pipe whether run individually
+     or through an auto script.
+
diff --git a/NetWare/testnlm/echo/echo.c b/NetWare/testnlm/echo/echo.c
new file mode 100644 (file)
index 0000000..fe468c3
--- /dev/null
@@ -0,0 +1,31 @@
+/**********************************************************************
+*
+*      C Source:               echo.c
+*      Instance:               idc_rads_2
+*      Description:    DOS echo Emulation
+*      %created_by:    smscm %
+*      %date_created:  Fri Apr 20 19:05:31 2001 %
+*
+**********************************************************************/
+#ifndef lint
+static char *_csrc = "@(#) %filespec: echo.c~1 %  (%full_filespec: echo.c~1:csrc:idc_rads#3 %)";
+#endif
+
+#include <stdio.h>
+//#include <process.h>
+#include "clibstuf.h"
+
+void main (int argc, char** argv)
+{
+  fnInitGpfGlobals();
+  if (argc>1 && argv[1]!=NULL && strcmp(argv[1],"-d")==0) {
+    int n;
+    for (n=0; n < argc; n++) {
+      printf("%2d: '%s'\n", n, argv[n]);
+    }
+  } else {
+    while (--argc) {
+      printf("%s%c", *++argv, argc==1 ? '\n' : ' ');
+    }
+  }
+}
diff --git a/NetWare/testnlm/type/type.c b/NetWare/testnlm/type/type.c
new file mode 100644 (file)
index 0000000..8d5c394
--- /dev/null
@@ -0,0 +1,48 @@
+/**********************************************************************
+*
+*      C Source:               type.c
+*      Instance:               idc_rads_2
+*      Description:    DOS type Emulation
+*      %created_by:    smscm %
+*      %date_created:  Fri Apr 20 19:05:34 2001 %
+*
+**********************************************************************/
+#ifndef lint
+static char *_csrc = "@(#) %filespec: type.c~1 %  (%full_filespec: type.c~1:csrc:idc_rads#3 %)";
+#endif
+
+#include <stdio.h>
+#include <nwfattr.h>
+#include "clibstuf.h"
+
+void main (int argc, char** argv)
+{
+  FILE* pfile = NULL;
+  int k;
+  int thechar;
+  char* defaultDir;
+
+  fnInitGpfGlobals();
+  SetCurrentNameSpace(NWOS2_NAME_SPACE);
+  defaultDir = getenv("PERL_ROOT");
+  if (!defaultDir || (strlen(defaultDir) == 0))
+    defaultDir = "sys:\\perl\\scripts";
+  chdir(defaultDir);
+
+  k = 1;
+  while (k < argc)
+  {
+    // open the next file and print it out
+    pfile = fopen(argv[k],"r");
+    if (pfile)
+    {
+      while ((thechar = getc(pfile)) != EOF)
+      {
+        if (thechar != 0x0d)
+          printf("%c",thechar);
+      }
+      fclose (pfile);
+    }
+    k++;
+  }
+}
diff --git a/NetWare/win32ish.h b/NetWare/win32ish.h
new file mode 100644 (file)
index 0000000..a8fcbcd
--- /dev/null
@@ -0,0 +1,46 @@
+
+/*
+ * Copyright Â© 2001 Novell, Inc. All Rights Reserved.
+ *
+ * You may distribute under the terms of either the GNU General Public
+ * License or the Artistic License, as specified in the README file.
+ *
+ */
+
+/*
+ * FILENAME            :       Win32ish.h
+ * DESCRIPTION :       For Win32 type definitions like BOOL.
+ * Author              :       HYAK
+ * Date                        :       January 2001.
+ *
+ */
+
+
+
+#ifndef __Win32ish_H__
+#define __Win32ish_H__
+
+
+#ifndef BOOL
+       typedef unsigned int BOOL;
+#endif
+
+#ifndef DWORD
+       typedef unsigned long DWORD;
+#endif
+
+typedef DWORD  LCID;
+typedef long HRESULT;
+typedef void* LPVOID;
+
+#ifndef TRUE
+       #define TRUE    1
+#endif
+
+#ifndef FALSE
+       #define FALSE   0
+#endif
+
+
+#endif         // __Win32ish_H__
+
diff --git a/README.netware b/README.netware
new file mode 100644 (file)
index 0000000..2113e7b
--- /dev/null
@@ -0,0 +1,304 @@
+This file is written in the POD format.  If you are reading it thro'
+a text editor, ignore the words like =head1, =over etc.
+
+=head1 Name
+
+Perl for NetWare5.x
+
+=head1 Description
+
+This file gives the instructions for building Perl5.6.1 for NetWare5.x.
+Please read and understand the terms under which this software is distributed.
+
+
+=head1 Build
+
+This section describes the steps to be performed to build a Perl NLM and other associated
+NLMs.
+
+=head2 Tools & SDK
+
+The build requires Watcom 11.x compiler and linker.  NetWare SDK, available at L<http://developer.novell.com/ndk/>,  is required.
+Apart from NetWare SDK, "NLM & NetWare Libraries for C" and "NetWare Server Protocol Libraries for C"
+are also required.  This is also available at the above mentioned site.
+Microsoft Visual C++ version 4.2 or later is also required.
+
+Currently the interpreter builds only with Watcom, we do have plans of making this work with
+CodeWarrior as well.
+
+=head2 Setup
+
+The build process is dependent on the location of the NetWare SDK.  Once the required software
+is installed, the build environment has to be setup.  The following batch files setup 
+the environment.
+
+I<Buildtype.bat> - This sets the build type to release or debug.
+
+I<SetNWBld.bat>  - This sets the NetWare SDK path, Compiler & other tools path & MPK SDK path.
+
+I<MPKBuild.bat>  - This is required only it we are building multi-processor enabled NLMs.
+
+These batch files are under NetWare\bat folder.  These batch files call a couple of other
+batch files to setup the environment.  Invoking the batch file with I</now> will show the 
+current settings and I</h> or I</?> gives the usage help.
+
+=head2 Make
+
+The makefile is located under the NetWare folder.  Type nmake at the WinNT command prompt. 
+The make process runs only under WinNT shell.  The makefile makes use of miniperl.exe to 
+run some of the Perl scripts.  Please run nmake from win32 folder which builds miniperl.exe before
+running nmake from NetWare folder.  The build process can be stopped after miniperl.exe is created.
+
+Currently the follwing two build types are tested on NetWare
+
+=over 4
+
+=item *
+
+USE_MULTI, USE_ITHREADS & USE_IMP_SYS defined
+
+=item *
+
+USE_MULTI & USE_IMP_SYS defined and USE_ITHREADS not defined
+
+=back
+
+=head2 Interpreter
+
+Once miniperl.exe creation is over, run nmake from the NetWare folder. This will build the 
+Perl interpreter for NetWare as I<perl.nlm>.  This is copied under the I<Release> folder if you
+are doing a release build else will be copied under I<Debug> folder for debug builds.
+
+=head2 Extensions
+
+The make process also creates the Perl extensions which are called NLPs (NetWare Loadable Perl).
+
+=head1 Install
+
+Installing NetWare Perl on Windows doesn't make any sense.  To install, type I<nmake nwinstall>. This
+will copy the binaries and module files to a NetWare server.  The makefile, by default sets the 
+drive letter to I<i:> which should be mapped to the I<sys> volume of a NetWare server.  The Perl 
+interpreter, I<perl.nlm>, is copied under I<sys:\perl\system> folder. Copy I<perl.nlm> to 
+I<sys:\system> folder. Before running I<nmake nwinstall>, make sure the NetWare server on which 
+the files have to go is mapped to the drive letter I<i:>.
+
+=head1 Build new extensions
+
+To build extensions other than standard extensions, NetWare Perl has to be installed on Windows as well.
+This can be done by invoking I<nmake install> on the Windows NT command prompt.  This will copy all
+the *.pm files and other required files.  Documentation files are not copied. This has be done after 
+installing Perl for Windows. Once this is done, to build any extension, do the following
+
+=over 4
+
+=item *
+perl -II<path to NetWare lib dir> -II<path to lib> Makefile.pl
+
+Ex: perl -Ic:/perl/5.6.1/lib/NetWare-multi-thread -Ic:\perl\5.6.1\lib MakeFile.pl
+
+=item *
+nmake
+
+=item *
+nmake install
+
+
+Install will copy the files into the Windows machine where NetWare Perl is installed, these files
+have to be copied to the NetWare server manually.  Alternatively, pass I<INSTALLSITELIB=i:\perl\lib>
+as an input to makefile.pl above.  Where I<i:> is the mapped drive to the sys: volume of the 
+server where Perl on NetWare is installed.  Now saying I<nmake install>, will copy the files 
+to the server.
+
+=back
+
+=head1 Known Issues
+
+=item * 
+
+With USE_ITHREADS not defined, backtick seems to be having some problems.
+
+=item *
+
+The utility scripts (pod2html.pl, pod2man.pl, perldoc.pl etc.) are not yet ported to work on NetWare.
+
+=item *
+
+Also fork() is not currently implemented.
+
+=head1 Acknowledgements
+
+For the porting purpose, the PerlHost of Win32 port was used as reference and NetWare portions are
+added. Also the makefile for Win32 is used as a reference to create the makefile for NetWare build.
+Additionally the make process for NetWare port uses miniperl.exe to run scripts during the make and
+installation process.
+
+=head1 Author
+
+Guruprasad S (sguruprasad@novell.com)
+
+=head1 Date
+
+=over 4
+
+=item *
+
+Created - 18th Jan 2001
+
+=item *
+
+Modified -  16th April 2001
+
+=back
+This file is written in the POD format.  If you are reading it thro'
+a text editor, ignore the words like =head1, =over etc.
+
+=head1 Name
+
+Perl for NetWare5.x
+
+=head1 Description
+
+This file gives the instructions for building Perl5.6.1 for NetWare5.x.
+Please read and understand the terms under which this software is distributed.
+
+
+=head1 Build
+
+This section describes the steps to be performed to build a Perl NLM and other associated
+NLMs.
+
+=head2 Tools & SDK
+
+The build requires Watcom 11.x compiler and linker.  NetWare SDK, available at L<http://developer.novell.com/ndk/>,  is required.
+Apart from NetWare SDK, "NLM & NetWare Libraries for C" and "NetWare Server Protocol Libraries for C"
+are also required.  This is also available at the above mentioned site.
+Microsoft Visual C++ version 4.2 or later is also required.
+
+Currently the interpreter builds only with Watcom, we do have plans of making this work with
+CodeWarrior as well.
+
+=head2 Setup
+
+The build process is dependent on the location of the NetWare SDK.  Once the required software
+is installed, the build environment has to be setup.  The following batch files setup 
+the environment.
+
+I<Buildtype.bat> - This sets the build type to release or debug.
+
+I<SetNWBld.bat>  - This sets the NetWare SDK path, Compiler & other tools path & MPK SDK path.
+
+I<MPKBuild.bat>  - This is required only it we are building multi-processor enabled NLMs.
+
+These batch files are under NetWare\bat folder.  These batch files call a couple of other
+batch files to setup the environment.  Invoking the batch file with I</now> will show the 
+current settings and I</h> or I</?> gives the usage help.
+
+=head2 Make
+
+The makefile is located under the NetWare folder.  Type nmake at the WinNT command prompt. 
+The make process runs only under WinNT shell.  The makefile makes use of miniperl.exe to 
+run some of the Perl scripts.  Please run nmake from win32 folder which builds miniperl.exe before
+running nmake from NetWare folder.  The build process can be stopped after miniperl.exe is created.
+
+Currently the follwing two build types are tested on NetWare
+
+=over 4
+
+=item *
+
+USE_MULTI, USE_ITHREADS & USE_IMP_SYS defined
+
+=item *
+
+USE_MULTI & USE_IMP_SYS defined and USE_ITHREADS not defined
+
+=back
+
+=head2 Interpreter
+
+Once miniperl.exe creation is over, run nmake from the NetWare folder. This will build the 
+Perl interpreter for NetWare as I<perl.nlm>.  This is copied under the I<Release> folder if you
+are doing a release build else will be copied under I<Debug> folder for debug builds.
+
+=head2 Extensions
+
+The make process also creates the Perl extensions which are called NLPs (NetWare Loadable Perl).
+
+=head1 Install
+
+Installing NetWare Perl on Windows doesn't make any sense.  To install, type I<nmake nwinstall>. This
+will copy the binaries and module files to a NetWare server.  The makefile, by default sets the 
+drive letter to I<i:> which should be mapped to the I<sys> volume of a NetWare server.  The Perl 
+interpreter, I<perl.nlm>, is copied under I<sys:\perl\system> folder. Copy I<perl.nlm> to 
+I<sys:\system> folder. Before running I<nmake nwinstall>, make sure the NetWare server on which 
+the files have to go is mapped to the drive letter I<i:>.
+
+=head1 Build new extensions
+
+To build extensions other than standard extensions, NetWare Perl has to be installed on Windows as well.
+This can be done by invoking I<nmake install> on the Windows NT command prompt.  This will copy all
+the *.pm files and other required files.  Documentation files are not copied. This has be done after 
+installing Perl for Windows. Once this is done, to build any extension, do the following
+
+=over 4
+
+=item *
+perl -II<path to NetWare lib dir> -II<path to lib> Makefile.pl
+
+Ex: perl -Ic:/perl/5.6.1/lib/NetWare-multi-thread -Ic:\perl\5.6.1\lib MakeFile.pl
+
+=item *
+nmake
+
+=item *
+nmake install
+
+
+Install will copy the files into the Windows machine where NetWare Perl is installed, these files
+have to be copied to the NetWare server manually.  Alternatively, pass I<INSTALLSITELIB=i:\perl\lib>
+as an input to makefile.pl above.  Where I<i:> is the mapped drive to the sys: volume of the 
+server where Perl on NetWare is installed.  Now saying I<nmake install>, will copy the files 
+to the server.
+
+=back
+
+=head1 Known Issues
+
+=item * 
+
+With USE_ITHREADS not defined, backtick seems to be having some problems.
+
+=item *
+
+The utility scripts (pod2html.pl, pod2man.pl, perldoc.pl etc.) are not yet ported to work on NetWare.
+
+=item *
+
+Also fork() is not currently implemented.
+
+=head1 Acknowledgements
+
+For the porting purpose, the PerlHost of Win32 port was used as reference and NetWare portions are
+added. Also the makefile for Win32 is used as a reference to create the makefile for NetWare build.
+Additionally the make process for NetWare port uses miniperl.exe to run scripts during the make and
+installation process.
+
+=head1 Author
+
+Guruprasad S (sguruprasad@novell.com)
+
+=head1 Date
+
+=over 4
+
+=item *
+
+Created - 18th Jan 2001
+
+=item *
+
+Modified -  16th April 2001
+
+=back
diff --git a/XSUB.h b/XSUB.h
index a5f8e59..87a05d0 100644 (file)
--- a/XSUB.h
+++ b/XSUB.h
@@ -258,6 +258,15 @@ C<xsubpp>.  See L<perlxs/"The VERSIONCHECK: Keyword">.
 
 #if (defined(PERL_CAPI) || defined(PERL_IMPLICIT_SYS)) && !defined(PERL_CORE)
 #  ifndef NO_XSLOCKS
+# if defined (NETWARE) && defined (USE_STDIO)
+#    define times              PerlProc_times
+#    define setuid             PerlProc_setuid
+#    define setgid             PerlProc_setgid
+#    define getpid             PerlProc_getpid
+#    define pause              PerlProc_pause
+#    define exit               PerlProc_exit
+#    define _exit              PerlProc__exit
+# else
 #    undef closedir
 #    undef opendir
 #    undef stdin
@@ -273,6 +282,35 @@ C<xsubpp>.  See L<perlxs/"The VERSIONCHECK: Keyword">.
 #    undef ungetc
 #    undef fileno
 
+//Following symbols were giving redefinition errors while building extensions - sgp 17th Oct 2000
+#ifdef NETWARE
+#      undef readdir
+#      undef fstat
+#      undef stat
+#      undef longjmp
+#      undef endhostent
+#      undef endnetent
+#      undef endprotoent
+#      undef endservent
+#      undef gethostbyaddr
+#      undef gethostbyname
+#      undef gethostent
+#      undef getnetbyaddr
+#      undef getnetbyname
+#      undef getnetent
+#      undef getprotobyname
+#      undef getprotobynumber
+#      undef getprotoent
+#      undef getservbyname
+#      undef getservbyport
+#      undef getservent
+#      undef inet_ntoa
+#      undef sethostent
+#      undef setnetent
+#      undef setprotoent
+#      undef setservent
+#endif /* NETWARE */
+
 #    define mkdir              PerlDir_mkdir
 #    define chdir              PerlDir_chdir
 #    define rmdir              PerlDir_rmdir
@@ -410,6 +448,7 @@ C<xsubpp>.  See L<perlxs/"The VERSIONCHECK: Keyword">.
 #    define shutdown           PerlSock_shutdown
 #    define socket             PerlSock_socket
 #    define socketpair         PerlSock_socketpair
+#      endif   /* NETWARE && USE_STDIO */
 #  endif  /* NO_XSLOCKS */
 #endif  /* PERL_CAPI */
 
index 5f12b9d..4b90187 100644 (file)
--- a/dosish.h
+++ b/dosish.h
 #    define PERL_SYS_INIT(c,v) Perl_win32_init(c,v)
 #    define BIT_BUCKET "nul"
 #  else
-#    define PERL_SYS_INIT(c,v)
-#    define BIT_BUCKET "\\dev\\nul" /* "wanna be like, umm, Newlined, or somethin?" */
+#       ifdef NETWARE
+#      define PERL_SYS_INIT(c,v)       Perl_nw5_init(c,v)
+#      define BIT_BUCKET "nul"
+#    else
+#      define PERL_SYS_INIT(c,v)
+#      define BIT_BUCKET "\\dev\\nul" /* "wanna be like, umm, Newlined, or somethin?" */
+#    endif /* NETWARE */
 #  endif
 #endif /* DJGPP */
 
index 4a11318..575e77c 100644 (file)
@@ -107,12 +107,16 @@ sub get_files {
        open(CPPI,"> errno.c") or
            die "Cannot open errno.c";
 
-       print CPPI "#include <errno.h>\n";
+       if ($^O eq 'NetWare') {
+               print CPPI "#include <nwerrno.h>\n";
+       } else {
+               print CPPI "#include <errno.h>\n";
+       }
 
        close(CPPI);
 
        # invoke CPP and read the output
-       if ($^O eq 'MSWin32') {
+       if ($^O eq 'MSWin32' || $^O eq 'NetWare') {
            open(CPPO,"$Config{cpprun} $Config{cppflags} errno.c |") or
                die "Cannot run '$Config{cpprun} $Config{cppflags} errno.c'";
        } else {
@@ -122,14 +126,14 @@ sub get_files {
        }
 
        my $pat;
-       if ($^O eq 'MSWin32' and $Config{cc} =~ /^bcc/i) {
+       if (($^O eq 'MSWin32' || $^O eq 'NetWare') and $Config{cc} =~ /^bcc/i) {
            $pat = '^/\*\s+(.+)\s+\d+\s*:\s+\*/';
        }
        else {
            $pat = '^#\s*(?:line)?\s*\d+\s+"([^"]+)"';
        }
        while(<CPPO>) {
-           if ($^O eq 'os2' or $^O eq 'MSWin32') {
+           if ($^O eq 'os2' or $^O eq 'MSWin32' or $^O eq 'NetWare') {
                if (/$pat/o) {
                   my $f = $1;
                   $f =~ s,\\\\,/,g;
@@ -157,7 +161,11 @@ sub write_errno_pm {
     open(CPPI,"> errno.c") or
        die "Cannot open errno.c";
 
-    print CPPI "#include <errno.h>\n";
+    if ($^O eq 'NetWare') {
+               print CPPI "#include <nwerrno.h>\n";
+       } else {
+               print CPPI "#include <errno.h>\n";
+       }
 
     foreach $err (keys %err) {
        print CPPI '"',$err,'" [[',$err,']]',"\n";
@@ -173,7 +181,7 @@ sub write_errno_pm {
            $cpp =~ s/sys\$input//i;
            open(CPPO,"$cpp  errno.c |") or
                die "Cannot exec $Config{cppstdin}";
-       } elsif ($^O eq 'MSWin32') {
+       } elsif ($^O eq 'MSWin32' || $^O eq 'NetWare') {
            open(CPPO,"$Config{cpprun} $Config{cppflags} errno.c |") or
                die "Cannot run '$Config{cpprun} $Config{cppflags} errno.c'";
        } else {
index 8bdc133..ef91a97 100644 (file)
@@ -430,7 +430,11 @@ sockatmark (sock)
      {
        int flag = 0;
 #   ifdef SIOCATMARK
-       if (ioctl(fd, SIOCATMARK, &flag) != 0)
+       #ifdef NETWARE
+       if (ioctl(fd, SIOCATMARK, (void*)&flag) != 0)
+       #else
+          if (ioctl(fd, SIOCATMARK, &flag) != 0)
+       #endif
         XSRETURN_UNDEF;
 #   else
        not_here("IO::Socket::atmark");
index 80af6d3..c2e9852 100644 (file)
@@ -2,6 +2,15 @@
 #define _POSIX_
 #endif
 
+#ifdef NETWARE
+       #define _POSIX_
+       //Ideally this should be somewhere down in the includes
+       //but putting it in other places is giving compiler errors.
+       //Also here I am unable to check for HAS_UNAME since it wouldn't have yet
+       //come into the file at this stage - sgp 18th Oct 2000
+       #include <sys/utsname.h>
+#endif /* NETWARE */
+
 #define PERL_NO_GET_CONTEXT
 
 #include "EXTERN.h"
@@ -65,7 +74,7 @@
 #include <fcntl.h>
 
 #ifdef HAS_TZNAME
-#  if !defined(WIN32) && !defined(__CYGWIN__)
+#  if !defined(WIN32) && !defined(__CYGWIN__) && !defined(NETWARE)
 extern char *tzname[];
 #  endif
 #else
@@ -126,7 +135,7 @@ char *tzname[] = { "" , "" };
 #if defined (__CYGWIN__)
 #    define tzname _tzname
 #endif
-#if defined (WIN32)
+#if defined (WIN32) || defined (NETWARE)
 #  undef mkfifo
 #  define mkfifo(a,b) not_here("mkfifo")
 #  define ttyname(a) (char*)not_here("ttyname")
@@ -156,6 +165,10 @@ char *tzname[] = { "" , "" };
 #  define sigdelset(a,b)       not_here("sigdelset")
 #  define sigfillset(a)                not_here("sigfillset")
 #  define sigismember(a,b)     not_here("sigismember")
+#ifndef NETWARE
+#  define setuid(a)            not_here("setuid")
+#  define setgid(a)            not_here("setgid")
+#endif /* NETWARE */
 #else
 
 #  ifndef HAS_MKFIFO
@@ -182,7 +195,7 @@ char *tzname[] = { "" , "" };
 #  ifdef I_UTIME
 #    include <utime.h>
 #  endif
-#endif /* WIN32 */
+#endif /* WIN32 || NETWARE */
 #endif /* __VMS */
 
 typedef int SysRet;
@@ -269,7 +282,9 @@ unsigned long strtoul (const char *, char **, int);
 #define tcsetpgrp(a,b) not_here("tcsetpgrp")
 #endif
 #ifndef HAS_TIMES
+#ifndef NETWARE
 #define times(a) not_here("times")
+#endif /* NETWARE */
 #endif
 #ifndef HAS_UNAME
 #define uname(a) not_here("uname")
@@ -1156,7 +1171,7 @@ sigaction(sig, optaction, oldaction = 0)
        SV *                    optaction
        POSIX::SigAction        oldaction
     CODE:
-#ifdef WIN32
+#if defined(WIN32) || defined(NETWARE)
        RETVAL = not_here("sigaction");
 #else
 # This code is really grody because we're trying to make the signal
index 671a60f..2a37542 100644 (file)
 # include "sockadapt.h"
 #endif
 
+#ifdef NETWARE
+NETDB_DEFINE_CONTEXT
+NETINET_DEFINE_CONTEXT
+#endif
+
 #ifdef I_SYSUIO
 # include <sys/uio.h>
 #endif
index 9f49c13..a58f8e5 100755 (executable)
@@ -9,7 +9,7 @@ BEGIN {
 
 use strict;
 my ($Is_VMS, $Is_W32, $Is_OS2, $Is_Cygwin, $nonono, $dostrip,
-    $versiononly, $silent, $verbose, $otherperls, $archname);
+    $versiononly, $silent, $verbose, $otherperls, $archname,$Is_NetWare, $nwinstall);
 use vars qw /$depth/;
 
 BEGIN {
@@ -30,6 +30,12 @@ use ExtUtils::Packlist;
 use Config;
 use subs qw(unlink link chmod);
 
+$Is_NetWare = $Config{osname} eq 'NetWare';
+if ($Is_NetWare) {
+       $Is_W32 = 0;
+       $scr_ext = '.pl';
+}
+
 # override the ones in the rest of the script
 sub mkpath {
     File::Path::mkpath(@_) unless $nonono;
@@ -59,6 +65,7 @@ while (@ARGV) {
     $otherperls = 0 if $ARGV[0] eq '-o';
     $verbose = 1 if $ARGV[0] eq '-V' || $ARGV [0] eq '-n';
     $archname = 1 if $ARGV[0] eq '-A';
+       $nwinstall = 1 if $ARGV[0] eq '-netware';
     shift;
 }
 
@@ -157,6 +164,14 @@ if ($^O eq 'os390') {
     }
 }
 
+if ($nwinstall) {
+       # This is required only if we are installing on a NetWare server
+       $installscript = $Config{installnwscripts};
+       $installprivlib = $Config{installnwlib};
+       $installarchlib = $Config{installnwlib};
+       $installsitelib = $Config{installnwlib};
+}
+
 my $d_dosuid = $Config{d_dosuid};
 my $binexp = $Config{binexp};
 
@@ -178,14 +193,16 @@ if ($d_dosuid && $>) { die "You must run as root to install suidperl\n"; }
 -w $installbin         || $nonono || die "$installbin is not writable by you\n"
        unless $installbin =~ m#^/afs/# || $nonono;
 
+if (!$Is_NetWare) {
 -x 'perl' . $exe_ext   || die "perl isn't executable!\n";
 -x 'suidperl' . $exe_ext|| die "suidperl isn't executable!\n" if $d_dosuid;
 
 -f 't/rantests'                || $Is_W32
                         || warn "WARNING: You've never run 'make test' or",
                                 " some tests failed! (Installing anyway.)\n";
+} #if (!$Is_NetWare)
 
-if ($Is_W32 or $Is_Cygwin) {
+if (($Is_W32 and ! $Is_NetWare)  or $Is_Cygwin) {
   my $perldll;
 
   if ($Is_Cygwin) {
@@ -212,7 +229,7 @@ if ($Is_W32 or $Is_Cygwin) {
   copy("$perldll", "$installbin/$perldll");
   chmod(0755, "$installbin/$perldll");
    
-} # if ($Is_W32 or $Is_Cygwin)
+} # if (($Is_W32 and ! $Is_NetWare) or $Is_Cygwin)
 
 # This will be used to store the packlist
 my $packlist = ExtUtils::Packlist->new("$installarchlib/.packlist");
@@ -238,10 +255,26 @@ elsif ($^O eq 'mpeix') {
     link($Config{perlpath}, "$installbin/perl$ver$exe_ext");
 }
 elsif ($^O ne 'dos') {
-    safe_unlink("$installbin/$perl_verbase$ver$exe_ext");
-    copy("perl$exe_ext", "$installbin/$perl_verbase$ver$exe_ext");
-    strip("$installbin/$perl_verbase$ver$exe_ext");
-    chmod(0755, "$installbin/$perl_verbase$ver$exe_ext");
+       if (!$Is_NetWare) {
+               safe_unlink("$installbin/$perl_verbase$ver$exe_ext");
+               copy("perl$exe_ext", "$installbin/$perl_verbase$ver$exe_ext");
+               strip("$installbin/$perl_verbase$ver$exe_ext");
+               chmod(0755, "$installbin/$perl_verbase$ver$exe_ext");
+       }
+       else {
+               # If installing onto a NetWare server
+               if ($nwinstall) {
+                       # Copy perl.nlm, echo.nlm, type.nlm, a2p.nlm & cgi2perl.nlm
+                       mkpath($Config{installnwsystem}, 1, 0777);
+                       copy("netware\\".$ENV{'MAKE_TYPE'}."\\perl.nlm", $Config{installnwsystem});
+                       copy("netware\\testnlm\\echo\\echo.nlm", $Config{installnwsystem});
+                       copy("netware\\testnlm\\type\\type.nlm", $Config{installnwsystem});
+                       copy("x2p\\a2p.nlm", $Config{installnwsystem});
+                       chmod(0755, "$Config{installnwsystem}\\perl.nlm");
+                       mkpath($Config{installnwlcgi}, 1, 0777);
+                       copy("lib\\auto\\cgi2perl\\cgi2perl.nlm", $Config{installnwlcgi});
+               }
+       } #if (!$Is_NetWare)
 }
 else {
     safe_unlink("$installbin/$perl.exe");
@@ -315,7 +348,7 @@ foreach my $file (@corefiles) {
 # Install main perl executables
 # Make links to ordinary names if installbin directory isn't current directory.
 
-if (! $versiononly && ! samepath($installbin, '.') && ($^O ne 'dos') && ! $Is_VMS) {
+if (! $versiononly && ! samepath($installbin, '.') && ($^O ne 'dos') && ! $Is_VMS && ! $Is_NetWare) {
     safe_unlink("$installbin/$perl$exe_ext", "$installbin/suid$perl$exe_ext");
     if ($^O eq 'mpeix') {
        # MPE doesn't support hard links, so use a symlink.
@@ -350,7 +383,7 @@ if ($archname && ! samepath($installbin, '.') && ($^O ne 'dos') && ! $Is_VMS) {
 my $mainperl_is_instperl = 0;
 
 if ($Config{installusrbinperl} && $Config{installusrbinperl} eq 'define' &&
-    !$versiononly && !$nonono && !$Is_W32 && !$Is_VMS && -t STDIN && -t STDERR
+    !$versiononly && !$nonono && !$Is_W32 && !$Is_NetWare && !$Is_VMS && -t STDIN && -t STDERR
        && -w $mainperldir && ! samepath($mainperldir, $installbin)) {
     my($usrbinperl)    = "$mainperldir/$perl$exe_ext";
     my($instperl)      = "$installbin/$perl$exe_ext";
@@ -384,11 +417,12 @@ if ($Config{installusrbinperl} && $Config{installusrbinperl} eq 'define' &&
 }
 
 # Make links to ordinary names if installbin directory isn't current directory.
-
-if (!$versiononly && ! samepath($installbin, 'x2p')) {
-    safe_unlink("$installbin/a2p$exe_ext");
-    copy("x2p/a2p$exe_ext", "$installbin/a2p$exe_ext");
-    chmod(0755, "$installbin/a2p$exe_ext");
+if (!$Is_NetWare) {
+       if (!$versiononly && ! samepath($installbin, 'x2p')) {
+               safe_unlink("$installbin/a2p$exe_ext");
+               copy("x2p/a2p$exe_ext", "$installbin/a2p$exe_ext");
+               chmod(0755, "$installbin/a2p$exe_ext");
+       }
 }
 
 # cppstdin is just a script, but it is architecture-dependent, so
@@ -483,7 +517,7 @@ if ( !$versiononly || ($installprivlib =~ m/\Q$ver/)) {
 
 if (!$versiononly && $otherperls) {
     my ($path, @path);
-    my $dirsep = ($Is_OS2 || $Is_W32) ? ';' : ':' ;
+    my $dirsep = ($Is_OS2 || $Is_W32 || $Is_NetWare) ? ';' : ':' ;
     ($path = $ENV{"PATH"}) =~ s:\\:/:g ;
     @path = split(/$dirsep/, $path);
     if ($Is_VMS) {
@@ -542,7 +576,7 @@ sub unlink {
 
     foreach my $name (@names) {
        next unless -e $name;
-       chmod 0777, $name if ($Is_OS2 || $Is_W32 || $Is_Cygwin);
+       chmod 0777, $name if ($Is_OS2 || $Is_W32 || $Is_Cygwin || $Is_NetWare);
        print "  unlink $name\n" if $verbose;
        ( CORE::unlink($name) and ++$cnt 
          or warn "Couldn't unlink $name: $!\n" ) unless $nonono;
@@ -555,7 +589,7 @@ sub safe_unlink {
     my @names = @_;
     foreach my $name (@names) {
        next unless -e $name;
-       chmod 0777, $name if ($Is_OS2 || $Is_W32);
+       chmod 0777, $name if ($Is_OS2 || $Is_W32 || $Is_NetWare);
        print "  unlink $name\n" if $verbose;
        next if CORE::unlink($name);
        warn "Couldn't unlink $name: $!\n";
@@ -633,7 +667,7 @@ sub copy {
 sub samepath {
     my($p1, $p2) = @_;
 
-    return (lc($p1) eq lc($p2)) if $Is_W32;
+    return (lc($p1) eq lc($p2)) if ($Is_W32 || $Is_NetWare);
 
     if ($p1 ne $p2) {
        my($dev1, $ino1, $dev2, $ino2);
@@ -668,7 +702,7 @@ sub installlib {
     my $installlib = $installprivlib;
     if ($dir =~ /^auto/ ||
          ($name =~ /^(.*)\.(?:pm|pod)$/ && $archpms{$1}) ||
-         ($name =~ /^(.*)\.(?:h|lib)$/i && $Is_W32)
+         ($name =~ /^(.*)\.(?:h|lib)$/i && ($Is_W32 || $Is_NetWare))
        ) {
         $installlib = $installarchlib;
        return unless $do_installarchlib;
@@ -691,9 +725,21 @@ sub installlib {
            mkpath("$installlib/$dir", $verbose, 0777);
            # HP-UX (at least) needs to maintain execute permissions
            # on dynamically-loaded libraries.
-           copy_if_diff($_, "$installlib/$name")
-               and chmod($name =~ /\.(so|$dlext)$/o ? 0555 : 0444,
+               if ($Is_NetWare && !$nwinstall) {
+                       # Don't copy .nlp,.nlm files, doesn't make sense on Windows and also
+                       # if copied will give problems when building new extensions.
+                       # Has to be copied if we are installing on a NetWare server and hence
+                       # the check !$nwinstall
+                       if (!(/\.(?:nlp|nlm|bs)$/)) {
+                               copy_if_diff($_, "$installlib/$name")
+                               and chmod($name =~ /\.(so|$dlext)$/o ? 0555 : 0444,
+                          "$installlib/$name");
+                       }
+               } else {
+                       copy_if_diff($_, "$installlib/$name")
+                       and chmod($name =~ /\.(so|$dlext)$/o ? 0555 : 0444,
                           "$installlib/$name");
+               } #if ($Is_NetWare)         
        }
     }
 }
index 125a75a..081d8b2 100644 (file)
@@ -604,7 +604,11 @@ typedef int                (*LPLIOOpen3)(struct IPerlLIO*, const char*, int, int);
 typedef int            (*LPLIORead)(struct IPerlLIO*, int, void*, unsigned int);
 typedef int            (*LPLIORename)(struct IPerlLIO*, const char*,
                            const char*);
+#ifdef NETWARE
+typedef int            (*LPLIOSetmode)(struct IPerlLIO*, FILE*, int);
+#else
 typedef int            (*LPLIOSetmode)(struct IPerlLIO*, int, int);
+#endif /* NETWARE */
 typedef int            (*LPLIONameStat)(struct IPerlLIO*, const char*,
                            struct stat*);
 typedef char*          (*LPLIOTmpnam)(struct IPerlLIO*, char*);
index ad6bc40..564aeb1 100644 (file)
@@ -12,7 +12,7 @@ BEGIN {
     require Exporter;
     @EXPORT = @EXPORT = ();
     @EXPORT_OK = @EXPORT_OK = qw(AUTOLOAD);
-    $is_dosish = $^O eq 'dos' || $^O eq 'os2' || $^O eq 'MSWin32';
+    $is_dosish = $^O eq 'dos' || $^O eq 'os2' || $^O eq 'MSWin32' || $^O eq 'NetWare';
     $is_epoc = $^O eq 'epoc';
     $is_vms = $^O eq 'VMS';
     $is_macos = $^O eq 'MacOS';
@@ -57,7 +57,11 @@ AUTOLOAD {
                unless ($filename =~ m|^/|s) {
                    if ($is_dosish) {
                        unless ($filename =~ m{^([a-z]:)?[\\/]}is) {
-                            $filename = "./$filename";
+                            if ($^O ne 'NetWare') {
+                                       $filename = "./$filename";
+                               } else {
+                                       $filename = "$filename";
+                               }
                        }
                    }
                    elsif ($is_epoc) {
index 3147152..7feda7c 100644 (file)
@@ -263,7 +263,7 @@ sub autosplit_file {
     die "Package $def_package ($modpname.pm) does not ".
        "match filename $filename"
            unless ($filename =~ m/\Q$modpname.pm\E$/ or
-                   ($^O eq 'dos') or ($^O eq 'MSWin32') or
+                   ($^O eq 'dos') or ($^O eq 'MSWin32') or ($^O eq 'NetWare') or
                    $Is_VMS && $filename =~ m/$modpname.pm/i);
 
     my($al_idx_file) = catfile($autodir, $modpname, $IndexFile);
diff --git a/lib/ExtUtils/MM_NW5.pm b/lib/ExtUtils/MM_NW5.pm
new file mode 100644 (file)
index 0000000..5b156d6
--- /dev/null
@@ -0,0 +1,1056 @@
+package ExtUtils::MM_NW5;
+
+=head1 NAME
+
+ExtUtils::MM_NW5 - methods to override UN*X behaviour in ExtUtils::MakeMaker
+
+=head1 SYNOPSIS
+
+ use ExtUtils::MM_NW5; # Done internally by ExtUtils::MakeMaker if needed
+
+=head1 DESCRIPTION
+
+See ExtUtils::MM_Unix for a documentation of the methods provided
+there. This package overrides the implementation of these methods, not
+the semantics.
+
+=over
+
+=cut 
+
+use Config;
+#use Cwd;
+use File::Basename;
+require Exporter;
+
+Exporter::import('ExtUtils::MakeMaker',
+       qw( $Verbose &neatvalue));
+
+$ENV{EMXSHELL} = 'sh'; # to run `commands`
+unshift @MM::ISA, 'ExtUtils::MM_NW5';
+
+$BORLAND = 1 if $Config{'cc'} =~ /^bcc/i;
+$GCC     = 1 if $Config{'cc'} =~ /^gcc/i;
+$DMAKE = 1 if $Config{'make'} =~ /^dmake/i;
+$NMAKE = 1 if $Config{'make'} =~ /^nmake/i;
+$PERLMAKE = 1 if $Config{'make'} =~ /^pmake/i;
+$OBJ   = 1 if $Config{'ccflags'} =~ /PERL_OBJECT/i;
+
+# a few workarounds for command.com (very basic)
+{
+    package ExtUtils::MM_Win95;
+
+    # the $^O test may be overkill, but we want to be sure Win32::IsWin95()
+    # exists before we try it
+
+    unshift @MM::ISA, 'ExtUtils::MM_Win95'
+       if ($^O =~ /Win32/ && Win32::IsWin95());
+
+    sub xs_c {
+       my($self) = shift;
+       return '' unless $self->needs_linking();
+       '
+.xs.c:
+       $(PERL) -I$(PERL_ARCHLIB) -I$(PERL_LIB) $(XSUBPP) \\
+           $(XSPROTOARG) $(XSUBPPARGS) $*.xs > $*.c
+       '
+    }
+
+    sub xs_cpp {
+       my($self) = shift;
+       return '' unless $self->needs_linking();
+       '
+.xs.cpp:
+       $(PERL) -I$(PERL_ARCHLIB) -I$(PERL_LIB) $(XSUBPP) \\
+           $(XSPROTOARG) $(XSUBPPARGS) $*.xs > $*.cpp
+       ';
+    }
+
+    # many makes are too dumb to use xs_c then c_o
+    sub xs_o {
+       my($self) = shift;
+       return '' unless $self->needs_linking();
+       '
+.xs$(OBJ_EXT):
+       $(PERL) -I$(PERL_ARCHLIB) -I$(PERL_LIB) $(XSUBPP) \\
+           $(XSPROTOARG) $(XSUBPPARGS) $*.xs > $*.c
+       $(CCCMD) $(CCCDLFLAGS) -I$(PERL_INC) $(DEFINE) $*.c
+       ';
+    }
+}      # end of command.com workarounds
+
+sub dlsyms {
+    my($self,%attribs) = @_;
+
+    my($funcs) = $attribs{DL_FUNCS} || $self->{DL_FUNCS} || {};
+    my($vars)  = $attribs{DL_VARS} || $self->{DL_VARS} || [];
+    my($funclist) = $attribs{FUNCLIST} || $self->{FUNCLIST} || [];
+    my($imports)  = $attribs{IMPORTS} || $self->{IMPORTS} || {};
+    my(@m);
+    (my $boot = $self->{NAME}) =~ s/:/_/g;
+
+    if (not $self->{SKIPHASH}{'dynamic'}) {
+       push(@m,"
+$self->{BASEEXT}.def: Makefile.PL
+",
+     q!        $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -MExtUtils::Mksymlists \\
+     -e "Mksymlists('NAME' => '!, $self->{NAME},
+     q!', 'DLBASE' => '!,$self->{DLBASE},
+     q!', 'DL_FUNCS' => !,neatvalue($funcs),
+     q!, 'FUNCLIST' => !,neatvalue($funclist),
+     q!, 'IMPORTS' => !,neatvalue($imports),
+     q!, 'DL_VARS' => !, neatvalue($vars), q!);"
+!);
+    }
+    join('',@m);
+}
+
+sub replace_manpage_separator {
+    my($self,$man) = @_;
+    $man =~ s,/+,.,g;
+    $man;
+}
+
+sub maybe_command {
+    my($self,$file) = @_;
+    my @e = exists($ENV{'PATHEXT'})
+          ? split(/;/, $ENV{PATHEXT})
+         : qw(.com .exe .bat .cmd);
+    my $e = '';
+    for (@e) { $e .= "\Q$_\E|" }
+    chop $e;
+    # see if file ends in one of the known extensions
+    if ($file =~ /($e)$/i) {
+       return $file if -e $file;
+    }
+    else {
+       for (@e) {
+           return "$file$_" if -e "$file$_";
+       }
+    }
+    return;
+}
+
+sub file_name_is_absolute {
+    my($self,$file) = @_;
+    $file =~ m{^([a-z]:)?[\\/]}i ;
+}
+
+sub find_perl {
+    my($self, $ver, $names, $dirs, $trace) = @_;
+    my($name, $dir);
+    if ($trace >= 2){
+       print "Looking for perl $ver by these names:
+@$names
+in these dirs:
+@$dirs
+";
+    }
+    foreach $dir (@$dirs){
+       next unless defined $dir; # $self->{PERL_SRC} may be undefined
+       foreach $name (@$names){
+           my ($abs, $val);
+           if ($self->file_name_is_absolute($name)) { # /foo/bar
+               $abs = $name;
+           } elsif ($self->canonpath($name) eq $self->canonpath(basename($name))) { # foo
+               $abs = $self->catfile($dir, $name);
+           } else { # foo/bar
+               $abs = $self->canonpath($self->catfile($self->curdir, $name));
+           }
+           print "Checking $abs\n" if ($trace >= 2);
+           next unless $self->maybe_command($abs);
+           print "Executing $abs\n" if ($trace >= 2);
+           $val = `$abs -e "require $ver;" 2>&1`;
+           if ($? == 0) {
+               print "Using PERL=$abs\n" if $trace;
+               return $abs;
+           } elsif ($trace >= 2) {
+               print "Result: `$val'\n";
+           }
+       }
+    }
+    print STDOUT "Unable to find a perl $ver (by these names: @$names, in these dirs: @$dirs)\n";
+    0; # false and not empty
+}
+
+sub catdir {
+    my $self = shift;
+    my @args = @_;
+    for (@args) {
+       # append a slash to each argument unless it has one there
+       $_ .= "\\" if $_ eq '' or substr($_,-1) ne "\\";
+    }
+    my $result = $self->canonpath(join('', @args));
+    $result;
+}
+
+=item catfile
+
+Concatenate one or more directory names and a filename to form a
+complete path ending with a filename
+
+=cut
+
+sub catfile {
+    my $self = shift @_;
+    my $file = pop @_;
+    return $file unless @_;
+    my $dir = $self->catdir(@_);
+    $dir =~ s/(\\\.)$//;
+    $dir .= "\\" unless substr($dir,length($dir)-1,1) eq "\\";
+    return $dir.$file;
+}
+
+sub init_others
+{
+ my ($self) = @_;
+ &ExtUtils::MM_Unix::init_others;
+ $self->{'TOUCH'}  = '$(PERL) -I$(PERL_ARCHLIB) -I$(PERL_LIB) -MExtUtils::Command -e touch';
+ $self->{'CHMOD'}  = '$(PERL) -I$(PERL_ARCHLIB) -I$(PERL_LIB) -MExtUtils::Command -e chmod'; 
+ $self->{'CP'}     = '$(PERL) -I$(PERL_ARCHLIB) -I$(PERL_LIB) -MExtUtils::Command -e cp';
+ $self->{'RM_F'}   = '$(PERL) -I$(PERL_ARCHLIB) -I$(PERL_LIB) -MExtUtils::Command -e rm_f';
+ $self->{'RM_RF'}  = '$(PERL) -I$(PERL_ARCHLIB) -I$(PERL_LIB) -MExtUtils::Command -e rm_rf';
+ $self->{'MV'}     = '$(PERL) -I$(PERL_ARCHLIB) -I$(PERL_LIB) -MExtUtils::Command -e mv';
+ $self->{'NOOP'}   = 'rem';
+ $self->{'TEST_F'} = '$(PERL) -I$(PERL_ARCHLIB) -I$(PERL_LIB) -MExtUtils::Command -e test_f';
+ $self->{'LD'}     = $Config{'ld'} || 'link';
+ $self->{'AR'}     = $Config{'ar'} || 'lib';
+ $self->{'LDLOADLIBS'} ||= $Config{'libs'};
+ # -Lfoo must come first for Borland, so we put it in LDDLFLAGS
+ if ($BORLAND) {
+     my $libs = $self->{'LDLOADLIBS'};
+     my $libpath = '';
+     while ($libs =~ s/(?:^|\s)(("?)-L.+?\2)(?:\s|$)/ /) {
+         $libpath .= ' ' if length $libpath;
+         $libpath .= $1;
+     }
+     $self->{'LDLOADLIBS'} = $libs;
+     $self->{'LDDLFLAGS'} ||= $Config{'lddlflags'};
+     $self->{'LDDLFLAGS'} .= " $libpath";
+ }
+ $self->{'DEV_NULL'} = '> NUL';
+ # $self->{'NOECHO'} = ''; # till we have it working
+
+ # incpath is copied to makefile var INCLUDE in constants sub, here just make it empty
+ my $libpth = $Config{'libpth'};
+ $libpth =~ s( )(;);
+ $self->{'LIBPTH'} = $libpth;
+ $self->{'BASE_IMPORT'} = $Config{'base_import'};
+ # Additional import file specified from Makefile.pl
+ if($self->{'base_import'}) {
+       $self->{'BASE_IMPORT'} .= ',' . $self->{'base_import'};
+ }
+ $self->{'NLM_VERSION'} = $Config{'nlm_version'};
+ $self->{'MPKTOOL'}    = $Config{'mpktool'};
+ $self->{'TOOLPATH'}   = $Config{'toolpath'};
+}
+
+
+=item constants (o)
+
+Initializes lots of constants and .SUFFIXES and .PHONY
+
+=cut
+# NetWare override
+sub const_cccmd {
+    my($self,$libperl)=@_;
+    return $self->{CONST_CCCMD} if $self->{CONST_CCCMD};
+    return '' unless $self->needs_linking();
+    return $self->{CONST_CCCMD} =
+       q{CCCMD = $(CC) $(INC) $(CCFLAGS) $(OPTIMIZE) \\
+       $(PERLTYPE) $(LARGE) $(SPLIT) $(MPOLLUTE) \\
+       -DVERSION="$(VERSION)" -DXS_VERSION="$(XS_VERSION)"};
+}
+
+sub constants {
+    my($self) = @_;
+    my(@m,$tmp);
+
+# Added LIBPTH, BASE_IMPORT, ABSTRACT, NLM_VERSION BOOT_SYMBOL, NLM_SHORT_NAME
+# for NETWARE
+
+    for $tmp (qw/
+
+             AR_STATIC_ARGS NAME DISTNAME NAME_SYM VERSION
+             VERSION_SYM XS_VERSION INST_BIN INST_EXE INST_LIB
+             INST_ARCHLIB INST_SCRIPT PREFIX  INSTALLDIRS
+             INSTALLPRIVLIB INSTALLARCHLIB INSTALLSITELIB
+             INSTALLSITEARCH INSTALLBIN INSTALLSCRIPT PERL_LIB
+             PERL_ARCHLIB SITELIBEXP SITEARCHEXP LIBPERL_A MYEXTLIB
+             FIRST_MAKEFILE MAKE_APERL_FILE PERLMAINCC PERL_SRC
+             PERL_INC PERL FULLPERL LIBPTH BASE_IMPORT
+                 NLM_VERSION MPKTOOL TOOLPATH
+
+             / ) {
+       next unless defined $self->{$tmp};
+       push @m, "$tmp = $self->{$tmp}\n";
+    }
+
+       (my $boot = $self->{'NAME'}) =~ s/:/_/g;
+       $self->{'BOOT_SYMBOL'}=$boot;
+       push @m, "BOOT_SYMBOL = $self->{'BOOT_SYMBOL'}\n";
+
+       # If the final binary name is greater than 8 chars,
+       # truncate it here and rename it after creation
+       # otherwise, Watcom Linker fails
+       if(length($self->{'BASEEXT'}) > 8) {
+               $self->{'NLM_SHORT_NAME'} = substr($self->{'NAME'},0,8);
+               push @m, "NLM_SHORT_NAME = $self->{'NLM_SHORT_NAME'}\n";
+       }
+
+    push @m, qq{
+VERSION_MACRO = VERSION
+DEFINE_VERSION = -D\$(VERSION_MACRO)=\\\"\$(VERSION)\\\"
+XS_VERSION_MACRO = XS_VERSION
+XS_DEFINE_VERSION = -D\$(XS_VERSION_MACRO)=\\\"\$(XS_VERSION)\\\"
+};
+
+       # Get the include path and replace the spaces with ;
+       # Copy this to makefile as INCLUDE = d:\...;d:\;
+       (my $inc = $Config{'incpath'}) =~ s/ /;/g;
+
+       # Get the additional include path and append to INCLUDE, keep it in
+       # INC will give problems during compilation, hence reset it after getting
+       # the value
+       (my $add_inc = $self->{'INC'}) =~ s/ -I/;/g;
+       $self->{'INC'} = '';
+       push @m, qq{
+INCLUDE = $inc;$add_inc;
+};
+
+       # Set the path to Watcom binaries which might not have been set in
+       # any other place
+       push @m, qq{
+PATH = \$(PATH);\$(TOOLPATH)
+};
+
+    push @m, qq{
+MAKEMAKER = $INC{'ExtUtils\MakeMaker.pm'}
+MM_VERSION = $ExtUtils::MakeMaker::VERSION
+};
+
+    push @m, q{
+# FULLEXT = Pathname for extension directory (eg Foo/Bar/Oracle).
+# BASEEXT = Basename part of FULLEXT. May be just equal FULLEXT. (eg Oracle)
+# ROOTEXT = Directory part of FULLEXT with leading slash (eg /DBD)  !!! Deprecated from MM 5.32  !!!
+# PARENT_NAME = NAME without BASEEXT and no trailing :: (eg Foo::Bar)
+# DLBASE  = Basename part of dynamic library. May be just equal BASEEXT.
+};
+
+    for $tmp (qw/
+             FULLEXT BASEEXT PARENT_NAME DLBASE VERSION_FROM INC DEFINE OBJECT
+             LDFROM LINKTYPE
+             / ) {
+       next unless defined $self->{$tmp};
+       push @m, "$tmp = $self->{$tmp}\n";
+    }
+
+    push @m, "
+# Handy lists of source code files:
+XS_FILES= ".join(" \\\n\t", sort keys %{$self->{XS}})."
+C_FILES = ".join(" \\\n\t", @{$self->{C}})."
+O_FILES = ".join(" \\\n\t", @{$self->{O_FILES}})."
+H_FILES = ".join(" \\\n\t", @{$self->{H}})."
+HTMLLIBPODS    = ".join(" \\\n\t", sort keys %{$self->{HTMLLIBPODS}})."
+HTMLSCRIPTPODS = ".join(" \\\n\t", sort keys %{$self->{HTMLSCRIPTPODS}})."
+MAN1PODS = ".join(" \\\n\t", sort keys %{$self->{MAN1PODS}})."
+MAN3PODS = ".join(" \\\n\t", sort keys %{$self->{MAN3PODS}})."
+";
+
+    for $tmp (qw/
+             INST_HTMLPRIVLIBDIR INSTALLHTMLPRIVLIBDIR
+             INST_HTMLSITELIBDIR INSTALLHTMLSITELIBDIR
+             INST_HTMLSCRIPTDIR  INSTALLHTMLSCRIPTDIR
+             INST_HTMLLIBDIR                    HTMLEXT
+             INST_MAN1DIR        INSTALLMAN1DIR MAN1EXT
+             INST_MAN3DIR        INSTALLMAN3DIR MAN3EXT
+             /) {
+       next unless defined $self->{$tmp};
+       push @m, "$tmp = $self->{$tmp}\n";
+    }
+
+    push @m, qq{
+.USESHELL :
+} if $DMAKE;
+
+    push @m, q{
+.NO_CONFIG_REC: Makefile
+} if $ENV{CLEARCASE_ROOT};
+
+    # why not q{} ? -- emacs
+    push @m, qq{
+# work around a famous dec-osf make(1) feature(?):
+makemakerdflt: all
+
+.SUFFIXES: .xs .c .C .cpp .cxx .cc \$(OBJ_EXT)
+
+# Nick wanted to get rid of .PRECIOUS. I don't remember why. I seem to recall, that
+# some make implementations will delete the Makefile when we rebuild it. Because
+# we call false(1) when we rebuild it. So make(1) is not completely wrong when it
+# does so. Our milage may vary.
+# .PRECIOUS: Makefile    # seems to be not necessary anymore
+
+.PHONY: all config static dynamic test linkext manifest
+
+# Where is the Config information that we are using/depend on
+CONFIGDEP = \$(PERL_ARCHLIB)\\Config.pm \$(PERL_INC)\\config.h
+};
+
+    my @parentdir = split(/::/, $self->{PARENT_NAME});
+    push @m, q{
+# Where to put things:
+INST_LIBDIR      = }. $self->catdir('$(INST_LIB)',@parentdir)        .q{
+INST_ARCHLIBDIR  = }. $self->catdir('$(INST_ARCHLIB)',@parentdir)    .q{
+
+INST_AUTODIR     = }. $self->catdir('$(INST_LIB)','auto','$(FULLEXT)')       .q{
+INST_ARCHAUTODIR = }. $self->catdir('$(INST_ARCHLIB)','auto','$(FULLEXT)')   .q{
+};
+
+    if ($self->has_link_code()) {
+       push @m, '
+INST_STATIC  = $(INST_ARCHAUTODIR)\$(BASEEXT)$(LIB_EXT)
+INST_DYNAMIC = $(INST_ARCHAUTODIR)\$(DLBASE).$(DLEXT)
+INST_BOOT    = $(INST_ARCHAUTODIR)\$(BASEEXT).bs
+';
+    } else {
+       push @m, '
+INST_STATIC  =
+INST_DYNAMIC =
+INST_BOOT    =
+';
+    }
+
+    $tmp = $self->export_list;
+    push @m, "
+EXPORT_LIST = $tmp
+";
+    $tmp = $self->perl_archive;
+    push @m, "
+PERL_ARCHIVE = $tmp
+";
+
+#    push @m, q{
+#INST_PM = }.join(" \\\n\t", sort values %{$self->{PM}}).q{
+#
+#PM_TO_BLIB = }.join(" \\\n\t", %{$self->{PM}}).q{
+#};
+
+    push @m, q{
+TO_INST_PM = }.join(" \\\n\t", sort keys %{$self->{PM}}).q{
+
+PM_TO_BLIB = }.join(" \\\n\t", %{$self->{PM}}).q{
+};
+
+    join('',@m);
+}
+
+
+sub path {
+    my($self) = @_;
+    my $path = $ENV{'PATH'} || $ENV{'Path'} || $ENV{'path'};
+    my @path = split(';',$path);
+    foreach(@path) { $_ = '.' if $_ eq '' }
+    @path;
+}
+
+=item static_lib (o)
+
+Defines how to produce the *.a (or equivalent) files.
+
+=cut
+
+sub static_lib {
+    my($self) = @_;
+# Come to think of it, if there are subdirs with linkcode, we still have no INST_STATIC
+#    return '' unless $self->needs_linking(); #might be because of a subdir
+
+    return '' unless $self->has_link_code;
+
+    my(@m);
+    push(@m, <<'END');
+$(INST_STATIC): $(OBJECT) $(MYEXTLIB) $(INST_ARCHAUTODIR)\.exists
+       $(RM_RF) $@
+END
+
+    # If this extension has it's own library (eg SDBM_File)
+    # then copy that to $(INST_STATIC) and add $(OBJECT) into it.
+    push(@m, "\t$self->{CP} \$(MYEXTLIB) \$\@\n") if $self->{MYEXTLIB};
+
+    push @m,
+q{     $(AR) }.($BORLAND ? '$@ $(OBJECT:^"+")'
+                         : ($GCC ? '-ru $@ $(OBJECT)'
+                                 : '-out:$@ $(OBJECT)')).q{
+       }.$self->{NOECHO}.q{echo "$(EXTRALIBS)" > $(INST_ARCHAUTODIR)\extralibs.ld
+       $(CHMOD) 755 $@
+};
+
+# Old mechanism - still available:
+
+    push @m, "\t$self->{NOECHO}".q{echo "$(EXTRALIBS)" >> $(PERL_SRC)\ext.libs}."\n\n"
+       if $self->{PERL_SRC};
+
+    push @m, $self->dir_target('$(INST_ARCHAUTODIR)');
+    join('', "\n",@m);
+}
+
+=item dynamic_bs (o)
+
+Defines targets for bootstrap files.
+
+=cut
+
+sub dynamic_bs {
+    my($self, %attribs) = @_;
+    return '
+BOOTSTRAP =
+' unless $self->has_link_code();
+
+    return '
+BOOTSTRAP = '."$self->{BASEEXT}.bs".'
+
+# As Mkbootstrap might not write a file (if none is required)
+# we use touch to prevent make continually trying to remake it.
+# The DynaLoader only reads a non-empty file.
+$(BOOTSTRAP): '."$self->{MAKEFILE} $self->{BOOTDEP}".' $(INST_ARCHAUTODIR)\.exists
+       '.$self->{NOECHO}.'echo "Running Mkbootstrap for $(NAME) ($(BSLOADLIBS))"
+       '.$self->{NOECHO}.'$(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" \
+               -MExtUtils::Mkbootstrap \
+               -e "Mkbootstrap(\'$(BASEEXT)\',\'$(BSLOADLIBS)\');"
+       '.$self->{NOECHO}.'$(TOUCH) $(BOOTSTRAP)
+       $(CHMOD) 644 $@
+
+$(INST_BOOT): $(BOOTSTRAP) $(INST_ARCHAUTODIR)\.exists
+       '."$self->{NOECHO}$self->{RM_RF}".' $(INST_BOOT)
+       -'.$self->{CP}.' $(BOOTSTRAP) $(INST_BOOT)
+       $(CHMOD) 644 $@
+';
+}
+
+=item dynamic_lib (o)
+
+Defines how to produce the *.so (or equivalent) files.
+
+=cut
+
+sub dynamic_lib {
+       my($self, %attribs) = @_;
+    return '' unless $self->needs_linking(); #might be because of a subdir
+
+    return '' unless $self->has_link_code;
+
+    my($otherldflags) = $attribs{OTHERLDFLAGS} || ($BORLAND ? 'c0d32.obj': '');
+    my($inst_dynamic_dep) = $attribs{INST_DYNAMIC_DEP} || "";
+    my($ldfrom) = '$(LDFROM)';
+    my(@m);
+       (my $boot = $self->{NAME}) =~ s/:/_/g;
+       my ($mpk);
+    push(@m,'
+# This section creates the dynamically loadable $(INST_DYNAMIC)
+# from $(OBJECT) and possibly $(MYEXTLIB).
+OTHERLDFLAGS = '.$otherldflags.'
+INST_DYNAMIC_DEP = '.$inst_dynamic_dep.'
+
+$(INST_DYNAMIC): $(OBJECT) $(MYEXTLIB) $(BOOTSTRAP)
+');
+#      push(@m,
+#      q{      $(LD) -out:$@ $(LDDLFLAGS) }.$ldfrom.q{ $(OTHERLDFLAGS) }
+#      .q{$(MYEXTLIB) $(PERL_ARCHIVE) $(LDLOADLIBS) -def:$(EXPORT_LIST)});
+
+               # Create xdc data for an MT safe NLM in case of mpk build
+               if ( $self->{CCFLAGS} =~ m/ -DMPK_ON /) {
+                       $mpk=1;
+                       push @m, ' $(MPKTOOL) $(BASEEXT).xdc
+';
+               } else {
+                       $mpk=0;
+               }
+
+               push(@m,
+                       q{ $(LD) Form Novell NLM '$(DISTNAME) Extension, XS_VERSION=$(XS_VERSION)'} 
+                       );
+
+               # Taking care of long names like FileHandle, ByteLoader, SDBM_File etc
+               if($self->{NLM_SHORT_NAME}) {
+                       # In case of nlms with names exceeding 8 chars, build nlm in the 
+                       # current dir, rename and move to auto\lib.  If we create in auto\lib
+                       # in the first place, we can't rename afterwards.
+                       push(@m,
+                               q{ Name $(NLM_SHORT_NAME).$(DLEXT)}
+                               );
+               } else {
+                       push(@m,
+                               q{ Name $(INST_AUTODIR)\\$(BASEEXT).$(DLEXT)}
+                               );
+               }
+
+               push(@m,
+                  q{ Option Quiet Option Version = $(NLM_VERSION) Option Caseexact Option NoDefaultLibs Option screenname 'none' Option Synchronize }
+                  );
+
+               if ($mpk) {
+               push (@m, 
+               q{ Option XDCDATA=$(BASEEXT).xdc }
+               );
+               }
+
+               # Add additional lib files if any (SDBM_File)
+               if($self->{MYEXTLIB}) {
+                       push(@m,
+                               q{ Library $(MYEXTLIB) }
+                               );
+               }
+
+#For now lets comment all the Watcom lib calls
+#q{ LibPath $(LIBPTH) Library plib3s.lib Library math3s.lib Library clib3s.lib Library emu387.lib Library $(PERL_ARCHIVE) Library $(PERL_INC)\Main.lib}
+
+               push(@m,
+                               q{ Library $(PERL_ARCHIVE) Library $(PERL_INC)\Main.lib}                           
+                          .q{ Export boot_$(BOOT_SYMBOL) $(BASE_IMPORT) }
+                          .q{ FILE $(OBJECT:.obj=,)}
+                       );
+
+               # If it is having a short name, rename it 
+               if($self->{NLM_SHORT_NAME}) {
+                       push @m, '
+ if exist $(INST_AUTODIR)\\$(BASEEXT).$(DLEXT) del $(INST_AUTODIR)\\$(BASEEXT).$(DLEXT)';
+                       push @m, '
+ rename $(NLM_SHORT_NAME).$(DLEXT) $(BASEEXT).$(DLEXT)';
+                       push @m, '
+ move $(BASEEXT).$(DLEXT) $(INST_AUTODIR)';
+               }
+
+    push @m, '
+       $(CHMOD) 755 $@
+';
+
+    push @m, $self->dir_target('$(INST_ARCHAUTODIR)');
+    join('',@m);
+}
+
+sub perl_archive
+{
+    my ($self) = @_;
+    return '$(PERL_INC)\\'.$Config{'libperl'};
+}
+
+sub export_list
+{
+ my ($self) = @_;
+ return "$self->{BASEEXT}.def";
+}
+
+=item canonpath
+
+No physical check on the filesystem, but a logical cleanup of a
+path. On UNIX eliminated successive slashes and successive "/.".
+
+=cut
+
+sub canonpath {
+    my($self,$path) = @_;
+    $path =~ s/^([a-z]:)/\u$1/;
+    $path =~ s|/|\\|g;
+    $path =~ s|(.)\\+|$1\\|g ;                     # xx////xx  -> xx/xx
+    $path =~ s|(\\\.)+\\|\\|g ;                    # xx/././xx -> xx/xx
+    $path =~ s|^(\.\\)+|| unless $path eq ".\\";   # ./xx      -> xx
+    $path =~ s|\\$|| 
+             unless $path =~ m#^([a-z]:)?\\#;      # xx/       -> xx
+    $path .= '.' if $path =~ m#\\$#;
+    $path;
+}
+
+=item perl_script
+
+Takes one argument, a file name, and returns the file name, if the
+argument is likely to be a perl script. On MM_Unix this is true for
+any ordinary, readable file.
+
+=cut
+
+sub perl_script {
+    my($self,$file) = @_;
+    return $file if -r $file && -f _;
+    return "$file.pl" if -r "$file.pl" && -f _;
+    return "$file.bat" if -r "$file.bat" && -f _;
+    return;
+}
+
+=item pm_to_blib
+
+Defines target that copies all files in the hash PM to their
+destination and autosplits them. See L<ExtUtils::Install/DESCRIPTION>
+
+=cut
+
+sub pm_to_blib {
+    my $self = shift;
+    my($autodir) = $self->catdir('$(INST_LIB)','auto');
+    return q{
+pm_to_blib: $(TO_INST_PM)
+       }.$self->{NOECHO}.q{$(PERL) "-I$(INST_ARCHLIB)" "-I$(INST_LIB)" \
+       "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -MExtUtils::Install \
+        -e "pm_to_blib(}.
+       ($NMAKE ? 'qw[ <<pmfiles.dat ],'
+               : $DMAKE ? 'qw[ $(mktmp,pmfiles.dat $(PM_TO_BLIB:s,\\,\\\\,)\n) ],'
+                        : '{ qw[$(PM_TO_BLIB)] },'
+        ).q{'}.$autodir.q{')"
+       }. ($NMAKE ? q{
+$(PM_TO_BLIB)
+<<
+       } : '') . $self->{NOECHO}.q{$(TOUCH) $@
+};
+}
+
+=item test_via_harness (o)
+
+Helper method to write the test targets
+
+=cut
+
+sub test_via_harness {
+    my($self, $perl, $tests) = @_;
+    "\t$perl".q! -Mblib -I$(PERL_ARCHLIB) -I$(PERL_LIB) -e "use Test::Harness qw(&runtests $$verbose); $$verbose=$(TEST_VERBOSE); runtests @ARGV;" !."$tests\n";
+}
+
+
+=item tool_autosplit (override)
+
+Use Win32 quoting on command line.
+
+=cut
+
+sub tool_autosplit{
+    my($self, %attribs) = @_;
+    my($asl) = "";
+    $asl = "\$AutoSplit::Maxlen=$attribs{MAXLEN};" if $attribs{MAXLEN};
+    q{
+# Usage: $(AUTOSPLITFILE) FileToSplit AutoDirToSplitInto
+AUTOSPLITFILE = $(PERL) "-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" -MAutoSplit }.$asl.q{ -e "autosplit($$ARGV[0], $$ARGV[1], 0, 1, 1);"
+};
+}
+
+=item tools_other (o)
+
+Win32 overrides.
+
+Defines SHELL, LD, TOUCH, CP, MV, RM_F, RM_RF, CHMOD, UMASK_NULL in
+the Makefile. Also defines the perl programs MKPATH,
+WARN_IF_OLD_PACKLIST, MOD_INSTALL. DOC_INSTALL, and UNINSTALL.
+
+=cut
+
+sub tools_other {
+    my($self) = shift;
+    my @m;
+    my $bin_sh = $Config{sh} || 'cmd /c';
+    push @m, qq{
+SHELL = $bin_sh
+} unless $DMAKE;  # dmake determines its own shell 
+
+    for (qw/ CHMOD CP LD MV NOOP RM_F RM_RF TEST_F TOUCH UMASK_NULL DEV_NULL/ ) {
+       push @m, "$_ = $self->{$_}\n";
+    }
+
+    push @m, q{
+# The following is a portable way to say mkdir -p
+# To see which directories are created, change the if 0 to if 1
+MKPATH = $(PERL) -I$(PERL_ARCHLIB) -I$(PERL_LIB) -MExtUtils::Command -e mkpath
+
+# This helps us to minimize the effect of the .exists files A yet
+# better solution would be to have a stable file in the perl
+# distribution with a timestamp of zero. But this solution doesn't
+# need any changes to the core distribution and works with older perls
+EQUALIZE_TIMESTAMP = $(PERL) -I$(PERL_ARCHLIB) -I$(PERL_LIB) -MExtUtils::Command -e eqtime
+};
+
+
+    return join "", @m if $self->{PARENT};
+
+    push @m, q{
+# Here we warn users that an old packlist file was found somewhere,
+# and that they should call some uninstall routine
+WARN_IF_OLD_PACKLIST = $(PERL) -lwe "exit unless -f $$ARGV[0];" \\
+-e "print 'WARNING: I have found an old package in';" \\
+-e "print '    ', $$ARGV[0], '.';" \\
+-e "print 'Please make sure the two installations are not conflicting';"
+
+UNINST=0
+VERBINST=1
+
+MOD_INSTALL = $(PERL) -I$(INST_LIB) -I$(PERL_LIB) -MExtUtils::Install \
+-e "install({ @ARGV },'$(VERBINST)',0,'$(UNINST)');"
+
+DOC_INSTALL = $(PERL) -e "$$\=\"\n\n\";" \
+-e "print '=head2 ', scalar(localtime), ': C<', shift, '>', ' L<', shift, '>';" \
+-e "print '=over 4';" \
+-e "while (defined($$key = shift) and defined($$val = shift)) { print '=item *';print 'C<', \"$$key: $$val\", '>'; }" \
+-e "print '=back';"
+
+UNINSTALL =   $(PERL) -MExtUtils::Install \
+-e "uninstall($$ARGV[0],1,1); print \"\nUninstall is deprecated. Please check the";" \
+-e "print \" packlist above carefully.\n  There may be errors. Remove the\";" \
+-e "print \" appropriate files manually.\n  Sorry for the inconveniences.\n\""
+};
+
+    return join "", @m;
+}
+
+=item xs_o (o)
+
+Defines suffix rules to go from XS to object files directly. This is
+only intended for broken make implementations.
+
+=cut
+
+sub xs_o {     # many makes are too dumb to use xs_c then c_o
+    my($self) = shift;
+       return ''
+}
+
+=item top_targets (o)
+
+Defines the targets all, subdirs, config, and O_FILES
+
+=cut
+
+sub top_targets {
+# --- Target Sections ---
+
+    my($self) = shift;
+    my(@m);
+    push @m, '
+#all ::        config $(INST_PM) subdirs linkext manifypods
+';
+
+    push @m, '
+all :: pure_all htmlifypods manifypods
+       '.$self->{NOECHO}.'$(NOOP)
+' 
+         unless $self->{SKIPHASH}{'all'};
+    
+    push @m, '
+pure_all :: config pm_to_blib subdirs linkext
+       '.$self->{NOECHO}.'$(NOOP)
+
+subdirs :: $(MYEXTLIB)
+       '.$self->{NOECHO}.'$(NOOP)
+
+config :: '.$self->{MAKEFILE}.' $(INST_LIBDIR)\.exists
+       '.$self->{NOECHO}.'$(NOOP)
+
+config :: $(INST_ARCHAUTODIR)\.exists
+       '.$self->{NOECHO}.'$(NOOP)
+
+config :: $(INST_AUTODIR)\.exists
+       '.$self->{NOECHO}.'$(NOOP)
+';
+
+    push @m, $self->dir_target(qw[$(INST_AUTODIR) $(INST_LIBDIR) $(INST_ARCHAUTODIR)]);
+
+    if (%{$self->{HTMLLIBPODS}}) {
+       push @m, qq[
+config :: \$(INST_HTMLLIBDIR)/.exists
+       $self->{NOECHO}\$(NOOP)
+
+];
+       push @m, $self->dir_target(qw[$(INST_HTMLLIBDIR)]);
+    }
+
+    if (%{$self->{HTMLSCRIPTPODS}}) {
+       push @m, qq[
+config :: \$(INST_HTMLSCRIPTDIR)/.exists
+       $self->{NOECHO}\$(NOOP)
+
+];
+       push @m, $self->dir_target(qw[$(INST_HTMLSCRIPTDIR)]);
+    }
+
+    if (%{$self->{MAN1PODS}}) {
+       push @m, qq[
+config :: \$(INST_MAN1DIR)\\.exists
+       $self->{NOECHO}\$(NOOP)
+
+];
+       push @m, $self->dir_target(qw[$(INST_MAN1DIR)]);
+    }
+    if (%{$self->{MAN3PODS}}) {
+       push @m, qq[
+config :: \$(INST_MAN3DIR)\\.exists
+       $self->{NOECHO}\$(NOOP)
+
+];
+       push @m, $self->dir_target(qw[$(INST_MAN3DIR)]);
+    }
+
+    push @m, '
+$(O_FILES): $(H_FILES)
+' if @{$self->{O_FILES} || []} && @{$self->{H} || []};
+
+    push @m, q{
+help:
+       perldoc ExtUtils::MakeMaker
+};
+
+    push @m, q{
+Version_check:
+       }.$self->{NOECHO}.q{$(PERL) -I$(PERL_ARCHLIB) -I$(PERL_LIB) \
+               -MExtUtils::MakeMaker=Version_check \
+               -e "Version_check('$(MM_VERSION)')"
+};
+
+    join('',@m);
+}
+
+=item htmlifypods (o)
+
+Defines targets and routines to translate the pods into HTML manpages
+and put them into the INST_HTMLLIBDIR and INST_HTMLSCRIPTDIR
+directories.
+
+Same as MM_Unix version (changes command-line quoting).
+
+=cut
+
+sub htmlifypods {
+    my($self, %attribs) = @_;
+    return "\nhtmlifypods : pure_all\n\t$self->{NOECHO}\$(NOOP)\n" unless
+       %{$self->{HTMLLIBPODS}} || %{$self->{HTMLSCRIPTPODS}};
+    my($dist);
+    my($pod2html_exe);
+    if (defined $self->{PERL_SRC}) {
+       $pod2html_exe = $self->catfile($self->{PERL_SRC},'pod','pod2html');
+    } else {
+       $pod2html_exe = $self->catfile($Config{scriptdirexp},'pod2html');
+    }
+    unless ($pod2html_exe = $self->perl_script($pod2html_exe)) {
+       # No pod2html but some HTMLxxxPODS to be installed
+       print <<END;
+
+Warning: I could not locate your pod2html program. Please make sure,
+         your pod2html program is in your PATH before you execute 'make'
+
+END
+        $pod2html_exe = "-S pod2html";
+    }
+    my(@m);
+    push @m,
+qq[POD2HTML_EXE = $pod2html_exe\n],
+qq[POD2HTML = \$(PERL) -we "use File::Basename; use File::Path qw(mkpath); %m=\@ARGV;for (keys %m){" \\\n],
+q[-e "next if -e $$m{$$_} && -M $$m{$$_} < -M $$_ && -M $$m{$$_} < -M '],
+ $self->{MAKEFILE}, q[';" \\
+-e "print qq(Htmlifying $$m{$$_}\n);" \\
+-e "$$dir = dirname($$m{$$_}); mkpath($$dir) unless -d $$dir;" \\
+-e "system(qq[$$^X ].q["-I$(PERL_ARCHLIB)" "-I$(PERL_LIB)" $(POD2HTML_EXE) ].qq[$$_>$$m{$$_}])==0 or warn qq(Couldn\\047t install $$m{$$_}\n);" \\
+-e "chmod(oct($(PERM_RW))), $$m{$$_} or warn qq(chmod $(PERM_RW) $$m{$$_}: $$!\n);}"
+];
+    push @m, "\nhtmlifypods : pure_all ";
+    push @m, join " \\\n\t", keys %{$self->{HTMLLIBPODS}}, keys %{$self->{HTMLSCRIPTPODS}};
+
+    push(@m,"\n");
+    if (%{$self->{HTMLLIBPODS}} || %{$self->{HTMLSCRIPTPODS}}) {
+       push @m, "\t$self->{NOECHO}\$(POD2HTML) \\\n\t";
+       push @m, join " \\\n\t", %{$self->{HTMLLIBPODS}}, %{$self->{HTMLSCRIPTPODS}};
+    }
+    join('', @m);
+}
+
+=item manifypods (o)
+
+We don't want manpage process.
+
+=cut
+
+sub manifypods {
+    my($self) = shift;
+    return "\nmanifypods :\n\t$self->{NOECHO}\$(NOOP)\n";
+}
+
+=item dist_ci (o)
+
+Same as MM_Unix version (changes command-line quoting).
+
+=cut
+
+sub dist_ci {
+    my($self) = shift;
+    my @m;
+    push @m, q{
+ci :
+       $(PERL) -I$(PERL_ARCHLIB) -I$(PERL_LIB) -MExtUtils::Manifest=maniread \\
+               -e "@all = keys %{ maniread() };" \\
+               -e "print(\"Executing $(CI) @all\n\"); system(\"$(CI) @all\");" \\
+               -e "print(\"Executing $(RCS_LABEL) ...\n\"); system(\"$(RCS_LABEL) @all\");"
+};
+    join "", @m;
+}
+
+=item dist_core (o)
+
+Same as MM_Unix version (changes command-line quoting).
+
+=cut
+
+sub dist_core {
+    my($self) = shift;
+    my @m;
+    push @m, q{
+dist : $(DIST_DEFAULT)
+       }.$self->{NOECHO}.q{$(PERL) -le "print \"Warning: Makefile possibly out of date with $$vf\" if " \
+           -e "-e ($$vf=\"$(VERSION_FROM)\") and -M $$vf < -M \"}.$self->{MAKEFILE}.q{\";"
+
+tardist : $(DISTVNAME).tar$(SUFFIX)
+
+zipdist : $(DISTVNAME).zip
+
+$(DISTVNAME).tar$(SUFFIX) : distdir
+       $(PREOP)
+       $(TO_UNIX)
+       $(TAR) $(TARFLAGS) $(DISTVNAME).tar $(DISTVNAME)
+       $(RM_RF) $(DISTVNAME)
+       $(COMPRESS) $(DISTVNAME).tar
+       $(POSTOP)
+
+$(DISTVNAME).zip : distdir
+       $(PREOP)
+       $(ZIP) $(ZIPFLAGS) $(DISTVNAME).zip $(DISTVNAME)
+       $(RM_RF) $(DISTVNAME)
+       $(POSTOP)
+
+uutardist : $(DISTVNAME).tar$(SUFFIX)
+       uuencode $(DISTVNAME).tar$(SUFFIX) \\
+               $(DISTVNAME).tar$(SUFFIX) > \\
+               $(DISTVNAME).tar$(SUFFIX)_uu
+
+shdist : distdir
+       $(PREOP)
+       $(SHAR) $(DISTVNAME) > $(DISTVNAME).shar
+       $(RM_RF) $(DISTVNAME)
+       $(POSTOP)
+};
+    join "", @m;
+}
+
+=item pasthru (o)
+
+Defines the string that is passed to recursive make calls in
+subdirectories.
+
+=cut
+
+sub pasthru {
+    my($self) = shift;
+    return "PASTHRU = " . ($NMAKE ? "-nologo" : "");
+}
+
+
+
+1;
+__END__
+
+=back
+
+=cut 
+
+
index a4cd6f4..82fe312 100644 (file)
@@ -71,6 +71,7 @@ $Is_OS2   = $^O eq 'os2';
 $Is_Mac   = $^O eq 'MacOS';
 $Is_Win32 = $^O eq 'MSWin32';
 $Is_Cygwin= $^O eq 'cygwin';
+$Is_NetWare = $Config{'osname'} eq 'NetWare';
 
 require ExtUtils::MM_Unix;
 
@@ -84,6 +85,11 @@ if ($Is_OS2) {
 if ($Is_Mac) {
     require ExtUtils::MM_MacOS;
 }
+if ($Is_NetWare) {
+       $^O = 'NetWare';
+       require ExtUtils::MM_NW5;
+       $Is_Win32=0;
+}
 if ($Is_Win32) {
     require ExtUtils::MM_Win32;
 }
index 4a17471..d5f44f8 100644 (file)
@@ -75,6 +75,7 @@ sub copy {
        && !($from_a_handle && $^O eq 'mpeix')  # and neither can MPE/iX.
        && !($from_a_handle && $^O eq 'MSWin32')
        && !($from_a_handle && $^O eq 'MacOS')
+       && !($from_a_handle && $^O eq 'NetWare')
        )
     {
        return syscopy($from, $to);
index d28c2f9..e2bb8ab 100644 (file)
@@ -1077,7 +1077,7 @@ $File::Find::current_dir = File::Spec->curdir || '.';
 
 $File::Find::dont_use_nlink = 1
     if $^O eq 'os2' || $^O eq 'dos' || $^O eq 'amigaos' || $^O eq 'MSWin32' ||
-       $^O eq 'cygwin' || $^O eq 'epoc';
+       $^O eq 'cygwin' || $^O eq 'epoc' || $^O eq 'NetWare';
 
 # Set dont_use_nlink in your hint file if your system's stat doesn't
 # report the number of links in a directory as an indication
index 15a4af6..7428894 100644 (file)
@@ -502,6 +502,10 @@ if ($notty) {
     $console = undef;
   }
 
+  if ($^O eq 'NetWare') {
+       $console = undef;
+  }
+
   # Around a bug:
   if (defined $ENV{OS2_SHELL} and ($slave_editor or $ENV{WINDOWID})) { # In OS/2
     $console = undef;
@@ -2801,7 +2805,7 @@ sub methods_via {
 }
 
 sub setman { 
-    $doccmd = $^O !~ /^(?:MSWin32|VMS|os2|dos|amigaos|riscos|MacOS)\z/s
+    $doccmd = $^O !~ /^(?:MSWin32|VMS|os2|dos|amigaos|riscos|MacOS|NetWare)\z/s
                ? "man"             # O Happy Day!
                : "perldoc";        # Alas, poor unfortunates
 }
index 87e34b4..5d9b7a1 100644 (file)
@@ -50,9 +50,12 @@ while (@ARGV) {
     $define{$1} = $2 if ($flag =~ /^-D(\w+)=(.+)$/);
     $CCTYPE   = $1 if ($flag =~ /^CCTYPE=(\w+)$/);
     $PLATFORM = $1 if ($flag =~ /^PLATFORM=(\w+)$/);
+       if ($PLATFORM eq 'netware') {
+               $FILETYPE = $1 if ($flag =~ /^FILETYPE=(\w+)$/);
+       }
 }
 
-my @PLATFORM = qw(aix win32 os2 MacOS);
+my @PLATFORM = qw(aix win32 os2 MacOS netware);
 my %PLATFORM;
 @PLATFORM{@PLATFORM} = ();
 
@@ -72,7 +75,7 @@ my $perlio_sym  = "perlio.sym";
 if ($PLATFORM eq 'aix') {
     # Nothing for now.
 }
-elsif ($PLATFORM eq 'win32') {
+elsif ($PLATFORM eq 'win32' || $PLATFORM eq 'netware') {
     $CCTYPE = "MSVC" unless defined $CCTYPE;
     foreach ($thrdvar_h, $intrpvar_h, $perlvars_h, $global_sym,
                $pp_sym, $globvar_sym, $perlio_sym) {
@@ -86,7 +89,7 @@ elsif ($PLATFORM eq 'MacOS') {
     }
 }
 
-unless ($PLATFORM eq 'win32' || $PLATFORM eq 'MacOS') {
+unless ($PLATFORM eq 'win32' || $PLATFORM eq 'MacOS' || $PLATFORM eq 'netware') {
     open(CFG,$config_sh) || die "Cannot open $config_sh: $!\n";
     while (<CFG>) {
        if (/^(?:ccflags|optimize)='(.+)'$/) {
@@ -173,6 +176,17 @@ elsif ($PLATFORM eq 'aix') {
        print "#!\n";
     }
 }
+elsif ($PLATFORM eq 'netware') {
+       if ($FILETYPE eq 'def') {
+       print "LIBRARY Perl57\n";
+       print "DESCRIPTION 'Perl interpreter for NetWare'\n";
+       print "EXPORTS\n";
+       }
+       if ($define{PERL_IMPLICIT_SYS}) {
+       output_symbol("perl_get_host_info");
+       output_symbol("perl_alloc_override");
+       }
+}
 
 my %skip;
 my %export;
@@ -348,7 +362,56 @@ elsif ($PLATFORM eq 'MacOS') {
                    Perl_sys_intern_init
                    )];
 }
-
+elsif ($PLATFORM eq 'netware') {
+       skip_symbols [qw(
+                       PL_statusvalue_vms
+                       PL_archpat_auto
+                       PL_cryptseen
+                       PL_DBcv
+                       PL_generation
+                       PL_lastgotoprobe
+                       PL_linestart
+                       PL_modcount
+                       PL_pending_ident
+                       PL_sortcxix
+                       PL_sublex_info
+                       PL_timesbuf
+                       main
+                       Perl_ErrorNo
+                       Perl_GetVars
+                       Perl_do_exec3
+                       Perl_do_ipcctl
+                       Perl_do_ipcget
+                       Perl_do_msgrcv
+                       Perl_do_msgsnd
+                       Perl_do_semop
+                       Perl_do_shmio
+                       Perl_dump_fds
+                       Perl_init_thread_intern
+                       Perl_my_bzero
+                       Perl_my_htonl
+                       Perl_my_ntohl
+                       Perl_my_swap
+                       Perl_my_chsize
+                       Perl_same_dirent
+                       Perl_setenv_getix
+                       Perl_unlnk
+                       Perl_watch
+                       Perl_safexcalloc
+                       Perl_safexmalloc
+                       Perl_safexfree
+                       Perl_safexrealloc
+                       Perl_my_memcmp
+                       Perl_my_memset
+                       PL_cshlen
+                       PL_cshname
+                       PL_opsave
+                       Perl_do_exec
+                       Perl_getenv_len
+                       Perl_my_pclose
+                       Perl_my_popen
+                       )];
+}
 
 unless ($define{'DEBUGGING'}) {
     skip_symbols [qw(
@@ -870,6 +933,140 @@ elsif ($PLATFORM eq 'MacOS') {
 
     close MACSYMS;
 }
+elsif ($PLATFORM eq 'netware') {
+foreach my $symbol (qw(
+                       boot_DynaLoader
+                       Perl_init_os_extras
+                       Perl_thread_create
+                       Perl_nw5_init
+                       RunPerl
+                       AllocStdPerl
+                       FreeStdPerl
+                       do_spawn2
+                       do_aspawn
+                       nw_uname
+                       nw_stdin
+                       nw_stdout
+                       nw_stderr
+                       nw_feof
+                       nw_ferror
+                       nw_fopen
+                       nw_fclose
+                       nw_clearerr
+                       nw_getc
+                       nw_fgets
+                       nw_fputc
+                       nw_fputs
+                       nw_fflush
+                       nw_ungetc
+                       nw_fileno
+                       nw_fdopen
+                       nw_freopen
+                       nw_fread
+                       nw_fwrite
+                       nw_setbuf
+                       nw_setvbuf
+                       nw_vfprintf
+                       nw_ftell
+                       nw_fseek
+                       nw_rewind
+                       nw_tmpfile
+                       nw_fgetpos
+                       nw_fsetpos
+                       nw_dup
+                       nw_access
+                       nw_chmod
+                       nw_chsize
+                       nw_close
+                       nw_dup2
+                       nw_flock
+                       nw_isatty
+                       nw_link
+                       nw_lseek
+                       nw_stat
+                       nw_mktemp
+                       nw_open
+                       nw_read
+                       nw_rename
+                       nw_setmode
+                       nw_unlink
+                       nw_utime
+                       nw_write
+                       nw_chdir
+                       nw_rmdir
+                       nw_closedir
+                       nw_opendir
+                       nw_readdir
+                       nw_rewinddir
+                       nw_seekdir
+                       nw_telldir
+                       nw_htonl
+                       nw_htons
+                       nw_ntohl
+                       nw_ntohs
+                       nw_accept
+                       nw_bind
+                       nw_connect
+                       nw_endhostent
+                       nw_endnetent
+                       nw_endprotoent
+                       nw_endservent
+                       nw_gethostbyaddr
+                       nw_gethostbyname
+                       nw_gethostent
+                       nw_gethostname
+                       nw_getnetbyaddr
+                       nw_getnetbyname
+                       nw_getnetent
+                       nw_getpeername
+                       nw_getprotobyname
+                       nw_getprotobynumber
+                       nw_getprotoent
+                       nw_getservbyname
+                       nw_getservbyport
+                       nw_getservent
+                       nw_getsockname
+                       nw_getsockopt
+                       nw_inet_addr
+                       nw_listen
+                       nw_socket
+                       nw_recv
+                       nw_recvfrom
+                       nw_select
+                       nw_send
+                       nw_sendto
+                       nw_sethostent
+                       nw_setnetent
+                       nw_setprotoent
+                       nw_setservent
+                       nw_shutdown
+                       nw_crypt
+                       nw_execvp
+                       nw_kill
+                       nw_Popen
+                       nw_Pclose
+                       nw_Pipe
+                       nw_times
+                       nw_waitpid
+                       nw_getpid
+                       nw_spawnvp
+                       nw_os_id
+                       nw_open_osfhandle
+                       nw_get_osfhandle
+                       nw_abort
+                       nw_sleep
+                       nw_wait
+                       nw_dynaload
+                       nw_strerror
+                       fnFpSetMode
+                       fnInsertHashListAddrs
+                       fnGetHashListAddrs
+                       Perl_deb
+                          ))
+    {
+       try_symbol($symbol);
+    }
+}
 
 # Now all symbols should be defined because
 # next we are going to output them.
@@ -878,6 +1075,13 @@ foreach my $symbol (sort keys %export) {
     output_symbol($symbol);
 }
 
+if ($PLATFORM eq 'netware') {
+       # This may not be the right way to do.  This is to make sure
+       # that the last symbol will not contain a comma else
+       # Watcom linker cribs
+       print "\tdummy\n";
+}
+
 sub emit_symbol {
     my $symbol = shift;
     chomp($symbol);
@@ -919,6 +1123,9 @@ sub output_symbol {
     elsif ($PLATFORM eq 'aix' || $PLATFORM eq 'MacOS') {
        print "$symbol\n";
     }
+       elsif ($PLATFORM eq 'netware') {
+       print "\t$symbol,\n";
+       }
 }
 
 1;
diff --git a/perl.c b/perl.c
index a830230..be4a786 100644 (file)
--- a/perl.c
+++ b/perl.c
@@ -817,14 +817,24 @@ perl_free(pTHXx)
 #if defined(PERL_OBJECT)
     PerlMem_free(this);
 #else
-#  if defined(WIN32)
+#  if defined(WIN32) || defined(NETWARE)
 #  if defined(PERL_IMPLICIT_SYS)
-    void *host = w32_internal_host;
-    if (PerlProc_lasthost()) {
+    #ifdef NETWARE
+               void *host = nw_internal_host;
+       #else
+               void *host = w32_internal_host;
+       #endif
+       #ifndef NETWARE
+       if (PerlProc_lasthost()) {
        PerlIO_cleanup();
-    }
+       }
+       #endif
     PerlMem_free(aTHXx);
-    win32_delete_internal_host(host);
+       #ifdef NETWARE
+               nw5_delete_internal_host(host);
+       #else
+               win32_delete_internal_host(host);
+       #endif
 #else
     PerlIO_cleanup();
     PerlMem_free(aTHXx);
diff --git a/perl.h b/perl.h
index ba0c5c7..4c82ca7 100644 (file)
--- a/perl.h
+++ b/perl.h
@@ -360,15 +360,15 @@ register struct op *Perl_op asm(stringify(OP_IN_REGISTER));
  */
 
 /* define this once if either system, instead of cluttering up the src */
-#if defined(MSDOS) || defined(atarist) || defined(WIN32)
+#if defined(MSDOS) || defined(atarist) || defined(WIN32) || defined(NETWARE)
 #define DOSISH 1
 #endif
 
-#if defined(__STDC__) || defined(vax11c) || defined(_AIX) || defined(__stdc__) || defined(__cplusplus) || defined( EPOC)
+#if defined(__STDC__) || defined(vax11c) || defined(_AIX) || defined(__stdc__) || defined(__cplusplus) || defined( EPOC) || defined(NETWARE)
 # define STANDARD_C 1
 #endif
 
-#if defined(__cplusplus) || defined(WIN32) || defined(__sgi) || defined(OS2) || defined(__DGUX) || defined( EPOC) || defined(__QNX__)
+#if defined(__cplusplus) || defined(WIN32) || defined(__sgi) || defined(OS2) || defined(__DGUX) || defined( EPOC) || defined(__QNX__) || defined(NETWARE)
 # define DONT_DECLARE_STD 1
 #endif
 
@@ -777,6 +777,9 @@ typedef struct perl_mstats perl_mstats_t;
 #   endif
 # endif
 # ifdef I_NETDB
+#  ifdef NETWARE
+#   include<stdio.h>
+#  endif
 #  include <netdb.h>
 # endif
 # ifndef ENOTSOCK
@@ -1788,6 +1791,9 @@ typedef struct ptr_tbl PTR_TBL_t;
     * atomic.h everywhere */
 #  define EMULATE_ATOMIC_REFCOUNTS
 #  endif
+#  ifdef NETWARE
+#   include <nw5thread.h>
+#  else
 #  ifdef FAKE_THREADS
 #    include "fakethr.h"
 #  else
@@ -1818,12 +1824,17 @@ typedef pthread_key_t   perl_key;
 #      endif /* OS2 */
 #    endif /* WIN32 */
 #  endif /* FAKE_THREADS */
+#endif /* NETWARE */
 #endif /* USE_THREADS || USE_ITHREADS */
 
 #ifdef WIN32
 #  include "win32.h"
 #endif
 
+#ifdef NETWARE
+#  include "netware.h"
+#endif
+
 #ifdef VMS
 #   define STATUS_NATIVE       PL_statusvalue_vms
 #   define STATUS_NATIVE_EXPORT \
@@ -3596,7 +3607,9 @@ typedef struct am_table_short AMTS;
 
 #ifndef PERL_MICRO
 #   ifndef PERL_OLD_SIGNALS
-#       define PERL_ASYNC_CHECK() if (PL_sig_pending) despatch_signals()
+#              ifndef PERL_ASYNC_CHECK
+#                      define PERL_ASYNC_CHECK() if (PL_sig_pending) despatch_signals()
+#              endif
 #   endif
 #endif
 
index c9b7f72..590abf6 100644 (file)
--- a/perlio.c
+++ b/perlio.c
@@ -62,7 +62,11 @@ perlsio_binmode(FILE *fp, int iotype, int mode)
     return 0;
 #  else
     dTHX;
+       #ifdef NETWARE
+       if (PerlLIO_setmode(fp, mode) != -1) {
+       #else
     if (PerlLIO_setmode(fileno(fp), mode) != -1) {
+       #endif
 #    if defined(WIN32) && defined(__BORLANDC__)
        /* The translation mode of the stream is maintained independent
         * of the translation mode of the fd in the Borland RTL (heavy
index 4e508dd..78bd06a 100644 (file)
--- a/perlio.h
+++ b/perlio.h
 
 #if defined(PERL_IMPLICIT_SYS)
 #ifndef USE_PERLIO
+#ifndef NETWARE
 # define USE_PERLIO
 #endif
 #endif
+#endif
 
 #ifndef USE_PERLIO
 # define USE_STDIO
index c61f09e..c3b34c6 100644 (file)
--- a/pp_sys.c
+++ b/pp_sys.c
@@ -49,6 +49,10 @@ extern "C" int syscall(unsigned long,...);
 # include <sys/resource.h>
 #endif
 
+#ifdef NETWARE
+NETDB_DEFINE_CONTEXT
+#endif
+
 #ifdef HAS_SELECT
 # ifdef I_SYS_SELECT
 #  include <sys/select.h>
index 309ac71..b4b04da 100755 (executable)
@@ -36,7 +36,7 @@ if ($z eq $y) {print "ok 2\n";} else {print "not ok 2\n";}
 
 if ($count == 7) {print "ok 3\n";} else {print "not ok 3\n";}
 
-$_ = ($^O eq 'MSWin32') ? `type Comp.try`
+$_ = (($^O eq 'MSWin32') || $^O eq 'NetWare') ? `type Comp.try`
     : ($^O eq 'MacOS') ? `catenate Comp.try`
     : `cat Comp.try`;
 
index 9ae83e4..4891f5b 100755 (executable)
@@ -5,7 +5,8 @@
 print "1..3\n";
 
 $PERL = ($^O eq 'MSWin32') ? '.\perl'
-    : ($^O eq 'MacOS') ? $^X : './perl';
+        : (($^O eq 'NetWare') ? 'perl'
+           : ($^O eq 'MacOS') ? $^X : './perl');
 $x = `$PERL -le "print 'ok';"`;
 
 if ($x eq "ok\n") {print "ok 1\n";} else {print "not ok 1\n";}
index 2b8f23b..5df3420 100755 (executable)
@@ -18,6 +18,9 @@ close try;
 if ($^O eq 'MSWin32') {
   $x = `.\\perl -e "while (<>) {print \$.,\$_;}" Io_argv1.tmp Io_argv1.tmp`;
 }
+elsif ($^O eq 'NetWare') {
+  $x = `perl -e "while (<>) {print \$.,\$_;}" Io_argv1.tmp Io_argv1.tmp`;
+}
 else {
   $x = `./perl -e 'while (<>) {print \$.,\$_;}' Io_argv1.tmp Io_argv1.tmp`;
 }
@@ -26,6 +29,9 @@ if ($x eq "1a line\n2a line\n") {print "ok 1\n";} else {print "not ok 1\n";}
 if ($^O eq 'MSWin32') {
   $x = `.\\perl -le "print 'foo'" | .\\perl -e "while (<>) {print \$_;}" Io_argv1.tmp -`;
 }
+elsif ($^O eq 'NetWare') {
+  $x = `perl -le "print 'foo'" | perl -e "while (<>) {print \$_;}" Io_argv1.tmp -`;
+}
 else {
   $x = `echo foo|./perl -e 'while (<>) {print $_;}' Io_argv1.tmp -`;
 }
@@ -34,6 +40,9 @@ if ($x eq "a line\nfoo\n") {print "ok 2\n";} else {print "not ok 2\n";}
 if ($^O eq 'MSWin32') {
   $x = `.\\perl -le "print 'foo'" |.\\perl -e "while (<>) {print \$_;}"`;
 }
+elsif ($^O eq 'NetWare') {
+  $x = `perl -le "print 'foo'" | perl -e "while (<>) {print \$_;}"`;
+}
 else {
   $x = `echo foo|./perl -e 'while (<>) {print $_;}'`;
 }
index 9b656ec..a641db7 100755 (executable)
@@ -28,7 +28,7 @@ close(STDERR);
 open(STDOUT,">&dupout");
 open(STDERR,">&duperr");
 
-if ($^O eq 'MSWin32') { print `type Io.dup` }
+if (($^O eq 'MSWin32') || ($^O eq 'NetWare')) { print `type Io.dup` }
 else                  { system 'cat Io.dup' }
 unlink 'Io.dup';
 
index c445d5e..091bd44 100755 (executable)
--- a/t/io/fs.t
+++ b/t/io/fs.t
@@ -9,7 +9,7 @@ BEGIN {
 
 use Config;
 
-$Is_Dosish = ($^O eq 'MSWin32' or $^O eq 'dos' or
+$Is_Dosish = ($^O eq 'MSWin32' or $^O eq 'NetWare' or $^O eq 'dos' or
              $^O eq 'os2' or $^O eq 'mint');
 
 if (defined &Win32::IsWinNT && Win32::IsWinNT()) {
@@ -18,17 +18,17 @@ if (defined &Win32::IsWinNT && Win32::IsWinNT()) {
 
 print "1..29\n";
 
-$wd = (($^O eq 'MSWin32') ? `cd` : `pwd`);
+$wd = ((($^O eq 'MSWin32') || ($^O eq 'NetWare')) ? `cd` : `pwd`);
 chop($wd);
 
-if ($^O eq 'MSWin32') { `rmdir /s /q tmp 2>nul`; `mkdir tmp`; }
+if (($^O eq 'MSWin32') || ($^O eq 'NetWare')) { `rmdir /s /q tmp 2>nul`; `mkdir tmp`; }
 else {  `rm -f tmp 2>/dev/null; mkdir tmp 2>/dev/null`; }
 chdir './tmp';
 `/bin/rm -rf a b c x` if -x '/bin/rm';
 
 umask(022);
 
-if ($^O eq 'MSWin32') { print "ok 1 # skipped: bogus umask()\n"; }
+if (($^O eq 'MSWin32') || ($^O eq 'NetWare')) { print "ok 1 # skipped: bogus umask()\n"; }
 elsif ((umask(0)&0777) == 022) {print "ok 1\n";} else {print "not ok 1\n";}
 open(fh,'>x') || die "Can't create x";
 close(fh);
@@ -58,7 +58,7 @@ elsif (($mode & 0777) == 0666)
     {print "ok 5\n";} 
 else {print "not ok 5\n";}
 
-$newmode = $^O eq 'MSWin32' ? 0444 : 0777;
+$newmode = (($^O eq 'MSWin32') || ($^O eq 'NetWare')) ? 0444 : 0777;
 if ((chmod $newmode,'a') == 1) {print "ok 6\n";} else {print "not ok 6\n";}
 
 ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,
@@ -68,7 +68,7 @@ elsif (($mode & 0777) == $newmode) {print "ok 7\n";}
 else {print "not ok 7\n";}
 
 $newmode = 0700;
-if ($^O eq 'MSWin32') {
+if (($^O eq 'MSWin32') || ($^O eq 'NetWare')) {
     chmod 0444, 'x';
     $newmode = 0666;
 }
@@ -109,9 +109,9 @@ $foo = (utime 500000000,500000000 + $delta,'b');
 if ($foo == 1) {print "ok 16\n";} else {print "not ok 16 $foo\n";}
 ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,
     $blksize,$blocks) = stat('b');
-if ($^O eq 'MSWin32') { print "ok 17 # skipped: bogus (stat)[1]\n"; }
+if (($^O eq 'MSWin32') || ($^O eq 'NetWare')) { print "ok 17 # skipped: bogus (stat)[1]\n"; }
 elsif ($ino) {print "ok 17\n";} else {print "not ok 17\n";}
-if ($wd =~ m#$Config{'afsroot'}/# || $^O eq 'amigaos' || $^O eq 'dos' || $^O eq 'MSWin32')
+if ($wd =~ m#$Config{'afsroot'}/# || $^O eq 'amigaos' || $^O eq 'dos' || $^O eq 'MSWin32' || $^O eq 'NetWare')
     {print "ok 18 # skipped: granularity of the filetime\n";}
 elsif ($atime == 500000000 && $mtime == 500000000 + $delta)
     {print "ok 18\n";}
@@ -135,7 +135,7 @@ unlink 'c';
 chdir $wd || die "Can't cd back to $wd";
 
 unlink 'c';
-if ($^O ne 'MSWin32' and `ls -l perl 2>/dev/null` =~ /^l.*->/) {
+if ((($^O eq 'MSWin32') || ($^O eq 'NetWare')) and `ls -l perl 2>/dev/null` =~ /^l.*->/) {
     # we have symbolic links
     system("cp TEST TEST$$");
     # we have to copy because e.g. GNU grep gets huffy if we have
index ff410a7..4582cc2 100755 (executable)
@@ -13,6 +13,12 @@ if ($^O eq 'MSWin32') {
   `.\\perl -le "print 'foo'" > .b`;
   `.\\perl -le "print 'foo'" > .c`;
 }
+elsif ($^O eq 'NetWare') {
+  $CAT = 'perl -e "print<>"';
+  `perl -le "print 'foo'" > .a`;
+  `perl -le "print 'foo'" > .b`;
+  `perl -le "print 'foo'" > .c`;
+}
 elsif ($^O eq 'VMS') {
   $CAT = 'MCR []perl. -e "print<>"';
   `MCR []perl. -le "print 'foo'" > ./.a`;
index 10a5c5f..6070223 100755 (executable)
@@ -13,6 +13,12 @@ if ($^O eq 'MSWin32') {
   `.\\perl -le "print 'foo'" > .b`;
   `.\\perl -le "print 'foo'" > .c`;
 }
+elsif ($^O eq 'NetWare') {
+  $CAT = 'perl -e "print<>"';
+  `perl -le "print 'foo'" > .a`;
+  `perl -le "print 'foo'" > .b`;
+  `perl -le "print 'foo'" > .c`;
+}
 elsif ($^O eq 'VMS') {
   $CAT = 'MCR []perl. -e "print<>"';
   `MCR []perl. -le "print 'foo'" > ./.a`;
index c840c92..f2336dd 100755 (executable)
@@ -6,7 +6,7 @@ print "1..23\n";
 
 $TST = 'tst';
 
-$Is_Dosish = ($^O eq 'MSWin32' or $^O eq 'dos' or
+$Is_Dosish = ($^O eq 'MSWin32' or $^O eq 'NetWare' or $^O eq 'dos' or
              $^O eq 'os2' or $^O eq 'mint' or $^O eq 'cygwin');
 
 open($TST, 'harness') || (die "Can't open harness");
@@ -50,7 +50,7 @@ if ($. == 0) { print "not ok 14\n"; } else { print "ok 14\n"; }
 
 $curline = $.;
 open(other, 'harness') || (die "Can't open harness: $!");
-binmode other if $^O eq 'MSWin32';
+binmode other if (($^O eq 'MSWin32') || ($^O eq 'NetWare'));
 
 {
     local($.);
index 08d1f7c..30b3c7a 100755 (executable)
@@ -16,7 +16,7 @@ use Fcntl;
 
 print "1..12\n";
 
-$Is_Dosish = ($^O eq 'amigaos' || $^O eq 'MSWin32' or $^O eq 'dos' or
+$Is_Dosish = ($^O eq 'amigaos' || $^O eq 'MSWin32' || $^O eq 'NetWare' or $^O eq 'dos' or
              $^O eq 'os2' or $^O eq 'mint');
 
 unlink <Op_dbmx*>;
index 7f523b5..bc9d896 100644 (file)
@@ -30,6 +30,7 @@ chomp($a = `$^X $path "-MB::Stash" "-Mwarnings" -e1`);
 $a = join ',', sort split /,/, $a;
 $a =~ s/-u(PerlIO|open)(?:::\w+)?,//g if defined $Config{'useperlio'} and $Config{'useperlio'} eq 'define';
 $a =~ s/-uWin32,// if $^O eq 'MSWin32';
+$a =~ s/-uNetWare,// if $^O eq 'NetWare';
 $a =~ s/-u(Cwd|File|File::Copy|OS2),//g if $^O eq 'os2';
 $a =~ s/-uCwd,// if $^O eq 'cygwin';
   $b = '-uCarp,-uCarp::Heavy,-uDB,-uExporter,-uExporter::Heavy,-uattributes,'
index 5a3ecae..09b45d6 100644 (file)
@@ -30,7 +30,7 @@ eval { fastcwd };
 # Must find an external pwd (or equivalent) command.
 
 my $pwd_cmd =
-    ($^O eq "MSWin32") ? "cd" : (grep { -x && -f } map { "$_/pwd" }
+    ($^O eq "MSWin32" || $^O eq "NetWare") ? "cd" : (grep { -x && -f } map { "$_/pwd" }
                               split m/$Config{path_sep}/, $ENV{PATH})[0];
 
 if ($^O eq 'VMS') { $pwd_cmd = 'SHOW DEFAULT'; }
@@ -38,7 +38,7 @@ if ($^O eq 'VMS') { $pwd_cmd = 'SHOW DEFAULT'; }
 if (defined $pwd_cmd) {
     chomp(my $start = `$pwd_cmd`);
     # Win32's cd returns native C:\ style
-    $start =~ s,\\,/,g if $^O eq 'MSWin32';
+    $start =~ s,\\,/,g if ($^O eq 'MSWin32' || $^O eq "NetWare");
     # DCL SHOW DEFAULT has leading spaces
     $start =~ s/^\s+// if $^O eq 'VMS';
     if ($?) {
index 1822823..4b4a796 100755 (executable)
@@ -142,7 +142,7 @@ ok(19, $X = tie(%h, 'DB_File',$Dfile, O_RDWR|O_CREAT, 0640, $DB_BTREE )) ;
 
 my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,
    $blksize,$blocks) = stat($Dfile);
-ok(20, ($mode & 0777) == ($^O eq 'os2' ? 0666 : 0640) || $^O eq 'amigaos' || $^O eq 'MSWin32');
+ok(20, ($mode & 0777) == ($^O eq 'os2' ? 0666 : 0640) || $^O eq 'amigaos' || $^O eq 'MSWin32' || $^O eq 'NetWare');
 
 my ($key, $value, $i);
 while (($key,$value) = each(%h)) {
index effc60b..6f2ef37 100755 (executable)
@@ -108,7 +108,7 @@ ok(15, $X = tie(%h, 'DB_File',$Dfile, O_RDWR|O_CREAT, 0640, $DB_HASH ) );
 
 my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,
    $blksize,$blocks) = stat($Dfile);
-ok(16, ($mode & 0777) == ($^O eq 'os2' ? 0666 : 0640) || $^O eq 'amigaos' || $^O eq 'MSWin32');
+ok(16, ($mode & 0777) == ($^O eq 'os2' ? 0666 : 0640) || $^O eq 'amigaos' || $^O eq 'MSWin32' || $^O eq 'NetWare');
 
 my ($key, $value, $i);
 while (($key,$value) = each(%h)) {
index 4ca547f..6dd913c 100755 (executable)
@@ -153,7 +153,7 @@ my @h ;
 ok(17, $X = tie @h, 'DB_File', $Dfile, O_RDWR|O_CREAT, 0640, $DB_RECNO ) ;
 
 ok(18, ((stat($Dfile))[2] & 0777) == ($^O eq 'os2' ? 0666 : 0640)
-       ||  $^O eq 'MSWin32' || $^O eq 'amigaos') ;
+       ||  $^O eq 'MSWin32' ||  $^O eq 'NetWare' || $^O eq 'amigaos') ;
 
 #my $l = @h ;
 my $l = $X->length ;
index 0f3e177..eaddf49 100755 (executable)
@@ -72,7 +72,7 @@ if ($^O eq 'dos')
 
 ($rd,$wr) = FileHandle::pipe;
 
-if ($^O eq 'VMS' || $^O eq 'os2' || $^O eq 'amigaos' || $^O eq 'MSWin32' ||
+if ($^O eq 'VMS' || $^O eq 'os2' || $^O eq 'amigaos' || $^O eq 'MSWin32' || $^O eq 'NetWare' ||
     $Config{d_fork} ne 'define') {
   $wr->autoflush;
   $wr->printf("ok %d\n",11);
index 4c40463..dc667c9 100644 (file)
@@ -50,7 +50,7 @@ sub import { filter_add(bless []) }
 EOM
  
 my $a = `$Perl "-I." $Inc -e "use ${module} ;"  2>&1` ;
-ok(1, (($? >>8) != 0 or ($^O eq 'MSWin32' && $? != 0))) ;
+ok(1, (($? >>8) != 0 or (($^O eq 'MSWin32' || $^O eq 'NetWare') && $? != 0))) ;
 ok(2, $a =~ /^Can't locate object method "filter" via package "MyTest"/) ;
  
 # no reference parameter in filter_add
@@ -67,7 +67,7 @@ sub import { filter_add() }
 EOM
  
 $a = `$Perl "-I." $Inc -e "use ${module} ;"  2>&1` ;
-ok(3, (($? >>8) != 0 or ($^O eq 'MSWin32' && $? != 0))) ;
+ok(3, (($? >>8) != 0 or (($^O eq 'MSWin32' || $^O eq 'NetWare') && $? != 0))) ;
 #ok(4, $a =~ /^usage: filter_add\(ref\) at ${module}.pm/) ;
 ok(4, $a =~ /^Not enough arguments for Filter::Util::Call::filter_add/) ;
  
index 96b2c42..f9be237 100755 (executable)
@@ -27,7 +27,7 @@ ok(1);
 # The high security tests must currently be skipped on some platforms
 my $skipplat = ( (
                  # No sticky bits.
-                 $^O eq 'MSWin32' || $^O eq 'os2' || $^O eq 'dos'
+                 $^O eq 'MSWin32' || $^O eq 'NetWare' || $^O eq 'os2' || $^O eq 'dos'
                  ) ? 1 : 0 );
 
 # Can not run high security tests in perls before 5.6.0
index 951804c..0f5cfa0 100755 (executable)
@@ -30,7 +30,7 @@ my $Dfile = "Op.dbmx.pag";
 if (! -e $Dfile) {
        ($Dfile) = <Op.dbmx*>;
 }
-if ($^O eq 'amigaos' || $^O eq 'os2' || $^O eq 'MSWin32' || $^O eq 'dos') {
+if ($^O eq 'amigaos' || $^O eq 'os2' || $^O eq 'MSWin32' || $^O eq 'NetWare' || $^O eq 'dos') {
     print "ok 2 # Skipped: different file permission semantics\n";
 }
 else {
index e8aef85..ef9dd96 100755 (executable)
@@ -44,7 +44,7 @@ print "ok 2\n";
 
 # look up the user's home directory
 # should return a list with one item, and not set ERROR
-if ($^O ne 'MSWin32' && $^O ne 'VMS') {
+if ($^O ne 'MSWin32' && $^O ne 'NetWare' && $^O ne 'VMS') {
   eval {
     ($name, $home) = (getpwuid($>))[0,7];
     1;
@@ -71,14 +71,14 @@ print "ok 4\n";
 # should return an empty list
 # XXX since errfunc is NULL on win32, this test is not valid there
 @a = bsd_glob("asdfasdf", 0);
-if ($^O ne 'MSWin32' and scalar @a != 0) {
+if (($^O ne 'MSWin32' && $^O ne 'NetWare') and scalar @a != 0) {
     print "# |@a|\nnot ";
 }
 print "ok 5\n";
 
 # check bad protections
 # should return an empty list, and set ERROR
-if ($^O eq 'mpeix' or $^O eq 'MSWin32' or $^O eq 'os2' or $^O eq 'VMS'
+if ($^O eq 'mpeix' or $^O eq 'MSWin32' or $^O eq 'NetWare' or $^O eq 'os2' or $^O eq 'VMS'
     or $^O eq 'cygwin' or Cwd::cwd() =~ m#^$Config{'afsroot'}#s or not $>)
 {
     print "ok 6 # skipped\n";
index 881470c..3c3980c 100755 (executable)
@@ -42,7 +42,7 @@ print "not " unless @a >= 3;
 print "ok 4\n";
 
 # Test Win32 backslash nastiness...
-if ($^O ne 'MSWin32') {
+if ($^O ne 'MSWin32' && $^O ne 'NetWare') {
     print "ok 5\nok 6\nok 7\n";
 }
 else {
index 0f17264..8983a56 100755 (executable)
@@ -39,7 +39,7 @@ $stderr->fdopen($stdout,"w");
 
 print $stdout "ok 2\n";
 print $stderr "ok 3\n";
-if ($^O eq 'MSWin32') {
+if ($^O eq 'MSWin32' || $^O eq 'NetWare') {
     print `echo ok 4`;
     print `echo ok 5 1>&2`; # does this *really* work?
 }
@@ -54,7 +54,7 @@ $stdout->close;
 $stdout->fdopen($dupout,"w");
 $stderr->fdopen($duperr,"w");
 
-if ($^O eq 'MSWin32') { print `type Io.dup` }
+if ($^O eq 'MSWin32' || $^O eq 'NetWare') { print `type Io.dup` }
 else                  { system 'cat Io.dup' }
 unlink 'Io.dup';
 
index d391566..d31ea47 100755 (executable)
@@ -39,7 +39,7 @@ print "ok 2\n";
 
 $poll->poll(0.1);
 
-if ($^O eq 'MSWin32') {
+if ($^O eq 'MSWin32' || $^O eq 'NetWare') {
 print "ok 3 # skipped, doesn't work on non-socket fds\n";
 print "ok 4 # skipped, doesn't work on non-socket fds\n";
 }
index 5d1dce3..84660db 100755 (executable)
@@ -49,7 +49,7 @@ $sel->remove([\*STDOUT, 5]);
 print "not " unless $sel->count == 0 && !defined($sel->bits);
 print "ok 9\n";
 
-if ($^O eq 'MSWin32' || $^O eq 'dos') {  # 4-arg select is only valid on sockets
+if ($^O eq 'MSWin32' || $^O eq 'NetWare' || $^O eq 'dos') {  # 4-arg select is only valid on sockets
     print "# skipping tests 10..15\n";
     for (10 .. 15) { print "ok $_\n" }
     $sel->add(\*STDOUT);  # update
index 19afa2f..c98d701 100755 (executable)
@@ -29,7 +29,7 @@ $x->close;
 $x = new IO::File "< ./__taint__$$" || die("Cannot open ./__taint__$$\n");
 chop($unsafe = <$x>);
 eval { kill 0 * $unsafe };
-print "not " if $^O ne 'MSWin32' and ($@ !~ /^Insecure/o);
+print "not " if ((($^O ne 'MSWin32') && ($^O ne 'NetWare')) and ($@ !~ /^Insecure/o));
 print "ok 1\n";
 $x->close;
 
index e56fcd9..cb975e0 100755 (executable)
@@ -40,7 +40,7 @@ my $Dfile = "Op.dbmx.pag";
 if (! -e $Dfile) {
        ($Dfile) = <Op.dbmx*>;
 }
-if ($^O eq 'amigaos' || $^O eq 'os2' || $^O eq 'MSWin32') {
+if ($^O eq 'amigaos' || $^O eq 'os2' || $^O eq 'MSWin32' || $^O eq 'NetWare') {
     print "ok 2 # Skipped: different file permission semantics\n";
 }
 else {
index abc5b92..c3a1219 100644 (file)
@@ -41,7 +41,7 @@ print "ok 5\n";
 # VMS returns "LOCALHOST" under tcp/ip services V4.1 ECO 2, possibly others
 # OS/390 returns localhost.YADDA.YADDA
 
-if ($^O eq 'MSWin32' or $^O eq 'cygwin') {
+if ($^O eq 'MSWin32' or $^O eq 'NetWare' or $^O eq 'cygwin') {
   print "ok $_ # skipped on win32\n" for (6,7);
 } else {
   my $in_alias;
index b935d04..a43e70b 100755 (executable)
@@ -40,7 +40,7 @@ my $Dfile = "Op.dbmx.pag";
 if (! -e $Dfile) {
        ($Dfile) = <Op.dbmx*>;
 }
-if ($^O eq 'amigaos' || $^O eq 'os2' || $^O eq 'MSWin32') {
+if ($^O eq 'amigaos' || $^O eq 'os2' || $^O eq 'MSWin32' || $^O eq 'NetWare') {
     print "ok 2 # Skipped: different file permission semantics\n";
 }
 else {
index 85b807c..fe49189 100755 (executable)
@@ -6,7 +6,7 @@ BEGIN {
     require Config; import Config;
     if (!$Config{'d_fork'}
        # open2/3 supported on win32 (but not Borland due to CRT bugs)
-       && ($^O ne 'MSWin32' || $Config{'cc'} =~ /^bcc/i))
+       && (($^O ne 'MSWin32' && $^O ne 'NetWare') || $Config{'cc'} =~ /^bcc/i))
     {
        print "1..0\n";
        exit 0;
@@ -34,7 +34,7 @@ sub ok {
 }
 
 sub cmd_line {
-       if ($^O eq 'MSWin32') {
+       if ($^O eq 'MSWin32' || $^O eq 'NetWare') {
                return qq/"$_[0]"/;
        }
        else {
index a0da34f..7d2d411 100755 (executable)
@@ -6,7 +6,7 @@ BEGIN {
     require Config; import Config;
     if (!$Config{'d_fork'}
        # open2/3 supported on win32 (but not Borland due to CRT bugs)
-       && ($^O ne 'MSWin32' || $Config{'cc'} =~ /^bcc/i))
+       && (($^O ne 'MSWin32' && $^O ne 'NetWare') || $Config{'cc'} =~ /^bcc/i))
     {
        print "1..0\n";
        exit 0;
@@ -34,7 +34,7 @@ sub ok {
 }
 
 sub cmd_line {
-       if ($^O eq 'MSWin32') {
+       if ($^O eq 'MSWin32' || $^O eq 'NetWare') {
                my $cmd = shift;
                $cmd =~ tr/\r\n//d;
                $cmd =~ s/"/\\"/g;
index 33ab944..09bd88c 100755 (executable)
@@ -17,6 +17,7 @@ $| = 1;
 print "1..27\n";
 
 $Is_W32 = $^O eq 'MSWin32';
+$Is_NetWare = $^O eq 'NetWare';
 $Is_Dos = $^O eq 'dos';
 
 $testfd = open("TEST", O_RDONLY, 0) and print "ok 1\n";
index 3221ca4..57928e0 100755 (executable)
@@ -40,7 +40,7 @@ my $Dfile = "Op_dbmx.pag";
 if (! -e $Dfile) {
        ($Dfile) = <Op_dbmx.*>;
 }
-if ($^O eq 'amigaos' || $^O eq 'os2' || $^O eq 'MSWin32' || $^O eq 'dos') {
+if ($^O eq 'amigaos' || $^O eq 'os2' || $^O eq 'MSWin32' || $^O eq 'NetWare' || $^O eq 'dos') {
     print "ok 2 # Skipped: different file permission semantics\n";
 }
 else {
index 1815b19..c38b122 100644 (file)
@@ -8,7 +8,7 @@ BEGIN {
 BEGIN{
        # Don't do anything if POSIX is missing, or sigaction missing.
        eval { use POSIX; };
-       if($@ || $^O eq 'MSWin32') {
+       if($@ || $^O eq 'MSWin32' || $^O eq 'NetWare') {
                print "1..0\n";
                exit 0;
        }
index 6a5d9b7..8d9769f 100644 (file)
@@ -60,7 +60,7 @@ EOM
 print "# checking whether we have sparse files...\n";
 
 # Known have-nots.
-if ($^O eq 'MSWin32' || $^O eq 'VMS') {
+if ($^O eq 'MSWin32' || $^O eq 'NetWare' || $^O eq 'VMS') {
     print "1..0 # Skip: no sparse files in $^O\n";
     bye();
 }
index aa25de0..0e4c404 100755 (executable)
@@ -5,6 +5,7 @@ chdir 't' if -d 't';
 $Is_VMS = $^O eq 'VMS';
 $Is_MSWin32 = $^O eq 'MSWin32';
 $Is_MacOS = $^O eq 'MacOS';
+$Is_NetWare = $^O eq 'NetWare';
 $ENV{PERL5LIB} = "../lib" unless $Is_VMS;
 
 $|=1;
@@ -32,7 +33,9 @@ for (@prgs){
                    `.\\perl -I../lib $switch $tmpfile 2>&1` :
                      $Is_MacOS ?  
                        `$^X -I::lib $switch $tmpfile` :
-                         `./perl $switch $tmpfile 2>&1`;
+                           $Is_NetWare ?
+                               `perl -I../lib $switch $tmpfile 2>&1` :
+                                   `./perl $switch $tmpfile 2>&1`;
     my $status = $?;
     $results =~ s/\n+$//;
     # allow expected output to be written as if $prog is on STDIN
index 6334286..159392c 100755 (executable)
@@ -429,7 +429,7 @@ END
            $test++;
          }
 
-         if ($Config{d_fork} and $^O ne 'VMS' and $^O ne 'MSWin32') {
+         if ($Config{d_fork} and $^O ne 'VMS' and $^O ne 'MSWin32' and $^O ne 'NetWare') {
            # Fork off a new perl to run the tests.
            # (This is so we can catch spurious warnings.)
            $| = 1; print ""; $| = 0; # flush output before forking
@@ -466,9 +466,10 @@ END
            my $cmd = (($^O eq 'VMS') ? "MCR $^X"
                       : ($^O eq 'MSWin32') ? '.\perl'
                       : ($^O eq 'MacOS') ? $^X
+                      : ($^O eq 'NetWare') ? 'perl'
                       : './perl');
            $cmd .= " -w $cmdfile 2>$errfile";
-           if ($^O eq 'VMS' or $^O eq 'MSWin32') {
+           if ($^O eq 'VMS' or $^O eq 'MSWin32' or $^O eq 'NetWare') {
              # Use pipe instead of system so we don't inherit STD* from
              # this process, and then foul our pipe back to parent by
              # redirecting output in the child.
index f758f9c..18d8bab 100755 (executable)
@@ -50,7 +50,7 @@ foreach my $test (1 .. $max) {
     my($bang, $query, $code) = @{$tests{$test}};
     $code ||= 'die;';
     my $exit =
-       ($^O eq 'MSWin32'
+       (($^O eq 'MSWin32' || $^O eq 'NetWare')
         ? system qq($perl -e "\$! = $bang; \$? = $query; $code" 2> nul)
         : system qq($perl -e '\$! = $bang; \$? = $query; $code' 2> /dev/null));
 
index 57a114e..2defb47 100755 (executable)
@@ -5,7 +5,7 @@ $| = 1;                         # flush stdout
 $ENV{LC_ALL}   = 'C';          # Forge English error messages.
 $ENV{LANGUAGE} = 'C';          # Ditto in GNU.
 
-if ($^O eq 'MSWin32') {
+if ($^O eq 'MSWin32' || $^O eq 'NetWare') {
     # XXX the system tests could be written to use ./perl and so work on Win32
     print "1..0 # Skip: shh, win32\n";
     exit(0);
index fbcd098..b3faa19 100755 (executable)
@@ -7,7 +7,7 @@ BEGIN {
     @INC = '../lib';
     require Config; import Config;
     unless ($Config{'d_fork'}
-           or ($^O eq 'MSWin32' and $Config{useithreads}
+           or (($^O eq 'MSWin32' || $^O eq 'NetWare') and $Config{useithreads}
                and $Config{ccflags} =~ /-DPERL_IMPLICIT_SYS/ 
 #               and !defined $Config{'useperlio'}
                ))
@@ -33,7 +33,7 @@ $tmpfile = "forktmp000";
 1 while -f ++$tmpfile;
 END { close TEST; unlink $tmpfile if $tmpfile; }
 
-$CAT = (($^O eq 'MSWin32') ? '.\perl -e "print <>"' : 'cat');
+$CAT = (($^O eq 'MSWin32') ? '.\perl -e "print <>"' : (($^O eq 'NetWare') ? 'perl -e "print <>"' : 'cat'));
 
 for (@prgs){
     my $switch;
@@ -51,6 +51,9 @@ for (@prgs){
     if ($^O eq 'MSWin32') {
       $results = `.\\perl -I../lib $switch $tmpfile 2>&1`;
     }
+    elsif ($^O eq 'NetWare') {
+      $results = `perl -I../lib $switch $tmpfile 2>&1`;
+    }
     else {
       $results = `./perl $switch $tmpfile 2>&1`;
     }
@@ -255,7 +258,7 @@ ok 1 child
 $| = 1;
 $\ = "\n";
 my $getenv;
-if ($^O eq 'MSWin32') {
+if ($^O eq 'MSWin32' || $^O eq 'NetWare') {
     $getenv = qq[$^X -e "print \$ENV{TST}"];
 }
 else {
index 579e818..a0b4d55 100755 (executable)
@@ -29,7 +29,7 @@ label4:
 print "#2\t:$foo: == 4\n";
 if ($foo == 4) {print "ok 2\n";} else {print "not ok 2\n";}
 
-$PERL = ($^O eq 'MSWin32') ? '.\perl' : ($^O eq 'MacOS') ? $^X : './perl';
+$PERL = ($^O eq 'MSWin32') ? '.\perl' : ($^O eq 'MacOS') ? $^X : ($^O eq 'NetWare') ? 'perl' : './perl';
 $CMD = qq[$PERL -e "goto foo;" 2>&1 ];
 $x = `$CMD`;
 
index 082d2d1..0531826 100755 (executable)
@@ -10,7 +10,7 @@ sub quit {
     exit 0;
 }
 
-quit() if $^O eq 'MSWin32' or $^O =~ /lynxos/i;
+quit() if (($^O eq 'MSWin32' || $^O eq 'NetWare') or $^O =~ /lynxos/i);
 
 # We have to find a command that prints all (effective
 # and real) group names (not ids).  The known commands are:
index 44a92c4..2652555 100644 (file)
@@ -59,7 +59,7 @@ $| = 1;
 print "# checking whether we have sparse files...\n";
 
 # Known have-nots.
-if ($^O eq 'MSWin32' || $^O eq 'VMS') {
+if ($^O eq 'MSWin32' || $^O eq 'NetWare' || $^O eq 'VMS') {
     print "1..0 # Skip: no sparse files in $^O\n";
     bye();
 }
index c8b2d1c..935e574 100755 (executable)
@@ -21,11 +21,12 @@ sub ok {
 }
 
 $Is_MSWin32 = $^O eq 'MSWin32';
+$Is_NetWare = $^O eq 'NetWare';
 $Is_VMS     = $^O eq 'VMS';
 $Is_Dos   = $^O eq 'dos';
 $Is_os2   = $^O eq 'os2';
 $Is_Cygwin   = $^O eq 'cygwin';
-$PERL = ($Is_MSWin32 ? '.\perl' : './perl');
+$PERL = ($Is_MSWin32 ? '.\perl' : ($Is_NetWare ? 'perl' : './perl'));
 
 print "1..41\n";
 
@@ -39,7 +40,7 @@ open(FOO,'ajslkdfpqjsjfk');
 ok 2, $!, $!;
 close FOO; # just mention it, squelch used-only-once
 
-if ($Is_MSWin32 || $Is_Dos) {
+if ($Is_MSWin32 || $Is_NetWare || $Is_Dos) {
     ok "3 # skipped",1;
     ok "4 # skipped",1;
 }
@@ -211,7 +212,7 @@ else {
 
 # test case-insignificance of %ENV (these tests must be enabled only
 # when perl is compiled with -DENV_IS_CASELESS)
-if ($Is_MSWin32) {
+if ($Is_MSWin32 || $Is_NetWare) {
     %ENV = ();
     $ENV{'Foo'} = 'bar';
     $ENV{'fOo'} = 'baz';
index 679dd91..b00f4b1 100755 (executable)
@@ -17,7 +17,7 @@ $tmpfile = "misctmp000";
 1 while -f ++$tmpfile;
 END { while($tmpfile && unlink $tmpfile){} }
 
-$CAT = (($^O eq 'MSWin32') ? '.\perl -e "print <>"' : 'cat');
+$CAT = (($^O eq 'MSWin32') ? '.\perl -e "print <>"' : (($^O eq 'NetWare') ? 'perl -e "print <>"' : 'cat'));
 
 for (@prgs){
     my $switch;
@@ -35,6 +35,9 @@ for (@prgs){
     if ($^O eq 'MSWin32') {
       $results = `.\\perl -I../lib $switch $tmpfile 2>&1`;
     }
+       elsif ($^O eq 'NetWare') {
+      $results = `perl -I../lib $switch $tmpfile 2>&1`;
+    }
     else {
       $results = `./perl $switch $tmpfile 2>&1`;
     }
@@ -624,7 +627,7 @@ my $have_setlocale = $Config{d_setlocale} eq 'define';
 $have_setlocale = 0 if $@;
 # Visual C's CRT goes silly on strings of the form "en_US.ISO8859-1"
 # and mingw32 uses said silly CRT
-$have_setlocale = 0 if $^O eq 'MSWin32' && $Config{cc} =~ /^(cl|gcc)/i;
+$have_setlocale = 0 if (($^O eq 'MSWin32' || $^O eq 'NetWare') && $Config{cc} =~ /^(cl|gcc)/i);
 exit(0) unless $have_setlocale;
 my @locales;
 if (-x "/usr/bin/locale" && open(LOCALES, "/usr/bin/locale -a|")) {
index 83186ae..e365e59 100755 (executable)
@@ -342,6 +342,7 @@ AUTOSRAND:
     for (1..5) {
        my $PERL = (($^O eq 'VMS') ? "MCR $^X"
                    : ($^O eq 'MSWin32') ? '.\perl'
+                   : ($^O eq 'NetWare') ? 'perl'
                    : './perl');
        $pid = open PERL, qq[$PERL -e "print rand"|];
        die "Couldn't pipe from perl: $!" unless defined $pid;
index 3140f02..1364801 100755 (executable)
@@ -10,6 +10,7 @@ chdir 't' if -d 't';
 @INC = '../lib';
 $Is_VMS = $^O eq 'VMS';
 $Is_MSWin32 = $^O eq 'MSWin32';
+$Is_NetWare = $^O eq 'NetWare';
 $ENV{PERL5LIB} = "../lib" unless $Is_VMS;
 
 $|=1;
@@ -35,6 +36,8 @@ for (@prgs){
                   `MCR $^X "-I[-.lib]" $switch $tmpfile 2>&1` :
                      $Is_MSWin32 ?  
                          `.\\perl -I../lib $switch $tmpfile 2>&1` :
+                     $Is_NetWare ?  
+                         `perl -I../lib $switch $tmpfile 2>&1` :
                              `./perl $switch $tmpfile 2>&1`;
     my $status = $?;
     $results =~ s/\n+$//;
index 4e3e546..8aa91e5 100755 (executable)
@@ -51,6 +51,7 @@ print $_ eq '1:2:3:4:5:6:::' ? "ok 10\n" : "not ok 10 $_\n";
 
 # Does assignment to a list imply split to one more field than that?
 if ($^O eq 'MSWin32') { $foo = `.\\perl -D1024 -e "(\$a,\$b) = split;" 2>&1` }
+elsif ($^O eq 'NetWare') { $foo = `perl -D1024 -e "(\$a,\$b) = split;" 2>&1` }
 elsif ($^O eq 'VMS')  { $foo = `./perl "-D1024" -e "(\$a,\$b) = split;" 2>&1` }
 elsif ($^O eq 'MacOS'){ $foo = `$^X "-D1024" -e "(\$a,\$b) = split;"` }
 else                  { $foo = `./perl -D1024 -e '(\$a,\$b) = split;' 2>&1` }
index f7a2a4e..f3cf2ef 100755 (executable)
@@ -12,17 +12,18 @@ use Config;
 print "1..58\n";
 
 $Is_MSWin32 = $^O eq 'MSWin32';
+$Is_NetWare = $^O eq 'NetWare';
 $Is_Dos = $^O eq 'dos';
-$Is_Dosish = $Is_Dos || $^O eq 'os2' || $Is_MSWin32;
+$Is_Dosish = $Is_Dos || $^O eq 'os2' || $Is_MSWin32 || $Is_NetWare;
 $Is_Cygwin = $^O eq 'cygwin';
-chop($cwd = ($Is_MSWin32 ? `cd` : `pwd`));
+chop($cwd = (($Is_MSWin32 || $Is_NetWare) ? `cd` : `pwd`));
 
 $DEV = `ls -l /dev` unless $Is_Dosish or $Is_Cygwin;
 
 unlink "Op.stat.tmp";
 if (open(FOO, ">Op.stat.tmp")) {
   # hack to make Apollo update link count:
-  $junk = `ls Op.stat.tmp` unless ($Is_MSWin32 || $Is_Dos);
+  $junk = `ls Op.stat.tmp` unless ($Is_MSWin32 || $Is_NetWare || $Is_Dos);
 
   ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,
    $blksize,$blocks) = stat(FOO);
@@ -32,7 +33,7 @@ if (open(FOO, ">Op.stat.tmp")) {
   else {
     print "# res=$res, nlink=$nlink.\nnot ok 1\n";
   }
-  if ($Is_MSWin32 or $Is_Cygwin or $Is_Dos || ($mtime && $mtime == $ctime)) {
+  if ($Is_MSWin32 or $Is_NetWare or $Is_Cygwin or $Is_Dos || ($mtime && $mtime == $ctime)) {
     print "ok 2\n";
   }
   else {
@@ -85,7 +86,7 @@ else {
 print "#4      :$mtime: should != :$ctime:\n";
 
 unlink "Op.stat.tmp" or print "# unlink failed: $!\n";
-if ($Is_MSWin32) {  open F, '>Op.stat.tmp' and close F }
+if ($Is_MSWin32 || $Is_NetWare) {  open F, '>Op.stat.tmp' and close F }
 else             { `touch Op.stat.tmp` }
 
 if (-z 'Op.stat.tmp') {print "ok 5\n";} else {print "not ok 5\n";}
@@ -141,7 +142,7 @@ if (-e 'Op.stat.tmp') {print "ok 27\n";} else {print "not ok 27\n";}
 unlink 'Op.stat.tmp2';
 if (! -e 'Op.stat.tmp2') {print "ok 28\n";} else {print "not ok 28\n";}
 
-if ($Is_MSWin32 || $Is_Dos)
+if ($Is_MSWin32 || $Is_NetWare || $Is_Dos)
     {print "ok 29\n";}
 elsif ($DEV !~ /\nc.* (\S+)\n/)
     {print "ok 29\n";}
@@ -151,7 +152,7 @@ else
     {print "not ok 29\n";}
 if (! -c '.') {print "ok 30\n";} else {print "not ok 30\n";}
 
-if ($Is_MSWin32 || $Is_Dos)
+if ($Is_MSWin32 || $Is_NetWare || $Is_Dos)
     {print "ok 31\n";}
 elsif ($DEV !~ /\ns.* (\S+)\n/)
     {print "ok 31\n";}
@@ -161,7 +162,7 @@ else
     {print "not ok 31\n";}
 if (! -S '.') {print "ok 32\n";} else {print "not ok 32\n";}
 
-if ($Is_MSWin32 || $Is_Dos)
+if ($Is_MSWin32 || $Is_NetWare || $Is_Dos)
     {print "ok 33\n";}
 elsif ($DEV !~ /\nb.* (\S+)\n/)
     {print "ok 33\n";}
@@ -205,7 +206,7 @@ tty_test:
 # may not be available (at, cron  rsh etc), the PERL_SKIP_TTY_TEST env var
 # can be set to skip the tests that need a tty.
 unless($ENV{PERL_SKIP_TTY_TEST}) {
-    if ($Is_MSWin32) {
+    if ($Is_MSWin32 || $Is_NetWare) {
        print "ok 36\n";
        print "ok 37\n";
     }
@@ -236,7 +237,7 @@ else {
     print "ok 39\n";
 }
 open(null,"/dev/null");
-if (! -t null || -e '/xenix' || $^O eq 'machten' || $Is_MSWin32)
+if (! -t null || -e '/xenix' || $^O eq 'machten' || $Is_MSWin32 || $Is_NetWare)
        {print "ok 40\n";} else {print "not ok 40\n";}
 close(null);
 
index e43f850..251c7f8 100755 (executable)
@@ -6,7 +6,7 @@ chdir('op') || chdir('t/op') || die "sysio.t: cannot look for myself: $!";
 
 open(I, 'sysio.t') || die "sysio.t: cannot find myself: $!";
 
-$reopen = ($^O eq 'VMS' || $^O eq 'os2' || $^O eq 'MSWin32' || $^O eq 'dos' ||
+$reopen = ($^O eq 'VMS' || $^O eq 'os2' || $^O eq 'MSWin32' || $^O eq 'NetWare' || $^O eq 'dos' ||
           $^O eq 'mpeix');
 
 $x = 'abc';
index 0d1e747..c2bb2f8 100755 (executable)
@@ -40,9 +40,11 @@ BEGIN {
 
 my $Is_VMS = $^O eq 'VMS';
 my $Is_MSWin32 = $^O eq 'MSWin32';
+my $Is_NetWare = $^O eq 'NetWare';
 my $Is_Dos = $^O eq 'dos';
 my $Invoke_Perl = $Is_VMS ? 'MCR Sys$Disk:[]Perl.' :
-                  $Is_MSWin32 ? '.\perl' : './perl';
+                  ($Is_MSWin32 ? '.\perl' :
+                  ($Is_NetWare ? 'perl' : './perl'));
 my @MoreEnv = qw/IFS CDPATH ENV BASH_ENV/;
 
 if ($Is_VMS) {
@@ -99,7 +101,7 @@ sub test ($$;$) {
 }
 
 # We need an external program to call.
-my $ECHO = ($Is_MSWin32 ? ".\\echo$$" : "./echo$$");
+my $ECHO = ($Is_MSWin32 ? ".\\echo$$" : ($Is_NetWare ? "echo$$" : "./echo$$"));
 END { unlink $ECHO }
 open PROG, "> $ECHO" or die "Can't create $ECHO: $!";
 print PROG 'print "@ARGV\n"', "\n";
@@ -120,7 +122,7 @@ print "1..174\n";
 
     test 1, eval { `$echo 1` } eq "1\n";
 
-    if ($Is_MSWin32 || $Is_VMS || $Is_Dos) {
+    if ($Is_MSWin32 || $Is_NetWare || $Is_VMS || $Is_Dos) {
        print "# Environment tainting tests skipped\n";
        for (2..5) { print "ok $_\n" }
     }
@@ -144,7 +146,7 @@ print "1..174\n";
     }
 
     my $tmp;
-    if ($^O eq 'os2' || $^O eq 'amigaos' || $Is_MSWin32 || $Is_Dos) {
+    if ($^O eq 'os2' || $^O eq 'amigaos' || $Is_MSWin32 || $Is_NetWare || $Is_Dos) {
        print "# all directories are writeable\n";
     }
     else {
index 8e4cca8..2830974 100755 (executable)
@@ -7,8 +7,9 @@ BEGIN {
 
 print "1..44\n";
 
-my $CAT = ($^O eq 'MSWin32') ? 'type'
-       : ($^O eq 'MacOS') ? 'catenate' : 'cat';
+my $CAT = ($^O eq 'MSWin32' || $^O eq 'NetWare') ? 'type'
+       : ($^O eq 'MacOS') ? 'catenate'
+        : 'cat';
 
 format OUT =
 the quick brown @<<
index 0926a6e..e58616c 100755 (executable)
@@ -43,7 +43,7 @@ eval {
 
 # Visual C's CRT goes silly on strings of the form "en_US.ISO8859-1"
 # and mingw32 uses said silly CRT
-$have_setlocale = 0 if $^O eq 'MSWin32' && $Config{cc} =~ /^(cl|gcc)/i;
+$have_setlocale = 0 if (($^O eq 'MSWin32' || $^O eq 'NetWare') && $Config{cc} =~ /^(cl|gcc)/i);
 
 my $last = $have_setlocale ? &last : &last_without_setlocale;
 
index bbfb8ab..8b9083f 100755 (executable)
@@ -10,6 +10,7 @@ $| = 1;
 
 my $Is_VMS = $^O eq 'VMS';
 my $Is_MSWin32 = $^O eq 'MSWin32';
+my $Is_NetWare = $^O eq 'NetWare';
 my $tmpfile = "tmp0000";
 my $i = 0 ;
 1 while -f ++$tmpfile;
@@ -71,6 +72,8 @@ for (@prgs){
                   `.\\perl -I../lib $switch $tmpfile 2>&1` :
                   $^O eq 'MacOS' ?
                   `$^X -I::lib $switch $tmpfile` :
+                  $^O eq 'NetWare' ?
+                  `perl -I../lib $switch $tmpfile 2>&1` :
                   `./perl $switch $tmpfile 2>&1`;
     my $status = $?;
     $results =~ s/\n+$//;
index 7e48e20..2f684b4 100755 (executable)
@@ -13,6 +13,7 @@ print "1..", scalar @prgs, "\n";
 
 my $Is_VMS = $^O eq 'VMS';
 my $Is_MSWin32 = $^O eq 'MSWin32';
+my $Is_NetWare = $^O eq 'NetWare';
 my $tmpfile = "tmp0000";
 my $i = 0 ;
 1 while -f ++$tmpfile;
@@ -49,6 +50,8 @@ for (@prgs){
                   `./perl $switch $tmpfile 2>&1` :
                  $Is_MSWin32 ?
                   `.\\perl -I../lib $switch $tmpfile 2>&1` :
+                 $Is_NetWare ?
+                  `perl -I../lib $switch $tmpfile 2>&1` :
                   `./perl $switch $tmpfile 2>&1`;
     my $status = $?;
     $results =~ s/\n+$//;
index a8f9dbc..f224335 100644 (file)
@@ -25,7 +25,7 @@ EXPECT
 ########
 # mg.c
 use warnings 'signal' ;
-if ($^O eq 'MSWin32' || $^O eq 'VMS') {
+if ($^O eq 'MSWin32' || $^O eq 'NetWare' || $^O eq 'VMS') {
     print "SKIPPED\n# $^O, can't kill() to raise()\n"; exit;
 }
 $|=1;
@@ -35,7 +35,7 @@ SIGINT handler "fred" not defined.
 ########
 # mg.c
 no warnings 'signal' ;
-if ($^O eq 'MSWin32' || $^O eq 'VMS') {
+if ($^O eq 'MSWin32' || $^O eq 'NetWare' || $^O eq 'VMS') {
     print "SKIPPED\n# win32, can't kill() to raise()\n"; exit;
 }
 $|=1;
index 591f039..09b41fb 100644 (file)
@@ -11,6 +11,7 @@ $| = 1;
 
 my $Is_VMS     = $^O eq 'VMS';
 my $Is_MSWin32 = $^O eq 'MSWin32';
+my $Is_NetWare = $^O eq 'NetWare';
 my $tmpfile = "tmp0000";
 my $i = 0 ;
 1 while -f ++$tmpfile;
@@ -86,6 +87,8 @@ for (@prgs){
                   `./perl "-I../lib" $switch $tmpfile 2>&1` :
                  $Is_MSWin32 ?
                   `.\\perl -I../lib $switch $tmpfile 2>&1` :
+                 $Is_NetWare ?
+                  `perl -I../lib $switch $tmpfile 2>&1` :
                   `./perl -I../lib $switch $tmpfile 2>&1`;
     my $status = $?;
     $results =~ s/\n+$//;
index 4744aa0..87fcdbe 100644 (file)
--- a/thread.h
+++ b/thread.h
@@ -7,6 +7,9 @@
 #ifdef WIN32
 #  include <win32thread.h>
 #else
+#ifdef NETWARE
+#  include <nw5thread.h>
+#else
 #  ifdef OLD_PTHREADS_API /* Here be dragons. */
 #    define DETACH(t) \
     STMT_START {                                               \
@@ -54,6 +57,7 @@
 #    define pthread_mutexattr_default NULL
 #    define pthread_condattr_default  NULL
 #  endif
+#endif /* NETWARE */
 #endif
 
 #ifndef PTHREAD_CREATE
diff --git a/toke.c b/toke.c
index 424249f..fca0f73 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -4195,7 +4195,11 @@ Perl_yylex(pTHX)
                        loc = PerlIO_tell(PL_rsfp);
                        (void)PerlIO_seek(PL_rsfp, 0L, 0);
                    }
+#ifdef NETWARE
+                       if (PerlLIO_setmode(PL_rsfp, O_TEXT) != -1) {
+#else
                    if (PerlLIO_setmode(PerlIO_fileno(PL_rsfp), O_TEXT) != -1) {
+#endif /* NETWARE */
 #ifdef PERLIO_IS_STDIO /* really? */
 #  if defined(__BORLANDC__)
                        /* XXX see note in do_binmode() */
diff --git a/util.c b/util.c
index 7a8b815..d604562 100644 (file)
--- a/util.c
+++ b/util.c
@@ -1454,7 +1454,7 @@ Perl_vwarner(pTHX_ U32  err, const char* pat, va_list* args)
 
 #ifdef USE_ENVIRON_ARRAY
        /* VMS' and EPOC's my_setenv() is in vms.c and epoc.c */
-#if !defined(WIN32)
+#if !defined(WIN32) && !defined(NETWARE)
 void
 Perl_my_setenv(pTHX_ char *nam, char *val)
 {
@@ -1508,7 +1508,7 @@ Perl_my_setenv(pTHX_ char *nam, char *val)
 #endif  /* PERL_USE_SAFE_PUTENV */
 }
 
-#else /* WIN32 */
+#else /* WIN32 || NETWARE */
 
 void
 Perl_my_setenv(pTHX_ char *nam,char *val)
@@ -1525,7 +1525,7 @@ Perl_my_setenv(pTHX_ char *nam,char *val)
     Safefree(envstr);
 }
 
-#endif /* WIN32 */
+#endif /* WIN32 || NETWARE */
 
 I32
 Perl_setenv_getix(pTHX_ char *nam)
@@ -1786,7 +1786,7 @@ VTOH(vtohl,long)
 PerlIO *
 Perl_my_popen_list(pTHX_ char *mode, int n, SV **args)
 {
-#if (!defined(DOSISH) || defined(HAS_FORK) || defined(AMIGAOS)) && !defined(OS2) && !defined(VMS) && !defined(__OPEN_VM) && !defined(EPOC) && !defined(MACOS_TRADITIONAL)
+#if (!defined(DOSISH) || defined(HAS_FORK) || defined(AMIGAOS)) && !defined(OS2) && !defined(VMS) && !defined(__OPEN_VM) && !defined(EPOC) && !defined(MACOS_TRADITIONAL) && !defined(NETWARE)
     int p[2];
     register I32 This, that;
     register Pid_t pid;
@@ -2283,7 +2283,7 @@ Perl_my_pclose(pTHX_ PerlIO *ptr)
 }
 #endif /* !DOSISH */
 
-#if  (!defined(DOSISH) || defined(OS2) || defined(WIN32)) && !defined(MACOS_TRADITIONAL)
+#if  (!defined(DOSISH) || defined(OS2) || defined(WIN32) || defined(NETWARE)) && !defined(MACOS_TRADITIONAL)
 I32
 Perl_wait4pid(pTHX_ Pid_t pid, int *statusp, int flags)
 {
@@ -2345,7 +2345,7 @@ Perl_wait4pid(pTHX_ Pid_t pid, int *statusp, int flags)
     }
 #endif
 }
-#endif /* !DOSISH || OS2 || WIN32 */
+#endif /* !DOSISH || OS2 || WIN32 || NETWARE */
 
 void
 /*SUPPRESS 590*/
diff --git a/util.h b/util.h
index d188e34..28a5860 100644 (file)
--- a/util.h
+++ b/util.h
         || ((f)[0] && (f)[1] == ':')           /* drive name */        \
         || ((f)[0] == '\\' && (f)[1] == '\\')) /* UNC path */
 #  else                /* !WIN32 */
+#  ifdef NETWARE
+#    define PERL_FILE_IS_ABSOLUTE(f) \
+       (((f)[0] && (f)[1] == ':')              /* drive name */        \
+        || ((f)[0] == '\\' && (f)[1] == '\\')  /* UNC path */  \
+        ||     ((f)[3] == ':'))                                /* volume name, currently only sys */
+#  else                /* !NETWARE */
 #    if defined( DOSISH) || defined(EPOC)
 #      define PERL_FILE_IS_ABSOLUTE(f) \
        (*(f) == '/'                                                    \
@@ -32,5 +38,6 @@
 #        define PERL_FILE_IS_ABSOLUTE(f)       (*(f) == '/')
 #      endif /* MACOS_TRADITIONAL */
 #    endif     /* DOSISH */
+#   endif      /* NETWARE */
 #  endif       /* WIN32 */
 #endif         /* VMS */
index 1b1d00e..d4cb59f 100644 (file)
@@ -8,10 +8,13 @@
  * $Log:       a2py.c,v $
  */
 
-#if defined(OS2) || defined(WIN32)
+#if defined(OS2) || defined(WIN32) || defined(NETWARE)
 #if defined(WIN32)
 #include <io.h>
 #endif
+#if defined(NETWARE)
+#include "../netware/clibstuf.h"
+#endif
 #include "../patchlevel.h"
 #endif
 #include "util.h"
@@ -29,7 +32,7 @@ int oper4(int type, int arg1, int arg2, int arg3, int arg4);
 int oper5(int type, int arg1, int arg2, int arg3, int arg4, int arg5);
 STR *walk(int useval, int level, register int node, int *numericptr, int minprec);
 
-#if defined(OS2) || defined(WIN32)
+#if defined(OS2) || defined(WIN32) || defined(NETWARE)
 static void usage(void);
 
 static void
@@ -55,6 +58,10 @@ main(register int argc, register char **argv, register char **env)
     int i;
     STR *tmpstr;
 
+       #ifdef NETWARE
+               fnInitGpfGlobals();     // For importing the CLIB calls in place of Watcom calls
+       #endif  /* NETWARE */
+
     myname = argv[0];
     linestr = str_new(80);
     str = str_new(0);          /* first used for -I flags */
@@ -90,7 +97,7 @@ main(register int argc, register char **argv, register char **env)
        case 0:
            break;
        default:
-#if defined(OS2) || defined(WIN32)
+#if defined(OS2) || defined(WIN32) || defined(NETWARE)
            fprintf(stderr, "Unrecognized switch: %s\n",argv[0]);
             usage();
 #else
@@ -103,7 +110,7 @@ main(register int argc, register char **argv, register char **env)
     /* open script */
 
     if (argv[0] == Nullch) {
-#if defined(OS2) || defined(WIN32)
+#if defined(OS2) || defined(WIN32) || defined(NETWARE)
        if ( isatty(fileno(stdin)) )
            usage();
 #endif