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     &nbs