/*static char *SCCSID = "@(#)cmexec.c	6.2 90/12/10";                                 */
/****************************************************************************/
/*                                                                          */
/*                       IBM/Microsoft Confidential                         */
/*                                                                          */
/*                 Copyright (c) IBM Corporation  1987, 1990                */
/*                 Copyright (c) Microsoft Corp.  1987, 1990                */
/*                           All Rights Reserved                            */
/*                                                                          */
/****************************************************************************/
 /******* START OF SPECIFICATION ********************************/
 /*                                                             */
 /* SUBROUTINE  NAME:  comexecFS                                */
 /*                                                             */
 /* DESCRIPTIVE NAME:  common routine to EXEC FS utility        */
 /*                                                             */
 /* FUNCTION: Exec's the appropriate File system utility        */
 /*                                                             */
 /*           CHKDSK                                            */
 /*           FORMAT                                            */
 /*           RECOVER                                           */
 /*           SYS                                               */
 /*                                                             */
 /* NOTES:                                                      */
 /*                                                             */
 /* ENTRY POINT:  comexecFS                                     */
 /*   LINKAGE:                                                  */
 /*                                                             */
 /* INPUT:                                                      */
 /*        fs_ptr:  pointer to the FS name which is returned    */
 /*                 by com_getFSname                            */
 /*                                                             */
 /*        utility: pointer to the name of the utility          */
 /*                 chkdsk                                      */
 /*                 format                                      */
 /*                 recover                                     */
 /*                 sys                                         */
 /*                                                             */
 /* EXIT-NORMAL:    fs_ptr: unchanged                           */
 /*                 utility: unchanged                          */
 /*                                                             */
 /*                 the appropriate File System utility         */
 /*                 is EXECed                                   */
 /*                                                             */
 /* EXIT-ERROR:     return code = 6 (EXEC failed)               */
 /*                                                             */
 /*                                                             */
 /* EFFECTS:                                                    */
 /*                                                             */
 /* INTERNAL REFERENCES:   none                                 */
 /*        ROUTINES:                                            */
 /*                                                             */
 /*                                                             */
 /* EXTERNAL REFERENCES:   DOSLOADMODULE                        */
 /*        ROUTINES:       DOSGETMACHINEMODE                    */
 /*                        DOSGETPROCADDR                       */
 /* NOTE:                                                       */
 /*        This routine also displays the following message:    */
 /*                                                             */
 /*        MSG_CMM_NOT_SUPPORT_FS_IN_REAL                       */
 /*        MSG_CMM_EXEC_FAIL,STD_OUTPUT                         */
 /*        MSG_CMM_EXECING_PGM,STD_OUTPUT                       */
 /*                                                             */
 /*    WARNING: ******************************************      */
 /*             This common subroutine is created for           */
 /*             CHKDSK, FORMAT, RECOVER and SYS utilities       */
 /*             only.  If other utilities called this           */
 /*             routine will get UNKNOWN RESULT.                */
 /*                                                             */
 /************ END OF SOURCE FILE SPECIFICATIONS ****************/
/*  #include <doscall.h> */  /* csc */  /* DOS call             */
#include <basedef.h>              /* rename of far to FAR         */
#include "tmpdos16.h"       /* csc */
#include "tmpdos32.h"       /* csc */  /* 32 bit dos calls             */
#include <comsub.h>                    /* common subroutine    */
#include <string.h>                    /* C run time func      */
#include <utilmids.h>
#include <utlerror.h>
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include "drt.h"

 comexecFS(fs_ptr,utility)
 char *fs_ptr;
 char *utility;
 {
 #define      STD_OUTPUT        0
 #define      STD_ERROR         1
 #define      INSERT            1         /* insert varialbe into msg    */
 #define      NO_INSERT         0         /* not insert                  */
 #define      OBJNAMEBUFL      15         /* Length of object name buffer  */
 #define      REAL_MODE         0
 #define      ERROR_EXEC_FAIL   ERROR_UTILITY_SPECIFIC_2  /* VALUE = 6 */
 #define      ERROR_TERMINATE_DUE_TO_ERROR  ERROR_TERMINATE
/* unsigned doit( int (FAR pascal *)(), int, char FAR * FAR *, char FAR * FAR *);*/
 /*
 unsigned doit( int (FAR pascal *)(), unsigned long, char FAR * FAR *, char FAR * FAR *);
  */
 unsigned rc = 0;
 unsigned char mode;
 char obj_name_buf[OBJNAMEBUFL];   /* buffer to put obj name */
 unsigned handle;
 /*
 unsigned long proc;
  */
 int proc;
 char module_name[15];

 char FAR * FAR *newargv;
 char FAR * FAR *newenvp;
 register int i, top;
 char *p1, *p2;
 extern int __argc;
 extern char **__argv;

   strupr(utility);
   rc = DOSGETMACHINEMODE(
        (unsigned char _far16 *) &mode );
   if ( rc != 0 ) {
       com_dispmsg(rctomid(rc),STD_ERROR,NO_INSERT, 0);
       return(ERROR_TERMINATE_DUE_TO_ERROR);
   }

   if ( mode == REAL_MODE ) {
       com_dispmsg(MSG_CMM_NOT_SUPPORT_FS_IN_REAL,STD_ERROR,INSERT, fs_ptr);
       return(ERROR_EXEC_FAIL);
   } else {       /* Get command line      */
       strcpy(module_name,"U");
       strcat(module_name, fs_ptr);
       rc = DOSLOADMODULE (
             (char _far16 *) obj_name_buf,  /* Object name buffer (address) */
             (unsigned short)   OBJNAMEBUFL,   /* Object name buffer length */
             (char _far16 *) module_name,        /* Module name string */
             (unsigned short _far16 *) &handle);  /* Module handle (returned) */

       if ( rc != 0 )  {
            com_dispmsg(MSG_CMM_EXEC_FAIL,STD_ERROR,INSERT, module_name);
            return( ERROR_EXEC_FAIL );
       } else {
            rc = DOSGETPROCADDR (
                 (unsigned short)            handle,       /* Module handle */
                 (char _far16 *)          utility,      /* entry point in Module */
                 (unsigned long _far16 *) &proc);       /* Procedure address (returned) */

            if ( rc != 0 )  {
               com_dispmsg(MSG_CMM_EXEC_FAIL,STD_ERROR,INSERT, fs_ptr);
               return( ERROR_EXEC_FAIL );
            } else {          /* EXEC the Dynamic Module    */
               com_dispmsg(MSG_CMM_EXECING_PGM,STD_OUTPUT,INSERT, fs_ptr);

               p1 = malloc (__argc * sizeof (char FAR *));  /* build newargv */
               newargv = (char FAR * FAR *)p1;
               for (i=0; i<__argc; i++)
                   newargv [i] = (char FAR *)__argv [i];

               for (top=0; environ [top]; top++)   /* get total # of ENVP str*/
                   ;

               p2 = malloc (top * sizeof (char FAR *));
               newenvp = (char FAR * FAR *)p2;
               for (i=0; i<=top; i++)
                   newenvp [i] = (char FAR *)environ [i];
               newenvp [top] = (char FAR *) 0L;
/*
               rc = doit( (int (FAR pascal *)())  proc, __argc, newargv, newenvp);
 */
               free (p1);
               free (p2);

               DOSFREEMODULE((unsigned short)handle);
               if ( rc > ERROR_LEVEL_RANGE )
                   return(ERROR_TERMINATE_DUE_TO_ERROR);
               else
                   return( rc );

            }/* end of rc test for DOSGETPROCADDR */
       }     /* end of rc test for DOSLOADMODULE  */
   }         /* end of REAL_MODE test   */

 }

// unsigned doit( addr, argc, argv, envp )
// int ( FAR pascal *addr)();
// /*
// unsigned long argc;
//  */
// int argc;
// char FAR * FAR *argv;
// char FAR * FAR *envp;
// {
// unsigned rc;
// rc = (*addr) (argc, argv, envp);
// return (rc);
// }
