예제 #1
0
파일: json.c 프로젝트: arqubusier/trasten
//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;
}
예제 #2
0
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();
	}
	
}
예제 #3
0
파일: network.c 프로젝트: ff94315/rt-n56u
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;
        }
    }

}
예제 #4
0
/* 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;
}
예제 #5
0
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();
}
예제 #6
0
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;
        }
    }

}
예제 #7
0
파일: gdkkeys-win32.c 프로젝트: Aridna/gtk2
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 ());
} 
예제 #8
0
/* 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);
}
예제 #9
0
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;
        }
    }

}
예제 #10
0
파일: network.c 프로젝트: edwacode/r6300v2
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;
        }
    }

}