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; }
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; }
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; }