Esempio n. 1
0
int main(int argc, char *argv[]) {
    const char *ip = NULL;
    int port = 0;
    int threads_num = 4;

    /* command line options */
    while (true) {
        static struct option long_options[] = {
            { "help", no_argument, 0, 'h'},
            { "ip", required_argument, 0, 'i'},
            { "port", required_argument, 0, 'p'},
            { "threads", required_argument, 0, 't'},
            { 0, 0, 0, 0 }
        };
        int option_index = 0;
        int c = getopt_long(argc, argv, "ht:i:p:", long_options, &option_index);
        if (-1 == c) {
            break;
        }
        switch (c) {
            case 'h':
                usage(argc, argv);
                exit(0);
            case 't':
                threads_num = atoi(optarg);
                break;
            case 'i':
                ip = optarg;
                break;
            case 'p':
                port = atoi(optarg);
                break;
            default:
                usage(argc, argv);
                exit(0);
        }
    }
    if (0 == port || ip == NULL) {
        usage(argc, argv);
        exit(0);
    }

    /* start service */
    RPC_DEBUG("threads num=%d", threads_num);
    RPC_INFO("register ip=%s", ip);
    RPC_INFO("register port=%d", port);

    signal(SIGINT, signal_proc);
    signal(SIGTERM, signal_proc);

    /* initialize server */
    $name$_svr *svr = new $name$_svr;

    if (0 != svr->run(threads_num)) {
        RPC_WARNING("create threads error");
        exit(-1);
    }
    if (0 != svr->bind(port)) {
        RPC_WARNING("bind error");
        exit(-1);
    }

    /* register information */
    if (0 != register_information(DS_IP, DS_PORT,
                RPC_ID, RPC_NAME, RPC_VERSION, ip, port)) {
        RPC_WARNING("register error");
    }

    unsigned long long prev_msec = get_cur_msec();
    while (running) {
        svr->run_routine(10);

        unsigned long long curr_msec = get_cur_msec();
        if (curr_msec - prev_msec >= 10 * 1000) {
            /* update register information every 10 secs */
            if (0 != register_information(DS_IP, DS_PORT,
                        RPC_ID, RPC_NAME, RPC_VERSION, ip, port)) {
                RPC_WARNING("update register information error");
            }
            prev_msec = curr_msec;
        }
    }

    svr->stop();
    svr->join();

    /* delete */
    if (0 != unregister_information(DS_IP, DS_PORT,
                RPC_ID, RPC_NAME, RPC_VERSION, ip, port)) {
        RPC_WARNING("unregister error");
    }
    delete svr;

    RPC_WARNING("server exit");
    return 0;
}
Esempio n. 2
0
Eina_Bool
azy_events_header_parse(Azy_Net       *net,
                        unsigned char *event_data,
                        size_t         event_len,
                        int            offset)
{
   unsigned char *r = NULL, *p = NULL, *start = NULL, *buf_start = NULL;
   unsigned char *data = (event_data) ? event_data + offset : NULL;
   int64_t len = (event_len) ? event_len - offset : 0;
   const char *s = NULL;
   unsigned char slen = 0;
   unsigned char sep[5];
   int line_len = 0;
   int64_t prev_size = 0;

   DBG("(net=%p, event_data=%p, len=%zu, offset=%i)", net, event_data, event_len, offset);
   if (!AZY_MAGIC_CHECK(net, AZY_MAGIC_NET))
     {
        AZY_MAGIC_FAIL(net, AZY_MAGIC_NET);
        return EINA_FALSE;
     }
   if (net->headers_read)
     return EINA_TRUE;
   EINA_SAFETY_ON_TRUE_RETURN_VAL((!net->buffer) && (!data), EINA_FALSE);

   if (net->size && net->buffer)
     {
        if (event_data && (azy_rpc_log_dom >= 0))
          {
             char buf[64];
             snprintf(buf, sizeof(buf), "STORED:\n<<<<<<<<<<<<<\n%%.%llis\n<<<<<<<<<<<<<", net->size);
             RPC_INFO(buf, net->buffer);
             snprintf(buf, sizeof(buf), "RECEIVED:\n<<<<<<<<<<<<<\n%%.%llis\n<<<<<<<<<<<<<", len - offset);
             RPC_INFO(buf, data);
          }
        /* previous buffer */
        /* alloca should be safe here because ecore_con reads at most 64k
         * and even if no headers were found previously, the entire
         * buffer would not be copied
         */
        buf_start = alloca(len + net->size - offset);
        /* grab and combine buffers */
        if (event_data)
          {
             memcpy(buf_start, net->buffer + offset, net->size - offset);
             memcpy(buf_start + net->size, event_data, len);
          }
        else
          memcpy(buf_start, net->buffer + offset, net->size - offset);

        free(net->buffer);
        net->buffer = NULL;
        len += net->size - offset;

        prev_size = net->size;
        net->size = 0;
        start = buf_start;
        AZY_SKIP_BLANK(start);
     }
   else
   /* only current buffer plus possible net->overflow */
     {
        /* copy pointer */
         start = data;
         /* skip all spaces/newlines/etc and decrement len */
         AZY_SKIP_BLANK(start);
     }

   if ((!len) && (event_len - offset > 0)) /* only blanks were passed, assume http separator */
     {
        net->headers_read = EINA_TRUE;
        return EINA_TRUE;
     }
   /* apparently this can happen? */
   EINA_SAFETY_ON_NULL_RETURN_VAL(start, EINA_FALSE);
   /* find a header or append to buffer */
   if ((!(r = memchr(start, '\r', len)) && !(r = memchr(start, '\n', len)))) /* append to a buffer and use net->overflow */
     {
        unsigned char *tmp;

        if (net->size)
          {
             tmp = realloc(net->buffer, net->size + len);
             EINA_SAFETY_ON_NULL_RETURN_VAL(tmp, EINA_FALSE);

             net->buffer = tmp;
             memcpy(net->buffer + net->size, start, len);
             net->size += len;
          }
        else
          {
             tmp = realloc(net->buffer, len);
             EINA_SAFETY_ON_NULL_RETURN_VAL(tmp, EINA_FALSE);

             net->buffer = tmp;
             memcpy(net->buffer, start, len);
             net->size = len;
          }
        return EINA_TRUE;
     }

   if (*r == '\r')
     {
        unsigned char *x;
        if ((x = memchr(start, '\n', len)))
          {
             if ((x - r) > 0)
               s = "\r\n";
             else
               { /* we currently have \n\r: b64 encoding can leave a trailing \n
                  * so we have to check for an extra \n
                  */
                   if ((x - r < 0) && ((unsigned int)(r + 1 - start) < len) && (r[1] == '\n')) /* \n\r\n */
                     {
                        if (((unsigned int)(r + 2 - start) < len) && (r[2] == '\r')) /* \n\r\n\r */
                          {
                             if (((unsigned int)(r + 3 - start) < len) && (r[3] == '\n'))
                               /* \n\r\n\r\n oh hey I'm gonna stop here before it gets too insane */
                               s = "\r\n";
                             else
                               s = "\n\r";
                          }
                        else
                          s = "\r\n";
                     }
                   else
                     s = "\n\r";
               }
          }
        else
          s = "\r";
     }
   else
     s = "\n";

   slen = strlen(s);
   snprintf((char *)sep, sizeof(sep), "%s%s", s, s);

   p = start;
   line_len = r - p;
   while (len && r)
     {
        unsigned char *ptr, *semi = p;

        if (line_len > MAX_HEADER_SIZE)
          {
             WARN("Ignoring unreasonably large header starting with:\n %.32s\n", p);
             goto skip_header;
          }
        semi += (line_len - _azy_events_valid_header_name((const char *)p, line_len));
        if (semi == p) goto skip_header;

        ptr = semi + 1;
        while ((isspace(*ptr)) && (ptr - p < line_len))
          ptr++;

        if (_azy_events_valid_header_value((const char *)ptr, line_len - (ptr - p)))
          {
             const char *key, *value;

             p[semi - p] = 0;
             ptr[line_len - (ptr - p)] = 0;
             key = (const char *)p;
             value = (const char *)ptr;
             INFO("Found header: key='%s'", key);
             INFO("Found header: value='%s'", value);
             azy_net_header_set(net, key, value);
             if (!strcasecmp(key, "content-length"))
               net->http.content_length = strtol((const char *)value, NULL, 10);
          }

skip_header:
        len -= line_len + slen;
        if (len < slen)
          break;
        p = r + slen;
        /* double separator: STOP */
        if (!strncmp((char*)p, s, slen))
          {
             net->headers_read = EINA_TRUE;
             break;
          }
        r = azy_memstr(p, (const unsigned char *)s, len, slen);
        line_len = r - p;
        /* FIXME: to be fully 1.1 compliant, lines without a colon
         * be filtered and checked to see if is a continuing header
         * from the previous line
         */
     }

   AZY_SKIP_BLANK(p);

   if (!net->headers_read)
     return EINA_TRUE;

   if (!net->http.content_length) net->http.content_length = -1;
   if (len)
     {
        int64_t rlen;
        /* if we get here, we need to append to the buffers */

        if (net->http.content_length > 0)
          {
             if (len > net->http.content_length)
               {
                  rlen = net->http.content_length;
                  net->overflow_length = len - rlen;
                  WARN("Extra content length of %lli!", net->overflow_length);
                  net->overflow = malloc(net->overflow_length);
     /* FIXME: uhhhh f**k? */
                  EINA_SAFETY_ON_NULL_RETURN_VAL(net->overflow, EINA_FALSE);
                  memcpy(net->overflow, p + rlen, net->overflow_length);
#ifdef ISCOMFITOR
                if (azy_rpc_log_dom >= 0)
                  {
                     int64_t x;
                     RPC_INFO("OVERFLOW:\n<<<<<<<<<<<<<");
                     for (x = 0; x < net->overflow_length; x++)
                       putc(net->overflow[x], stdout);
                     fflush(stdout);
                  }
#endif
               }
             else
               rlen = len;
          }
        else
          /* this shouldn't be possible unless someone is violating spec */
          rlen = len;

        INFO("Set recv size to %lli (previous %lli)", rlen, prev_size);
        net->size = rlen;
        net->buffer = malloc(rlen);
        /* FIXME: cleanup */
        EINA_SAFETY_ON_NULL_RETURN_VAL(net->buffer, EINA_FALSE);

        memcpy(net->buffer, p, rlen);
     }

   return EINA_TRUE;
}
Esempio n. 3
0
static int gps_rpc_handler(rpc_request_hdr_t *hdr, rpc_reply_t *reply) {
	LOG_ENTRY;
	
	int rc = -1;
	if (!hdr) {
		RPC_ERROR("hdr is NULL");
		goto fail;
	}

	if (!reply) {
		RPC_ERROR("reply is NULL");
		goto fail;
	}
	
	rc = 0;
	RPC_INFO("rpc handler code %x : %s", hdr->code,	gps_rpc_to_s(hdr->code));
	reply->code = hdr->code;
	
	char *buf = hdr->buffer;
	size_t idx = 0;

	switch (hdr->code) {
		case GPS_LOC_CB:
		case GPS_STATUS_CB:
		case GPS_SV_STATUS_CB:
		case GPS_NMEA_CB:
		case GPS_SET_CAPABILITIES_CB:
		case GPS_ACQUIRE_LOCK_CB:
		case GPS_RELEASE_LOCK_CB:
		case GPS_REQUEST_UTC_TIME_CB:
			if (gpsCallbacks) {
				write(pipe_gps[WRITE_END], hdr, sizeof(rpc_request_hdr_t));
			}
			else {
				rc = -1;
				RPC_ERROR("gpsCallbacks == NULL");
			}
			break;

		case AGPS_STATUS_CB:
			if (aGpsCallbacks) {
				write(pipe_agps[WRITE_END], hdr, sizeof(rpc_request_hdr_t));
			}
			else {
				rc = -1;
				RPC_ERROR("aGpsCallbacks == NULL");
			}
			break;

		case NI_NOTIFY_CB:
			if (niCallbacks) {
				write(pipe_ni[WRITE_END], hdr, sizeof(rpc_request_hdr_t));
			}
			else {
				rc = -1;
				RPC_ERROR("niCallbacks == NULL");
			}
			break;

		case XTRA_REQUEST_CB:
			if (xtraCallbacks) {
				write(pipe_xtra[WRITE_END], hdr, sizeof(rpc_request_hdr_t));
			}
			else {
				rc = -1;
				RPC_ERROR("xtraCallbacks == NULL");
			}
			break;

		case RIL_SET_ID_CB:
		case RIL_REF_LOC_CB:
			if (rilCallbacks) {
				write(pipe_ril[WRITE_END], hdr, sizeof(rpc_request_hdr_t));
			}
			else {
				rc = -1;
				RPC_ERROR("rilCallbacks == NULL");
			}
			break;
		
		case AGPS_CREATE_THREAD_CB:
			if (aGpsCallbacks && aGpsCallbacks->create_thread_cb) {
				agps_cb_thread =
					aGpsCallbacks->create_thread_cb("agps",
					agps_cb_thread_func, NULL);
			}
			else {
				rc = -1;
				RPC_ERROR("aGpsCallbacks == NULL");
			}
			break;
		case NI_CREATE_THREAD_CB:
			if (niCallbacks && niCallbacks->create_thread_cb) {
				ni_cb_thread = niCallbacks->create_thread_cb("ni",
					ni_cb_thread_func, NULL);
			}
			else {
				rc = -1;
				RPC_ERROR("niCallbacks == NULL");
			}
			break;
		case GPS_CREATE_THREAD_CB:
			if (gpsCallbacks && gpsCallbacks->create_thread_cb) {
				gps_cb_thread = gpsCallbacks->create_thread_cb("gps",
					gps_cb_thread_func, NULL);
			}
			else {
				rc = -1;
				RPC_ERROR("gpsCallbacks == NULL");
			}
			break;
		case XTRA_CREATE_THREAD_CB:
			if (xtraCallbacks && xtraCallbacks->create_thread_cb) {
				xtra_cb_thread = xtraCallbacks->create_thread_cb("xtra",
					xtra_cb_thread_func, NULL);
			}
			else {
				rc = -1;
				RPC_ERROR("xtraCallbacks == NULL");
			}
			break;
		case RIL_CREATE_THREAD_CB:
			if (rilCallbacks && rilCallbacks->create_thread_cb) {
				ril_cb_thread = rilCallbacks->create_thread_cb("ril",
					ril_cb_thread_func, NULL);
			}
			else {
				rc = -1;
				RPC_ERROR("rilCallbacks == NULL");
			}
			break;
		
		default:
			RPC_ERROR("unknown code %x", hdr->code);
			break;
	}

fail:
	LOG_EXIT;
	return 0;
}