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);
}