Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
/* -*-C-*- * gnuserv.c -- pbreton Thu Jan 25 1996 * * Server code for handling requests from clients and forwarding them * on to the GNU Emacs process. * * This file is not part of GNU Emacs. * * Copying is permitted under those conditions described by the GNU * General Public License. * * Copyright (C) 1996 Peter Breton/Nico Francois * * Author: Peter Breton (pbreton@cs.umb.edu) * Based heavily on Andy Norman's gnuserv (ange@hplb.hpl.hp.com), * which in turn was based on 'etc/emacsclient.c' from the GNU * Emacs 18.52 distribution. * * Modifications: Nico Francois (nico.francois@scala.nl) * Mon Jun 3 1996 * Significant rework to use mailslots instead of named pipes. * Following improvements have been made: * - now works on Windows 95 as well as NT. * - uses a thread to handle client requests while the main process * reads the results from Emacs. * - results from Emacs are sent back to the appropriate client. * NOTE: currently still limited to clients that run on the same * machine as gnuserv! * - can be aborted so the task will not hang around on Win95 (not sure * if this was a problem on NT). * * Sat Jun 8 1996 * Moved reading from stdin to thread and waiting on mailslot to main * process. * Fixed problem with client mailslotname on Windows NT. * Sending result to mailslot will now open the mailslot only when needed. * This works around a problem with a sharing violation error on NT. * * Thu Jun 27 1996 * Cleaned up the code a bit and added more/better comments. * Sharing violation error on NT now properly handled in gnuslib.c. * Made gnuslib.c check for NT/95 and handle things differently when * running on Windows 95 (to avoid silly 100% CPU time usage on 95). * * $Log$ */ static char rcsid[] = "$Header$"; #include "gnuserv.h" static char *progname = NULL; static char message[GSERV_BUFSZ + 1]; enum { MSGTYPE_UNKNOWN, MSGTYPE_REQUEST, // Client will start request strings with "C:" MSGTYPE_RESULT, // Result string starts with "R:" }; void HandleClientRequests (HANDLE mailslot) { while (1) { int slotdone = FALSE; while (!slotdone) { DWORD clientid; DWORD bytesread; int msgtype; // Read the message and check to see if read was successful msgtype = MSGTYPE_UNKNOWN; while (ReadFile (mailslot, message, sizeof (message), &bytesread, (LPOVERLAPPED)NULL)) { // If we actually received anything, handle what we got. if (bytesread) { char *msg = message; message[bytesread] = '\0'; // For starters we'll need to find the message type if (msgtype == MSGTYPE_UNKNOWN) { if (!strncmp ("R:", message, 2)) { msgtype = MSGTYPE_RESULT; msg += 2; } else if (!strncmp ("C:", message, 2)) { msgtype = MSGTYPE_REQUEST; msg += 2; clientid = atol (msg); while (*msg && *msg++ != ' '); printf ("%u ", clientid); } } if (msgtype == MSGTYPE_REQUEST) { if (*msg) { printf ("%s", msg); } if (strchr (msg, EOT_CHR)) { fflush (stdout); slotdone = TRUE; break; } } else if (msgtype == MSGTYPE_RESULT) { // Send result back to client if (*msg) { HANDLE clientslot; // Get client-id from result string, then // skip until after ':' so we only send // the actual result string back. clientid = atol (msg); while (*msg && *msg++ != ':'); // Client will be waiting for the result // on a mailslot with the following name: // \\hostname\mailslot\emacs\gnuclient\ABADCAFE // With ABADCAFE being the clientid in hex (8 chars). // FIX! hostname is always . right now! clientslot = ConnectToMailslot (GNUSERV_DEFAULT_HOST, TRUE, clientid); if (clientslot != INVALID_HANDLE_VALUE) { // Don't use SendString() since we don't want // to know about any errors. DWORD byteswritten; WriteFile (clientslot, msg, strlen(msg) + 1, &byteswritten, (LPOVERLAPPED)NULL); DisconnectFromMailslot (clientslot); } } // Result message is terminated by a newline if (strchr (msg, '\n')) { slotdone = TRUE; break; } } } else { // We should only get here on Windows 95 (mailslot // timeout set to 0). // We did not receive anything. Sleep for 2/10th // of a second, then try again. Sleep (200); } } } } } // This function will run as a separate thread. // It will read results from stdin (sent by Emacs) and will send them // to the mailslot that is polled in our main loop. DWORD HandleEmacsResults (LPDWORD lpdwParam) { char inputbuff[256]; DWORD bytesread; HANDLE sendslot, in; // Get handle to stdin in = GetStdHandle (STD_INPUT_HANDLE); while (1) { while (ReadFile (in, inputbuff, sizeof (inputbuff), &bytesread, (LPOVERLAPPED)NULL)) { inputbuff[bytesread] = '\0'; // Send input (result) to our thread, so it can be sent // back to the client. sendslot = ConnectToMailslot (GNUSERV_DEFAULT_HOST, FALSE, 0); if (sendslot != INVALID_HANDLE_VALUE) { SendString (sendslot, "R:"); SendString (sendslot, inputbuff); DisconnectFromMailslot (sendslot); } } } return (0); } void main (int argc, char *argv[]) { HANDLE mailslot; DWORD threadid; HANDLE thread; progname = argv[0]; // Create mailslot. mailslot = CreateGnuServSlot (FALSE, 0); if (mailslot == INVALID_HANDLE_VALUE) exit (1); // Create thread to read Emacs results from stdin and send them // to our mailslot. thread = CreateThread ((LPSECURITY_ATTRIBUTES)NULL, 0, (LPTHREAD_START_ROUTINE)HandleEmacsResults, NULL, 0, &threadid); // Handle all client requests (and results) HandleClientRequests (mailslot); // Cleanup, then exit DisconnectFromMailslot (mailslot); }