//TODO ADD OPTIMISATIONS DURING KEY MATCHING int json_parse(json_parser *parser, const char *input_buff, size_t buff_sz){ int i; //The parser looks at one char at a time. //the character is only advanced by this for loop. for (; parser->buff_offset < buff_sz && input_buff[parser->buff_offset] != '\0'; parser->buff_offset++) { char c; int res; c = input_buff[parser->buff_offset]; switch (parser->state){ case JSON_STATE_BEGIN_VAL_OR_KEY: res = handle_begin_val_or_key(parser, c); break; case JSON_STATE_INT_ELEM: res = handle_int_elem(parser, c); break; case JSON_STATE_TRUE_ELEM: case JSON_STATE_FALSE_ELEM: case JSON_STATE_NULL_ELEM: res = handle_special_elem(parser, c); break; case JSON_STATE_KEY_OR_STR: case JSON_STATE_KEY_OR_STR_ESCAPE: res = handle_key_or_str(parser, c); break; case JSON_STATE_KEY_OR_STR_END: res = handle_key_or_str_end(parser, c); break; case JSON_STATE_TYPE: res = handle_type(parser, c); break; case JSON_STATE_INT: res = handle_int(parser, c); break; case JSON_STATE_TRUE: case JSON_STATE_FALSE: case JSON_STATE_NULL: res = handle_special(parser, c); break; case JSON_STATE_STR: case JSON_STATE_STR_ESCAPE: res = handle_str(parser, c); break; case JSON_STATE_END_VAL: res = handle_end_val(parser, c); break; case JSON_STATE_START: res = handle_start(parser, c); break; //parsing stop if we are done or if there was an error if (res <= 0) return res; } } //ran out of buffer, parser is either done or needs more input if (parser->level == 0) return JSON_DONE; return JSON_CONTINUE; }
void lexA(){ f.open(file, ifstream::in); skip_blanks(); char peek = f.peek(); if( is_number(peek) ){ get_number(peek); }else if( is_char(peek) ){ check_keyword(peek); }else if( is_special(peek) ){ handle_special(peek); }else{ get_identifier(); } }
void network_thread () { /* * We loop forever waiting on either data from the ppp drivers or from * our network socket. Control handling is no longer done here. */ struct sockaddr_in from; struct in_pktinfo to; unsigned int fromlen; int tunnel, call; /* Tunnel and call */ int recvsize; /* Length of data received */ struct buffer *buf; /* Payload buffer */ struct call *c, *sc; /* Call to send this off to */ struct tunnel *st; /* Tunnel */ fd_set readfds; /* Descriptors to watch for reading */ int max; /* Highest fd */ struct timeval tv, *ptv; /* Timeout for select */ struct msghdr msgh; struct iovec iov; char cbuf[256]; unsigned int refme, refhim; int * currentfd; int server_socket_processed; #ifdef HIGH_PRIO /* set high priority */ if (setpriority(PRIO_PROCESS, 0, -20) < 0) l2tp_log (LOG_INFO, "xl2tpd: can't set priority to high: %m"); #endif /* This one buffer can be recycled for everything except control packets */ buf = new_buf (MAX_RECV_SIZE); tunnel = 0; call = 0; for (;;) { int ret; process_signal(); max = build_fdset (&readfds); ptv = process_schedule(&tv); ret = select (max + 1, &readfds, NULL, NULL, ptv); if (ret <= 0) { #ifdef DEBUG_MORE if (ret == 0) { if (gconfig.debug_network) { l2tp_log (LOG_DEBUG, "%s: select timeout\n", __FUNCTION__); } } else { if (gconfig.debug_network) { l2tp_log (LOG_DEBUG, "%s: select returned error %d (%s)\n", __FUNCTION__, errno, strerror (errno)); } } #endif continue; } if (FD_ISSET (control_fd, &readfds)) { do_control (); } server_socket_processed = 0; currentfd = NULL; st = tunnels.head; while (st || !server_socket_processed) { if (st && (st->udp_fd == -1)) { st=st->next; continue; } if (st) { currentfd = &st->udp_fd; } else { currentfd = &server_socket; server_socket_processed = 1; } if (FD_ISSET (*currentfd, &readfds)) { /* * Okay, now we're ready for reading and processing new data. */ recycle_buf (buf); /* Reserve space for expanding payload packet headers */ buf->start += PAYLOAD_BUF; buf->len -= PAYLOAD_BUF; memset(&from, 0, sizeof(from)); memset(&to, 0, sizeof(to)); fromlen = sizeof(from); memset(&msgh, 0, sizeof(struct msghdr)); iov.iov_base = buf->start; iov.iov_len = buf->len; msgh.msg_control = cbuf; msgh.msg_controllen = sizeof(cbuf); msgh.msg_name = &from; msgh.msg_namelen = fromlen; msgh.msg_iov = &iov; msgh.msg_iovlen = 1; msgh.msg_flags = 0; /* Receive one packet. */ recvsize = recvmsg(*currentfd, &msgh, 0); if (recvsize < MIN_PAYLOAD_HDR_LEN) { if (recvsize < 0) { if (errno == ECONNREFUSED) { close(*currentfd); } if ((errno == ECONNREFUSED) || (errno == EBADF)) { *currentfd = -1; } if (errno != EAGAIN) l2tp_log (LOG_WARNING, "%s: recvfrom returned error %d (%s)\n", __FUNCTION__, errno, strerror (errno)); } else { l2tp_log (LOG_WARNING, "%s: received too small a packet\n", __FUNCTION__); } if (st) st=st->next; continue; } refme=refhim=0; struct cmsghdr *cmsg; /* Process auxiliary received data in msgh */ for (cmsg = CMSG_FIRSTHDR(&msgh); cmsg != NULL; cmsg = CMSG_NXTHDR(&msgh,cmsg)) { /* extract destination(our) addr */ if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) { struct in_pktinfo* pktInfo = ((struct in_pktinfo*)CMSG_DATA(cmsg)); to = *pktInfo; } /* extract IPsec info out */ else if (gconfig.ipsecsaref && cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == gconfig.sarefnum) { unsigned int *refp; refp = (unsigned int *)CMSG_DATA(cmsg); refme =refp[0]; refhim=refp[1]; } } /* * some logic could be added here to verify that we only * get L2TP packets inside of IPsec, or to provide different * classes of service to packets not inside of IPsec. */ buf->len = recvsize; fix_hdr (buf->start); extract (buf->start, &tunnel, &call); if (gconfig.debug_network) { l2tp_log(LOG_DEBUG, "%s: recv packet from %s, size = %d, " "tunnel = %d, call = %d ref=%u refhim=%u\n", __FUNCTION__, inet_ntoa (from.sin_addr), recvsize, tunnel, call, refme, refhim); } if (gconfig.packet_dump) { do_packet_dump (buf); } if (!(c = get_call (tunnel, call, from.sin_addr, from.sin_port, refme, refhim))) { if ((c = get_tunnel (tunnel, from.sin_addr.s_addr, from.sin_port))) { /* * It is theoretically possible that we could be sent * a control message (say a StopCCN) on a call that we * have already closed or some such nonsense. To * prevent this from closing the tunnel, if we get a * call on a valid tunnel, but not with a valid CID, * we'll just send a ZLB to ack receiving the packet. */ if (gconfig.debug_tunnel) l2tp_log (LOG_DEBUG, "%s: no such call %d on tunnel %d. Sending special ZLB\n", __FUNCTION__, call, tunnel); if (handle_special (buf, c, call) == 0) /* get a new buffer */ buf = new_buf (MAX_RECV_SIZE); } #ifdef DEBUG_MORE else{ l2tp_log (LOG_DEBUG, "%s: unable to find call or tunnel to handle packet. call = %d, tunnel = %d Dumping.\n", __FUNCTION__, call, tunnel); } #endif } else { if (c->container) { c->container->my_addr = to; } buf->peer = from; /* Handle the packet */ c->container->chal_us.vector = NULL; if (handle_packet (buf, c->container, c)) { if (gconfig.debug_tunnel) l2tp_log (LOG_DEBUG, "%s: bad packet\n", __FUNCTION__); } if (c->cnu) { /* Send Zero Byte Packet */ control_zlb (buf, c->container, c); c->cnu = 0; } } } if (st) st=st->next; } /* * finished obvious sources, look for data from PPP connections. */ st = tunnels.head; while (st) { sc = st->call_head; while (sc) { if ((sc->fd >= 0) && FD_ISSET (sc->fd, &readfds)) { /* Got some payload to send */ int result; while ((result = read_packet (sc)) > 0) { add_payload_hdr (sc->container, sc, sc->ppp_buf); if (gconfig.packet_dump) { do_packet_dump (sc->ppp_buf); } sc->prx = sc->data_rec_seq_num; if (sc->zlb_xmit) { deschedule (sc->zlb_xmit); sc->zlb_xmit = NULL; } sc->tx_bytes += sc->ppp_buf->len; sc->tx_pkts++; udp_xmit (sc->ppp_buf, st); recycle_payload (sc->ppp_buf, sc->container->peer); } if (result != 0) { l2tp_log (LOG_WARNING, "%s: tossing read packet, error = %s (%d). Closing call.\n", __FUNCTION__, strerror (-result), -result); strcpy (sc->errormsg, strerror (-result)); sc->needclose = -1; } } sc = sc->next; } st = st->next; } } }
/* build_target_list() * * inputs - pointer to given source (oper/client etc.) * - pointer to list of nicks/channels * - pointer to table to place results * - pointer to text (only used if source_p is an oper) * output - number of valid entities * side effects - target_table is modified to contain a list of * pointers to channels or clients * if source client is an oper * all the classic old bizzare oper privmsg tricks * are parsed and sent as is, if prefixed with $ * to disambiguate. * */ static int build_target_list(int p_or_n, const char *command, struct Client *source_p, char *nicks_channels, const char *text) { int type = 0; char *p = NULL, *nick = NULL; char *target_list = NULL; struct Channel *chptr = NULL; struct Client *target_p = NULL; target_list = nicks_channels; ntargets = 0; for (nick = strtoken(&p, target_list, ","); nick; nick = strtoken(&p, NULL, ",")) { const char *with_prefix = NULL; /* * Channels are privmsg'd a lot more than other clients, moved up * here plain old channel msg? */ if (IsChanPrefix(*nick)) { if ((chptr = hash_find_channel(nick))) { if (!duplicate_ptr(chptr)) { if (ntargets >= ConfigGeneral.max_targets) { sendto_one_numeric(source_p, &me, ERR_TOOMANYTARGETS, nick, ConfigGeneral.max_targets); return 1; } targets[ntargets].ptr = chptr; targets[ntargets++].type = ENTITY_CHANNEL; } } else { if (p_or_n != NOTICE) sendto_one_numeric(source_p, &me, ERR_NOSUCHNICK, nick); } continue; } /* Look for a PRIVMSG/NOTICE to another client */ if ((target_p = find_person(source_p, nick))) { if (!duplicate_ptr(target_p)) { if (ntargets >= ConfigGeneral.max_targets) { sendto_one_numeric(source_p, &me, ERR_TOOMANYTARGETS, nick, ConfigGeneral.max_targets); return 1; } targets[ntargets].ptr = target_p; targets[ntargets].type = ENTITY_CLIENT; targets[ntargets++].flags = 0; } continue; } /* @#channel or +#channel message ? */ type = 0; with_prefix = nick; /* Allow %+@ if someone wants to do that */ while (1) { if (*nick == '@') type |= CHFL_CHANOP; else if (*nick == '%') type |= CHFL_CHANOP | CHFL_HALFOP; else if (*nick == '+') type |= CHFL_CHANOP | CHFL_HALFOP | CHFL_VOICE; else break; ++nick; } if (type) { if (EmptyString(nick)) /* If it's a '\0' dump it, there is no recipient */ { sendto_one_numeric(source_p, &me, ERR_NORECIPIENT, command); continue; } /* * At this point, nick+1 should be a channel name i.e. #foo or &foo * if the channel is found, fine, if not report an error */ if ((chptr = hash_find_channel(nick))) { if (IsClient(source_p) && !HasFlag(source_p, FLAGS_SERVICE)) { if (!has_member_flags(find_channel_link(source_p, chptr), CHFL_CHANOP|CHFL_HALFOP|CHFL_VOICE)) { sendto_one_numeric(source_p, &me, ERR_CHANOPRIVSNEEDED, with_prefix); return -1; } } if (!duplicate_ptr(chptr)) { if (ntargets >= ConfigGeneral.max_targets) { sendto_one_numeric(source_p, &me, ERR_TOOMANYTARGETS, nick, ConfigGeneral.max_targets); return 1; } targets[ntargets].ptr = chptr; targets[ntargets].type = ENTITY_CHANOPS_ON_CHANNEL; targets[ntargets++].flags = type; } } else { if (p_or_n != NOTICE) sendto_one_numeric(source_p, &me, ERR_NOSUCHNICK, nick); } continue; } if (*nick == '$' || strchr(nick, '@')) handle_special(p_or_n, command, source_p, nick, text); else { if (p_or_n != NOTICE) { if (!IsDigit(*nick) || MyClient(source_p)) sendto_one_numeric(source_p, &me, ERR_NOSUCHNICK, nick); } } } return 1; }
int main(int argc, char **argv) { struct ir_command command; struct ir_command timeoutCommand; int c; int led_brightness = 1; while ((c = getopt (argc, argv, "mBi:b:s:H:hd")) != -1) switch (c) { case 'm': multi_mode = 1; break; case 'i': idle_mode = atol(optarg); break; case 'b': button_mode = atol(optarg); break; case 's': special_mode = atol(optarg); break; case 'H': hold_mode = atol(optarg); break; case 'd': debug = 1; break; case 'h': usage(argc,argv); exit(0); break; case 'B': led_brightness = 0; break; case '?': switch(optopt) { case 'i': case 'b': case 's': case 'H': fprintf (stderr, "Option -%c requires an argument.\n", optopt); break; default: if (isprint (optopt)) fprintf (stderr, "Unknown option `-%c'.\n", optopt); else fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt); } return 1; default: abort(); } set_led_brightness(led_brightness); memset(&timeoutCommand, 0, sizeof(timeoutCommand)); if(debug) printf("Creating socket...\n"); sockfd = socket(AF_INET, SOCK_DGRAM, 0); if (sockfd < 0) { printf("Error creating socket\n"); return -1; } if(debug) printf("Preparing button map...\n"); button_map[EVENT_UP] = new CPacketBUTTON(EVENT_UP, "JS0:AppleRemote", BTN_DOWN); button_map[EVENT_DOWN] = new CPacketBUTTON(EVENT_DOWN, "JS0:AppleRemote", BTN_DOWN); button_map[EVENT_LEFT] = new CPacketBUTTON(EVENT_LEFT, "JS0:AppleRemote", BTN_DOWN); button_map[EVENT_RIGHT] = new CPacketBUTTON(EVENT_RIGHT, "JS0:AppleRemote", BTN_DOWN); button_map[EVENT_PLAY] = new CPacketBUTTON(EVENT_PLAY, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); button_map[EVENT_MENU] = new CPacketBUTTON(EVENT_MENU, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); button_map[EVENT_HOLD_PLAY] = new CPacketBUTTON(EVENT_HOLD_PLAY, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); button_map[EVENT_HOLD_MENU] = new CPacketBUTTON(EVENT_HOLD_MENU, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); button_map[EVENT_UP | EVENT_RELEASE ] = new CPacketBUTTON(EVENT_UP, "JS0:AppleRemote", BTN_UP); button_map[EVENT_DOWN | EVENT_RELEASE ] = new CPacketBUTTON(EVENT_DOWN, "JS0:AppleRemote", BTN_UP); button_map[EVENT_LEFT | EVENT_RELEASE ] = new CPacketBUTTON(EVENT_LEFT, "JS0:AppleRemote", BTN_UP); button_map[EVENT_RIGHT | EVENT_RELEASE ] = new CPacketBUTTON(EVENT_RIGHT, "JS0:AppleRemote", BTN_UP); button_map[EVENT_EXTRA_PLAY] = new CPacketBUTTON(EVENT_EXTRA_PLAY, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); button_map[EVENT_EXTRA_PAUSE] = new CPacketBUTTON(EVENT_EXTRA_PAUSE, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); button_map[EVENT_EXTRA_STOP] = new CPacketBUTTON(EVENT_EXTRA_STOP, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); button_map[EVENT_EXTRA_REPLAY] = new CPacketBUTTON(EVENT_EXTRA_REPLAY, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); button_map[EVENT_EXTRA_SKIP] = new CPacketBUTTON(EVENT_EXTRA_SKIP, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); button_map[EVENT_EXTRA_REWIND] = new CPacketBUTTON(EVENT_EXTRA_REWIND, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); button_map[EVENT_EXTRA_FORWARD] = new CPacketBUTTON(EVENT_EXTRA_FORWARD, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); button_map[EVENT_EXTRA_PAGEUP] = new CPacketBUTTON(EVENT_EXTRA_PAGEUP, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); button_map[EVENT_EXTRA_PAGEDOWN] = new CPacketBUTTON(EVENT_EXTRA_PAGEDOWN, "JS0:AppleRemote", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_UP] = new CPacketBUTTON(EVENT_HARMONY_UP, "JS0:Harmony", BTN_DOWN); multi_map[EVENT_HARMONY_UP | EVENT_RELEASE] = new CPacketBUTTON(EVENT_HARMONY_UP, "JS0:Harmony", BTN_UP); multi_map[EVENT_HARMONY_DOWN] = new CPacketBUTTON(EVENT_HARMONY_DOWN, "JS0:Harmony", BTN_DOWN); multi_map[EVENT_HARMONY_DOWN | EVENT_RELEASE] = new CPacketBUTTON(EVENT_HARMONY_DOWN, "JS0:Harmony", BTN_UP); multi_map[EVENT_HARMONY_LEFT] = new CPacketBUTTON(EVENT_HARMONY_LEFT, "JS0:Harmony", BTN_DOWN); multi_map[EVENT_HARMONY_LEFT | EVENT_RELEASE] = new CPacketBUTTON(EVENT_HARMONY_LEFT, "JS0:Harmony", BTN_UP); multi_map[EVENT_HARMONY_RIGHT] = new CPacketBUTTON(EVENT_HARMONY_RIGHT, "JS0:Harmony", BTN_DOWN); multi_map[EVENT_HARMONY_RIGHT | EVENT_RELEASE] = new CPacketBUTTON(EVENT_HARMONY_RIGHT, "JS0:Harmony", BTN_UP); multi_map[EVENT_HARMONY_OK] = new CPacketBUTTON(EVENT_HARMONY_OK, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_MENU] = new CPacketBUTTON(EVENT_HARMONY_MENU, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_HOLD_OK] = new CPacketBUTTON(EVENT_HARMONY_HOLD_OK, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_HOLD_MENU] = new CPacketBUTTON(EVENT_HARMONY_HOLD_MENU, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_PLAY] = new CPacketBUTTON(EVENT_HARMONY_PLAY, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_STOP] = new CPacketBUTTON(EVENT_HARMONY_STOP, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_PAUSE] = new CPacketBUTTON(EVENT_HARMONY_PAUSE, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_REPLAY] = new CPacketBUTTON(EVENT_HARMONY_REPLAY, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_SKIP] = new CPacketBUTTON(EVENT_HARMONY_SKIP, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_REWIND] = new CPacketBUTTON(EVENT_HARMONY_REWIND, "JS0:Harmony", BTN_DOWN); multi_map[EVENT_HARMONY_REWIND | EVENT_RELEASE] = new CPacketBUTTON(EVENT_HARMONY_REWIND, "JS0:Harmony", BTN_UP); multi_map[EVENT_HARMONY_FORWARD] = new CPacketBUTTON(EVENT_HARMONY_FORWARD, "JS0:Harmony", BTN_DOWN); multi_map[EVENT_HARMONY_FORWARD | EVENT_RELEASE] = new CPacketBUTTON(EVENT_HARMONY_FORWARD, "JS0:Harmony", BTN_UP); multi_map[EVENT_HARMONY_RECORD] = new CPacketBUTTON(EVENT_HARMONY_RECORD, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_PREV] = new CPacketBUTTON(EVENT_HARMONY_PREV, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_GUIDE] = new CPacketBUTTON(EVENT_HARMONY_GUIDE, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_INFO] = new CPacketBUTTON(EVENT_HARMONY_INFO, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_EXIT] = new CPacketBUTTON(EVENT_HARMONY_EXIT, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_VOLUP] = new CPacketBUTTON(EVENT_HARMONY_VOLUP, "JS0:Harmony", BTN_DOWN); multi_map[EVENT_HARMONY_VOLUP | EVENT_RELEASE] = new CPacketBUTTON(EVENT_HARMONY_VOLUP, "JS0:Harmony", BTN_UP); multi_map[EVENT_HARMONY_VOLDOWN] = new CPacketBUTTON(EVENT_HARMONY_VOLDOWN, "JS0:Harmony", BTN_DOWN); multi_map[EVENT_HARMONY_VOLDOWN | EVENT_RELEASE] = new CPacketBUTTON(EVENT_HARMONY_VOLDOWN, "JS0:Harmony", BTN_UP); multi_map[EVENT_HARMONY_1] = new CPacketBUTTON(EVENT_HARMONY_1, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_2] = new CPacketBUTTON(EVENT_HARMONY_2, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_3] = new CPacketBUTTON(EVENT_HARMONY_3, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_4] = new CPacketBUTTON(EVENT_HARMONY_4, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_5] = new CPacketBUTTON(EVENT_HARMONY_5, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_6] = new CPacketBUTTON(EVENT_HARMONY_6, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_7] = new CPacketBUTTON(EVENT_HARMONY_7, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_8] = new CPacketBUTTON(EVENT_HARMONY_8, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_9] = new CPacketBUTTON(EVENT_HARMONY_9, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_0] = new CPacketBUTTON(EVENT_HARMONY_0, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_CLEAR] = new CPacketBUTTON(EVENT_HARMONY_CLEAR, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_ENTER] = new CPacketBUTTON(EVENT_HARMONY_ENTER, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_MUTE] = new CPacketBUTTON(EVENT_HARMONY_MUTE, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_ASPECT] = new CPacketBUTTON(EVENT_HARMONY_ASPECT, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_F1] = new CPacketBUTTON(EVENT_HARMONY_F1, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_F2] = new CPacketBUTTON(EVENT_HARMONY_F2, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_F3] = new CPacketBUTTON(EVENT_HARMONY_F3, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_F4] = new CPacketBUTTON(EVENT_HARMONY_F4, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_F5] = new CPacketBUTTON(EVENT_HARMONY_F5, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_F6] = new CPacketBUTTON(EVENT_HARMONY_F6, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_F7] = new CPacketBUTTON(EVENT_HARMONY_F7, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_F8] = new CPacketBUTTON(EVENT_HARMONY_F8, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_F9] = new CPacketBUTTON(EVENT_HARMONY_F9, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_F10] = new CPacketBUTTON(EVENT_HARMONY_F10, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_F11] = new CPacketBUTTON(EVENT_HARMONY_F11, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_F12] = new CPacketBUTTON(EVENT_HARMONY_F12, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_F13] = new CPacketBUTTON(EVENT_HARMONY_F13, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_F14] = new CPacketBUTTON(EVENT_HARMONY_F14, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_CHANUP] = new CPacketBUTTON(EVENT_HARMONY_CHANUP, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_CHANDOWN] = new CPacketBUTTON(EVENT_HARMONY_CHANDOWN, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_LRGDOWN] = new CPacketBUTTON(EVENT_HARMONY_LRGDOWN, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_LRGUP] = new CPacketBUTTON(EVENT_HARMONY_LRGUP, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_PWRTOGGLE] = new CPacketBUTTON(EVENT_HARMONY_PWRTOGGLE, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_QUEUE] = new CPacketBUTTON(EVENT_HARMONY_QUEUE, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_SLEEP] = new CPacketBUTTON(EVENT_HARMONY_SLEEP, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_RED] = new CPacketBUTTON(EVENT_HARMONY_RED, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_GREEN] = new CPacketBUTTON(EVENT_HARMONY_GREEN, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_YELLOW] = new CPacketBUTTON(EVENT_HARMONY_YELLOW, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); multi_map[EVENT_HARMONY_BLUE] = new CPacketBUTTON(EVENT_HARMONY_BLUE, "JS0:Harmony", BTN_DOWN | BTN_NO_REPEAT | BTN_QUEUE); pairedRemoteId = readPairedAddressId(); if(debug) printf("Paired to: %x\n", pairedRemoteId); if(debug) printf("Ready!\n"); set_led(LEDMODE_WHITE); int keydown = 0; set_led(idle_mode); while(1){ int result = usb_interrupt_read(get_ir(), 0x82, (char*) &command, sizeof(command), keydown ? BUTTON_TIMEOUT : 0); if(result > 0) { // we have an IR code! unsigned long start = millis(); if(debug) dumphex((unsigned char*) &command, result); if(command.flags == 0x26) { // set command.event = 0xee; } switch(command.event) { case 0xee: case 0xe5: if(pairedRemoteId == 0 || command.address == pairedRemoteId || (is_multi_candidate(command))) { set_led(button_mode); handle_button(command); } break; case 0xe0: set_led(special_mode); handle_special(command); break; default: if(debug) printf("Unknown event %x\n", command.event); } keydown = 1; } else if(result == -110) { // timeout, reset led keydown = 0; set_led(idle_mode); handle_button(timeoutCommand); handle_special(timeoutCommand); } else { // something else keydown = 0; if(debug) printf("Got nuffing: %d\n", result); } } reattach(); }
void network_thread () { /* * We loop forever waiting on either data from the ppp drivers or from * our network socket. Control handling is no longer done here. */ struct sockaddr_in from, to; unsigned int fromlen, tolen; int tunnel, call; /* Tunnel and call */ int recvsize; /* Length of data received */ struct buffer *buf; /* Payload buffer */ struct call *c, *sc; /* Call to send this off to */ struct tunnel *st; /* Tunnel */ fd_set readfds; /* Descriptors to watch for reading */ int max; /* Highest fd */ struct timeval tv, *ptv; /* Timeout for select */ struct msghdr msgh; struct iovec iov; char cbuf[256]; unsigned int refme, refhim; /* This one buffer can be recycled for everything except control packets */ buf = new_buf (MAX_RECV_SIZE); tunnel = 0; call = 0; for (;;) { int ret; process_signal(); max = build_fdset (&readfds); ptv = process_schedule(&tv); ret = select (max + 1, &readfds, NULL, NULL, ptv); if (ret <= 0) { if (ret == 0) { if (gconfig.debug_network) { l2tp_log (LOG_DEBUG, "%s: select timeout\n", __FUNCTION__); } } else { if (gconfig.debug_network) { l2tp_log (LOG_DEBUG, "%s: select returned error %d (%s)\n", __FUNCTION__, errno, strerror (errno)); } } continue; } if (FD_ISSET (control_fd, &readfds)) { do_control (); } if (FD_ISSET (server_socket, &readfds)) { /* * Okay, now we're ready for reading and processing new data. */ recycle_buf (buf); /* Reserve space for expanding payload packet headers */ buf->start += PAYLOAD_BUF; buf->len -= PAYLOAD_BUF; memset(&from, 0, sizeof(from)); memset(&to, 0, sizeof(to)); fromlen = sizeof(from); tolen = sizeof(to); memset(&msgh, 0, sizeof(struct msghdr)); iov.iov_base = buf->start; iov.iov_len = buf->len; msgh.msg_control = cbuf; msgh.msg_controllen = sizeof(cbuf); msgh.msg_name = &from; msgh.msg_namelen = fromlen; msgh.msg_iov = &iov; msgh.msg_iovlen = 1; msgh.msg_flags = 0; /* Receive one packet. */ recvsize = recvmsg(server_socket, &msgh, 0); if (recvsize < MIN_PAYLOAD_HDR_LEN) { if (recvsize < 0) { if (errno != EAGAIN) l2tp_log (LOG_WARNING, "%s: recvfrom returned error %d (%s)\n", __FUNCTION__, errno, strerror (errno)); } else { l2tp_log (LOG_WARNING, "%s: received too small a packet\n", __FUNCTION__); } continue; } refme=refhim=0; /* extract IPsec info out */ if(gconfig.ipsecsaref) { struct cmsghdr *cmsg; /* Process auxiliary received data in msgh */ for (cmsg = CMSG_FIRSTHDR(&msgh); cmsg != NULL; cmsg = CMSG_NXTHDR(&msgh,cmsg)) { if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_IPSEC_REFINFO) { unsigned int *refp; refp = (unsigned int *)CMSG_DATA(cmsg); refme =refp[0]; refhim=refp[1]; } } } /* * some logic could be added here to verify that we only * get L2TP packets inside of IPsec, or to provide different * classes of service to packets not inside of IPsec. */ buf->len = recvsize; fix_hdr (buf->start); extract (buf->start, &tunnel, &call); if (gconfig.debug_network) { l2tp_log(LOG_DEBUG, "%s: recv packet from %s, size = %d, " "tunnel = %d, call = %d ref=%u refhim=%u\n", __FUNCTION__, inet_ntoa (from.sin_addr), recvsize, tunnel, call, refme, refhim); } if (gconfig.packet_dump) { do_packet_dump (buf); } if (! (c = get_call (tunnel, call, from.sin_addr.s_addr, from.sin_port, refme, refhim))) { if ((c = get_tunnel (tunnel, from.sin_addr.s_addr, from.sin_port))) { /* * It is theoretically possible that we could be sent * a control message (say a StopCCN) on a call that we * have already closed or some such nonsense. To * prevent this from closing the tunnel, if we get a * call on a valid tunnel, but not with a valid CID, * we'll just send a ZLB to ack receiving the packet. */ if (gconfig.debug_tunnel) l2tp_log (LOG_DEBUG, "%s: no such call %d on tunnel %d. Sending special ZLB\n", __FUNCTION__); handle_special (buf, c, call); /* get a new buffer */ buf = new_buf (MAX_RECV_SIZE); } else l2tp_log (LOG_DEBUG, "%s: unable to find call or tunnel to handle packet. call = %d, tunnel = %d Dumping.\n", __FUNCTION__, call, tunnel); } else { buf->peer = from; /* Handle the packet */ c->container->chal_us.vector = NULL; if (handle_packet (buf, c->container, c)) { if (gconfig.debug_tunnel) l2tp_log (LOG_DEBUG, "%s: bad packet\n", __FUNCTION__); }; if (c->cnu) { /* Send Zero Byte Packet */ control_zlb (buf, c->container, c); c->cnu = 0; } }; } /* * finished obvious sources, look for data from PPP connections. */ st = tunnels.head; while (st) { sc = st->call_head; while (sc) { if ((sc->fd >= 0) && FD_ISSET (sc->fd, &readfds)) { /* Got some payload to send */ int result; recycle_payload (buf, sc->container->peer); /* #ifdef DEBUG_FLOW_MORE l2tp_log (LOG_DEBUG, "%s: rws = %d, pSs = %d, pLr = %d\n", __FUNCTION__, sc->rws, sc->pSs, sc->pLr); #endif if ((sc->rws>0) && (sc->pSs > sc->pLr + sc->rws) && !sc->rbit) { #ifdef DEBUG_FLOW log(LOG_DEBUG, "%s: throttling payload (call = %d, tunnel = %d, Lr = %d, Ss = %d, rws = %d)!\n",__FUNCTION__, sc->cid, sc->container->tid, sc->pLr, sc->pSs, sc->rws); #endif sc->throttle = -1; We unthrottle in handle_packet if we get a payload packet, valid or ZLB, but we also schedule a dethrottle in which case the R-bit will be set FIXME: Rate Adaptive timeout? tv.tv_sec = 2; tv.tv_usec = 0; sc->dethrottle = schedule(tv, dethrottle, sc); } else */ /* while ((result=read_packet(buf,sc->fd,sc->frame & SYNC_FRAMING))>0) { */ while ((result = read_packet (buf, sc->fd, SYNC_FRAMING)) > 0) { add_payload_hdr (sc->container, sc, buf); if (gconfig.packet_dump) { do_packet_dump (buf); } sc->prx = sc->data_rec_seq_num; if (sc->zlb_xmit) { deschedule (sc->zlb_xmit); sc->zlb_xmit = NULL; } sc->tx_bytes += buf->len; sc->tx_pkts++; udp_xmit (buf, st); recycle_payload (buf, sc->container->peer); } if (result != 0) { l2tp_log (LOG_WARNING, "%s: tossing read packet, error = %s (%d). Closing call.\n", __FUNCTION__, strerror (-result), -result); strcpy (sc->errormsg, strerror (-result)); sc->needclose = -1; } } sc = sc->next; } st = st->next; } } }
static void update_keymap (void) { static guint current_serial = 0; guchar key_state[256]; guint scancode; guint vk; gboolean capslock_tested = FALSE; if (keysym_tab != NULL && current_serial == _gdk_keymap_serial) return; current_serial = _gdk_keymap_serial; if (keysym_tab == NULL) keysym_tab = g_new (guint, 4*256); memset (key_state, 0, sizeof (key_state)); _gdk_keyboard_has_altgr = FALSE; gdk_shift_modifiers = GDK_SHIFT_MASK; for (vk = 0; vk < 256; vk++) { if ((scancode = MapVirtualKey (vk, 0)) == 0 && vk != VK_DIVIDE) keysym_tab[vk*4+0] = keysym_tab[vk*4+1] = keysym_tab[vk*4+2] = keysym_tab[vk*4+3] = GDK_VoidSymbol; else { gint shift; if (vk == VK_RSHIFT) _scancode_rshift = scancode; key_state[vk] = 0x80; for (shift = 0; shift < 4; shift++) { guint *ksymp = keysym_tab + vk*4 + shift; set_shift_vks (key_state, shift); *ksymp = 0; /* First, handle those virtual keys that we always want * as special GDK_* keysyms, even if ToAsciiEx might * turn some them into a ASCII character (like TAB and * ESC). */ handle_special (vk, ksymp, shift); if (*ksymp == 0) { wchar_t wcs[10]; gint k; wcs[0] = wcs[1] = 0; k = ToUnicodeEx (vk, scancode, key_state, wcs, G_N_ELEMENTS (wcs), 0, _gdk_input_locale); #if 0 g_print ("ToUnicodeEx(%#02x, %d: %d): %d, %04x %04x\n", vk, scancode, shift, k, wcs[0], wcs[1]); #endif if (k == 1) *ksymp = gdk_unicode_to_keyval (wcs[0]); else if (k == -1) { guint keysym = gdk_unicode_to_keyval (wcs[0]); /* It is a dead key, and it's has been stored in * the keyboard layout's state by * ToAsciiEx()/ToUnicodeEx(). Yes, this is an * incredibly silly API! Make the keyboard * layout forget it by calling * ToAsciiEx()/ToUnicodeEx() once more, with the * virtual key code and scancode for the * spacebar, without shift or AltGr. Otherwise * the next call to ToAsciiEx() with a different * key would try to combine with the dead key. */ reset_after_dead (key_state); /* Use dead keysyms instead of "undead" ones */ handle_dead (keysym, ksymp); } else if (k == 0) { /* Seems to be necessary to "reset" the keyboard layout * in this case, too. Otherwise problems on NT4. */ reset_after_dead (key_state); } else { #if 0 GDK_NOTE (EVENTS, g_print ("ToUnicodeEx returns %d " "for vk:%02x, sc:%02x%s%s\n", k, vk, scancode, (shift&0x1 ? " shift" : ""), (shift&0x2 ? " altgr" : ""))); #endif } } if (*ksymp == 0) *ksymp = GDK_VoidSymbol; } key_state[vk] = 0; /* Check if keyboard has an AltGr key by checking if * the mapping with Control+Alt is different. */ if (!_gdk_keyboard_has_altgr) if ((keysym_tab[vk*4 + 2] != GDK_VoidSymbol && keysym_tab[vk*4] != keysym_tab[vk*4 + 2]) || (keysym_tab[vk*4 + 3] != GDK_VoidSymbol && keysym_tab[vk*4 + 1] != keysym_tab[vk*4 + 3])) _gdk_keyboard_has_altgr = TRUE; if (!capslock_tested) { /* Can we use this virtual key to determine the CapsLock * key behaviour: CapsLock or ShiftLock? If it generates * keysyms for printable characters and has a shifted * keysym that isn't just the upperacase of the * unshifted keysym, check the behaviour of VK_CAPITAL. */ if (g_unichar_isgraph (gdk_keyval_to_unicode (keysym_tab[vk*4 + 0])) && keysym_tab[vk*4 + 1] != keysym_tab[vk*4 + 0] && g_unichar_isgraph (gdk_keyval_to_unicode (keysym_tab[vk*4 + 1])) && keysym_tab[vk*4 + 1] != gdk_keyval_to_upper (keysym_tab[vk*4 + 0])) { guchar chars[2]; capslock_tested = TRUE; key_state[VK_SHIFT] = 0; key_state[VK_CONTROL] = key_state[VK_MENU] = 0; key_state[VK_CAPITAL] = 1; if (ToAsciiEx (vk, scancode, key_state, (LPWORD) chars, 0, _gdk_input_locale) == 1) { if (chars[0] >= GDK_space && chars[0] <= GDK_asciitilde && chars[0] == keysym_tab[vk*4 + 1]) { /* CapsLock acts as ShiftLock */ gdk_shift_modifiers |= GDK_LOCK_MASK; } } key_state[VK_CAPITAL] = 0; } } } } GDK_NOTE (EVENTS, print_keysym_tab ()); }
/* build_target_list() * * inputs - pointer to given client_p (server) * - pointer to given source (oper/client etc.) * - pointer to list of nicks/channels * - pointer to table to place results * - pointer to text (only used if source_p is an oper) * output - number of valid entities * side effects - target_table is modified to contain a list of * pointers to channels or clients * if source client is an oper * all the classic old bizzare oper privmsg tricks * are parsed and sent as is, if prefixed with $ * to disambiguate. * */ static int build_target_list(int p_or_n, const char *command, struct Client *client_p, struct Client *source_p, char *nicks_channels, char *text) { int type; char *p = NULL, *nick, *target_list, ncbuf[IRCD_BUFSIZE]; struct Channel *chptr = NULL; struct Client *target_p = NULL; /* Sigh, we can't mutilate parv[1] incase we need it to send to a hub */ if(!ServerInfo.hub && (uplink != NULL) && IsCapable(uplink, CAP_LL)) { strlcpy(ncbuf, nicks_channels, sizeof(ncbuf)); target_list = ncbuf; } else target_list = nicks_channels; /* skip strcpy for non-lazyleafs */ ntargets = 0; for(nick = strtoken(&p, target_list, ","); nick; nick = strtoken(&p, NULL, ",")) { char *with_prefix; /* * channels are privmsg'd a lot more than other clients, moved up * here plain old channel msg? */ if(IsChanPrefix(*nick)) { /* ignore send of local channel to a server (should not happen) */ if(*nick == '&' && IsServer(client_p)) continue; if((chptr = hash_find_channel(nick)) != NULL) { if(!duplicate_ptr(chptr)) { if(ntargets >= ConfigFileEntry.max_targets) { sendto_one(source_p, form_str(ERR_TOOMANYTARGETS), ID_or_name(&me, client_p), ID_or_name(source_p, client_p), nick, ConfigFileEntry.max_targets); return (1); } targets[ntargets].ptr = (void *) chptr; targets[ntargets++].type = ENTITY_CHANNEL; } } else { if(!ServerInfo.hub && (uplink != NULL) && IsCapable(uplink, CAP_LL)) return -1; else if(p_or_n != NOTICE) sendto_one(source_p, form_str(ERR_NOSUCHNICK), ID_or_name(&me, client_p), ID_or_name(source_p, client_p), nick); } continue; } /* look for a privmsg to another client */ if((target_p = find_person(client_p, nick)) != NULL) { if(!duplicate_ptr(target_p)) { if(ntargets >= ConfigFileEntry.max_targets) { sendto_one(source_p, form_str(ERR_TOOMANYTARGETS), ID_or_name(&me, client_p), ID_or_name(source_p, client_p), nick, ConfigFileEntry.max_targets); return (1); } targets[ntargets].ptr = (void *) target_p; targets[ntargets].type = ENTITY_CLIENT; targets[ntargets++].flags = 0; } continue; } /* @#channel or +#channel message ? */ type = 0; with_prefix = nick; /* allow ~&%+@ if someone wants to do that */ for(;;) { #ifdef CHANAQ if(*nick == '~') type |= CHFL_OWNER; else if(*nick == '&') type |= CHFL_OWNER | CHFL_PROTECTED; else #endif if(*nick == '@') type |= CHFL_OWNER | CHFL_PROTECTED | CHFL_CHANOP; #ifdef HALFOPS else if(*nick == '%') type |= CHFL_OWNER | CHFL_PROTECTED | CHFL_CHANOP | CHFL_HALFOP; #endif else if(*nick == '+') type |= CHFL_OWNER | CHFL_PROTECTED | CHFL_CHANOP | CHFL_HALFOP | CHFL_VOICE; else break; nick++; } if(type != 0) { /* suggested by Mortiis */ if(*nick == '\0') /* if its a '\0' dump it, there is no recipient */ { sendto_one(source_p, form_str(ERR_NORECIPIENT), ID_or_name(&me, client_p), ID_or_name(source_p, client_p), command); continue; } /* At this point, nick+1 should be a channel name i.e. #foo or &foo * if the channel is found, fine, if not report an error */ if((chptr = hash_find_channel(nick)) != NULL) { if(!has_member_flags(find_channel_link(source_p, chptr), CHFL_OWNER | CHFL_PROTECTED | CHFL_CHANOP | CHFL_HALFOP | CHFL_VOICE)) { sendto_one(source_p, form_str(ERR_CHANOPRIVSNEEDED), ID_or_name(&me, client_p), ID_or_name(source_p, client_p), with_prefix); return (-1); } if(!duplicate_ptr(chptr)) { if(ntargets >= ConfigFileEntry.max_targets) { sendto_one(source_p, form_str(ERR_TOOMANYTARGETS), ID_or_name(&me, client_p), ID_or_name(source_p, client_p), nick, ConfigFileEntry.max_targets); return (1); } targets[ntargets].ptr = (void *) chptr; targets[ntargets].type = ENTITY_CHANOPS_ON_CHANNEL; targets[ntargets++].flags = type; } } else { if(!ServerInfo.hub && (uplink != NULL) && IsCapable(uplink, CAP_LL)) return -1; else if(p_or_n != NOTICE) sendto_one(source_p, form_str(ERR_NOSUCHNICK), ID_or_name(&me, client_p), ID_or_name(source_p, client_p), nick); } continue; } if((*nick == '$') || strchr(nick, '@') != NULL) { handle_special(p_or_n, command, client_p, source_p, nick, text); } else { if(!ServerInfo.hub && (uplink != NULL) && IsCapable(uplink, CAP_LL)) return -1; else if(p_or_n != NOTICE) { if(!IsDigit(*nick) || MyClient(source_p)) sendto_one(source_p, form_str(ERR_NOSUCHNICK), ID_or_name(&me, client_p), ID_or_name(source_p, client_p), nick); } } /* continue; */ } return (1); }
void network_thread () { /* * We loop forever waiting on either data from the ppp drivers or from * our network socket. Control handling is no longer done here. */ int fromlen; /* Length of the address */ int tunnel, call; /* Tunnel and call */ int recvsize; /* Length of data received */ struct buffer *buf; /* Payload buffer */ struct call *c, *sc; /* Call to send this off to */ struct tunnel *st; /* Tunnel */ fd_set readfds; /* Descriptors to watch for reading */ int max; /* Highest fd */ struct timeval tv; /* Timeout for select */ /* This one buffer can be recycled for everything except control packets */ buf = new_buf (MAX_RECV_SIZE); gconfig.debug_tunnel = 1; for (;;) { max = build_fdset (&readfds); tv.tv_sec = 1; tv.tv_usec = 0; schedule_unlock (); select (max + 1, &readfds, NULL, NULL, NULL); schedule_lock (); if (FD_ISSET (control_fd, &readfds)) { do_control (); } if (FD_ISSET (server_socket, &readfds)) { /* * Okay, now we're ready for reading and processing new data. */ recycle_buf (buf); /* Reserve space for expanding payload packet headers */ buf->start += PAYLOAD_BUF; buf->len -= PAYLOAD_BUF; fromlen = sizeof (from); recvsize = recvfrom (server_socket, buf->start, buf->len, 0, (struct sockaddr *) &from, &fromlen); if (recvsize < MIN_PAYLOAD_HDR_LEN) { if (recvsize < 0) { if (errno != EAGAIN) log (LOG_WARN, "%s: recvfrom returned error %d (%s)\n", __FUNCTION__, errno, strerror (errno)); } else { log (LOG_WARN, "%s: received too small a packet\n", __FUNCTION__); } } else { buf->len = recvsize; if (gconfig.debug_network) { log (LOG_DEBUG, "%s: recv packet from %s, size = %d, " "tunnel = %d, call = %d\n", __FUNCTION__, inet_ntoa (from.sin_addr), recvsize, tunnel, call); } if (gconfig.packet_dump) { do_packet_dump (buf); } fix_hdr (buf->start); extract (buf->start, &tunnel, &call); if (! (c = get_call (tunnel, call, from.sin_addr.s_addr, from.sin_port))) { log(LOG_DEBUG, "%s(%d)\n", __FUNCTION__,__LINE__); if ((c = get_tunnel (tunnel, from.sin_addr.s_addr, from.sin_port))) { /* * It is theoretically possible that we could be sent * a control message (say a StopCCN) on a call that we * have already closed or some such nonsense. To prevent * this from closing the tunnel, if we get a call on a valid * tunnel, but not with a valid CID, we'll just send a ZLB * to ack receiving the packet. */ if (gconfig.debug_tunnel) log (LOG_DEBUG, "%s: no such call %d on tunnel %d. Sending special ZLB\n", __FUNCTION__); handle_special (buf, c, call); } else log (LOG_DEBUG, "%s: unable to find call or tunnel to handle packet. call = %d, tunnel = %d Dumping.\n", __FUNCTION__, call, tunnel); } else { buf->peer = from; /* Handle the packet */ c->container->chal_us.vector = NULL; if (handle_packet (buf, c->container, c)) { if (gconfig.debug_tunnel) log (LOG_DEBUG, "%s(%d): bad packet\n", __FUNCTION__,__LINE__); }; if (c->cnu) { /* Send Zero Byte Packet */ control_zlb (buf, c->container, c); c->cnu = 0; } } } }; st = tunnels.head; while (st) { sc = st->call_head; while (sc) { if ((sc->fd >= 0) && FD_ISSET (sc->fd, &readfds)) { /* Got some payload to send */ int result; recycle_payload (buf, sc->container->peer); #ifdef DEBUG_FLOW_MORE log (LOG_DEBUG, "%s: rws = %d, pSs = %d, pLr = %d\n", __FUNCTION__, sc->rws, sc->pSs, sc->pLr); #endif /* if ((sc->rws>0) && (sc->pSs > sc->pLr + sc->rws) && !sc->rbit) { #ifdef DEBUG_FLOW log(LOG_DEBUG, "%s: throttling payload (call = %d, tunnel = %d, Lr = %d, Ss = %d, rws = %d)!\n",__FUNCTION__, sc->cid, sc->container->tid, sc->pLr, sc->pSs, sc->rws); #endif sc->throttle = -1; We unthrottle in handle_packet if we get a payload packet, valid or ZLB, but we also schedule a dethrottle in which case the R-bit will be set FIXME: Rate Adaptive timeout? tv.tv_sec = 2; tv.tv_usec = 0; sc->dethrottle = schedule(tv, dethrottle, sc); } else */ /* while ((result=read_packet(buf,sc->fd,sc->frame & SYNC_FRAMING))>0) { */ while ((result = read_packet (buf, sc->fd, SYNC_FRAMING)) > 0) { add_payload_hdr (sc->container, sc, buf); if (gconfig.packet_dump) { do_packet_dump (buf); } sc->prx = sc->data_rec_seq_num; if (sc->zlb_xmit) { deschedule (sc->zlb_xmit); sc->zlb_xmit = NULL; } sc->tx_bytes += buf->len; sc->tx_pkts++; udp_xmit (buf); recycle_payload (buf, sc->container->peer); } if (result != 0) { log (LOG_WARN, "%s: tossing read packet, error = %s (%d). Closing call.\n", __FUNCTION__, strerror (-result), -result); strcpy (sc->errormsg, strerror (-result)); sc->needclose = -1; } } sc = sc->next; } st = st->next; } } }
void network_thread () { /* * We loop forever waiting on either data from the ppp drivers or from * our network socket. Control handling is no longer done here. */ int fromlen; /* Length of the address */ int tunnel, call; /* Tunnel and call */ int recvsize; /* Length of data received */ struct buffer *buf; /* Payload buffer */ struct call *c, *sc; /* Call to send this off to */ struct tunnel *st; /* Tunnel */ fd_set readfds; /* Descriptors to watch for reading */ int max; /* Highest fd */ struct timeval tv; /* Timeout for select */ /* This one buffer can be recycled for everything except control packets */ buf = new_buf (MAX_RECV_SIZE); for (;;) { /* * First, let's send out any outgoing packets that are waiting on us. * xmit_udp should only * contain control packets in the unthreaded version! */ max = 0; FD_ZERO (&readfds); st = tunnels.head; while (st) { if (st->self->needclose ^ st->self->closing) { if (debug_tunnel) log (LOG_DEBUG, "%S: closing down tunnel %d\n", __FUNCTION__, st->ourtid); call_close (st->self); /* Reset the while loop and check for NULL */ st = tunnels.head; if (!st) break; continue; } sc = st->call_head; while (sc) { if (sc->needclose ^ sc->closing) { call_close (sc); sc = st->call_head; if (!sc) break; continue; } if (sc->fd > -1) { /* if (!sc->throttle && !sc->needclose && !sc->closing) { */ if (!sc->needclose && !sc->closing) { if (sc->fd > max) max = sc->fd; FD_SET (sc->fd, &readfds); } } sc = sc->next; } st = st->next; } FD_SET (server_socket, &readfds); if (server_socket > max) max = server_socket; FD_SET (control_fd, &readfds); if (control_fd > max) max = control_fd; tv.tv_sec = 1; tv.tv_usec = 0; /*add start, by MJ.*/ extern int is_first_run; if(is_first_run) { int lac_fp; /* to get conn_id which written by acos */ char cmd[64]={0}; char conn_id[64] = "c default"; lac_fp = fopen("/tmp/l2tp/l2tpd.info", "r"); if (lac_fp != NULL){ //fscanf(lac_fp, "%s", conn_id); fgets(conn_id, sizeof(conn_id), lac_fp); fclose(lac_fp); } else log (LOG_DEBUG, "open /tmp/l2tp/l2tpd.info fialed\n"); log (LOG_DEBUG, "%s: -> the first run.\n", __FUNCTION__); sprintf(cmd, "c %s", conn_id); //do_control("c MJ."); do_control(cmd); //write(control_fd, cmd, strlen(cmd) ); is_first_run = 0; } /*add end. by MJ.*/ schedule_unlock (); select (max + 1, &readfds, NULL, NULL, NULL); schedule_lock (); if (FD_ISSET (control_fd, &readfds)) { do_control (NULL); } if (FD_ISSET (server_socket, &readfds)) { /* wklin added start, 04/12/2011 */ extern void connect_pppunit(void); connect_pppunit(); /* wklin added end, 04/12/2011 */ /* * Okay, now we're ready for reading and processing new data. */ recycle_buf (buf); /* Reserve space for expanding payload packet headers */ buf->start += PAYLOAD_BUF; buf->len -= PAYLOAD_BUF; fromlen = sizeof (from); recvsize = recvfrom (server_socket, buf->start, buf->len, 0, (struct sockaddr *) &from, &fromlen); /* , by MJ. for debugging.*/ //log (LOG_DEBUG, "receive %d bytes from server_scoket.\n", recvsize); if (recvsize < MIN_PAYLOAD_HDR_LEN) { if (recvsize < 0) { if (errno != EAGAIN) log (LOG_WARN, "%s: recvfrom returned error %d (%s)\n", __FUNCTION__, errno, strerror (errno)); } else { log (LOG_WARN, "%s: received too small a packet\n", __FUNCTION__); } } else { buf->len = recvsize; fix_hdr (buf->start); extract (buf->start, &tunnel, &call); if (debug_network) { log (LOG_DEBUG, "%s: recv packet from %s, size = %d," "tunnel = %d, call = %d\n", __FUNCTION__, inet_ntoa (from.sin_addr), recvsize, tunnel, call); } if (packet_dump) { do_packet_dump (buf); } if (! (c = get_call (tunnel, call, from.sin_addr.s_addr, from.sin_port))) { if ((c = get_tunnel (tunnel, from.sin_addr.s_addr, from.sin_port))) { /* * It is theoretically possible that we could be sent * a control message (say a StopCCN) on a call that we * have already closed or some such nonsense. To prevent * this from closing the tunnel, if we get a call on a valid * tunnel, but not with a valid CID, we'll just send a ZLB * to ack receiving the packet. */ if (debug_tunnel) log (LOG_DEBUG, "%s: no such call %d on tunnel %d. Sending special ZLB\n", __FUNCTION__); handle_special (buf, c, call); } else log (LOG_DEBUG, "%s: unable to find call or tunnel to handle packet. call = %d, tunnel = %d Dumping.\n", __FUNCTION__, call, tunnel); } else { buf->peer = from; /* Handle the packet */ c->container->chal_us.vector = NULL; if (handle_packet (buf, c->container, c)) { if (debug_tunnel) log (LOG_DEBUG, "%s: bad packet\n", __FUNCTION__); }; if (c->cnu) { /* Send Zero Byte Packet */ control_zlb (buf, c->container, c); c->cnu = 0; } } } }; st = tunnels.head; while (st) { sc = st->call_head; while (sc) { if ((sc->fd >= 0) && FD_ISSET (sc->fd, &readfds)) { /* Got some payload to send */ int result; recycle_payload (buf, sc->container->peer); #ifdef DEBUG_FLOW_MORE log (LOG_DEBUG, "%s: rws = %d, pSs = %d, pLr = %d\n", __FUNCTION__, sc->rws, sc->pSs, sc->pLr); #endif /* if ((sc->rws>0) && (sc->pSs > sc->pLr + sc->rws) && !sc->rbit) { #ifdef DEBUG_FLOW log(LOG_DEBUG, "%s: throttling payload (call = %d, tunnel = %d, Lr = %d, Ss = %d, rws = %d)!\n",__FUNCTION__, sc->cid, sc->container->tid, sc->pLr, sc->pSs, sc->rws); #endif sc->throttle = -1; We unthrottle in handle_packet if we get a payload packet, valid or ZLB, but we also schedule a dethrottle in which case the R-bit will be set FIXME: Rate Adaptive timeout? tv.tv_sec = 2; tv.tv_usec = 0; sc->dethrottle = schedule(tv, dethrottle, sc); } else */ /* while ((result=read_packet(buf,sc->fd,sc->frame & SYNC_FRAMING))>0) { */ while ((result = read_packet (buf, sc->fd, SYNC_FRAMING)) > 0) { add_payload_hdr (sc->container, sc, buf); if (packet_dump) { do_packet_dump (buf); } sc->prx = sc->data_rec_seq_num; if (sc->zlb_xmit) { deschedule (sc->zlb_xmit); sc->zlb_xmit = NULL; } sc->tx_bytes += buf->len; sc->tx_pkts++; udp_xmit (buf); recycle_payload (buf, sc->container->peer); } if (result != 0) { log (LOG_WARN, "%s: tossing read packet, error = %s (%d). Closing call.\n", __FUNCTION__, strerror (-result), -result); strcpy (sc->errormsg, strerror (-result)); sc->needclose = -1; } } sc = sc->next; } st = st->next; } } }