home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / pipdos11.zip / pd.c < prev    next >
C/C++ Source or Header  |  1995-07-05  |  10KB  |  333 lines

  1. /**********************************************************/
  2. /**********************************************************/
  3. /***                                                    ***/
  4. /***  Program name: PIPEDOS.C                           ***/
  5. /***                                                    ***/
  6. /***  Created     : 4th July 1995                       ***/
  7. /***                                                    ***/
  8. /***  Author      : Scott Maxwell                       ***/
  9. /***                                                    ***/
  10. /***  Purpose     : Use OS/2 named pipes to redirect    ***/
  11. /***                STDIN, STDOUT and STDERR from a     ***/
  12. /***                DOS session to an OS/2 window.      ***/
  13. /***                                                    ***/
  14. /***  Compile     : icc /O+ pd.c                        ***/
  15. /***                                                    ***/
  16. /***  (C) 1995 Scott Maxwell                            ***/
  17. /***                                                    ***/
  18. /**********************************************************/
  19.  
  20. #define DO_STDIN
  21.  
  22. /**********************************************************/
  23. /***  DEFINES                                           ***/
  24. /**********************************************************/
  25. #define INCL_DOSNMPIPES
  26. #define INCL_DOSSESMGR      /* Session Manager values */
  27. #define INCL_DOSQUEUES
  28. #define INCL_DOSPROCESS
  29. #define INCL_DOSERRORS
  30. #define INCL_DOSDATETIME
  31. #define INCL_DOSFILEMGR
  32. #define INCL_DOSSEMAPHORES
  33.  
  34. /**********************************************************/
  35. /***  INCLUDES and VARIABLES                            ***/
  36. /**********************************************************/
  37. #include <os2.h>
  38. #include <stdlib.h>
  39. #include <string.h>
  40. #include <stdio.h>
  41.  
  42. void _Optlink OutThread(void *threadArg);
  43. void _Optlink InThread(void *threadArg);
  44.  
  45. #define QUEUENAME "\\QUEUES\\PIPEDOS.QUE"
  46. #define PIPENAME  "/pipe/pipedos."
  47.  
  48. #define BUFLEN 0x201
  49.  
  50. unsigned long eventSem[3];
  51. HMTX ioSync;
  52.  
  53. /**********************************************************/
  54. /***  MAIN PROGRAM                                      ***/
  55. /**********************************************************/
  56. int main(int argc, char *argv[])
  57. {
  58.   BOOL fEnd_Correct=FALSE;
  59.  
  60.   STARTDATA   StartData;    /* Start session data structure */
  61.   ULONG       SessID;       /* Session ID (returned) */
  62.   PID         sessionPid;   /* Process ID (returned) */
  63.   UCHAR       ObjBuf[100];  /* Object buffer */
  64.   APIRET      rc;           /* Return code */
  65.   HQUEUE      QueueHandle;
  66.   REQUESTDATA Request;       /* Request-identification data */
  67.   ULONG       DataLength;    /* Length of element received */
  68.   PVOID       DataAddress;   /* Address of element received */
  69.   BYTE        ElemPriority;  /* Priority of element received */
  70.   unsigned short *shrt;
  71.   char          buffer[BUFLEN], *bptr;
  72.  
  73.  
  74.   DosCreateMutexSem(0,&ioSync,0,0);
  75.   
  76.   DosCreateEventSem(NULL,&eventSem[0],0,0);
  77.   rc = _beginthread(InThread, 0, 0x8000, (void*)0); /*stdin*/
  78.   if (rc == -1) {
  79.     printf("_beginthread error\n");
  80.     exit (1);
  81.   } /*end-if*/
  82.   rc = DosWaitEventSem(eventSem[0],2000);
  83.   if (rc) {
  84.     printf("Timeout\n");
  85.     exit (1);
  86.   } /*end-if*/
  87.   DosCreateEventSem(NULL,&eventSem[1],0,0);
  88.   rc = _beginthread(OutThread, 0, 0x8000, (void*)1); /*stdout*/
  89.   if (rc == -1) {
  90.     printf("_beginthread error\n");
  91.     exit (1);
  92.   } /*end-if*/
  93.   rc = DosWaitEventSem(eventSem[1],2000);
  94.   if (rc) {
  95.     printf("Timeout\n");
  96.     exit (1);
  97.   } /*end-if*/
  98.   DosCreateEventSem(NULL,&eventSem[2],0,0);
  99.   rc = _beginthread(OutThread, 0, 0x8000, (void*)2); /*stderr*/
  100.   if (rc == -1) {
  101.     printf("_beginthread error\n");
  102.     exit (1);
  103.   } /*end-if*/
  104.   rc = DosWaitEventSem(eventSem[2],2000);
  105.   if (rc) {
  106.     printf("Timeout\n");
  107.     exit (1);
  108.   } /*end-if*/
  109.   
  110.   
  111.   if (argc < 2) {
  112.     printf("PipeDOS is a DOS executor to allow seamless running of\n");
  113.     printf("DOS command line utilities in an OS/2 window.\n");
  114.     printf("(C) 1995 Scott Maxwell\n\n");
  115.     printf("USAGE: %s dos_command dos_parameters\n",argv[0]);
  116.     return 1;
  117.   }
  118.   
  119.   rc = DosCreateQueue(&QueueHandle,             /* Queue handle */
  120.               QUE_FIFO |                /* Ordering for elements */
  121.               QUE_CONVERT_ADDRESS,      /* 16-bit address conversion */
  122.               QUEUENAME);    /* Queue name string  */
  123.  
  124.   StartData.Length = sizeof(STARTDATA);
  125.   StartData.Related = SSF_RELATED_CHILD;
  126.   StartData.FgBg = SSF_FGBG_BACK;
  127.   StartData.TraceOpt = SSF_TRACEOPT_NONE;
  128.   StartData.PgmTitle = "PipeDOS Child";
  129.   StartData.PgmName = 0;    /* DOS session */
  130.  
  131.   strcpy(buffer,"/c _pd");
  132.   bptr = buffer+strlen(buffer);
  133.   while(*++argv) {
  134.     *bptr = ' ';
  135.     bptr++;
  136.     strcpy(bptr,*argv);
  137.     bptr+=strlen(*argv);
  138.   }
  139.   StartData.PgmInputs = buffer;
  140.   StartData.TermQ = QUEUENAME;
  141.   StartData.Environment = "DPMI_MEMORY_LIMIT=32\0EMS_MEMORY_LIMIT=8192\0XMS_MEMORY_LIMIT=8192\0E:\DOS_AUTOEXEC=E:\AutoPD.EXE\0";
  142.   StartData.InheritOpt = SSF_INHERTOPT_PARENT;
  143.   StartData.SessionType = SSF_TYPE_VDM;
  144.   StartData.IconFile = 0;
  145.   StartData.PgmHandle = 0;
  146.   StartData.PgmControl = SSF_CONTROL_INVISIBLE;
  147.   StartData.Reserved = 0;
  148.   StartData.ObjectBuffer = ObjBuf;
  149.   StartData.ObjectBuffLen = 100;
  150.   rc = DosStartSession(&StartData, &SessID, &sessionPid);
  151.  
  152.   if (rc != 0) {
  153.     printf("DosStartSession error: return code = %ld", rc);
  154.     return rc;
  155.   }
  156.  
  157.  
  158.   /****************************************************************/
  159.   /* now we wait for our DOS session to connect to us             */
  160.   /****************************************************************/
  161.  
  162.   rc = DosReadQueue(QueueHandle, &Request, &DataLength,
  163.                           &DataAddress, 0, 0,
  164.                           &ElemPriority, 0L);
  165.  
  166.   if (rc != 0) {
  167.     printf("DosReadQueue error: return code = %ld", rc);
  168.     return rc;
  169.   }
  170.  
  171.   rc = DosCloseQueue(QueueHandle);         /* Close the queue */
  172.   if (rc!= NO_ERROR) {
  173.     printf ("DosCloseQueue error: return code = %u\n", rc);
  174.     return 1;
  175.   }
  176.  
  177.   rc = DosWaitEventSem(eventSem[1],1000);
  178.   rc = DosWaitEventSem(eventSem[2],1000);
  179.  
  180.   DosCloseEventSem(eventSem[0]);
  181.   DosCloseEventSem(eventSem[1]);
  182.   DosCloseEventSem(eventSem[2]);
  183.   DosCloseMutexSem(ioSync);
  184.   shrt = DataAddress;
  185.   return shrt[1];
  186. }
  187.  
  188.  
  189.  
  190. /****************************************************************/
  191. /* This is our thread process which creates N named pipes then  */
  192. /* waits for the DOS sessions to connect to them.               */
  193. /****************************************************************/
  194. #define LINELEN 0x100
  195.  
  196. void _Optlink OutThread(void *vthreadArg)
  197. {
  198.   APIRET rc;
  199.   char          buffer[LINELEN+1];
  200.   char *pipename;
  201.   unsigned long cnt;
  202.   FILE *f;
  203.   int threadArg = (int)vthreadArg;
  204.   HPIPE PipeHandle;
  205.  
  206.   switch (threadArg) {
  207.   case 1:
  208.     pipename = PIPENAME"1";
  209.     f = stdout;
  210.     break;
  211.   case 2:
  212.     pipename = PIPENAME"2";
  213.     f = stderr;
  214.     break;
  215.   default:
  216.     fprintf(stderr,"Unknown stream\n");
  217.     exit(1);
  218.   }
  219.   rc = DosCreateNPipe(pipename,    /* create pipe    */
  220.                       &PipeHandle,
  221.                       NP_NOINHERIT|NP_ACCESS_DUPLEX,
  222.                       NP_WAIT | NP_READMODE_BYTE | NP_TYPE_BYTE | NP_UNLIMITED_INSTANCES,
  223.                       2048,    /* outbuffer */
  224.                       4096,    /* inbuffer */
  225.                       0L);    /* timeout */
  226.   if (rc != 0) {
  227.     printf("Couldn't create pipe\n");
  228.     exit(1);
  229.   }
  230.  
  231.   if (threadArg == 1)
  232.     DosRequestMutexSem( ioSync, -1);
  233.   DosPostEventSem(eventSem[threadArg]);
  234.   DosResetEventSem(eventSem[threadArg],&cnt);
  235.  
  236.   /****************************************************************/
  237.   /* now we wait for our DOS session to connect to us             */
  238.   /****************************************************************/
  239.  
  240.   rc = DosConnectNPipe(PipeHandle);
  241.   if (rc != 0) {
  242.     DosBeep(100,200);
  243.     exit(1);
  244.   }
  245.  
  246.   if (threadArg == 2)
  247.     DosRequestMutexSem( ioSync, -1);
  248.   do {
  249.     DosSleep(100);
  250.     rc=DosRead(PipeHandle,buffer,LINELEN,&cnt);
  251.     if (rc != 0) {
  252.       printf("DosRead: rc=%hu\n",rc);
  253.       exit(1);
  254.     }
  255.     if (cnt) {
  256.       int a, from;
  257.       static int last=-1;
  258.       for (a=0, from=0; a<cnt; a++) {
  259.     if (buffer[a] == 0xa) {
  260.       if (a>from && buffer[a-1] == 0xd)
  261.         buffer[a-1] = 0;
  262.       else
  263.         buffer[a] = 0;
  264.       fputs(&buffer[from],f);
  265.       fputc(10,f);
  266.       from = a+1;
  267.     }
  268.       }
  269.       if (from < a) {
  270.     buffer[a]=0;
  271.     if (buffer[a-1] == 0xd)
  272.       buffer[a-1] = 0;
  273.     fputs(&buffer[from],f);
  274.       }
  275.       fflush(0);
  276.     }
  277.   } while (cnt);
  278.   DosReleaseMutexSem(ioSync);
  279.   DosClose(PipeHandle);
  280.   DosPostEventSem(eventSem[threadArg]);
  281. }
  282.  
  283.  
  284.  
  285.  
  286. void _Optlink InThread(void *vthreadArg)
  287. {
  288.   APIRET rc;
  289.   char *pipename;
  290.   unsigned long cnt=1;
  291.   char c;
  292.   FILE *f;
  293.   int threadArg = (int)vthreadArg;
  294.   HPIPE PipeHandle;
  295.  
  296.   rc = DosCreateNPipe(PIPENAME"0",    /* create pipe    */
  297.                       &PipeHandle,
  298.                       NP_NOINHERIT|NP_ACCESS_DUPLEX,
  299.                       NP_WAIT | NP_READMODE_BYTE | NP_TYPE_BYTE | NP_UNLIMITED_INSTANCES,
  300.                       4096,    /* outbuffer */
  301.                       4096,    /* inbuffer */
  302.                       0L);    /* timeout */
  303.   if (rc != 0) {
  304.     printf("Couldn't create pipe\n");
  305.     exit(1);
  306.   }
  307.   DosPostEventSem(eventSem[0]);
  308.  
  309.  
  310.   /****************************************************************/
  311.   /* now we wait for our DOS session to connect to us             */
  312.   /****************************************************************/
  313.  
  314.   rc = DosConnectNPipe(PipeHandle);
  315.   if (rc != 0) {
  316.     DosBeep(100,200);
  317.     exit(1);
  318.   }
  319.  
  320.   while(1) {
  321.      DosSleep(100);
  322.      while (_kbhit()) {
  323.       c = _getch();
  324.         rc=DosWrite(PipeHandle,&c,1,&cnt);
  325.         rc=DosWrite(PipeHandle,&c,1,&cnt);
  326.         if (rc != 0) {
  327.           printf("DosWrite: rc=%hu\n",rc);
  328.           exit(1);
  329.         }
  330.     }
  331.   }
  332. }
  333.