summaryrefslogtreecommitdiff
path: root/NetWare/Nwpipe.c
diff options
context:
space:
mode:
Diffstat (limited to 'NetWare/Nwpipe.c')
-rw-r--r--NetWare/Nwpipe.c704
1 files changed, 704 insertions, 0 deletions
diff --git a/NetWare/Nwpipe.c b/NetWare/Nwpipe.c
new file mode 100644
index 0000000000..2da2b065c3
--- /dev/null
+++ b/NetWare/Nwpipe.c
@@ -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;
+}
+