[gpm] [PATCH 4/18] separate-client-handling.patch
Dmitry Torokhov
dtor_core@ameritech.net
Tue Aug 10 08:52:26 CEST 2004
===================================================================
ChangeSet@1.8, 2004-08-10 00:52:46-05:00, dtor_core@ameritech.net
Separate client handling code into separate source file, cleanups.
Makefile.in | 2
client.c | 318 ++++++++++++++++++++++++++++++++++++++++++
gpm.c | 414 +++++++++----------------------------------------------
headers/client.h | 57 +++++++
headers/gpmInt.h | 21 --
5 files changed, 446 insertions(+), 366 deletions(-)
===================================================================
diff -Nru a/src/Makefile.in b/src/Makefile.in
--- a/src/Makefile.in 2004-08-10 01:17:58 -05:00
+++ b/src/Makefile.in 2004-08-10 01:17:58 -05:00
@@ -14,7 +14,7 @@
# Main portion: regular build rules
GSRC = main.c gpm.c gpn.c mice.c special.c twiddler.c synaptics.c \
- startup.c server_tools.c console.c
+ startup.c server_tools.c console.c client.c
GOBJ = $(GSRC:.c=.o) report.o tools.o
diff -Nru a/src/client.c b/src/client.c
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/src/client.c 2004-08-10 01:17:58 -05:00
@@ -0,0 +1,318 @@
+/*
+ * client.c - GPM client handling (server side)
+ *
+ * Copyright (C) 1993 Andreq Haylett <ajh@gec-mrc.co.uk>
+ * Copyright (C) 1994-1999 Alessandro Rubini <rubini@linux.it>
+ * Copyright (C) 1998 Ian Zimmerman <itz@rahul.net>
+ * Copyright (c) 2001,2002 Nico Schottelius <nico-gpm@schottelius.org>
+ * Copyright (C) 2003 Dmitry Torokhov <dtor@mail.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ ********/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> /* strerror(); ?!? */
+#include <errno.h>
+#include <unistd.h> /* select(); */
+#include <signal.h> /* SIGPIPE */
+#include <time.h> /* time() */
+#include <sys/fcntl.h> /* O_RDONLY */
+#include <sys/stat.h> /* mkdir() */
+#include <sys/time.h> /* timeval */
+#include <sys/types.h> /* socket() */
+#include <sys/socket.h> /* socket() */
+#include <sys/un.h> /* struct sockaddr_un */
+
+#include "headers/gpmInt.h"
+#include "headers/message.h"
+#include "headers/console.h"
+#include "headers/client.h"
+
+/* who the f*** runs gpm without glibc? doesn't have dietlibc __socklent_t? */
+#if !defined(__GLIBC__)
+ typedef unsigned int __socklen_t;
+#endif /* __GLIBC__ */
+
+#ifndef max
+#define max(a,b) ((a)>(b) ? (a) : (b))
+#endif
+
+extern int errno;
+
+struct client_info *cinfo[MAX_VC + 1];
+
+/*-------------------------------------------------------------------*
+ * This was inline, and incurred in a compiler bug (2.7.0)
+ *-------------------------------------------------------------------*/
+static int get_data(int fd, Gpm_Connect *data)
+{
+ static int len;
+
+#ifdef GPM_USE_MAGIC
+ while ((len = read(whence, &check, sizeof(int))) == 4 &&
+ check != GPM_MAGIC)
+ gpm_report(GPM_PR_INFO, GPM_MESS_NO_MAGIC);
+
+ if (len == 0) return 0;
+
+ if (check != GPM_MAGIC) {
+ gpm_report(GPM_PR_INFO, GPM_MESS_NOTHING_MORE);
+ return -1;
+ }
+#endif
+
+ len = read(fd, data, sizeof(Gpm_Connect));
+
+ return len ? (len == sizeof(Gpm_Connect) ? 1 : -1) : 0;
+}
+
+/*-------------------------------------------------------------------*/
+int listen_for_clients(void)
+{
+ struct sockaddr_un ctladdr;
+ int fd, len;
+
+ unlink(GPM_NODE_CTL);
+
+ if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
+ gpm_report(GPM_PR_OOPS, GPM_MESS_SOCKET_PROB);
+
+ memset(&ctladdr, 0, sizeof(ctladdr));
+ ctladdr.sun_family = AF_UNIX;
+ strcpy(ctladdr.sun_path, GPM_NODE_CTL);
+ len = sizeof(ctladdr.sun_family) + strlen(GPM_NODE_CTL);
+
+ if (bind(fd, (struct sockaddr *)&ctladdr, len) == -1)
+ gpm_report(GPM_PR_OOPS, GPM_MESS_BIND_PROB, ctladdr.sun_path);
+
+ /* needs to be 0777, so all users can _try_ to access gpm */
+ chmod(GPM_NODE_CTL, 0777);
+ listen(fd, 5); /* Queue up calls */
+
+ return fd;
+}
+
+/*-------------------------------------------------------------------*/
+struct client_info *accept_client_connection(int fd)
+{
+ struct client_info *info;
+ Gpm_Connect *request;
+ int newfd;
+#if !defined(__GLIBC__)
+ int len;
+#else /* __GLIBC__ */
+ size_t len; /* isn't that generally defined in C ??? -- nico */
+#endif /* __GLIBC__ */
+ struct sockaddr_un addr; /* reuse this each time */
+#ifndef SO_PEERCRED
+ struct stat statbuf;
+ time_t staletime;
+#endif
+ uid_t uid;
+
+ /*....................................... Accept */
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+
+ len = sizeof(addr);
+ if ((newfd = accept(fd, (struct sockaddr *)&addr, &len)) < 0) {
+ gpm_report(GPM_PR_ERR, GPM_MESS_ACCEPT_FAILED, strerror(errno));
+ return NULL;
+ }
+
+ gpm_report(GPM_PR_INFO, GPM_MESS_CONECT_AT, newfd);
+
+ if (!(info = malloc(sizeof(struct client_info))))
+ gpm_report(GPM_PR_OOPS, GPM_MESS_NO_MEM);
+
+ request = &info->data;
+ if (get_data(newfd, request) == -1)
+ goto err;
+
+ if (request->vc > MAX_VC) {
+ gpm_report(GPM_PR_WARN,GPM_MESS_REQUEST_ON, request->vc, MAX_VC);
+ goto err;
+ }
+
+#ifndef SO_PEERCRED
+ if (stat(addr.sun_path, &statbuf) == -1 || !S_ISSOCK(statbuf.st_mode)) {
+ gpm_report(GPM_PR_ERR,GPM_MESS_ADDRES_NSOCKET,addr.sun_path);
+ goto err;
+ }
+
+ unlink(addr.sun_path); /* delete socket */
+
+ staletime = time(0) - 30;
+ if (statbuf.st_atime < staletime ||
+ statbuf.st_ctime < staletime ||
+ statbuf.st_mtime < staletime) {
+ gpm_report(GPM_PR_ERR, GPM_MESS_SOCKET_OLD);
+ goto err;
+ }
+
+ uid = statbuf.st_uid; /* owner of socket */
+#else
+ {
+ struct ucred sucred;
+ socklen_t credlen = sizeof(struct ucred);
+
+ if (getsockopt(newfd, SOL_SOCKET, SO_PEERCRED, &sucred, &credlen) == -1) {
+ gpm_report(GPM_PR_ERR,GPM_MESS_GETSOCKOPT, strerror(errno));
+ goto err;
+ }
+ uid = sucred.uid;
+ gpm_report(GPM_PR_DEBUG,GPM_MESS_PEER_SCK_UID, uid);
+ }
+#endif
+
+ if (uid != 0 && !is_console_owner(request->vc, uid)) {
+ gpm_report(GPM_PR_WARN, GPM_MESS_FAILED_CONNECT, uid, request->vc);
+ goto err;
+ }
+
+ /* register the connection information in the right place */
+ info->next = cinfo[request->vc];
+ info->fd = newfd;
+ cinfo[request->vc] = info;
+ gpm_report(GPM_PR_DEBUG, GPM_MESS_LONG_STATUS,
+ request->pid, request->vc, request->eventMask, request->defaultMask,
+ request->minMod, request->maxMod);
+
+ return info;
+
+err:
+ free(info);
+ close(newfd);
+
+ return NULL;
+}
+
+/*-------------------------------------------------------------------*/
+void remove_client(struct client_info *ci, int vc)
+{
+ struct client_info *p, *prev = NULL;
+
+ for (p = cinfo[vc]; p; prev = p, p = p->next) {
+ if (p == ci) {
+ if (!prev) /* it is on top of the stack */
+ cinfo[vc] = p->next;
+ else
+ prev->next = p->next;
+ break;
+ }
+ }
+ if (p) free(p);
+}
+
+/*-------------------------------------------------------------------*/
+void notify_clients_resize(void)
+{
+ struct client_info *ci;
+ int i;
+
+ for (i = 0; i < MAX_VC + 1; i++)
+ for (ci = cinfo[i]; ci; ci = ci->next)
+ kill(ci->data.pid, SIGWINCH);
+}
+
+/*-------------------------------------------------------------------*/
+/* returns 0 if the event has not been processed, and 1 if it has */
+int do_client(struct client_info *cinfo, Gpm_Event *event)
+{
+ Gpm_Connect *info = &cinfo->data;
+ /* value to return if event is not used */
+ int res = !(info->defaultMask & event->type);
+
+ /* instead of returning 0, scan the stack of clients */
+ if ((info->minMod & event->modifiers) < info->minMod)
+ goto try_next;
+ if ((info->maxMod & event->modifiers) < event->modifiers)
+ goto try_next;
+
+ /* if not managed, use default mask */
+ if (!(info->eventMask & GPM_BARE_EVENTS(event->type))) {
+ if (res) return res;
+ else goto try_next;
+ }
+
+ /* WARNING */ /* This can generate a SIGPIPE... I'd better catch it */
+ MAGIC_P((write(cinfo->fd, &magic, sizeof(int))));
+ write(cinfo->fd, event, sizeof(Gpm_Event));
+
+ return info->defaultMask & GPM_HARD ? res : 1; /* HARD forces pass-on */
+
+ try_next:
+ if (cinfo->next != 0)
+ return do_client(cinfo->next, event); /* try the next */
+
+ return 0; /* no next, not used */
+}
+
+/*-------------------------------------------------------------------*/
+/* returns 0 if client disconnects, -1 - error, 1 -successs */
+int process_client_request(struct client_info *ci, int vc,
+ int x, int y, int buttons, int clicks,
+ int three_button_mouse)
+{
+ int rc;
+ Gpm_Connect conn;
+ static Gpm_Event event;
+
+ gpm_report(GPM_PR_INFO, GPM_MESS_CON_REQUEST, ci->fd, vc);
+ if (vc > MAX_VC) return -1;
+
+ /* itz 10-22-96 this shouldn't happen now */
+ if (vc == -1) gpm_report(GPM_PR_OOPS, GPM_MESS_UNKNOWN_FD);
+
+ rc = get_data(ci->fd, &conn);
+
+ if (rc == 0) { /* no data */
+ gpm_report(GPM_PR_INFO, GPM_MESS_CLOSE);
+ close(ci->fd);
+ return 0;
+ }
+
+ if (rc == -1) return -1; /* too few bytes */
+
+ if (conn.pid != 0) {
+ ci->data = conn;
+ return 1;
+ }
+
+ /* Aha, request for information (so-called snapshot) */
+ switch (conn.vc) {
+ case GPM_REQ_SNAPSHOT:
+ event.vc = get_console_state(&event.modifiers);
+ event.x = x; event.y = y;
+ event.buttons = buttons;
+ event.clicks = clicks;
+ event.dx = console.max_x; event.dy = console.max_y;
+ /* fall through */
+
+ case GPM_REQ_BUTTONS:
+ event.type = (three_button_mouse == 1 ? 3 : 2); /* buttons */
+ write(ci->fd, &event, sizeof(Gpm_Event));
+ break;
+
+ case GPM_REQ_NOPASTE:
+ selection_disable_paste();
+ gpm_report(GPM_PR_INFO, GPM_MESS_DISABLE_PASTE, vc);
+ break;
+ }
+
+ return 1;
+}
+
diff -Nru a/src/gpm.c b/src/gpm.c
--- a/src/gpm.c 2004-08-10 01:17:58 -05:00
+++ b/src/gpm.c 2004-08-10 01:17:58 -05:00
@@ -30,25 +30,20 @@
#include <time.h> /* time() */
#include <sys/fcntl.h> /* O_RDONLY */
#include <sys/wait.h> /* wait() */
-#include <sys/stat.h> /* mkdir() */
#include <sys/time.h> /* timeval */
-#include <sys/types.h> /* socket() */
-#include <sys/socket.h> /* socket() */
-#include <sys/un.h> /* struct sockaddr_un */
#include "headers/gpmInt.h"
#include "headers/message.h"
#include "headers/console.h"
-
-/* who the f*** runs gpm without glibc? doesn't have dietlibc __socklent_t? */
-#if !defined(__GLIBC__)
- typedef unsigned int __socklen_t;
-#endif /* __GLIBC__ */
+#include "headers/client.h"
#ifndef max
#define max(a,b) ((a)>(b) ? (a) : (b))
#endif
+#define NULL_SET ((fd_set *)NULL)
+#define resetTimeout() (timeout.tv_sec=SELECT_TIME,timeout.tv_usec=0)
+
extern int errno;
static void gpm_killed(int);
@@ -83,9 +78,14 @@
struct repeater repeater;
int eventFlag=0;
-Gpm_Cinfo *cinfo[MAX_VC+1];
fd_set selSet, readySet, connSet;
+static struct {
+ int x, y;
+ int buttons;
+ int clicks;
+} state;
+
/* BRAINDEAD..ok not really, but got to leave anyway... FIXME */
/* argc and argv for mice initialization */
static int mouse_argc[3]; /* 0 for default (unused) and two mice */
@@ -130,39 +130,6 @@
return argv;
}
-/*-------------------------------------------------------------------*/
-/* returns 0 if the event has not been processed, and 1 if it has */
-static inline int do_client(Gpm_Cinfo *cinfo, Gpm_Event *event)
-{
- Gpm_Connect info=cinfo->data;
- int fd=cinfo->fd;
- /* value to return if event is not used */
- int res = !(info.defaultMask & event->type);
-
- /* instead of returning 0, scan the stack of clients */
- if ((info.minMod & event->modifiers) < info.minMod)
- goto scan;
- if ((info.maxMod & event->modifiers) < event->modifiers)
- goto scan;
-
- /* if not managed, use default mask */
- if (!(info.eventMask & GPM_BARE_EVENTS(event->type))) {
- if (res) return res;
- else goto scan;
- }
-
- /* WARNING */ /* This can generate a SIGPIPE... I'd better catch it */
- MAGIC_P((write(fd,&magic, sizeof(int))));
- write(fd,event, sizeof(Gpm_Event));
-
- return info.defaultMask & GPM_HARD ? res : 1; /* HARD forces pass-on */
-
- scan:
- if (cinfo->next != 0)
- return do_client (cinfo->next, event); /* try the next */
- return 0; /* no next, not used */
-}
-
/*-------------------------------------------------------------------
* fetch the actual device data from the mouse device, dependent on
* what Gpm_Type is being passed.
@@ -223,10 +190,6 @@
return data;
}
-
-static int statusX,statusY,statusB; /* to return info */
-static int statusC=0; /* clicks */
-
/*-------------------------------------------------------------------*/
void handle_console_resize(Gpm_Event *ePtr)
{
@@ -237,11 +200,11 @@
old_x = console.max_x; old_y = console.max_y;
refresh_console_size();
if (!old_x) { /* first invocation, place the pointer in the middle */
- statusX = ePtr->x = console.max_x / 2;
- statusY = ePtr->y = console.max_y / 2;
+ state.x = ePtr->x = console.max_x / 2;
+ state.y = ePtr->y = console.max_y / 2;
} else { /* keep the pointer in the same position where it was */
- statusX = ePtr->x = ePtr->x * console.max_x / old_x;
- statusY = ePtr->y = ePtr->y * console.max_y / old_y;
+ state.x = ePtr->x = ePtr->x * console.max_x / old_x;
+ state.y = ePtr->y = ePtr->y * console.max_y / old_y;
}
for (i=1; i <= 1+opt_double; i++) {
@@ -402,7 +365,7 @@
/*....................................... fill missing fields */
event->x += event->dx, event->y += event->dy;
- statusB=event->buttons;
+ state.buttons = event->buttons;
event->vc = get_console_state(&shift_state);
if (event->vc != last_active) {
@@ -419,31 +382,32 @@
switch(event->type) { /* now provide the cooked bits */
case GPM_DOWN:
GET_TIME(tv2);
- if (tv1.tv_sec && (DIF_TIME(tv1,tv2)<opt_time)) /* check first click */
- statusC++, statusC%=3; /* 0, 1 or 2 */
+ if (tv1.tv_sec && (DIF_TIME(tv1, tv2) < opt_time)) /* check first click */
+ state.clicks++, state.clicks %= 3; /* 0, 1 or 2 */
else
- statusC=0;
- event->type|=(GPM_SINGLE<<statusC);
+ state.clicks = 0;
+ event->type |= GPM_SINGLE << state.clicks;
break;
case GPM_UP:
GET_TIME(tv1);
- event->buttons^=oldB; /* for button-up, tell which one */
- event->type|= (oldT&GPM_MFLAG);
- event->type|=(GPM_SINGLE<<statusC);
+ event->buttons ^= oldB; /* for button-up, tell which one */
+ event->type |= oldT & GPM_MFLAG;
+ event->type |= GPM_SINGLE << state.clicks;
break;
case GPM_DRAG:
event->type |= GPM_MFLAG;
- event->type|=(GPM_SINGLE<<statusC);
+ event->type |= GPM_SINGLE << state.clicks;
break;
case GPM_MOVE:
- statusC=0;
+ state.clicks = 0;
+
default:
break;
}
- event->clicks=statusC;
+ event->clicks = state.clicks;
/* UGLY - FIXME! */
/* The current policy is to force the following behaviour:
@@ -489,7 +453,7 @@
event->clicks);
/* update the global state */
- statusX=event->x; statusY=event->y;
+ state.x = event->x; state.y = event->y;
if (opt_special && event->type & GPM_DOWN)
return processSpecial(event);
@@ -497,213 +461,6 @@
return 1;
}
-/*-------------------------------------------------------------------*
- * This was inline, and incurred in a compiler bug (2.7.0)
- *-------------------------------------------------------------------*/
-static int get_data(Gpm_Connect *where, int whence)
-{
- static int i;
-
-#ifdef GPM_USE_MAGIC
- while ((i=read(whence,&check,sizeof(int)))==4 && check!=GPM_MAGIC)
- gpm_report(GPM_PR_INFO,GPM_MESS_NO_MAGIC);
-
- if (!i) return 0;
- if (check!=GPM_MAGIC) {
- gpm_report(GPM_PR_INFO,GPM_MESS_NOTHING_MORE);
- return -1;
- }
-#endif
-
- if ((i=read(whence, where, sizeof(Gpm_Connect)))!=sizeof(Gpm_Connect)) {
- return i ? -1 : 0;
- }
-
- return 1;
-}
-
-/*-------------------------------------------------------------------*/
- /* returns -1 if closing connection */
-static inline int processRequest(Gpm_Cinfo *ci, int vc)
-{
- int i;
- Gpm_Cinfo *cinfoPtr, *next;
- Gpm_Connect conn;
- static Gpm_Event event;
-
- gpm_report(GPM_PR_INFO,GPM_MESS_CON_REQUEST, ci->fd, vc);
- if (vc>MAX_VC) return -1;
-
- /* itz 10-22-96 this shouldn't happen now */
- if (vc==-1) gpm_report(GPM_PR_OOPS,GPM_MESS_UNKNOWN_FD);
-
- i=get_data(&conn,ci->fd);
-
- if (!i) { /* no data */
- gpm_report(GPM_PR_INFO,GPM_MESS_CLOSE);
- close(ci->fd);
- FD_CLR(ci->fd,&connSet);
- FD_CLR(ci->fd,&readySet);
- if (cinfo[vc]->fd == ci->fd) { /* it was on top of the stack */
- cinfoPtr = cinfo[vc];
- cinfo[vc]=cinfo[vc]->next; /* pop the stack */
- free(cinfoPtr);
- return -1;
- }
- /* somewhere inside the stack, have to walk it */
- cinfoPtr = cinfo[vc];
- while (cinfoPtr && cinfoPtr->next) {
- if (cinfoPtr->next->fd == ci->fd) {
- next = cinfoPtr->next;
- cinfoPtr->next = next->next;
- free (next);
- break;
- }
- cinfoPtr = cinfoPtr->next;
- }
- return -1;
- } /* not data */
-
- if (i == -1) return -1; /* too few bytes */
-
- if (conn.pid!=0) {
- ci->data = conn;
- return 0;
- }
-
- /* Aha, request for information (so-called snapshot) */
- switch(conn.vc) {
- case GPM_REQ_SNAPSHOT:
- event.vc = get_console_state(&event.modifiers);
- event.x=statusX; event.y=statusY;
- event.dx = console.max_x; event.dy = console.max_y;
- event.buttons= statusB;
- event.clicks=statusC;
- /* fall through */
- /* missing break or do you want this ??? */
-
- case GPM_REQ_BUTTONS:
- event.type= (opt_three==1 ? 3 : 2); /* buttons */
- write(ci->fd,&event,sizeof(Gpm_Event));
- break;
-
- case GPM_REQ_NOPASTE:
- selection_disable_paste();
- gpm_report(GPM_PR_INFO, GPM_MESS_DISABLE_PASTE, vc);
- break;
- }
-
- return 0;
-}
-
-/*-------------------------------------------------------------------*/
-static inline int processConn(int fd) /* returns newfd or -1 */
-{
- Gpm_Cinfo *info;
- Gpm_Connect *request;
- int vc, newfd;
-#if !defined(__GLIBC__)
- int len;
-#else /* __GLIBC__ */
- size_t len; /* isn't that generally defined in C ??? -- nico */
-#endif /* __GLIBC__ */
- struct sockaddr_un addr; /* reuse this each time */
-#ifndef SO_PEERCRED
- struct stat statbuf;
- time_t staletime;
-#endif
- uid_t uid;
-
-/*....................................... Accept */
-
- bzero((char *)&addr,sizeof(addr));
- addr.sun_family=AF_UNIX;
-
- len=sizeof(addr);
- if ((newfd=accept(fd,(struct sockaddr *)&addr, &len))<0) {
- gpm_report(GPM_PR_ERR,GPM_MESS_ACCEPT_FAILED,strerror(errno));
- return -1;
- }
-
- gpm_report(GPM_PR_INFO,GPM_MESS_CONECT_AT,newfd);
-
- info=malloc(sizeof(Gpm_Cinfo));
- if (!info) gpm_report(GPM_PR_OOPS,GPM_MESS_NO_MEM);
- request=&(info->data);
-
- if(get_data(request,newfd)==-1) {
- free(info);
- close(newfd);
- return -1;
- }
-
- if ((vc=request->vc)>MAX_VC) {
- gpm_report(GPM_PR_WARN,GPM_MESS_REQUEST_ON, vc, MAX_VC);
- free(info);
- close(newfd);
- return -1;
- }
-
-#ifndef SO_PEERCRED
- if (stat (addr.sun_path, &statbuf) == -1 || !S_ISSOCK(statbuf.st_mode)) {
- gpm_report(GPM_PR_ERR,GPM_MESS_ADDRES_NSOCKET,addr.sun_path);
- free(info); /* itz 10-12-95 verify client's right */
- close(newfd);
- return -1; /* to read requested tty */
- }
-
- unlink(addr.sun_path); /* delete socket */
-
- staletime = time(0) - 30;
- if (statbuf.st_atime < staletime
- || statbuf.st_ctime < staletime
- || statbuf.st_mtime < staletime) {
- gpm_report(GPM_PR_ERR,GPM_MESS_SOCKET_OLD);
- free (info);
- close(newfd);
- return -1; /* socket is ancient */
- }
-
- uid = statbuf.st_uid; /* owner of socket */
-#else
- {
- struct ucred sucred;
- socklen_t credlen = sizeof(struct ucred);
-
- if(getsockopt(newfd, SOL_SOCKET, SO_PEERCRED, &sucred, &credlen) == -1) {
- gpm_report(GPM_PR_ERR,GPM_MESS_GETSOCKOPT, strerror(errno));
- free(info);
- close(newfd);
- return -1;
- }
- uid = sucred.uid;
- gpm_report(GPM_PR_DEBUG,GPM_MESS_PEER_SCK_UID, uid);
- }
-#endif
- if (uid != 0 && !is_console_owner(vc, uid)) {
- gpm_report(GPM_PR_WARN, GPM_MESS_FAILED_CONNECT, uid, vc); /*SUSPECT!*/
- free(info);
- close(newfd);
- return -1;
- }
-
- /* register the connection information in the right place */
- info->next=cinfo[vc];
- info->fd=newfd;
- cinfo[vc]=info;
- gpm_report(GPM_PR_DEBUG,GPM_MESS_LONG_STATUS,
- request->pid, request->vc, request->eventMask, request->defaultMask,
- request->minMod, request->maxMod);
-
- /* if the client gets motions, give it the current position */
- if(request->eventMask & GPM_MOVE) {
- Gpm_Event event={0,0,vc,0,0,statusX,statusY,GPM_MOVE,0,0};
- do_client(info, &event);
- }
-
- return newfd;
-}
-
/*-------------------------------------------------------------------*/
static void gpm_killed(int signo)
{
@@ -720,13 +477,13 @@
/*-------------------------------------------------------------------*/
int old_main()
{
- int ctlfd, newfd;
- struct sockaddr_un ctladdr;
- int i, len, text_mode, fd;
+ int ctlfd;
+ int i, text_mode, fd;
struct timeval timeout;
- int maxfd=-1;
+ int maxfd = -1;
int pending;
Gpm_Event event;
+ struct client_info *ci;
for (i = 1; i <= 1+opt_double; i++) {
which_mouse=mouse_table+i; /* used to access options */
@@ -759,43 +516,21 @@
signal(SIGINT, gpm_killed);
signal(SIGUSR1, gpm_killed); /* usr1 is used by a new gpm killing the old */
signal(SIGWINCH,gpm_killed); /* winch can be sent if console is resized */
-
-/*....................................... create your nodes */
-
- /* control node */
-
- if((ctlfd=socket(AF_UNIX,SOCK_STREAM,0))==-1) gpm_report(GPM_PR_OOPS,GPM_MESS_SOCKET_PROB);
- bzero((char *)&ctladdr,sizeof(ctladdr));
- ctladdr.sun_family=AF_UNIX;
- strcpy(ctladdr.sun_path,GPM_NODE_CTL);
- unlink(GPM_NODE_CTL);
-
- len=sizeof(ctladdr.sun_family)+strlen(GPM_NODE_CTL);
- if(bind(ctlfd,(struct sockaddr *)(&ctladdr),len) == -1)
- gpm_report(GPM_PR_OOPS,GPM_MESS_BIND_PROB,ctladdr.sun_path);
- maxfd=max(maxfd,ctlfd);
-
- /* needs to be 0777, so all users can _try_ to access gpm */
- chmod(GPM_NODE_CTL,0777);
+ signal(SIGPIPE, SIG_IGN); /* WARN */
handle_console_resize(&event); /* get screen dimensions */
-/*....................................... wait for mouse and connections */
-
- listen(ctlfd, 5); /* Queue up calls */
-
-#define NULL_SET ((fd_set *)NULL)
-#define resetTimeout() (timeout.tv_sec=SELECT_TIME,timeout.tv_usec=0)
+ ctlfd = listen_for_clients();
+ /*....................................... wait for mouse and connections */
FD_ZERO(&connSet);
- FD_SET(ctlfd,&connSet);
-
- if (opt_double) FD_SET(mouse_table[2].fd,&connSet);
+ FD_SET(ctlfd, &connSet);
+ maxfd = max(maxfd, ctlfd);
- readySet=connSet;
- FD_SET(mouse_table[1].fd,&readySet);
+ if (opt_double) FD_SET(mouse_table[2].fd, &connSet);
- signal(SIGPIPE,SIG_IGN); /* WARN */
+ readySet = connSet;
+ FD_SET(mouse_table[1].fd, &readySet);
/*--------------------------------------- main loop begins here */
@@ -815,16 +550,11 @@
resetTimeout();
} /* go on */
- if(opt_resize) { /* did the console resize? */
+ if (opt_resize) { /* did the console resize? */
handle_console_resize(&event);
opt_resize--;
- signal(SIGWINCH,gpm_killed); /* reinstall handler */
-
- /* and notify clients */
- for(i=0; i<MAX_VC+1; i++) {
- Gpm_Cinfo *ci;
- for (ci = cinfo[i]; ci; ci = ci->next) kill(ci->data.pid,SIGWINCH);
- }
+ signal(SIGWINCH, gpm_killed); /* reinstall handler */
+ notify_clients_resize();
}
if (pending < 0) {
@@ -882,53 +612,49 @@
}
/*..................... got connection, process it */
-
- if (pending && FD_ISSET(ctlfd,&selSet)) {
- FD_CLR(ctlfd,&selSet); pending--;
- newfd=processConn(ctlfd);
- if (newfd>=0) {
- FD_SET(newfd,&connSet);
- FD_SET(newfd,&readySet);
- maxfd=max(maxfd,newfd);
+ if (pending && FD_ISSET(ctlfd, &selSet)) {
+ FD_CLR(ctlfd, &selSet);
+ pending--;
+ if ((ci = accept_client_connection(ctlfd))) {
+ if (ci->data.eventMask & GPM_MOVE) {
+ Gpm_Event event = { 0, 0, ci->data.vc, 0, 0,
+ state.x, state.y, GPM_MOVE, 0, 0 };
+ do_client(ci, &event);
+ }
+ FD_SET(ci->fd, &connSet);
+ FD_SET(ci->fd, &readySet);
+ maxfd = max(maxfd, ci->fd);
}
}
/*........................ got request */
-
- /* itz 10-22-96 check _all_ clients, not just those on top! */
- for (i=0; pending && (i<=MAX_VC); i++) {
- Gpm_Cinfo* ci;
+ /* itz 10-22-96 check _all_ clients, not just those on top! */
+ for (i = 0; pending && i <= MAX_VC; i++) {
for (ci = cinfo[i]; pending && ci; ci = ci->next) {
- if (FD_ISSET(ci->fd,&selSet)) {
- FD_CLR(ci->fd,&selSet); pending--;
- /* itz Sat Sep 12 21:10:22 PDT 1998 */
- /* this code is clearly incorrect; the next highest
- descriptor after the one we're closing is not necessarily
- being used. Fortunately, it doesn't hurt simply to leave this
- out. */
-
-#ifdef NOTDEF
- if ((processRequest(ci,i)==-1) && maxfd==ci->fd) maxfd--;
-#else
- (void)processRequest(ci,i);
-#endif
+ if (FD_ISSET(ci->fd, &selSet)) {
+ FD_CLR(ci->fd, &selSet);
+ pending--;
+ if (!process_client_request(ci, i, state.x, state.y, state.clicks,
+ state.buttons, opt_three)) {
+ FD_CLR(ci->fd, &connSet);
+ FD_CLR(ci->fd, &readySet);
+ remove_client(ci, i);
+ }
}
}
}
/*.................. look for a spare fd */
-
/* itz 10-22-96 this shouldn't happen now! */
- for (i=0; pending && i<=maxfd; i++) {
- if (FD_ISSET(i,&selSet)) {
- FD_CLR(i,&selSet);
+ for (i = 0; pending && i <= maxfd; i++) {
+ if (FD_ISSET(i, &selSet)) {
+ FD_CLR(i, &selSet);
pending--;
- gpm_report(GPM_PR_WARN,GPM_MESS_STRANGE_DATA,i);
+ gpm_report(GPM_PR_WARN, GPM_MESS_STRANGE_DATA,i);
}
}
/*................... all done. */
-
- if(pending) gpm_report(GPM_PR_OOPS,GPM_MESS_SELECT_PROB);
+ if (pending) gpm_report(GPM_PR_OOPS, GPM_MESS_SELECT_PROB);
} /* while(1) */
}
diff -Nru a/src/headers/client.h b/src/headers/client.h
--- /dev/null Wed Dec 31 16:00:00 196900
+++ b/src/headers/client.h 2004-08-10 01:17:58 -05:00
@@ -0,0 +1,57 @@
+/*
+ * client.h - GPM client handling (server side)
+ *
+ * Copyright (C) 2003 Dmitry Torokhov <dtor@mail.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ ********/
+
+#ifndef __GPM_CLIENT_H
+#define __GPM_CLIENT_H_
+
+#ifdef HAVE_LINUX_TTY_H
+#include <linux/tty.h>
+#endif
+
+#include "headers/gpm.h"
+
+/* FIXME: still needed ?? */
+/* How many virtual consoles are managed? */
+#ifndef MAX_NR_CONSOLES
+# define MAX_NR_CONSOLES 64 /* this is always sure */
+#endif
+
+#define MAX_VC MAX_NR_CONSOLES /* doesn't work before 1.3.77 */
+
+struct client_info {
+ Gpm_Connect data;
+ int fd;
+ struct client_info *next;
+};
+
+struct Gpm_Event;
+
+extern struct client_info *cinfo[MAX_VC + 1];
+
+int listen_for_clients(void);
+struct client_info *accept_client_connection(int fd);
+void remove_client(struct client_info *ci, int vc);
+void notify_clients_resize(void);
+int do_client(struct client_info *cinfo, struct Gpm_Event *event);
+int process_client_request(struct client_info *ci, int vc,
+ int x, int y, int buttons, int clicks,
+ int three_button_mouse);
+
+#endif /* __GPM_CLIENT_H_ */
diff -Nru a/src/headers/gpmInt.h b/src/headers/gpmInt.h
--- a/src/headers/gpmInt.h 2004-08-10 01:17:58 -05:00
+++ b/src/headers/gpmInt.h 2004-08-10 01:17:58 -05:00
@@ -35,18 +35,6 @@
/* timeout for the select() syscall */
#define SELECT_TIME 86400 /* one day */
-#ifdef HAVE_LINUX_TTY_H
-#include <linux/tty.h>
-#endif
-
-/* FIXME: still needed ?? */
-/* How many virtual consoles are managed? */
-#ifndef MAX_NR_CONSOLES
-# define MAX_NR_CONSOLES 64 /* this is always sure */
-#endif
-
-#define MAX_VC MAX_NR_CONSOLES /* doesn't work before 1.3.77 */
-
/* How many buttons may the mouse have? */
/* #define MAX_BUTTONS 3 ===> not used, it is hardwired :-( */
@@ -143,13 +131,6 @@
#define GPM_EXTRA_MAGIC_1 0xAA
#define GPM_EXTRA_MAGIC_2 0x55
-typedef struct Gpm_Cinfo {
- Gpm_Connect data;
- int fd;
- struct Gpm_Cinfo *next;
-} Gpm_Cinfo;
-
-
/*....................................... Global variables */
/* this structure is used to hide the dual-mouse stuff */
@@ -192,7 +173,6 @@
extern int opt_double;
extern Gpm_Type mice[]; /* where the hell are the descriptions...*/
-extern Gpm_Cinfo *cinfo[MAX_VC+1];
/* new variables <CLEAN> */
@@ -240,7 +220,6 @@
/* gpn.c */
void cmdline(int argc, char **argv);
int giveInfo(int request, int fd);
-int loadlut(char *charset);
int usage(char *whofailed);
struct Gpm_Type *find_mouse_by_name(char *name);
void check_uniqueness(void);
More information about the gpm
mailing list