int client_handle_request(struct clients *cls, int fd) { int n, t; int toread; struct buffer *buffer = cls->clients[fd].msg; char *str; if (ioctl(fd, FIONREAD, &toread)) { debugprintf("%s: FIONREAD\n", errno); return -1; } if (buffer->used + toread >= MAX_MSG_SIZE) { debugprintf("client sent %d bytes, too much data!\n", buffer->used + toread); client_remove(cls, fd); close(fd); return -1; } buffer_grow(buffer, toread); n = recv(fd, buffer->buf + buffer->used, MAX_MSG_SIZE - buffer->used, 0); buffer->used += n; if (n <= 0) { if (n < 0) perror("recv"); client_remove(cls, fd); close(fd); return; } if (buffer->buf[buffer->used - 1] != '\n') return 0; buffer->buf[buffer->used] = '\0'; str = malloc(MAX_MSG_SIZE); if (!str) perror("malloc"); t = snprintf(str, MAX_MSG_SIZE, "%i: %s", fd, buffer->buf); spam_everyone(cls, fd, str, t); buffer->used = 0; free(str); }
static void event_unmapnotify(XEvent *e) { XUnmapEvent *ev = &e->xunmap; struct client *c; struct _systray *s; if((c = client_gb_win(ev->window)) && ev->send_event && ev->event == W->root) { int d; unsigned char *ret = NULL; if(XGetWindowProperty(EVDPY(e), c->win, W->net_atom[wm_state], 0, 2, False, W->net_atom[wm_state], (Atom*)&d, &d, (long unsigned int*)&d, (long unsigned int*)&d, &ret) == Success) if(*ret == NormalState) client_remove(c); } else if((s = systray_find(ev->window))) { systray_del(s); systray_update(); } }
static void client_cb(struct aeEventLoop *eventLoop, int fd, void *clientData, int mask) { struct node *client = (struct node *)clientData; /* read */ char buffer[512]; int len = read(fd, buffer, 512); if (len <= 0) { fprintf(stderr, "Client closed: %d.", fd); aeDeleteFileEvent(eventLoop, fd, mask); client_remove(client); return; } /* push to total and split */ int count = 0; client->buffer = sdscatlen(client->buffer, buffer, len); sds *lines = sdssplitlen(client->buffer, sdslen(client->buffer), "\n", 1, &count); /* translate */ int i; for (i = 0; i < count; i++) { translate(lines[i], client); sdsfree(lines[i]); } free(lines); sdsclear(client->buffer); }
/* close all clients and then close server */ void close_server(int fd) { struct node *it = client_list->next; while (it) { struct node *next = it->next; client_remove(it); it = next; } }
static void event_destroynotify(XEvent *e) { XDestroyWindowEvent *ev = &e->xdestroywindow; struct client *c; struct _systray *s; if((c = client_gb_win(ev->window))) client_remove(c); else if((s = systray_find(ev->window))) { ewmh_set_wm_state(s->win, WithdrawnState); systray_del(s); systray_update(); } }
static void client_exited_disable_cb(const struct ofono_error *error, void *data) { struct ofono_location_reporting *lr = data; if (error->type != OFONO_ERROR_TYPE_NO_ERROR) { ofono_error("Disabling location-reporting failed"); return; } client_remove(lr); lr->enabled = FALSE; signal_enabled(lr); }
static void location_reporting_disable_cb(const struct ofono_error *error, void *data) { struct ofono_location_reporting *lr = data; DBusMessage *reply; if (error->type != OFONO_ERROR_TYPE_NO_ERROR) { ofono_error("Disabling location-reporting failed"); reply = __ofono_error_failed(lr->pending); __ofono_dbus_pending_reply(&lr->pending, reply); return; } client_remove(lr); lr->enabled = FALSE; reply = dbus_message_new_method_return(lr->pending); __ofono_dbus_pending_reply(&lr->pending, reply); signal_enabled(lr); }
int main_loop( CamConfig *ccfg, Socket *picture_sock, char *picture_mem ){ Socket *listen_socket; SockSet *readset = NULL, *writeset = NULL; list_t *client_sockets; lnode_t *node; int cfg_listen_port, highest_fd, picture_client_ready; int num_sclients, num_clients; ClientInfo *clientinfo, *clientinfo2; if( (client_sockets = list_create( -1 )) == NULL) return -1; cfg_listen_port = camconfig_query_def_int( ccfg, SEC_SOCKET, "listen_port", CAMCONFIG_DEF_LISTEN_PORT ); if( (readset = sockset_new()) == NULL || (writeset = sockset_new()) == NULL ) { camserv_log( MODNAME, "Error allocating memory for socksets!"); if( readset ) sockset_dest( readset ); if( writeset ) sockset_dest( writeset ); list_destroy( client_sockets ); return -1; } if((listen_socket = socket_serve_tcp( NULL, cfg_listen_port, 100 )) == NULL ) { camserv_log( MODNAME, "Error setting up socket on port \"%d\". Exiting", cfg_listen_port ); list_destroy( client_sockets ); sockset_dest( readset ); sockset_dest( writeset ); return -1; } highest_fd = MAX( socket_query_fd( listen_socket ), socket_query_fd( picture_sock )); clientinfo = clientinfo_new( listen_socket ); clientinfo2 = clientinfo_new( picture_sock ); if( !clientinfo || !clientinfo2 || sockset_add_fd( readset, listen_socket, clientinfo ) == -1 || sockset_add_fd( readset, picture_sock, clientinfo2 ) == -1 ) { camserv_log( MODNAME, "Error adding initial sockets to sockset!"); sockset_dest( readset ); sockset_dest( writeset ); if( clientinfo ) clientinfo_dest( clientinfo ); if( clientinfo2 ) clientinfo_dest( clientinfo2 ); list_destroy( client_sockets ); return -1; } num_clients = 0; num_sclients = 0; picture_client_ready = 1; setup_signals(); Abort = 0; while( !Abort ){ int sel_res, i, nset_socks; void **set_socks; /* Only need to execute this if we have a streaming client */ if( (num_sclients > 0) && picture_client_ready == 1 ){ send( socket_query_fd( picture_sock ), "0", sizeof( "0" ), 0 ); picture_client_ready = 0; } sockset_reset( readset ); sockset_reset( writeset ); sel_res = sockset_select( highest_fd + 1, readset, writeset, NULL ); /* Service the event */ if( sel_res == -1 ){ camserv_log( MODNAME, "select() failure: %s", strerror( errno )); break; } else if( sel_res == 0 ){ camserv_log( MODNAME, "Unexpected select() fall through!" ); continue; } /* Readable sockets */ set_socks = sockset_query_socks( readset ); nset_socks = sockset_query_nsocks( readset ); for( i=0; i< nset_socks; i++ ){ ClientInfo *new_cinfo; clientinfo = set_socks[ i ]; if( clientinfo->socket == listen_socket ) { /* New client */ if( (new_cinfo = accept_client( listen_socket )) == NULL ) continue; if( (node = lnode_create( new_cinfo )) == NULL ){ clientinfo_dest( new_cinfo ); continue; } if( sockset_add_fd( readset, new_cinfo->socket, new_cinfo ) == -1 ){ camserv_log( MODNAME, "Failed to add socket %d to socket read set!", socket_query_fd( new_cinfo->socket )); clientinfo_dest( new_cinfo ); lnode_destroy( node ); continue; } if( socket_query_fd( new_cinfo->socket ) > highest_fd ) highest_fd = socket_query_fd( new_cinfo->socket ); list_append( client_sockets, node ); num_clients++; /* Init resource limit for this client */ new_cinfo->create_time = time( NULL ); new_cinfo->bytes = 0; new_cinfo->frames = 0; new_cinfo->max_seconds = camconfig_query_def_int( ccfg, SEC_SOCKET, "max_seconds", 0 ); new_cinfo->max_bytes = camconfig_query_def_int( ccfg, SEC_SOCKET, "max_bytes", 0 ); new_cinfo->max_frames = camconfig_query_def_int( ccfg, SEC_SOCKET, "max_frames", 0 ); /* Send fresh request for a picture */ send( socket_query_fd( picture_sock ), "0", sizeof( "0" ), 0 ); picture_client_ready = 0; /* Put this read socket on hold until the picture comes back */ sockset_hold( readset, new_cinfo->socket ); } else { char cmdbuf[ 1024 ]; int readlen; clientinfo = set_socks[ i ]; /* Regular joe client, set readable */ if( (readlen = read( socket_query_fd( clientinfo->socket), cmdbuf, sizeof( cmdbuf ) - 1)) <= 0 ) { camserv_log( MODNAME, "Closing socket: %s", socket_query_remote_name( clientinfo->socket )); if (clientinfo->client_type == CLIENT_T_BROWSER || clientinfo->client_type == CLIENT_T_PROXY) { num_sclients--; } client_remove( client_sockets, clientinfo ); sockset_del_fd( readset, clientinfo->socket ); sockset_unhold_all( writeset ); sockset_del_fd( writeset, clientinfo->socket ); clientinfo_dest( clientinfo ); num_clients--; } else { if( clientinfo->socket == picture_sock ) { if( dispatch_pictaker( cmdbuf, picture_mem ) == -1 ) camserv_log( MODNAME, "Pictaker dispatch failure!"); sockset_unhold_all( writeset ); /* Release the read hold as the picture has now been taken */ sockset_unhold_all( readset ); picture_client_ready = 1; } else { /* Information from a regular client */ cmdbuf[ readlen ] = '\0'; if( clientinfo->client_type == CLIENT_T_UNINIT ) { char *preamble; int pre_size; /* Figure out what type of client we have */ if( !strncmp( cmdbuf, "GET", 3 )) { if( strstr( cmdbuf, "/singleframe" )) { clientinfo->client_type = CLIENT_T_SINGLE; } else { clientinfo->client_type = CLIENT_T_BROWSER; num_sclients++; } } else if( !strncmp( cmdbuf, "PROXY", 5 )) { clientinfo->client_type = CLIENT_T_PROXY; /* Here we are in the same state as being done writing a pic */ clientinfo->state = CINFO_STATE_PICTURE; num_sclients++; databuf_buf_set( clientinfo->writebuf, NULL, 0 ); } else clientinfo->client_type = CLIENT_T_BROWSER; if( clientinfo->client_type != CLIENT_T_PROXY ) { /* Send the initial preamble. Only now we can decide which type of preamble to send (single vs. multi-part) */ if( clientinfo->client_type == CLIENT_T_SINGLE ) preamble = get_single_preamble_text( &pre_size ); else preamble = get_multi_preamble_text( &pre_size ); databuf_buf_set( clientinfo->writebuf, preamble, pre_size ); } if( sockset_add_fd( writeset, clientinfo->socket, clientinfo ) == -1 ) { camserv_log( MODNAME, "Failed to add socket %d to write set!", socket_query_fd( clientinfo->socket )); } } } } } } if( set_socks != NULL ) free( set_socks ); /* Writable sockets */ set_socks = sockset_query_socks( writeset ); nset_socks = sockset_query_nsocks( writeset ); for( i=0; i< nset_socks; i++ ){ ClientInfo *cinfo; cinfo = set_socks[ i ]; if( cinfo->client_type == CLIENT_T_BROWSER || cinfo->client_type == CLIENT_T_SINGLE ) { int result; if( (result = write_regular_client( cinfo, writeset )) != 0 ){ /* result: 1=close requested, -1=error detected */ if( result == -1 ) camserv_log( MODNAME, "Databuf write error on socket: %s\n", socket_query_remote_name( cinfo->socket )); if (cinfo->client_type == CLIENT_T_BROWSER) { num_sclients--; } client_remove( client_sockets, cinfo ); sockset_del_fd( readset, cinfo->socket ); sockset_del_fd( writeset, cinfo->socket ); clientinfo_dest( cinfo ); num_clients--; } } else { if( write_proxy_client( cinfo, writeset ) == -1 ){ camserv_log( MODNAME, "Databuf write error on socket: %d", socket_query_fd( cinfo->socket )); /* Should be proxy, but better check */ if (cinfo->client_type == CLIENT_T_PROXY) { num_sclients--; } client_remove( client_sockets, cinfo ); sockset_del_fd( readset, cinfo->socket ); sockset_del_fd( writeset, cinfo->socket ); clientinfo_dest( cinfo ); num_clients--; } } } if( set_socks != NULL ) free( set_socks ); } camserv_log( MODNAME, "Aborting."); sockset_dest( readset ); sockset_dest( writeset ); for( node = list_first( client_sockets) ; node; node=list_next( client_sockets, node )) { clientinfo_dest( node->data ); } /* Tell the picture taker to get out! Get out! */ camserv_log( MODNAME, "Closing picture taker"); send( socket_query_fd( picture_sock ), "9", sizeof( "9" ), 0 ); sleep( 3 ); camserv_log( MODNAME, "done\n"); list_destroy_nodes( client_sockets ); list_destroy( client_sockets ); socket_dest( listen_socket ); return 0; }
void handle_event(XEvent *ev) { client *c = owner(ev->xany.window); #ifdef DEBUG_EVENTS if(ev->type != Expose && ev->type != MotionNotify && !(ev->type == ConfigureNotify && ev->xconfigure.window != root)) /* this makes the output slightly more manageable */ printf(NAME ": handle_event(): got %s\n\twindow: 0x%X (%s)\n", event_name(ev), (unsigned int) ev->xany.window, c ? c->name : ((ev->xany.window == root) ? "root" : "unknown")); #endif if((evh && evh(ev)) || button_handle_event(ev) || ewmh_handle_event(ev) || screens_handle_event(ev)) { #ifdef DEBUG_EVENTS if(ev->type != Expose && ev->type != MotionNotify && (ev->type != ConfigureNotify && ev->xconfigure.window != root)) printf(NAME ": handle_event(): external event handler claimed last event\n"); #endif return; } if(c) { if(!has_child(c->parent, c->window) && ev->type != DestroyNotify && ev->type != UnmapNotify) return; switch(ev->type) { case UnmapNotify: if(c->window == ev->xunmap.window) { #ifdef DEBUG_EVENTS printf(NAME ": handle_event(): handling UnmapNotify event\n\twindow: 0x%X (%s)\n", (unsigned int) c->window, c->name); #endif if(has_child(c->parent, c->window)) { client_deparent(c); set_wm_state(c->window, WithdrawnState); } client_remove(c); ewmh_update_clist(); } return; case PropertyNotify: if(ev->xproperty.atom == XA_WM_NAME) { #ifdef DEBUG_EVENTS printf(NAME ": handle_event(): handling PropertyNotify event\n\twindow: 0x%X (%s)\n\tproperty: XA_WM_NAME\n", (unsigned int) c->window, c->name); #endif if(c->name != no_title) XFree(c->name); #ifdef USE_XFT if(xftfont) XftDrawDestroy(c->title_draw); #endif XFreePixmap(dpy, c->title_pixmap); XFetchName(dpy, c->window, &c->name); client_update_name(c); XClearWindow(dpy, c->title); if(evh == wlist_handle_event) { XClearWindow(dpy, c->wlist_item); wlist_item_draw(c); } } if(ev->xproperty.atom == XA_WM_NORMAL_HINTS) { #ifdef DEBUG_EVENTS printf(NAME ": handle_event(): handling PropertyNotify event\n\twindow: 0x%X (%s)\n\tproperty: XA_WM_NORMAL_HINTS\n", (unsigned int) c->window, c->name); #endif get_normal_hints(c); } return; case ClientMessage: if(ev->xclient.message_type == xa_wm_change_state && ev->xclient.data.l[0] == IconicState) { #ifdef DEBUG_EVENTS printf(NAME ": handling ClientMessage event\n\twindow: 0x%X (%s)\n", (unsigned int) c->window, c->name); #endif client_iconify(c); return; } break; /* we might later need this event */ case EnterNotify: if(c != current && !(c->flags & CLICK_FOCUS) && !click_focus && ev->xcrossing.mode != NotifyGrab && ev->xcrossing.mode != NotifyUngrab && ev->xcrossing.detail != NotifyInferior && (ev->xcrossing.window == c->parent || ev->xcrossing.window == c->wlist_item) && ev->xcrossing.send_event == False) { #ifdef DEBUG_EVENTS printf(NAME ": handle_event(): handling EnterNotify event\n\twindow: 0x%X (%s)\n", (unsigned int) c->window, c->name); #endif client_focus(c, true); } return; case Expose: if(ev->xexpose.count == 0 && evh == wlist_handle_event && c && ev->xexpose.window == c->wlist_item) wlist_item_draw(c); return; case ButtonPress: #ifdef DEBUG_EVENTS printf(NAME ": handle_event(): handling ButtonPress event\n\twindow: 0x%X (%s)\n", (unsigned int) c->window, c->name); #endif if(c != current) client_focus(c, true); XAllowEvents(dpy, ReplayPointer, CurrentTime); if(ev->xbutton.window != c->window) { if(lastclick + doubleclick_time > ev->xbutton.time && lastbutton == ev->xbutton.button && lastclick_client == c) { client_action(c, buttonaction(ev->xbutton.button, true), ev); lastclick = 0; lastclick_client = NULL; lastbutton = None; return; } lastclick = ev->xbutton.time; lastclick_client = c; lastbutton = ev->xbutton.button; client_action(c, buttonaction(ev->xbutton.button, false), ev); } else if(click_raise) client_raise(c); return; case FocusIn: /* we ignore pointer events, these happen if the input focus is on the root window */ if(allow_focus_stealing && c != current && ev->xfocus.mode != NotifyGrab && ev->xfocus.mode != NotifyUngrab && ev->xfocus.detail != NotifyPointer) { #ifdef DEBUG_EVENTS printf(NAME ": handle_event(): handling FocusIn event\n\twindow: 0x%X (%s)\n", (unsigned int) c->window, c->name); #endif client_focus(c, false); } return; case FocusOut: if(c == current && ev->xfocus.mode != NotifyGrab && ev->xfocus.mode != NotifyUngrab && ev->xfocus.detail != NotifyInferior) { #ifdef DEBUG_EVENTS printf(NAME ": handle_event(): handling FocusOut event\n\twindow: 0x%X (%s)\n", (unsigned int) c->window, c->name); #endif if(allow_focus_stealing && ev->xfocus.detail != NotifyAncestor) { #ifdef DEBUG_EVENTS printf("\tfocus lost\n"); #endif client_focus(NULL, false); /* we do this so windows that aren't managed can take focus */ } else { #ifdef DEBUG_EVENTS printf("\tre-focussing this window\n"); #endif take_focus(c); } } return; #ifdef USE_SHAPE default: if(ev->type == shape_event) { #ifdef DEBUG_EVENTS printf(NAME ": handle_event(): handling ShapeNotify event\n\twindow 0x%X (%s)\n", (unsigned int) c->window, c->name); #endif set_shape(c); return; } #endif } } switch(ev->type) { case MapRequest: c = owner(ev->xmaprequest.window); #ifdef DEBUG_EVENTS printf(NAME ": handle_event(): handling MapRequest event\n\twindow: 0x%X (%s)\n", (unsigned int) ev->xmaprequest.window, c ? c->name : "unknown"); #endif if(c) { if(c->flags & ICONIC && has_child(c->parent, c->window)) { client_restore(c); if(focus_new) client_focus(c, true); } } else if(has_child(root, ev->xmaprequest.window)) client_add(ev->xmaprequest.window, false); return; case DestroyNotify: c = owner(ev->xdestroywindow.window); if(c) if(c->window == ev->xdestroywindow.window) { #ifdef DEBUG_EVENTS printf(NAME ": handle_event(): handling DestroyNotify event\n\twindow 0x%X (%s)\n", (unsigned int) c->window, c->name); #endif client_remove(c); } return; case ConfigureRequest: c = owner(ev->xconfigurerequest.window); #ifdef DEBUG_EVENTS printf(NAME ": handle_event(): handling ConfigureRequest event\n\twindow 0x%X (%s)\n", (unsigned int) ev->xconfigurerequest.window, c ? c->name : "unknown"); #endif if(correct_center) screens_correct_center(&ev->xconfigurerequest.x, &ev->xconfigurerequest.y, &ev->xconfigurerequest.width, &ev->xconfigurerequest.height); if(c) { if(!has_child(c->parent, c->window)) return; if(ev->xconfigurerequest.value_mask & CWX) c->x = ev->xconfigurerequest.x - gxo(c, false); if(ev->xconfigurerequest.value_mask & CWY) c->y = ev->xconfigurerequest.y - gyo(c, false); if(ev->xconfigurerequest.value_mask & CWWidth) c->width = ev->xconfigurerequest.width; if(ev->xconfigurerequest.value_mask & CWHeight) c->height = ev->xconfigurerequest.height; client_update(c); #ifdef DEBUG printf(NAME ": handle_event(): reconfigured client 0x%X (%s) to %ix%i+%i+%i\n", (unsigned int) c->window, c->name, c->width, c->height, c->x, c->y); #endif } else if(has_child(root, ev->xconfigurerequest.window)) { XWindowChanges wc; wc.sibling = ev->xconfigurerequest.above; wc.stack_mode = ev->xconfigurerequest.detail; wc.x = ev->xconfigurerequest.x; wc.y = ev->xconfigurerequest.y; wc.width = ev->xconfigurerequest.width; wc.height = ev->xconfigurerequest.height; XConfigureWindow(dpy, ev->xconfigurerequest.window, ev->xconfigurerequest.value_mask, &wc); } return; case MapNotify: if(correct_center_unmanaged && ev->xany.window == root && !owner(ev->xmap.window)) { #ifdef DEBUG_EVENTS printf(NAME ": handle_event(): handling MapNotify event\n\twindow 0x%X (unknown)\n", (unsigned int) ev->xmap.window); #endif window_correct_center(ev->xmap.window); } return; case MappingNotify: if(ev->xmapping.request != MappingPointer) { #ifdef DEBUG_EVENTS printf(NAME ": handle_event(): handling MappingNotify event\n"); #endif keys_ungrab(); XRefreshKeyboardMapping(&ev->xmapping); keys_update(); } return; case KeyPress: #ifdef DEBUG_EVENTS printf(NAME ": handle_event(): handling KeyPress event\n"); #endif client_action(current, keyaction(ev), ev); return; case ButtonPress: if(ev->xbutton.window != root) return; #ifdef DEBUG_EVENTS printf(NAME ": handle_event(): handling ButtonPress event\n"); #endif if(lastclick + doubleclick_time > ev->xbutton.time && lastbutton == ev->xbutton.button && lastclick_client == NULL) { client_action(current, root_buttonaction(ev->xbutton.button, true), ev); lastclick = 0; lastclick_client = NULL; lastbutton = None; return; } lastclick = ev->xbutton.time; lastclick_client = NULL; lastbutton = ev->xbutton.button; client_action(current, root_buttonaction(ev->xbutton.button, false), ev); return; case ClientMessage: if(ev->xclient.message_type == xa_internal_message) { if(((Atom) ev->xclient.data.l[0]) == xa_quit) { #ifdef DEBUG printf(NAME ": handle_event(): quit message received\n"); #endif exit(0); } if(((Atom) ev->xclient.data.l[0]) == xa_reinit) { #ifdef DEBUG printf(NAME ": handle_event(): reinitialize message received\n"); #endif cfg_reinitialize(); } } } }