home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / os2 / os2exec.zip / OS2EXECD.C < prev    next >
C/C++ Source or Header  |  1993-01-05  |  8KB  |  293 lines

  1. /* os2execd.c */
  2.  
  3. /* Written by Eberhard Mattes */
  4.  
  5. /* Copyright (c) 1992-1993 by Eberhard Mattes */
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <direct.h>
  11. #include <process.h>
  12. #define INCL_DOSMISC
  13. #define INCL_DOSNMPIPES
  14. #define INCL_DOSPROCESS
  15. #define INCL_WINWINDOWMGR
  16. #define INCL_WINSWITCHLIST
  17. #include <os2.h>
  18.  
  19. #define FALSE 0
  20. #define TRUE  1
  21.  
  22. typedef unsigned char byte;
  23.  
  24. static byte buf[4096];
  25. static CHAR args[4096+256];
  26. static CHAR prog_buf[256];
  27. static PCHAR org_env;
  28. static PCHAR new_env;
  29. static HPIPE hp;
  30.  
  31. static USHORT org_env_size;
  32. static USHORT new_env_size;
  33. static USHORT new_env_alloc;
  34.  
  35. static void send (byte cmd, byte *src, int len);
  36. static void out_of_mem (void);
  37. int main (int argc, char *argv[]);
  38.  
  39.  
  40. static void out_of_mem (void)
  41. {
  42.   fprintf (stderr, "Out of memory\n");
  43.   exit (2);
  44. }
  45.  
  46.  
  47. static void send (byte cmd, byte *src, int len)
  48. {
  49.   USHORT rc, cb;
  50.  
  51.   buf[0] = (byte)((len + 1) % 256);
  52.   buf[1] = (byte)((len + 1) / 256);
  53.   buf[2] = cmd;
  54.   memmove (buf+3, src, len);
  55.   rc = DosWrite (hp, buf, len+3, &cb);
  56.   if (rc != 0)
  57.     {
  58.       fprintf (stderr, "DosWrite: rc=%hu\n", rc);
  59.       exit (2);
  60.     }
  61. }
  62.  
  63.  
  64. int main (int argc, char *argv[])
  65. {
  66.   USHORT rc, cb;
  67.   byte header[2], result[12], *p, *q;
  68.   int sys_rc, drive, i, len, verbose, sw, quit;
  69.   CHAR failname[256], *shell, *prog;
  70.   RESULTCODES results;
  71.   SEL env_sel;
  72.   USHORT cmd_off;
  73.   HWND hwndActive;
  74.  
  75.   puts ("os2execd -- Version 1.0a -- Copyright (c) 1992-1993 by Eberhard Mattes");
  76.   verbose = FALSE; sw = FALSE; quit = FALSE;
  77.   for (i = 1; i < argc; ++i)
  78.     if (strcmp (argv[i], "-v") == 0)
  79.       verbose = TRUE;
  80.     else if (strcmp (argv[i], "-s") == 0)
  81.       sw = TRUE;
  82.     else
  83.       {
  84.         fprintf (stderr, "Usage: os2execd [-s] [-v]\n\n");
  85.         fprintf (stderr, "  -s  Switch windows\n");
  86.         fprintf (stderr, "  -v  Verbose\n");
  87.         return (2);
  88.       }
  89.   shell = getenv ("COMSPEC");
  90.   if (shell == NULL)
  91.     shell = "cmd.exe";
  92.   if (DosGetEnv (&env_sel, &cmd_off) != 0)
  93.     {
  94.       fprintf (stderr, "DosGetEnv failed\n");
  95.       return (2);
  96.     }
  97.   org_env = MAKEP (env_sel, 0);
  98.   org_env_size = 0;
  99.   while (org_env[org_env_size++] != 0)
  100.     while (org_env[org_env_size++] != 0)
  101.       ;
  102.   new_env_size = new_env_alloc = org_env_size;
  103.   new_env = malloc (new_env_alloc);
  104.   if (new_env == NULL) out_of_mem ();
  105.   memmove (new_env, org_env, org_env_size);
  106.   rc = DosMakeNmPipe ("/pipe/os2exec.em", &hp,
  107.                       NP_ACCESS_DUPLEX | NP_NOINHERIT,
  108.                       NP_WAIT | NP_READMODE_BYTE | NP_TYPE_BYTE
  109.                       | NP_UNLIMITED_INSTANCES,
  110.                       4096, 4096, 0L);
  111.   if (rc != 0)
  112.     {
  113.       fprintf (stderr, "DosMakeNmPipe: rc=%hu\n", rc);
  114.       return (2);
  115.     }
  116.  new:
  117.   rc = DosConnectNmPipe (hp);
  118.   if (rc != 0)
  119.     {
  120.       fprintf (stderr, "DosConnectNmPipe: rc=%hu\n", rc);
  121.       return (2);
  122.     }
  123.   if (verbose)
  124.     fprintf (stderr, "--- Connected\n");
  125.   for (;;)
  126.     {
  127.       rc = DosRead (hp, header, sizeof (header), &cb);
  128.       if (rc != 0)
  129.         {
  130.           fprintf (stderr, "DosRead: rc=%hu\n", rc);
  131.           return (2);
  132.         }
  133.       if (cb != 2)
  134.         break;
  135.       rc = DosRead (hp, buf, header[0] + 256 * header[1], &cb);
  136.       if (rc != 0)
  137.         {
  138.           fprintf (stderr, "DosRead: rc=%hu\n", rc);
  139.           return (2);
  140.         }
  141.       if (cb == 0)
  142.         break;
  143.       buf[cb] = 0;
  144.       if (verbose)
  145.         {
  146.           fprintf (stderr, "--- Message: <");
  147.           fwrite (buf, cb, 1, stderr);
  148.           fprintf (stderr, ">\n");
  149.         }
  150.       switch (buf[0])
  151.         {
  152.         case 'A':       /* Return code acknowledgement */
  153.           if (verbose)
  154.             fprintf (stderr, "--- Return code acknowledged\n");
  155.           goto done;
  156.         case 'C':       /* Command: CMD.EXE */
  157.         case 'X':       /* Command: DosExecPgm */
  158.           if (verbose)
  159.             fprintf (stderr, "--- Command: %s\n", buf+1);
  160.           if (sw)
  161.             {
  162.               hwndActive = WinQueryActiveWindow (HWND_DESKTOP, FALSE);
  163.               WinSwitchToProgram (WinQuerySwitchHandle (0, getpid ()));
  164.             }
  165.           if (buf[0] == 'C')
  166.             {
  167.               prog = shell;
  168.               p = args;
  169.               strcpy (p, shell); p = strchr (p, 0) + 1;
  170.               strcpy (p, "/c ");
  171.               strcat (p, buf+1); p = strchr (p, 0) + 1;
  172.               *p = 0;
  173.             }
  174.           else
  175.             {
  176.               q = buf + 1;
  177.               while (*q == ' ' || *q == '\t')
  178.                 ++q;
  179.               for (i = 0; i < sizeof (prog_buf) - 5; ++i)
  180.                 {
  181.                   if (*q == 0 || *q == ' ' || *q == '\t')
  182.                     break;
  183.                   prog_buf[i] = *q;
  184.                   ++q;
  185.                 }
  186.               prog_buf[i] = 0;
  187.               prog = prog_buf;
  188.               p = args;
  189.               strcpy (p, prog); p = strchr (p, 0) + 1;
  190.               strcpy (p, q); p = strchr (p, 0) + 1;
  191.               *p = 0;
  192.               i = FALSE;
  193.               for (q = prog_buf; *q != 0; ++q)
  194.                 if (*q == ':' || *q == '\\' || *q == ':')
  195.                   i = FALSE;
  196.                 else if (*q == '.')
  197.                   i = TRUE;
  198.               if (!i)
  199.                 strcat (prog_buf, ".exe");
  200.             }
  201.           if (verbose)
  202.             fprintf (stderr, "--- Program: %s\n", prog);
  203.           rc = DosExecPgm (failname, sizeof (failname),
  204.                            EXEC_SYNC,
  205.                            args, new_env, &results, prog);
  206.           if (rc != 0)
  207.             {
  208.               fprintf (stderr, "--- DosExecPgm failed, rc=%hu\n", rc);
  209.               sys_rc = -1;
  210.             }
  211.           else
  212.             sys_rc = results.codeResult;
  213.           if (sw && hwndActive != NULL)
  214.             WinSwitchToProgram (WinQuerySwitchHandle (hwndActive, 0));
  215.           sprintf (result, "%d", sys_rc);
  216.           send ('R', result, strlen (result));
  217.           fputchar ('\n');
  218.           memmove (new_env, org_env, org_env_size);
  219.           new_env_size = org_env_size;
  220.           break;
  221.         case 'E':
  222.           p = strchr (buf+1, '=');
  223.           if (p != NULL)
  224.             {
  225.               len = (p - (buf+1)) + 1;
  226.               i = 0;
  227.               while (new_env[i] != 0)
  228.                 if (memcmp (new_env+i, buf+1, len) == 0)
  229.                   break;
  230.                 else
  231.                   i += strlen (new_env+i) + 1;
  232.               if (new_env[i] != 0)
  233.                 {
  234.                   len = strlen (new_env+i) + 1;
  235.                   memmove (new_env + i, new_env + i + len,
  236.                            new_env_size - (i + len));
  237.                   new_env_size -= len;
  238.                 }
  239.               len = strlen (buf+1) + 1;
  240.               if (new_env_size + len > new_env_alloc)
  241.                 {
  242.                   new_env_alloc = new_env_size + len;
  243.                   new_env = realloc (new_env, new_env_alloc);
  244.                   if (new_env == NULL) out_of_mem ();
  245.                 }
  246.               memmove (new_env + new_env_size - 1, buf + 1, len);
  247.               new_env_size += len;
  248.               new_env[new_env_size-1] = 0;
  249.             }
  250.           break;
  251.         case 'Q':       /* Quit */
  252.           if (verbose)
  253.             fprintf (stderr, "--- Quit\n");
  254.           send ('A', "", 0);
  255.           quit = TRUE;
  256.           goto done;
  257.         case 'W':       /* Working directory */
  258.           p = buf + 1;
  259.           drive = toupper (p[0]);
  260.           if (drive >= 'A' && drive <= 'Z' && p[1] == ':')
  261.             {
  262.               if (verbose)
  263.                 fprintf (stderr, "--- Change drive: %c\n", drive);
  264.               _chdrive (drive - 'A' + 1);
  265.               p += 2;
  266.             }
  267.           if (verbose)
  268.             fprintf (stderr, "--- Change directory: %s\n", p);
  269.           chdir (p);
  270.           break;
  271.         }
  272.     }
  273. done:
  274.   if (verbose)
  275.     fprintf (stderr, "--- Disconnect\n");
  276.   rc = DosDisConnectNmPipe (hp);
  277.   if (rc != 0)
  278.     {
  279.       fprintf (stderr, "DosDisConnectNmPipe: rc=%hu\n", rc);
  280.       return (2);
  281.     }
  282.   if (!quit)
  283.     goto new;
  284.   
  285.   rc = DosClose (hp);
  286.   if (rc != 0)
  287.     {
  288.       fprintf (stderr, "DosClose: rc=%hu\n", rc);
  289.       return (2);
  290.     }
  291.   return (0);
  292. }
  293.