home *** CD-ROM | disk | FTP | other *** search
- /* The routines in this file provide support for external program
- execution under the Microsoft Windows environment on an IBM-PC or
- compatible computer.
-
- Must be compiled with Borland C++ 2.0 or later version.
-
- It should not be compiled if the WINDOW_MSWIN symbol is not set */
-
- #include "estruct.h"
- #include <stdio.h>
- #include "eproto.h"
- #include "edef.h"
- #include "elang.h"
-
- #include "mswin.h"
-
- extern char *getenv (char *);
-
- /* local data */
- static HWND hPrgWnd; /* window handle of the external program task */
-
-
- /* HandleTimer: checks the existence of the external program window */
- /* =========== */
-
- static void pascal near HandleTimer (HWND hDlg)
-
- /* This function uses a 200ms timer to check the existence of the window
- indicated by hPrgWnd. When that window handle becomes invalid, it is
- assumed that the external program has exited and the WAITFORPRG
- dialog box is terminated with a TRUE result. If there is a problem
- setting the timer, the dialog box is terminated with a FALSE result
- after a message box announcing the problem has been displayed. */
- {
- if (IsWindow (hPrgWnd)) {
- while (!SetTimer (hDlg, 1, 200, NULL)) {
- /* bad: problem setting the timer */
- if (MessageBox (hDlg, TEXT337, NULL, MB_RETRYCANCEL) == IDCANCEL) {
- /* "cannot monitor external program" */
- EndDialog (hDlg, FALSE); /* give up! */
- return;
- }
- /* else: attempt a retry */
- }
- }
- else {
- EndDialog (hDlg, TRUE);
- }
- } /* HandleTimer */
-
- /* WAITFORPRGDlgProc: dialog proc for WAITFORPRG dialog box */
- /* ================= */
- int EXPORT far pascal WAITFORPRGDlgProc (HWND hDlg, WORD wMsg,
- WORD wParam, DWORD lParam)
- {
- switch (wMsg) {
- case WM_INITDIALOG:
- SetWindowText (hDlg, PROGNAME);
- HandleTimer (hDlg);
- return TRUE;
- case WM_TIMER:
- HandleTimer (hDlg);
- break;
- case WM_COMMAND:
- if (wParam == 2) { /* Cancel */
- KillTimer (hDlg, 1);
- EndDialog (hDlg, FALSE);
- }
- break;
- default:
- return FALSE;
- }
- return FALSE;
- } /* WAITFORPRGDlgProc */
-
- /* LaunchPrgEnumProc: used by LaunchPrg */
- /* ================= */
- BOOL EXPORT far pascal LaunchPrgEnumProc (HWND hWnd, DWORD lParam)
-
- /* this function sets hPrgWnd when it finds a window that matches the
- module instance handle passed in lParam */
- {
- if (GetWindowWord (hWnd, GWW_HINSTANCE) == LOWORD(lParam)) {
- hPrgWnd = hWnd;
- return FALSE; /* found it, stop enumerating */
- }
- return TRUE;
- } /* LaunchPrgEnumProc */
-
- /* LaunchPrg: launches and monitors an external program */
- /* ========= */
-
- static BOOL pascal near LaunchPrg (char *Cmd, BOOL DOSApp,
- char *InFile, char *OutFile)
-
- /* Returns TRUE if all went well, FALSE if wait cancelled and FAILED if
- failed to launch.
-
- Cmd is the command string to launch.
-
- DOSApp is TRUE if the external program is a DOS program to be run
- under a DOS shell. If DOSApp is FALSE, the program is launched
- directly as a Windows application. In that case, the InFile parameter
- is ignored, and the value of the OutFile parameter is used only to
- determine if the program should be monitored. the string referenced
- by OutFile is irrelevant.
-
- InFile is the name of the file to pipe into stdin (if NULL, nothing
- is piped in)
-
- OutFile is the name of the file where stdout is expected to be
- redirected. If it is NULL, stdout is not redirected and the LaunchPrg
- return immediately after starting the DOS box.
-
- If OutFile is not NULL, the external program is monitored. LaunchPrg
- returns only when the external program has terminated or the user has
- cancelled the wait (in which case LaunchPrg returns FALSE). */
- {
- char FullCmd [256];
- HANDLE hModule;
- FARPROC ProcInstance;
- int nCmdShow;
-
- if (SetWorkingDir () != 0) {
- mlwrite (TEXT334); /* "[No such directory]" */
- return FALSE;
- }
- if (DOSApp) {
- if (OutFile || !Cmd) {
- GetProfileString (ProgName, "DOSExec", "",
- FullCmd, 256 - NFILEN);
- }
- else FullCmd[0] = '\0';
- if (FullCmd[0] == '\0') {
- GetProfileString (ProgName, "DOSBox", "command.com",
- FullCmd, 256 - NFILEN);
- }
- /* the DOSBox profileString should be the name of a PIF file for
- command.com that specifies no arguments and no starting dir.
- The DOSExec should be similar but specify "Close window on
- exit" */
- if (Cmd) {
- if ((strlen (FullCmd) + strlen (Cmd) + 3) >= 256) return FALSE;
- strcat (FullCmd, " /c");
- strcat (FullCmd, Cmd);
- }
- if (InFile) {
- if ((strlen (FullCmd) + strlen (InFile) + 2) >= 256) return FALSE;
- strcat (FullCmd, " <");
- strcat (FullCmd, InFile);
- }
- if (OutFile) {
- if ((strlen (FullCmd) + strlen (OutFile) + 2) >= 256) return FALSE;
- strcat (FullCmd, " >");
- strcat (FullCmd, OutFile);
- }
- }
- if (GetWinFlags () & WF_ENHANCED) {
- if (OutFile) nCmdShow = SW_SHOWMINIMIZED;
- else nCmdShow = SW_SHOWNORMAL;
- }
- else nCmdShow = SW_SHOWNORMAL;
-
- hModule = WinExec (DOSApp ? FullCmd : Cmd, nCmdShow);
- /* here we GOoooo */
-
- if (hModule < 32) {
- mlwrite (TEXT3); /* "[Execution failed]" */
- return FAILED;
- }
- if (!OutFile) return TRUE; /* no need to synchronize */
- hPrgWnd = 0;
- ProcInstance = MakeProcInstance ((FARPROC)LaunchPrgEnumProc,
- hEmacsInstance);
- EnumWindows (ProcInstance, (DWORD)hModule);
- FreeProcInstance (ProcInstance);
- if (hPrgWnd != 0) {
- /*-put up a dialog box to wait for the external program termination */
- int Result;
-
- ProcInstance = MakeProcInstance ((FARPROC)WAITFORPRGDlgProc,
- hEmacsInstance);
- Result = DialogBox (hEmacsInstance, "WAITFORPRG",
- hFrameWnd, ProcInstance);
- FreeProcInstance (ProcInstance);
- return Result;
- }
- else return TRUE; /* we assume it has zipped past us! */
- } /* LaunchPrg */
-
- /* spawncli: launch DOS shell. Bound to ^X-C */
- /* ======== */
-
- PASCAL spawncli (int f, int n)
- {
- /*-don't allow this command if restricted */
- if (restflag) return resterr();
-
- return LaunchPrg (NULL, TRUE, NULL, NULL);
- } /* spawncli */
-
- /* spawn: run a one-liner in a DOS box. Bound to ^X-! */
- /* ===== */
-
- PASCAL spawn (int f, int n)
- {
- char Line[NLINE];
- int Result;
-
- /*-don't allow this command if restricted */
- if (restflag) return resterr();
-
- if ((Result = mlreply ("!", Line, NLINE)) != TRUE) return Result;
- return LaunchPrg (Line, TRUE, NULL, NULL);
- } /* spawn */
-
- /* execprg: run another program with arguments. Bound to ^X-$ */
- /* ======= */
-
- PASCAL execprg (int f, int n)
- {
- char Line[NLINE];
- int Result;
-
- /*-don't allow this command if restricted */
- if (restflag) return resterr();
-
- /*-get the program command line */
- if (mlreply ("$", Line, NLINE) != TRUE) return FALSE;
-
- Result = LaunchPrg (Line, FALSE, NULL, f ? Line : NULL);
- if (Result == FAILED) {
- mlwrite (TEXT3); /* "[Execution failed]" */
- }
- return Result;
- } /* execprg */
-
- /* pipecmd: pipe a one-liner into a window. Bound to ^X-@ */
- /* ======= */
-
- PASCAL pipecmd (int f, int n)
-
- /* this function fills a buffer named "command" with the output of the
- DOS one-liner. If the command buffer already exist, it is overwritten
- only if it has not been changed */
- {
- char Line[NLINE];
- char OutFile[NFILEN];
- static char bname[] = "command";
- BUFFER *bp;
- WINDOW *wp;
- int Result;
- int bmode;
-
- /*-don't allow this command if restricted */
- if (restflag) return resterr();
-
- /*-get the command to pipe-in */
- if (mlreply ("@", Line, NLINE) != TRUE) return FALSE;
-
- /*-find the "command" buffer */
- if ((bp = bfind (bname, FALSE, 0)) != NULL) {
- /*-make sure the contents can safely be blown away */
- if (bp->b_flag & BFCHG) {
- if (mlyesno (TEXT32) != TRUE) return FALSE;
- /* discard changes */
- }
- }
- else if ((bp = bfind (bname, TRUE, 0)) == NULL) {
- mlwrite (TEXT137);
- /* cannot create buffer */
- return FALSE;
- }
- GetTempFileName (0, "UE", 0, OutFile);
- Result = LaunchPrg (Line, TRUE, NULL, OutFile);
- if (Result == FAILED) {
- mlwrite (TEXT3);
- /* [execution failed] */
- unlink (OutFile);
- }
- else {
- if (Result == TRUE) {
- BUFFER *temp_bp;
-
- temp_bp = curbp;
- swbuffer (bp); /* make this buffer the current one */
- bmode = bp->b_mode;
- bp->b_mode &= ~(MDVIEW | BFCHG);
- Result = readin (OutFile, FALSE);
- bp->b_fname[0] = '\0'; /* clear file name */
- if (Result == TRUE) {
- bp->b_mode |= MDVIEW; /* force VIEW mode */
- lchange (WFMODE); /* update all relevant mode lines */
- bp->b_flag &= ~BFCHG; /* remove by-product BFCHG flag */
- }
- else {
- bp->b_mode = bmode; /* restore mode */
- swbuffer (temp_bp);
- }
- unlink (OutFile);
- /* note that the file is not deleted if the wait was cancelled */
- }
- }
- return Result;
- } /* pipecmd */
-
- /* filter: filter a buffer through a DOS box. Bound to ^X-# */
- /* ====== */
-
- PASCAL filter (int f, int n)
- {
- char Line[NLINE];
- char InFile[NFILEN];
- char OutFile[NFILEN];
- char fname[NFILEN];
- BUFFER *bp;
- WINDOW *wp;
- int Result;
-
- /*-don't allow this command if restricted */
- if (restflag) return resterr();
-
- /*-get the filter command line */
- if (mlreply ("#", Line, NLINE) != TRUE) return FALSE;
-
- bp = curbp;
- strcpy (fname, bp->b_fname);
- GetTempFileName (0, "UE", 0, InFile);
- Result = writeout (InFile, "w");
- if (Result != TRUE) {
- mlwrite (TEXT2);
- /* cannot write filter file */
- }
- else {
- GetTempFileName (0, "UE", 0, OutFile);
- Result = LaunchPrg (Line, TRUE, InFile, OutFile);
- if (Result == FAILED) {
- mlwrite (TEXT3);
- /* [execution failed] */
- unlink (OutFile);
- unlink (InFile);
- }
- else {
- if (Result == TRUE) {
- Result = readin (OutFile, FALSE);
- unlink (OutFile);
- unlink (InFile);
- }
- /* note that he files are not deleted if the wait was cancelled */
- if (Result == TRUE) {
- lchange (WFMODE); /* update all relevant mode lines */
- }
- }
- }
- strcpy (bp->b_fname, fname); /* restore original file name */
- return Result;
- } /* filter */
-