=================================================================== ChangeSet@xxx, 2004-08-10 00:52:46-05:00, dtor_core@xxxxxxxxxxxxx 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@xxxxxxxxxxxxx> + * Copyright (C) 1994-1999 Alessandro Rubini <rubini@xxxxxxxx> + * Copyright (C) 1998 Ian Zimmerman <itz@xxxxxxxxx> + * Copyright (c) 2001,2002 Nico Schottelius <nico-gpm@xxxxxxxxxxxxxxx> + * Copyright (C) 2003 Dmitry Torokhov <dtor@xxxxxxx> + * + * 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@xxxxxxx> + * + * 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); _______________________________________________ gpm mailing list gpm@xxxxxxxxxxxxxx http://lists.linux.it/listinfo/gpm