コード例 #1
0
ファイル: proxy.c プロジェクト: jdbrandon/proxy
/* Read a request from a connection socket and parses its information into a 
 * req_t struct.
 * Initally based on csapp echo() p.911
 * Allocates memory for request hdrs
 * returns -1 on failure, 1 if the content is local, and 0 if the content is
 * remote
 */
int process_request(int fd, req_t* req){
    size_t n;
    char buf[MAXLINE];
    rio_t rio;

    req->domain = NULL;
    req->path = NULL;
    req->hdrs = NULL;

    //Parse domain and path information    
    Rio_readinitb(&rio, fd);
    if((n = Rio_readlineb(&rio, buf, MAXLINE)) != 0){
        if(parse_req(buf, req) == -1)
            return -1;
    }
    else return -1;
    //parse header information
    while((n = Rio_readlineb(&rio, buf, MAXLINE)) != 0){   
        if(strcmp(buf, "\r\n") == 0)
            break;
        if(req->hdrs != NULL){
            n = strlen(req->hdrs) + strlen(buf) + 1;
            req->hdrs = Realloc(req->hdrs,strlen(req->hdrs)+ n);
            strcat(req->hdrs, handle_hdr(buf));
        } else {
            req->hdrs = Malloc(n+1);
            strcpy(req->hdrs, handle_hdr(buf));
        }
    }
    return 0;
}
コード例 #2
0
ファイル: main.c プロジェクト: intelrsasw/intelRSD
static void main_loop(int fd)
{
	int ret_code;
	char cmd_string[JSONRPC_MAX_STRING_LEN] = {0};
	fd_set fds;
	struct sockaddr_in addr;
	socklen_t addrlen = sizeof(addr);
	jrpc_req_pkg_t req;
	json_t *rsp = NULL;
	int func_id = 0;
	int reg_connection = -1;

	char *rsp_str = malloc(JSONRPC_MAX_STRING_LEN);

	if (rsp_str == NULL)
		goto err;

	for (;;) {
		FD_ZERO(&fds);
		FD_SET(fd, &fds);

		ret_code = select(fd + 1, &fds, NULL, NULL, NULL);
		if (ret_code < 0)
			continue;

		memset(cmd_string, 0, sizeof(cmd_string));
		ret_code = recvfrom(fd, cmd_string, sizeof(cmd_string), 0, (struct sockaddr *)&addr, &addrlen);
		if (ret_code < 0)
			continue;

		rsp = json_object();
		if (rsp == NULL)
			goto err;

		rmm_log(INFO, "receive: %s.\n", cmd_string);
		parse_req(cmd_string, &req, &func_id);
		ret_code = process_req(func_id, &req, rsp);
		jrpc_req_pkg_free(&req);
		if (ret_code < 0) {
			continue;
		}

		memset(rsp_str, 0, JSONRPC_MAX_STRING_LEN);
		ret_code = jrpc_create_result_rsp_string(req.id, JSONRPC_ID_TYPE_NORMAL, rsp, JSON_OBJECT, rsp_str);
		if (ret_code < 0)
			continue;

		rmm_log(INFO, "send: %s.\n", rsp_str);
		sendto(fd, rsp_str, strnlen_s(rsp_str, JSONRPC_MAX_STRING_LEN)+1, 0, (struct sockaddr *)&addr, addrlen);
	}

	free(rsp_str);

err:

	close(fd);
	return;
}
コード例 #3
0
ファイル: control.c プロジェクト: coyizumi/cs111
int
main(int argc, char **argv)
{
  unsigned int vid = UINT_MAX, pid = UINT_MAX; /* impossible VID:PID */
  int c;

  /*
   * Initialize setup struct.  This step is required, and initializes
   * internal fields in the struct.
   *
   * All the "public" fields are named exactly the way as the USB
   * standard describes them, namely:
   *
   *	setup.bmRequestType: bitmask, bit 7 is direction
   *	                              bits 6/5 is request type
   *	                                       (standard, class, vendor)
   *	                              bits 4..0 is recipient
   *	                                       (device, interface, endpoint,
   *	                                        other)
   *	setup.bRequest:      the request itself (see get_req() for standard
   *	                                         requests, or specific value)
   *	setup.wValue:        a 16-bit value
   *	setup.wIndex:        another 16-bit value
   *	setup.wLength:       length of associated data transfer, direction
   *	                     depends on bit 7 of bmRequestType
   */
  LIBUSB20_INIT(LIBUSB20_CONTROL_SETUP, &setup);

  while ((c = getopt(argc, argv, "i:p:v:")) != -1)
    switch (c)
      {
      case 'i':
	intr_ep = strtol(optarg, NULL, 0);
	break;

      case 'p':
	pid = strtol(optarg, NULL, 0);
	break;

      case 'v':
	vid = strtol(optarg, NULL, 0);
	break;

      default:
	usage();
	break;
      }
  argc -= optind;
  argv += optind;

  if (vid != UINT_MAX || pid != UINT_MAX)
    {
      if (intr_ep != 0 && (intr_ep & 0x80) == 0)
	{
	  fprintf(stderr, "Interrupt endpoint must be of type IN\n");
	  usage();
	}

      if (argc > 0)
	{
	  do_request = true;

	  int rv = parse_req(argc, argv);
	  if (rv < 0)
	    return EX_USAGE;
	  argc = rv;

	  if (argc > 0)
	    {
	      for (out_len = 0; argc > 0 && out_len < BUFLEN; out_len++, argc--)
		{
		  unsigned n = strtoul(argv[out_len], 0, 0);
		  if (n > 255)
		    fprintf(stderr,
			    "Warning: data #%d 0x%0x > 0xff, truncating\n",
			    out_len, n);
		  out_buf[out_len] = (uint8_t)n;
		}
	      out_len++;
	      if (argc > 0)
		fprintf(stderr,
			"Data count exceeds maximum of %d, ignoring %d elements\n",
			BUFLEN, optind);
	    }
	}
    }

  struct libusb20_backend *be;
  struct libusb20_device *dev;

  if ((be = libusb20_be_alloc_default()) == NULL)
    {
      perror("libusb20_be_alloc()");
      return 1;
    }

  dev = NULL;
  while ((dev = libusb20_be_device_foreach(be, dev)) != NULL)
    {
      struct LIBUSB20_DEVICE_DESC_DECODED *ddp =
      libusb20_dev_get_device_desc(dev);

      printf("Found device %s (VID:PID = 0x%04x:0x%04x)\n",
	     libusb20_dev_get_desc(dev),
	     ddp->idVendor, ddp->idProduct);

      if (ddp->idVendor == vid && ddp->idProduct == pid)
	doit(dev);
    }

  libusb20_be_free(be);
  return 0;
}
コード例 #4
0
ファイル: check_redis.c プロジェクト: huayl/pelikan
END_TEST


/*
 * request
 */

START_TEST(test_quit)
{
#define QUIT "quit"
#define SERIALIZED "*1\r\n$4\r\n" QUIT "\r\n"
#define INVALID "*2\r\n$4\r\n" QUIT "\r\n$3\r\nnow\r\n"
    int ret;
    struct element *el;

    test_reset();

    req->type = REQ_QUIT;
    el = array_push(req->token);
    el->type = ELEM_BULK;
    el->bstr = (struct bstring){sizeof(QUIT) - 1, QUIT};
    ret = compose_req(&buf, req);
    ck_assert_int_eq(ret, sizeof(SERIALIZED) - 1);
    ck_assert_int_eq(cc_bcmp(buf->rpos, SERIALIZED, ret), 0);

    el->type = ELEM_UNKNOWN; /* this effectively resets *el */
    request_reset(req);
    ck_assert_int_eq(parse_req(req, buf), PARSE_OK);
    ck_assert_int_eq(req->type, REQ_QUIT);
    ck_assert_int_eq(req->token->nelem, 1);
    el = array_first(req->token);
    ck_assert_int_eq(el->type, ELEM_BULK);
    ck_assert_int_eq(cc_bcmp(el->bstr.data, QUIT, sizeof(QUIT) - 1), 0);

    /* invalid number of arguments */
    test_reset();
    buf_write(buf, INVALID, sizeof(INVALID) - 1);
    ck_assert_int_eq(parse_req(req, buf), PARSE_EINVALID);
#undef INVALID
#undef SERIALIZED
#undef QUIT
}
END_TEST


START_TEST(test_ping)
{
#define PING "ping"
#define VAL "hello"
#define S_PING "*1\r\n$4\r\n" PING "\r\n"
#define S_ECHO "*2\r\n$4\r\n" PING "\r\n$5\r\nhello\r\n"
    int ret;
    struct element *el;

    test_reset();

    /* simple ping */
    buf_write(buf, S_PING, sizeof(S_PING) - 1);
    ck_assert_int_eq(parse_req(req, buf), PARSE_OK);
    ck_assert_int_eq(req->type, REQ_PING);

    /* ping as echo */
    test_reset();

    req->type = REQ_PING;
    el = array_push(req->token);
    el->type = ELEM_BULK;
    el->bstr = (struct bstring){sizeof(PING) - 1, PING};
    el = array_push(req->token);
    el->type = ELEM_BULK;
    el->bstr = (struct bstring){sizeof(VAL) - 1, VAL};
    ret = compose_req(&buf, req);
    ck_assert_int_eq(ret, sizeof(S_ECHO) - 1);
    ck_assert_int_eq(cc_bcmp(buf->rpos, S_ECHO, ret), 0);

    el->type = ELEM_UNKNOWN; /* resets *el */
    request_reset(req);
    ck_assert_int_eq(parse_req(req, buf), PARSE_OK);
    ck_assert_int_eq(req->type, REQ_PING);
    ck_assert_int_eq(req->token->nelem, 2);
    el = array_first(req->token);
    ck_assert_int_eq(el->type, ELEM_BULK);
    ck_assert_int_eq(cc_bcmp(el->bstr.data, PING, sizeof(PING) - 1), 0);
    el = array_get(req->token, 1);
    ck_assert_int_eq(el->type, ELEM_BULK);
    ck_assert_int_eq(cc_bcmp(el->bstr.data, VAL, sizeof(VAL) - 1), 0);
#undef S_ECHO
#undef ECHO
#undef S_PING
#undef QUIT
}
END_TEST

START_TEST(test_unfin_req)
{
    char *token[4] = {
        "*2\r\n",
        "*2\r\n$3\r\n",
        "*2\r\n$3\r\nfoo\r\n",
        "*2\r\n$3\r\nfoo\r\n$3\r\n",
    };

    for (int i = 0; i < 4; i++) {
        char *pos;
        size_t len;

        len = strlen(token[i]);
        buf_reset(buf);
        buf_write(buf, token[i], len);
        pos = buf->rpos;
        ck_assert_int_eq(parse_req(req, buf), PARSE_EUNFIN);
        ck_assert(buf->rpos == pos);
    }
}
END_TEST

/*
 * response
 */
START_TEST(test_ok)
{
#define OK "OK"
#define SERIALIZED "+" OK "\r\n"
    int ret;
    struct element *el;

    test_reset();

    rsp->type = ELEM_STR;
    el = array_push(rsp->token);
    el->type = ELEM_STR;
    el->bstr = (struct bstring){sizeof(OK) - 1, OK};
    ret = compose_rsp(&buf, rsp);
    ck_assert_int_eq(ret, sizeof(SERIALIZED) - 1);
    ck_assert_int_eq(cc_bcmp(buf->rpos, SERIALIZED, ret), 0);

    el->type = ELEM_UNKNOWN; /* resets *el */
    response_reset(rsp);
    ck_assert_int_eq(parse_rsp(rsp, buf), PARSE_OK);
    ck_assert_int_eq(rsp->type, ELEM_STR);
    ck_assert_int_eq(rsp->token->nelem, 1);
    el = array_first(rsp->token);
    ck_assert_int_eq(el->type, ELEM_STR);
    ck_assert_int_eq(cc_bcmp(el->bstr.data, OK, sizeof(OK) - 1), 0);
#undef SERIALIZED
#undef OK
}
END_TEST

START_TEST(test_array_reply)
{
#define SERIALIZED "*5\r\n:-10\r\n$-1\r\n-ERR invalid arg\r\n+foo\r\n$5\r\nHELLO\r\n"
    size_t len = sizeof(SERIALIZED) - 1;
    struct element *el;

    test_reset();

    buf_write(buf, SERIALIZED, len);
    ck_assert_int_eq(parse_rsp(rsp, buf), PARSE_OK);
    ck_assert_int_eq(rsp->type, ELEM_ARRAY);
    ck_assert_int_eq(rsp->token->nelem, 5);
    el = array_first(rsp->token);
    ck_assert_int_eq(el->type, ELEM_INT);
    el = array_get(rsp->token, 1);
    ck_assert_int_eq(el->type, ELEM_NIL);
    el = array_get(rsp->token, 2);
    ck_assert_int_eq(el->type, ELEM_ERR);
    el = array_get(rsp->token, 3);
    ck_assert_int_eq(el->type, ELEM_STR);
    el = array_get(rsp->token, 4);
    ck_assert_int_eq(el->type, ELEM_BULK);
    ck_assert_int_eq(el->bstr.len, 5);
    ck_assert_int_eq(cc_bcmp(el->bstr.data, "HELLO", 5), 0);
    ck_assert_int_eq(buf_rsize(buf), 0);

    ck_assert_int_eq(compose_rsp(&buf, rsp), len);
    ck_assert_int_eq(buf_rsize(buf), len);
    ck_assert_int_eq(cc_bcmp(buf->rpos, SERIALIZED, len), 0);
#undef SERIALIZED
}
END_TEST

/*
 * edge cases
 */
START_TEST(test_empty_buf)
{
    struct element el;
    test_reset();

    ck_assert(!token_is_array(buf));
    ck_assert_int_eq(parse_element(&el, buf), PARSE_EUNFIN);
    ck_assert_int_eq(parse_rsp(rsp, buf), PARSE_EUNFIN);
    ck_assert_int_eq(parse_req(req, buf), PARSE_EUNFIN);
}
END_TEST

/*
 * request/response pool
 */

START_TEST(test_req_pool_basic)
{
#define POOL_SIZE 10
    int i;
    struct request *reqs[POOL_SIZE];
    request_options_st options = {
        .request_ntoken = {.type = OPTION_TYPE_UINT, .val.vuint = REQ_NTOKEN},
        .request_poolsize = {.type = OPTION_TYPE_UINT, .val.vuint = POOL_SIZE}};

    request_setup(&options, NULL);

    for (i = 0; i < POOL_SIZE; i++) {
        reqs[i] = request_borrow();
        ck_assert_msg(reqs[i] != NULL, "expected to borrow a request");
    }
    ck_assert_msg(request_borrow() == NULL, "expected request pool to be depleted");
    for (i = 0; i < POOL_SIZE; i++) {
        request_return(&reqs[i]);
        ck_assert_msg(reqs[i] == NULL, "expected request to be nulled after return");
    }

    request_teardown();
#undef POOL_SIZE
}
END_TEST

START_TEST(test_rsp_pool_basic)
{
#define POOL_SIZE 10
    int i;
    struct response *rsps[POOL_SIZE];
    response_options_st options = {
        .response_ntoken = {.type = OPTION_TYPE_UINT, .val.vuint = RSP_NTOKEN},
        .response_poolsize = {.type = OPTION_TYPE_UINT, .val.vuint = POOL_SIZE}};

    response_setup(&options, NULL);

    for (i = 0; i < POOL_SIZE; i++) {
        rsps[i] = response_borrow();
        ck_assert_msg(rsps[i] != NULL, "expected to borrow a response");
    }
    ck_assert_msg(response_borrow() == NULL, "expected response pool to be depleted");
    for (i = 0; i < POOL_SIZE; i++) {
        response_return(&rsps[i]);
        ck_assert_msg(rsps[i] == NULL, "expected response to be nulled after return");
    }

    response_teardown();
#undef POOL_SIZE
}
END_TEST

/*
 * test suite
 */
static Suite *
redis_suite(void)
{
    Suite *s = suite_create(SUITE_NAME);

    /* token */
    TCase *tc_token = tcase_create("token");
    suite_add_tcase(s, tc_token);

    tcase_add_test(tc_token, test_simple_string);
    tcase_add_test(tc_token, test_error);
    tcase_add_test(tc_token, test_integer);
    tcase_add_test(tc_token, test_bulk_string);
    tcase_add_test(tc_token, test_array);
    tcase_add_test(tc_token, test_nil_bulk);
    tcase_add_test(tc_token, test_unfin_token);

    /* basic requests */
    TCase *tc_request = tcase_create("request");
    suite_add_tcase(s, tc_request);

    tcase_add_test(tc_request, test_quit);
    tcase_add_test(tc_request, test_ping);
    tcase_add_test(tc_request, test_unfin_req);

    /* basic responses */
    TCase *tc_response = tcase_create("response");
    suite_add_tcase(s, tc_response);

    tcase_add_test(tc_response, test_ok);
    tcase_add_test(tc_response, test_array_reply);

    /* edge cases */
    TCase *tc_edge = tcase_create("edge cases");
    suite_add_tcase(s, tc_edge);
    tcase_add_test(tc_edge, test_empty_buf);

    /* req/rsp objects, pooling */
    TCase *tc_pool = tcase_create("request/response pool");
    suite_add_tcase(s, tc_pool);

    tcase_add_test(tc_pool, test_req_pool_basic);
    tcase_add_test(tc_pool, test_rsp_pool_basic);

    return s;
}

/* TODO(yao): move main to a different file, keep most test files main-less */
int
main(void)
{
    int nfail;

    /* setup */
    test_setup();

    Suite *suite = redis_suite();
    SRunner *srunner = srunner_create(suite);
    srunner_set_log(srunner, DEBUG_LOG);
    srunner_run_all(srunner, CK_ENV); /* set CK_VEBOSITY in ENV to customize */
    nfail = srunner_ntests_failed(srunner);
    srunner_free(srunner);

    /* teardown */
    test_teardown();

    return (nfail == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}
コード例 #5
0
ファイル: parser.c プロジェクト: fourks/goaccess
static int
parse_format (GLogItem * glog, const char *fmt, const char *date_format,
              char *str)
{
  const char *p;
  double serve_secs;
  int special = 0;
  struct tm tm;
  unsigned long long bandw, serve_time;

  if (str == NULL || *str == '\0')
    return 1;

  memset (&tm, 0, sizeof (tm));

  /* iterate over the log format */
  for (p = fmt; *p; p++) {
    if (*p == '%') {
      special++;
      continue;
    }
    if (special && *p != '\0') {
      char *pch, *sEnd, *bEnd, *tkn = NULL, *end = NULL;
      errno = 0;
      bandw = 0;
      serve_time = 0;
      serve_secs = 0;

      switch (*p) {
         /* date */
       case 'd':
         if (glog->date)
           return 1;
         /* parse date format including dates containing spaces,
          * i.e., syslog date format (Jul 15 20:10:56) */
         tkn = parse_string (&str, p[1], count_matches (date_format, ' ') + 1);
         if (tkn == NULL)
           return 1;
         end = strptime (tkn, date_format, &tm);
         if (end == NULL || *end != '\0') {
           free (tkn);
           return 1;
         }
         glog->date = tkn;
         break;
         /* remote hostname (IP only) */
       case 'h':
         if (glog->host)
           return 1;
         tkn = parse_string (&str, p[1], 1);
         if (tkn == NULL)
           return 1;
         if (invalid_ipaddr (tkn)) {
           free (tkn);
           return 1;
         }
         glog->host = tkn;
         break;
         /* request method */
       case 'm':
         if (glog->method)
           return 1;
         tkn = parse_string (&str, p[1], 1);
         if (tkn == NULL)
           return 1;
         if (!extract_method (tkn)) {
           free (tkn);
           return 1;
         }
         glog->method = tkn;
         break;
         /* request not including method or protocol */
       case 'U':
         if (glog->req)
           return 1;
         tkn = parse_string (&str, p[1], 1);
         if (tkn == NULL || *tkn == '\0')
           return 1;
         if ((glog->req = decode_url (tkn)) == NULL)
           return 1;
         free (tkn);
         break;
         /* request protocol */
       case 'H':
         if (glog->protocol)
           return 1;
         tkn = parse_string (&str, p[1], 1);
         if (tkn == NULL)
           return 1;
         if (invalid_protocol (tkn)) {
           free (tkn);
           return 1;
         }
         glog->protocol = tkn;
         break;
         /* request, including method + protocol */
       case 'r':
         if (glog->req)
           return 1;
         tkn = parse_string (&str, p[1], 1);
         if (tkn == NULL)
           return 1;
         glog->req = parse_req (tkn, &glog->method, &glog->protocol);
         free (tkn);
         break;
         /* Status Code */
       case 's':
         if (glog->status)
           return 1;
         tkn = parse_string (&str, p[1], 1);
         if (tkn == NULL)
           return 1;
         strtol (tkn, &sEnd, 10);
         if (tkn == sEnd || *sEnd != '\0' || errno == ERANGE) {
           free (tkn);
           return 1;
         }
         glog->status = tkn;
         break;
         /* size of response in bytes - excluding HTTP headers */
       case 'b':
         if (glog->resp_size)
           return 1;
         tkn = parse_string (&str, p[1], 1);
         if (tkn == NULL)
           return 1;
         bandw = strtol (tkn, &bEnd, 10);
         if (tkn == bEnd || *bEnd != '\0' || errno == ERANGE)
           bandw = 0;
         glog->resp_size = bandw;
         conf.bandwidth = 1;
         free (tkn);
         break;
         /* referrer */
       case 'R':
         if (glog->ref)
           return 1;
         tkn = parse_string (&str, p[1], 1);
         if (tkn == NULL)
           tkn = alloc_string ("-");
         if (tkn != NULL && *tkn == '\0') {
           free (tkn);
           tkn = alloc_string ("-");
         }
         if (strcmp (tkn, "-") != 0)
           extract_referer_site (tkn, glog->site);
         glog->ref = tkn;
         break;
         /* user agent */
       case 'u':
         if (glog->agent)
           return 1;
         tkn = parse_string (&str, p[1], 1);
         if (tkn != NULL && *tkn != '\0') {
           /* Make sure the user agent is decoded (i.e.: CloudFront)
            * and replace all '+' with ' ' (i.e.: w3c) */
           glog->agent = char_replace (decode_url (tkn), '+', ' ');
           free (tkn);
           break;
         } else if (tkn != NULL && *tkn == '\0') {
           free (tkn);
           tkn = alloc_string ("-");
         }
         /* must be null */
         else {
           tkn = alloc_string ("-");
         }
         glog->agent = tkn;
         break;
         /* time taken to serve the request, in seconds */
       case 'T':
         if (glog->serve_time)
           return 1;
         /* ignore seconds if we have microseconds */
         if (strstr (fmt, "%D") != NULL)
           break;

         tkn = parse_string (&str, p[1], 1);
         if (tkn == NULL)
           return 1;
         if (strchr (tkn, '.') != NULL)
           serve_secs = strtod (tkn, &bEnd);
         else
           serve_secs = strtoull (tkn, &bEnd, 10);

         if (tkn == bEnd || *bEnd != '\0' || errno == ERANGE)
           serve_secs = 0;
         /* convert it to microseconds */
         if (serve_secs > 0)
           glog->serve_time = serve_secs * SECS;
         else
           glog->serve_time = 0;
         conf.serve_usecs = 1;
         free (tkn);
         break;
         /* time taken to serve the request, in microseconds */
       case 'D':
         if (glog->serve_time)
           return 1;
         tkn = parse_string (&str, p[1], 1);
         if (tkn == NULL)
           return 1;
         serve_time = strtoull (tkn, &bEnd, 10);
         if (tkn == bEnd || *bEnd != '\0' || errno == ERANGE)
           serve_time = 0;
         glog->serve_time = serve_time;
         conf.serve_usecs = 1;
         free (tkn);
         break;
         /* everything else skip it */
       default:
         if ((pch = strchr (str, p[1])) != NULL)
           str += pch - str;
      }
      if ((str == NULL) || (*str == '\0'))
        return 0;
      special = 0;
    } else if (special && isspace (p[0])) {
      return 1;
    } else
      str++;
  }
  return 0;
}
コード例 #6
0
ファイル: httpd.c プロジェクト: xinbot/6.033
static void
process_client(int fd)
{
    register int ebp __asm__ ("ebp");
    char reqpath[256];
    char pn[1024];
    struct stat st;
    const char *errmsg;

    fprintf(stderr, "\nreqpath = %p\nebp     = 0x%x\nunlink  = %p\n",
            reqpath, ebp, unlink);

    cur_f = fdopen(fd, "w+");

    errmsg = parse_req(reqpath);
    if (errmsg) {
        http_err(500, "Error parsing request: %s", errmsg);
        return;
    }

    sprintf(pn, "%s/%s", cur_dir, reqpath);

    if (stat(pn, &st) < 0) {
        http_err(404, "File not found or not accessible: %s", pn);
        return;
    }

    if (S_ISDIR(st.st_mode)) {
        /* For directories, use index.html in that directory */
        strcat(pn, "/index.html");
        if (stat(pn, &st) < 0) {
            http_err(404, "File not found or not accessible: %s", pn);
            return;
        }
    }

    if (S_ISREG(st.st_mode) && (st.st_mode & S_IXUSR)) {
        /* executable bits -- run as CGI script */
        fflush(cur_f);

        signal(SIGCHLD, SIG_DFL);
        int pid = fork();
        if (pid < 0) {
            http_err(500, "Cannot fork: %s", strerror(errno));
            return;
        }

        if (pid == 0) {
            /* Child process */
            int nullfd = open("/dev/null", O_RDONLY);
            dup2(nullfd, 0);
            dup2(fileno(cur_f), 1);
            dup2(fileno(cur_f), 2);

            close(nullfd);
            fclose(cur_f);

            execl(pn, pn, 0);
            err(1, "execl");
        }

        int status;
        waitpid(pid, &status, 0);
        fclose(cur_f);
    } else {
        /* Non-executable: serve contents */
        int fd = open(pn, O_RDONLY);
        if (fd < 0) {
            http_err(500, "Cannot open %s: %s", pn, strerror(errno));
            return;
        }

        fprintf(cur_f, "HTTP/1.0 200 OK\r\n");
        fprintf(cur_f, "Content-Type: text/html\r\n");
        fprintf(cur_f, "\r\n");

        for (;;) {
            char readbuf[1024];
            int cc = read(fd, &readbuf[0], sizeof(readbuf));
            if (cc <= 0)
                break;

            fwrite(&readbuf[0], 1, cc, cur_f);
        }

        close(fd);
        fclose(cur_f);
    }
}
コード例 #7
0
ファイル: MasterControl.c プロジェクト: dreamshader/Robot
/*
 * *************************************************************
 * main of connection server
 * *************************************************************
*/
int main(int argc, char *argv[])
{

   srv_opts_t run_options;
   int RequestCmd;
   void *res;


   initialize( &run_options );
   get_arguments ( argc, argv, &run_options );

   if( run_options.run_as_daemon )
   {
      if( (run_options.error_code = start_daemon( &run_options )) != E_NOERR )
      {
         do_log(&run_options, LOG_CRITERROR);
         cleanup_and_exit( &run_options );
      }
   }

   if( (run_options.error_code = make_socket( &run_options )) != E_NOERR )
   {
      do_log(&run_options, LOG_CRITERROR);
      cleanup_and_exit( &run_options );
   }


   if( prepareThreads( &run_options ) != E_NOERR )
   {
         do_log(&run_options, LOG_CRITERROR);
         cleanup_and_exit( &run_options );
   }
   else
   {
      if( (run_options.error_code = ctl_create_thread( &run_options, MAINCTL_THREAD_NUM)) != E_NOERR )
      {
         do_log(&run_options, LOG_CRITERROR);
         cleanup_and_exit( &run_options );
      }
   }

// while no exit request
   RequestCmd = 0;
   do
   {

      if( (run_options.error_code = wait_client( &run_options )) != E_NOERR )
      {
         do_log(&run_options, LOG_CRITERROR);
         cleanup_and_exit( &run_options );
      }
      else
      {
         if( (run_options.error_code = get_request( &run_options )) != E_NOERR )
         {
            do_log(&run_options, LOG_CRITERROR);
            cleanup_and_exit( &run_options );
         }
         else
         {
            switch( RequestCmd =  parse_req( run_options.p_rcv_buf ) )
            {
               case CTLREQ_EXIT:
                  sprintf(run_options.p_rsp_buf, "Assume exit: %s\n", run_options.p_rcv_buf );
                  send_response(&run_options);
                  close(run_options.cli_socket);
                  break;
               case CTLREQ_API:
                  sprintf(run_options.p_rsp_buf, "Assume API: %s\n", run_options.p_rcv_buf );
                  send_response(&run_options);
                  close(run_options.cli_socket);
                  break;
               default:
                  // assume telnet request
                  sprintf(run_options.p_rsp_buf, "Assume telnet: %s\n", run_options.p_rcv_buf );
                  send_response(&run_options);
                  close(run_options.cli_socket);
                  break;
            }
         }
      }

   } while( RequestCmd != CTLREQ_EXIT );

   if( pthread_attr_destroy(&run_options.tattr) != 0 )
   {
      run_options.error_code = E_FAIL;
      run_options.sys_errno = errno;
      sprintf( run_options.logbuffer, "destroy attr failed, errno was %d\n", errno );
      do_log(&run_options, LOG_WARN);
   }

   run_options.mainctl_run = 0;
   run_options.api_run = 0;
   run_options.telnet_run = 0;

   if( run_options.tinfo[MAINCTL_THREAD_NUM].thread_id >= 0 )
   {
      pthread_join(run_options.tinfo[MAINCTL_THREAD_NUM].thread_id, &res);
   }

   if( run_options.tinfo[API_THREAD_NUM].thread_id >= 0 )
   {
      pthread_join(run_options.tinfo[API_THREAD_NUM].thread_id, &res);
   }

   if( run_options.tinfo[TELNET_THREAD_NUM].thread_id >= 0 )
   {
      pthread_join(run_options.tinfo[TELNET_THREAD_NUM].thread_id, &res);
   }

   pthread_cancel(run_options.tinfo[MAINCTL_THREAD_NUM].thread_id);
   pthread_cancel(run_options.tinfo[API_THREAD_NUM].thread_id);
   pthread_cancel(run_options.tinfo[TELNET_THREAD_NUM].thread_id);

   // and die
   cleanup_and_exit( &run_options );
}