Пример #1
0
int   LG::Terminate (int rc)
{
      double dsec;
		int    min, sec, thou, i;
		char   num[14] = "             ";

		if (n_states > org_states) org_states = n_states;
		if (n_prods > max_n_prods) max_n_prods = n_prods; // brute force fix.
		else max_n_prods++;										  // brute force fix again.
		if (n_prods < 0) n_prods = 0; // In case of early syntax error.

	  	if (optn[LG_VERBOSE] > 1)
		{
         optncount[MAX_SYM]   = n_symbs;
         optncount[MAX_PRO]   = n_prods;
         optncount[MAX_TAIL]  = n_tails;
         optncount[MAX_EBNF]  = amt_space;
         optncount[MAX_STA]   = org_states;
         optncount[MAX_FIN]   = n_finals;
         optncount[MAX_KER]   = n_kernels;
         optncount[MAX_NTT]   = n_nonttran;
         optncount[MAX_TT]    = n_termtran;
         optncount[MAX_TTA]   = n_ttas;
         optncount[MAX_LB]    = n_lookbacks;
         optncount[MAX_LA]    = n_lookah;
         optncount[MAX_INC]   = n_includes;
         optncount[MAX_CH]    = max_child_usage;
         optncount[MAX_ND]    = 0;
			for (i = 0; *MAOption[i].name != 0; i++)
			{
				prt_num (MAOption[i].desc, optncount[MAOption[i].numb], MAOption[i].name, optn[MAOption[i].numb]);
			}
	  	   prt_logonly ("\n");
		}

		char* es  = "s";
		char* ws  = "s";

		if (n_errors    == 1) es  = "";
		if (n_warnings  == 1) ws  = "";										   

      time2 = clock ();
      dsec  = (double)(time2-time1) / CLOCKS_PER_SEC;
      min   =  dsec/60;
      sec   =  dsec-min*60;
      thou  = (dsec-min*60-sec)*1000;
      int x = memory_max/1024/1024;
      int y = memory_max/1024 - 1024*x;

		prt_log ("%1d min %1d.%03d sec, %d.%03d MB, %d warning%s, %d error%s.\n\n", 
		min, sec, thou, x, y, n_warnings, ws, n_errors, es);

		close_con ();
		close_grm ();
		close_sta ();
		close_lst ();

      if (n_errors > 0) quit (n_errors);
		return 0;
}
Пример #2
0
int   PG::Terminate (int rc)
{
      double dsec;
		int i, min, sec, thou;

      inputt ();

      if (optn[PG_VERBOSE] > 1)
      {
         optncount[MAX_SYM]   = Symtab::n_symbols;
         optncount[MAX_PRO]   = N_prods;
         optncount[MAX_TAIL]  = N_tails;
         optncount[MAX_EBNF]  = 0;
         optncount[MAX_STA]   = org_states;
         optncount[MAX_FIN]   = n_finals;
         optncount[MAX_KER]   = n_kernels;
         optncount[MAX_NTT]   = n_nttran;
         optncount[MAX_TT]    = n_ttran;
         optncount[MAX_TTA]   = n_ttas;
         optncount[MAX_LB]    = n_lookbacks;
         optncount[MAX_LA]    = n_lookah;
         optncount[MAX_INC]   = n_includes;
         optncount[MAX_CH]    = max_child_usage;
         optncount[MAX_ND]    = n_nditems;
			for (i = 0; *MAOption[i].name != 0; i++)
			{
				prt_num (MAOption[i].desc, optncount[MAOption[i].numb], MAOption[i].name, optn[MAOption[i].numb]);
			}
	  	   prt_logonly ("\n");
      }
		PGParser::terminate ();

		char* es = "s";
		char* ws = "s";
		char* cs = "s";
		if (n_errors    == 1) es = "";
		if (n_warnings  == 1) ws = "";
		if (c_states    == 1) cs = "";

      time2 = clock ();
      dsec  = (double)(time2-time1) / CLOCKS_PER_SEC;
      min   = dsec/60;
      sec   = dsec-min*60;
      thou  = (dsec-min*60-sec)*1000;
      int x = memory_max/1024/1024;
      int y = memory_max/1024 - 1024*x;

		prt_log ("%1d min %1d.%03d sec, %d.%03d MB, %d warning%s, %d error%s.\n\n", 
		min, sec, thou, x, y, n_warnings, ws, n_errors, es);

      close_con ();
		close_grm ();
	//	close_log ();
		close_sta ();
		close_lst ();

      if (n_errors > 0) quit (n_errors);
		return 0;
}
Пример #3
0
/*
 * Get version number
 */
static gint get_version(QQInfo *info)
{
	int ret = NO_ERR;
	Request *req = request_new();
	Response *rps = NULL;
	gint res = 0;
	request_set_method(req, "GET");
	request_set_version(req, "HTTP/1.1");
	request_set_uri(req, VERPATH);
	request_set_default_headers(req);
	request_add_header(req, "Host", LOGINPAGEHOST);

	Connection *con = connect_to_host(LOGINPAGEHOST, 80);
	if(con == NULL){
		g_warning("Can NOT connect to server!(%s, %d)"
				, __FILE__, __LINE__);
		request_del(req);
		return NETWORK_ERR;
	}
	send_request(con, req);
	res = rcv_response(con, &rps);
	close_con(con);
	connection_free(con);
	const gchar *retstatus = rps -> status -> str;
	if (-1 == res || !rps) {
		g_warning("Null point access (%s, %d)\n", __FILE__, __LINE__);
		ret = -1;
		goto error;
	}
	if(g_strstr_len(retstatus, -1, "200") == NULL){
		g_warning("Server status %s (%s, %d)", retstatus
				, __FILE__, __LINE__);
		ret = NETWORK_ERR;
		goto error;
	}
	
	gchar *lb, *rb;
	gchar *ms = rps -> msg -> str;
	lb = g_strstr_len(ms, -1, "(");
	if(lb == NULL){
		g_warning("Get version  error!! %s (%s, %d)",rps -> msg -> str
                                        , __FILE__, __LINE__);
		ret = NETWORK_ERR;
		goto error;
	}
	++lb;
	rb = g_strstr_len(ms, -1, ")");
	*rb = '\0';
	info -> version = g_string_new(lb);
	g_debug("Version: %s(%s, %d)", lb, __FILE__, __LINE__);
error:
	request_del(req);
	response_del(rps);
	return ret;
}
Пример #4
0
static gint do_send_buddy_msg(QQInfo *info, QQSendMsg *msg, GError **err)
{
    GString *uin = msg -> to_uin;

    gint ret_code = 0;
	gint res = 0;
    gchar params[3000];
    g_debug("Send msg to %s!(%s, %d)", uin -> str, __FILE__, __LINE__);

    Request *req = request_new();
    Response *rps = NULL;
    request_set_method(req, "POST");
    request_set_version(req, "HTTP/1.1");
    request_set_uri(req, MSGFRIPATH);
    request_set_default_headers(req);
    request_add_header(req, "Host", MSGHOST);
    request_add_header(req, "Cookie", info -> cookie -> str);
    request_add_header(req, "Origin", "http://d.web2.qq.com");
    request_add_header(req, "Content-Type", 
            "application/x-www-form-urlencoded");
    request_add_header(req, "Referer"
            , "http://"MSGHOST"/proxy.html?v=20110331002&callback=2");
    GString *content;
    content = qq_sendmsg_contents_tostring(msg);
    g_snprintf(params, 3000, "r={\"to\":%s,\"face\":%s,"
                "%s,\"msg_id\":%s,"
                "\"clientid\":\"%s\",\"psessionid\":\"%s\"}"
                , uin -> str, msg -> face -> str
                , content -> str
                , msg -> msg_id -> str
                , info -> clientid -> str
                , info -> psessionid -> str);
    g_string_free(content, TRUE);
    gchar *euri = g_uri_escape_string(params, "=", FALSE);
    request_append_msg(req, euri, strlen(euri));
    g_free(euri);

    g_snprintf(params, 3000, "%u", (unsigned int)strlen(req -> msg -> str));
    request_add_header(req, "Content-Length", params);

    Connection *con = connect_to_host(MSGHOST, 80);
    if(con == NULL){
        g_warning("Can NOT connect to server!(%s, %d)"
                , __FILE__, __LINE__);
        request_del(req);
        return -1;
    }

    send_request(con, req);
    res = rcv_response(con, &rps);
    close_con(con);
    connection_free(con);

	if (-1 == res || !rps) {
		g_warning("Null point access (%s, %d)\n", __FILE__, __LINE__);
		ret_code = -1;
		goto error;
	}
    const gchar *retstatus = rps -> status -> str;
    json_t *json = NULL;
    if(g_strstr_len(retstatus, -1, "200") == NULL){
        /*
         * Maybe some error occured.
         */
        g_warning("Resoponse status is NOT 200, but %s (%s, %d)"
                , retstatus, __FILE__, __LINE__);
        ret_code = -1;
        goto error;
    }

    switch(json_parse_document(&json, rps -> msg -> str))
    {
    case JSON_OK:
        break;
    default:
        g_warning("json_parser_document: syntax error. (%s, %d)"
                , __FILE__, __LINE__);
    }

    json_t *val = json_find_first_label_all(json, "result");
    if(val != NULL){
        val = val -> child;
        if(g_strstr_len(val -> text, -1, "ok") == NULL){
            g_warning("Server return error. %s (%s, %d)"
                    , val -> text, __FILE__, __LINE__);
        }
    }else{
        g_warning("Server return: (%s, %d)%s", __FILE__, __LINE__
                , rps -> msg -> str);
    }
    json_free_value(&json);
error:
    request_del(req);
    response_del(rps);
    return ret_code;
}
Пример #5
0
static void memcached_io_cb(liEventBase *watcher, int events) {
	liMemcachedCon *con = LI_CONTAINER_OF(li_event_io_from(watcher), liMemcachedCon, con_watcher);

	if (1 == g_atomic_int_get(&con->refcount) && li_event_active(&con->con_watcher)) {
		memcached_stop_io(con);
		return;
	}

	if (-1 == con->fd) {
		memcached_connect(con);
		return;
	}

	li_memcached_con_acquire(con); /* make sure con isn't freed in the middle of something */

	if (events & LI_EV_WRITE) {
		int i;
		ssize_t written, len;
		gchar *data;
		send_item *si;

		si = g_queue_peek_head(&con->out);

		for (i = 0; si && (i < 10); i++) { /* don't send more than 10 chunks */
			data = si->buf->addr + si->pos;
			len = si->len;
			written = write(li_event_io_fd(&con->con_watcher), data, len);
			if (written < 0) {
				switch (errno) {
				case EINTR:
					continue;
				case EAGAIN:
#if EWOULDBLOCK != EAGAIN
				case EWOULDBLOCK:
#endif
					goto write_eagain;
				default: /* Fatal error, connection has to be closed */
					g_clear_error(&con->err);
					g_set_error(&con->err, LI_MEMCACHED_ERROR, LI_MEMCACHED_CONNECTION, "Couldn't write socket '%s': %s",
						li_sockaddr_to_string(con->addr, con->tmpstr, TRUE)->str,
						g_strerror(errno));
					close_con(con);
					goto out;
				}
			} else {
				si->pos += written;
				si->len -= written;
				if (0 == si->len) {
					send_queue_item_free(si);
					g_queue_pop_head(&con->out);
					si = g_queue_peek_head(&con->out);
				}
			}
		}

write_eagain:
		send_queue_clean(&con->out);
	}

	if (events & LI_EV_READ) {
		do {
			handle_read(con);
		} while (con->remaining && con->remaining->used > 0);
	}

out:
	memcached_update_io(con);
	li_memcached_con_release(con);
}
Пример #6
0
static void handle_read(liMemcachedCon *con) {
	int_request *cur;

	if (NULL == (cur = con->cur_req)) {
		cur = con->cur_req = g_queue_peek_head(&con->req_queue);

		if (NULL == cur) {
			/* unexpected read event, perhaps just eof */
			g_clear_error(&con->err);
			g_set_error(&con->err, LI_MEMCACHED_ERROR, LI_MEMCACHED_CONNECTION, "Connection closed: unexpected read event");
			close_con(con);
			return;
		}

		reset_item(&con->curitem);
		if (con->data) con->data->used = 0;
		if (con->line) con->line->used = 0;

		/* init read state */
		switch (cur->type) {
		case REQ_GET:
			con->get_data_size = 0;
			con->get_have_header = FALSE;
			break;
		case REQ_SET:
			break;
		}
	}

	switch (cur->type) {
	case REQ_GET:
		if (!con->get_have_header) {
			char *pos, *next;

			/* wait for header line */
			if (!try_read_line(con)) return;

			con->get_have_header = TRUE;

			if (3 == con->line->used && 0 == memcmp("END", con->line->addr, 3)) {
				/* key not found */
				if (cur->req.callback) {
					cur->req.callback(&cur->req, LI_MEMCACHED_NOT_FOUND, NULL, NULL);
				}
				con->cur_req = NULL;
				free_request(con, cur);
				return;
			}

			/* con->line is 0 terminated */

			if (0 != strncmp("VALUE ", con->line->addr, 6)) {
				g_clear_error(&con->err);
				g_set_error(&con->err, LI_MEMCACHED_ERROR, LI_MEMCACHED_CONNECTION, "Protocol error: Unexpected response for GET: '%s'", con->line->addr);
				close_con(con);
				return;
			}

			/* VALUE <key> <flags> <bytes> [<cas unique>]\r\n */

			/* <key> */
			pos = con->line->addr + 6;
			next = strchr(pos, ' ');
			if (NULL == next) goto req_get_header_error;

			con->curitem.key = g_string_new_len(pos, next - pos);

			/* <flags> */
			pos = next + 1;
			con->curitem.flags = strtoul(pos, &next, 10);
			if (' ' != *next || pos == next) goto req_get_header_error;

			/* <bytes> */
			pos = next + 1;
			con->get_data_size = g_ascii_strtoll(pos, &next, 10);
			if (pos == next) goto req_get_header_error;

			/* [<cas unique>] */
			if (' ' == *next) {
				pos = next + 1;
				con->curitem.cas = g_ascii_strtoll(pos, &next, 10);
				if (pos == next) goto req_get_header_error;
			}

			if ('\0' != *next) {
				goto req_get_header_error;
			}

			con->line->used = 0;

			goto req_get_header_done;

req_get_header_error:
			g_clear_error(&con->err);
			g_set_error(&con->err, LI_MEMCACHED_ERROR, LI_MEMCACHED_CONNECTION, "Protocol error: Couldn't parse VALUE respone: '%s'", con->line->addr);
			close_con(con);
			return;

req_get_header_done: ;
		}
		if (NULL == con->data || con->data->used < con->get_data_size) {
			/* wait for data */
			if (!try_read_data(con, con->get_data_size)) return;
		}
		/* wait for END\r\n */
		if (!try_read_line(con)) return;

		if (3 == con->line->used && 0 == memcmp("END", con->line->addr, 3)) {
			/* Move data to item */
			con->curitem.data = con->data;
			con->data = NULL;
			if (cur->req.callback) {
				cur->req.callback(&cur->req, LI_MEMCACHED_OK, &con->curitem, NULL);
			}
			reset_item(&con->curitem);
		} else {
			g_clear_error(&con->err);
			g_set_error(&con->err, LI_MEMCACHED_ERROR, LI_MEMCACHED_CONNECTION, "Protocol error: GET response not terminated with END (got '%s')", con->line->addr);
			close_con(con);
			return;
		}

		con->cur_req = NULL;
		free_request(con, cur);
		return;

	case REQ_SET:
		if (!try_read_line(con)) return;

		if (6 == con->line->used && 0 == memcmp("STORED", con->line->addr, 6)) {
			if (cur->req.callback) {
				cur->req.callback(&cur->req, LI_MEMCACHED_OK, NULL, NULL);
			}
		} else {
			g_clear_error(&con->err);
			g_set_error(&con->err, LI_MEMCACHED_ERROR, LI_MEMCACHED_CONNECTION, "Protocol error: unepxected SET response: '%s'", con->line->addr);
			close_con(con);
			return;
		}

		con->cur_req = NULL;
		free_request(con, cur);
		return;
	}
}
Пример #7
0
static gboolean try_read_data(liMemcachedCon *con, gsize datalen) {
	liBuffer *data;
	ssize_t r;

	datalen += 2; /* \r\n */

	/* if we have remaining data use it for a new line */
	if ((!con->data || con->data->used == 0) && con->remaining && con->remaining->used > 0) {
		liBuffer *tmp = con->remaining; con->remaining = con->data; con->data = tmp;
	}

	if (!con->data) con->data = li_buffer_new_slice(MAX(BUFFER_CHUNK_SIZE, datalen));

	if (con->data->alloc_size < datalen) {
		data = li_buffer_new_slice(MAX(BUFFER_CHUNK_SIZE, datalen));
		memcpy(data->addr, con->data->addr, (data->used = con->data->used));
		li_buffer_release(con->data);
		con->data = data;
	}

	g_assert(NULL == con->remaining || 0 == con->remaining->used); /* there shouldn't be any data in remaining while we fill con->data */

	data = con->data;

	if (data->used < datalen) {
		/* read more data */
		r = net_read(con->fd, data->addr + data->used, data->alloc_size - data->used);
		if (r == 0) {
			/* EOF */
			g_clear_error(&con->err);
			g_set_error(&con->err, LI_MEMCACHED_ERROR, LI_MEMCACHED_CONNECTION, "Connection closed by peer");
			close_con(con);
			return FALSE;
		} else if (r < 0) {
			switch (errno) {
			case EAGAIN:
#if EWOULDBLOCK != EAGAIN
			case EWOULDBLOCK:
#endif
				break;
			default:
				g_clear_error(&con->err);
				g_set_error(&con->err, LI_MEMCACHED_ERROR, LI_MEMCACHED_CONNECTION, "Connection closed: %s", g_strerror(errno));
				close_con(con);
				break;
			}
			return FALSE;
		}

		data->used += r;
	}

	if (data->used >= datalen) {
		if (data->addr[datalen-2] != '\r' || data->addr[datalen-1] != '\n') {
			/* Protocol error: data block not terminated with \r\n */
			g_clear_error(&con->err);
			g_set_error(&con->err, LI_MEMCACHED_ERROR, LI_MEMCACHED_CONNECTION, "Protocol error: data block not terminated with \\r\\n");
			close_con(con);
			return FALSE;
		}
		add_remaining(con, data->addr + datalen, data->used - datalen);
		data->used = datalen - 2;
		data->addr[datalen-2] = '\0';
		return TRUE;
	}

	return FALSE;
}
Пример #8
0
static gboolean try_read_line(liMemcachedCon *con) {
	liBuffer *line;
	ssize_t r;

	if (!con->line) con->line = li_buffer_new_slice(BUFFER_CHUNK_SIZE);
	if (!con->remaining) con->remaining = li_buffer_new_slice(BUFFER_CHUNK_SIZE);

	/* if we have remaining data use it for a new line */
	if (con->line->used == 0 && con->remaining->used > 0) {
		liBuffer *tmp = con->remaining; con->remaining = con->line; con->line = tmp;
	}

	g_assert(NULL == con->remaining || 0 == con->remaining->used); /* there shouldn't be any data in remaining while we fill con->line */

	line = con->line;

	if (line->used > 0) {
		/* search for \r\n */
		gchar *addr = line->addr;
		gsize i, len = line->used;
		for (i = 0; i < len; i++) {
			if (addr[i] == '\r') {
				i++;
				if (i < len && addr[i] == '\n') {
					add_remaining(con, addr + i+1, len - (i+1));
					line->used = i-1;
					line->addr[i-1] = '\0';
					return TRUE;
				}
			}
		}
	}

	if (line->used > 1024) {
		/* Protocol error: we don't parse line longer than 1024 */
		g_clear_error(&con->err);
		g_set_error(&con->err, LI_MEMCACHED_ERROR, LI_MEMCACHED_CONNECTION, "Protocol error: line too long");
		close_con(con);
		return FALSE;
	}

	/* need more data */
	r = net_read(con->fd, line->addr + line->used, line->alloc_size - line->used);
	if (r == 0) {
		/* EOF */
		g_clear_error(&con->err);
		g_set_error(&con->err, LI_MEMCACHED_ERROR, LI_MEMCACHED_CONNECTION, "Connection closed by peer");
		close_con(con);
		return FALSE;
	} else if (r < 0) {
		switch (errno) {
		case EAGAIN:
#if EWOULDBLOCK != EAGAIN
		case EWOULDBLOCK:
#endif
			break;
		default:
			g_clear_error(&con->err);
			g_set_error(&con->err, LI_MEMCACHED_ERROR, LI_MEMCACHED_CONNECTION, "Connection closed: %s", g_strerror(errno));
			close_con(con);
			break;
		}
		return FALSE;
	}

	line->used += r;

	if (line->used > 0) {
		/* search for \r\n */
		gchar *addr = line->addr;
		gsize i, len = line->used;
		for (i = 0; i < len; i++) {
			if (addr[i] == '\r') {
				i++;
				if (i < len && addr[i] == '\n') {
					add_remaining(con, addr + i+1, len - (i+1));
					line->used = i-1;
					line->addr[i-1] = '\0';
					return TRUE;
				}
			}
		}
	}

	return FALSE;
}
Пример #9
0
static gint do_logout(QQInfo *info, GError **err)
{
    gint ret_code = 0;
	gint res = 0;
	g_debug("Logout... (%s, %d)", __FILE__, __LINE__);
	if(info -> psessionid == NULL || info -> psessionid -> len <= 0){
		g_warning("Need psessionid !!(%s, %d)", __FILE__, __LINE__);
		return -1;
	}

	gchar params[300];
	Request *req = request_new();
	Response *rps = NULL;
	request_set_method(req, "GET");
	request_set_version(req, "HTTP/1.1");
	g_sprintf(params, LOGOUTPATH"?clientid=%s&psessionid=%s&t=%ld"
			, info -> clientid -> str
			, info -> psessionid -> str, get_now_millisecond());
	request_set_uri(req, params);
	request_set_default_headers(req);
	request_add_header(req, "Host", LOGOUTHOST);
	request_add_header(req, "Cookie", info -> cookie -> str);
	request_add_header(req, "Referer", REFERER);

	Connection *con = connect_to_host(LOGOUTHOST, 80);
	if(con == NULL){
		g_warning("Can NOT connect to server!(%s, %d)"
				, __FILE__, __LINE__);
		request_del(req);
		return -1;
	}

	send_request(con, req);
	res = rcv_response(con, &rps);
	close_con(con);
	connection_free(con);

	if (-1 == res || !rps) {
		g_warning("Null point access (%s, %d)\n", __FILE__, __LINE__);
		ret_code = -1;
		goto error;
	}
	const gchar *retstatus = rps -> status -> str;
	if(g_strstr_len(retstatus, -1, "200") == NULL){
		/*
		 * Maybe some error occured.
		 */
		g_warning("Resoponse status is NOT 200, but %s (%s, %d)"
				, retstatus, __FILE__, __LINE__);
        ret_code = -1;
		goto error;
	}

	json_t *json = NULL;
	switch(json_parse_document(&json, rps -> msg -> str))
	{
	case JSON_OK:
		break;
	default:
		g_warning("json_parser_document: syntax error. (%s, %d)"
				, __FILE__, __LINE__);
        ret_code = -1;
		goto error;
	}

	json_t *retcode, *result;
	retcode = json_find_first_label_all(json, "retcode");
	result = json_find_first_label_all(json, "result");
	if(retcode != NULL && result != NULL){
		if(g_strstr_len(result -> child -> text, -1, "ok") != NULL){
			g_debug("Logout ok!(%s, %d)", __FILE__, __LINE__);
            ret_code = 0;
		}
	}else{
		g_debug("(%s, %d)%s", __FILE__, __LINE__, rps -> msg -> str);
	}
	
	json_free_value(&json);
error:
	request_del(req);
	response_del(rps);
	return ret_code;
}
Пример #10
0
/*
 * Get the psessionid.
 *
 * This function is the last step of loginning
 */
static int get_psessionid(QQInfo *info)
{
	int ret = NO_ERR;
	gint res = 0;
	if(info -> ptwebqq == NULL || info -> ptwebqq -> len <= 0){
		g_warning("Need ptwebqq!!(%s, %d)", __FILE__, __LINE__);
		return PARAMETER_ERR;
	}
	
	Request *req = request_new();
	Response *rps = NULL;
	request_set_method(req, "POST");
	request_set_version(req, "HTTP/1.1");
	request_set_uri(req, PSIDPATH);
	request_set_default_headers(req);
	request_add_header(req, "Host", PSIDHOST);
	request_add_header(req, "Cookie2", "$Version=1");
	request_add_header(req, "Referer"
			, "http://d.web2.qq.com/proxy.html?v=20101025002");
	GString *clientid = generate_clientid();
	info -> clientid = clientid;
	g_debug("clientid: %s", clientid -> str);

	gchar* msg = g_malloc(500);
	g_snprintf(msg, 500, "{\"status\":\"%s\",\"ptwebqq\":\"%s\","
			"\"passwd_sig\":""\"\",\"clientid\":\"%s\""
			", \"psessionid\":null}"
			, info -> me -> status -> str, info -> ptwebqq -> str
			, clientid -> str);

	gchar *escape = g_uri_escape_string(msg, NULL, FALSE);
	g_snprintf(msg, 500, "r=%s", escape);
	g_free(escape);

	request_append_msg(req, msg, strlen(msg));
	gchar cl[10];
	g_sprintf(cl, "%u", (unsigned int)strlen(msg));
	request_add_header(req, "Content-Length", cl);
	request_add_header(req, "Content-Type"
			, "application/x-www-form-urlencoded");
	g_free(msg);

	gchar *cookie = g_malloc(2000);
	gint idx = 0;
	if(info -> ptvfsession != NULL){
		idx += g_snprintf(cookie + idx, 2000 - idx, "ptvfsession=%s; "
				, info -> ptvfsession -> str);
	}
	idx += g_snprintf(cookie + idx, 2000 - idx, "%s"
			, info -> cookie -> str);
	request_add_header(req, "Cookie", cookie);
	g_free(cookie);

	Connection *con = connect_to_host(PSIDHOST, 80);
	if(con == NULL){
		g_warning("Can NOT connect to server!(%s, %d)"
				, __FILE__, __LINE__);
		request_del(req);
		return NETWORK_ERR;
	}

	send_request(con, req);
	res = rcv_response(con, &rps);

	if (-1 == res || !rps) {
		g_warning("Null point access (%s, %d)\n", __FILE__, __LINE__);
		ret = -1;
		goto error;
	}
	const gchar *retstatus = rps -> status -> str;
	if(g_strstr_len(retstatus, -1, "200") == NULL){
		g_warning("Server status %s (%s, %d)", retstatus
				, __FILE__, __LINE__);
		ret = NETWORK_ERR;
		goto error;
	}

	json_t *json = NULL;
	switch(json_parse_document(&json, rps -> msg -> str))
	{
	case JSON_OK:
		break;
	default:
		g_warning("json_parser_document: syntax error. (%s, %d)"
				, __FILE__, __LINE__);
		ret = NETWORK_ERR;
		goto error;
	}

	json_t *val;
	val = json_find_first_label_all(json, "retcode");
	if(val -> child -> text[0] != '0'){
		g_warning("Server return code %s(%s, %d)", val -> child -> text
				, __FILE__, __LINE__);
		ret = NETWORK_ERR;
		goto error;
	}
	val = json_find_first_label_all(json, "seskey");
	if(val != NULL){
		g_debug("seskey: %s (%s, %d)", val -> child -> text
				, __FILE__, __LINE__);
		info -> seskey = g_string_new(val -> child -> text);
	}
	val = json_find_first_label_all(json, "cip");
	if(val != NULL){
		info -> cip = g_string_new(val -> child -> text);
	}
	val = json_find_first_label_all(json, "index");
	if(val != NULL){
		info -> index = g_string_new(val -> child -> text);
	}
	val = json_find_first_label_all(json, "port");
	if(val != NULL){
		info -> port = g_string_new(val -> child -> text);
	}
	val = json_find_first_label_all(json, "status");
	{
		g_debug("status: %s (%s, %d)", val -> child -> text
				, __FILE__, __LINE__);
	}
	val = json_find_first_label_all(json, "vfwebqq");
	if(val != NULL){
		g_debug("vfwebqq: %s (%s, %d)", val -> child -> text
				, __FILE__, __LINE__);
		info -> vfwebqq = g_string_new(val -> child -> text);
	}
	val = json_find_first_label_all(json, "psessionid");
	if(val != NULL){
		g_debug("psessionid: %s (%s, %d)", val -> child -> text
				, __FILE__, __LINE__);
		info -> psessionid = g_string_new(val -> child -> text);
	}else{
		g_debug("Can not find pesssionid!(%s, %d): %s"
				, __FILE__, __LINE__, rps -> msg -> str);
	}

error:
	json_free_value(&json);	
	close_con(con);
	connection_free(con);
	request_del(req);
	response_del(rps);
	return ret;
}
Пример #11
0
/*
 * Check if we need input the verify code.
 * The result is stored in info.
 *
 * return -1 if error ocurs or return 0
 */
static gint check_verify_code(QQInfo *info)
{
	g_debug("Check veriry code...(%s, %d)", __FILE__, __LINE__);
	gint ret = 0;
	gchar params[300];

	Request *req = request_new();
	Response *rps = NULL;
	int res = 0;
	request_set_method(req, "GET");
	request_set_version(req, "HTTP/1.1");
	g_sprintf(params, VCCHECKPATH"?uin=%s&appid="APPID"&r=%.16f"
			, info -> me -> uin -> str, g_random_double());
	request_set_uri(req, params);
	request_set_default_headers(req);
	request_add_header(req, "Host", LOGINHOST);

	Connection *con = connect_to_host(LOGINHOST, 80);

	send_request(con, req);
	res = rcv_response(con, &rps);
	close_con(con);
	connection_free(con);

	if (-1 == res || !rps) {
		g_warning("Null point access (%s, %d)\n", __FILE__, __LINE__);
		ret = -1;
		goto error;
	}
	const gchar *retstatus = rps -> status -> str;
	if(g_strstr_len(retstatus, -1, "200") == NULL){
		g_warning("Server status %s (%s, %d)", retstatus
				, __FILE__, __LINE__);
		ret = NETWORK_ERR;
		goto error;
	}

	/*
	 * The http message body has two format:
	 *
	 * 	ptui_checkVC('1','9ed32e3f644d968809e8cbeaaf2cce42de62df
	 * 					ee12c14b74');
	 * 	ptui_checkVC('0','!LOB');
	 * The former means we need verify code image and the second 
	 * parameter is vc_type.
	 * The later means we don't need the verify code image. The second
	 * parameter is the verify code. The vc_type is in the header 
	 * "Set-Cookie".
	 */

	gchar *c, *s;
       	s = rps -> msg -> str;
	if(g_strstr_len(s, -1, "ptui_checkVC") == NULL){
		g_warning("Get vc_type error!(%s, %d)", __FILE__, __LINE__);
		ret = NETWORK_ERR;
		goto error;
	}

	g_debug("check vc return: %s(%s, %d)", s, __FILE__, __LINE__);
	c = g_strstr_len(s, -1, "'");
	++c;
	if(*c == '0'){
		/*
		 * We got the verify code.
		 */
		info -> need_vcimage = FALSE;
		s = c;
		c = g_strstr_len(s, -1, "'");
		s = c + 1; 
		c = g_strstr_len(s, -1, "'");
		s = c + 1;
		c = g_strstr_len(s, -1, "'");
		*c = '\0';
		info -> verify_code = g_string_new(s);
		g_debug("Verify code : %s (%s, %d)", info -> verify_code -> str
				, __FILE__, __LINE__);
		/*
		 * We need get the ptvfsession from the header "Set-Cookie"
		 */
		info -> ptvfsession = get_cookie(rps, "ptvfsession");
	}else if(*c == '1'){
		/*
		 * We need get the verify image.
		 */
		info -> need_vcimage = TRUE;
		s = c;
		c = g_strstr_len(s, -1, "'");
		s = c + 1;
		c = g_strstr_len(s, -1, "'");
		s = c + 1;
		c = g_strstr_len(s, -1, "'");
		*c = '\0';
		info -> vc_type = g_string_new(s);
		g_debug("We need verify code image! vc_type: %s (%s, %d)"
				, info -> vc_type -> str, __FILE__, __LINE__);
	}else{
		g_warning("Unknown return value!(%s, %d)", __FILE__, __LINE__);
		ret = NETWORK_ERR;
		goto error;
	}
error:
	request_del(req);
	response_del(rps);
	return ret;
}
Пример #12
0
/*
 * Get ptca and skey
 * return the status returned by the server.
 * If error occured, store the error message in info -> errmsg
 */
static gint get_ptcz_skey(QQInfo *info, const gchar *p)
{
	gint ret = 0;
	gint res = 0;
	gchar params[300];

	Request *req = request_new();
	Response *rps = NULL;
	request_set_method(req, "GET");
	request_set_version(req, "HTTP/1.1");
	g_sprintf(params, LOGINPATH"?u=%s&p=%s&verifycode=%s&webqq_type=40&"
			"remember_uin=0&aid="APPID"&login2qq=1&u1=%s&h=1&"
			"ptredirect=0&ptlang=2052&from_ui=1&pttype=1"
			"&dumy=&fp=loginerroralert&action=4-30-764935&mibao_css=m_webqq"
			, info -> me -> uin -> str, p, info -> verify_code -> str
			, LOGIN_S_URL);
	request_set_uri(req, params);
	request_set_default_headers(req);
	request_add_header(req, "Host", LOGINHOST);
	request_add_header(req, "Referer", "http://ui.ptlogin2.qq.com/cgi-bin/"
						"login?target=self&style=4&appid=1003903&enable_ql"
						"ogin=0&no_verifyimg=1&s_url=http%3A%2F%2Fweb2.qq.c"
						"om%2Floginproxy.html%3Flogin_level%3D3"
						"&f_url=loginerroralert");
	if(info -> ptvfsession != NULL){
		g_sprintf(params, "ptvfsession=%s; "
				, info -> ptvfsession -> str);
		request_add_header(req, "Cookie", params);
	}

	Connection *con = connect_to_host(LOGINHOST, 80);
	if(con == NULL){
		g_warning("Can NOT connect to server!(%s, %d)"
				, __FILE__, __LINE__);
		request_del(req);
		return -1;
	}

	send_request(con, req);
	res = rcv_response(con, &rps);
	close_con(con);
	connection_free(con);

	if (-1 == res || !rps) {
		g_warning("Null point access (%s, %d)\n", __FILE__, __LINE__);
		ret = -1;
		goto error;
	}
	const gchar *retstatus = rps -> status -> str;
	if(g_strstr_len(retstatus, -1, "200") == NULL){
		g_warning("Server status %s (%s, %d)", retstatus
				, __FILE__, __LINE__);
		ret = -1;
		goto error;
	}

	gint status;
	gchar *sbe = g_strstr_len(rps -> msg -> str, -1, "'");
	++sbe;
	gchar *sen = g_strstr_len(sbe, -1, "'");
	*sen = '\0';
	status = strtol(sbe, NULL, 10);
	*sen = '\'';
	ret = status;
	if(status == 0){
		g_debug("Success.(%s, %d)", __FILE__, __LINE__);
	}else if(status == 1){
		g_warning("Server busy! Please try again.(%s, %d)"
				, __FILE__, __LINE__);
		//g_sprintf(info -> errmsg, "Server busy!");
		goto error;
	}else if(status == 2){
		g_warning("Out of date QQ number!(%s, %d)"
				, __FILE__, __LINE__);
		//g_sprintf(info -> errmsg, "Out of date QQ number.");
		goto error;
	}else if(status == 3){
		g_warning("Wrong password!(%s, %d)", __FILE__, __LINE__);
		//g_sprintf(info -> errmsg, "Wrong password.");
		goto error;
	}else if(status == 4){
		g_warning("Wrong verify code!(%s, %d)", __FILE__, __LINE__);
		//g_sprintf(info -> errmsg, "Wrong verify code.");
		goto error;
	}else if(status == 5){
		g_warning("Verify failed!(%s, %d)", __FILE__, __LINE__);
		//g_sprintf(info -> errmsg, "Verify failed.");
		goto error;
	}else if(status == 6){
		g_warning("You may need to try login again.(%s, %d)", __FILE__
				, __LINE__);
		//g_sprintf(info -> errmsg, "Please try again.");
		goto error;
	}else if(status == 7){
		g_warning("Wrong input!(%s, %d)", __FILE__, __LINE__);
		//g_sprintf(info -> errmsg, "Wrong input.");
		goto error;
	}else if(status == 8){
		g_warning("Too many logins on this IP. Please try again.(%s, %d)"
				, __FILE__, __LINE__);
		//g_sprintf(info -> errmsg, "Too many logins on this IP.");
		goto error;
	}else{
		g_warning("Server response message:(%s, %d)\n\t%s"
				, __FILE__, __LINE__, rps -> msg -> str);
		goto error;
	}

	info -> ptcz = get_cookie(rps, "ptcz");
	info -> skey = get_cookie(rps, "skey");
	info -> ptwebqq = get_cookie(rps, "ptwebqq");
	info -> ptuserinfo = get_cookie(rps, "ptuserinfo");
    info -> uin = get_cookie(rps, "uin");
    info -> ptisp = get_cookie(rps, "ptisp");
    info -> pt2gguin = get_cookie(rps, "pt2gguin");
	//sotre the cookie
	info -> cookie = g_string_new("");
    g_string_append(info -> cookie, "ptcz=");
    g_string_append(info -> cookie, info -> ptcz -> str);
    g_string_append(info -> cookie, ";skey=");
    g_string_append(info -> cookie, info -> skey -> str);
    g_string_append(info -> cookie, ";ptwebqq=");
    g_string_append(info -> cookie, info -> ptwebqq -> str);
    g_string_append(info -> cookie, ";ptuserinfo=");
    g_string_append(info -> cookie, info -> ptuserinfo -> str);
    g_string_append(info -> cookie, ";uin=");
    g_string_append(info -> cookie, info -> uin -> str);
    g_string_append(info -> cookie, ";ptisp=");
    g_string_append(info -> cookie, info -> ptisp -> str);
    g_string_append(info -> cookie, ";pt2gguin=");
    g_string_append(info -> cookie, info -> pt2gguin -> str);
error:
	request_del(req);
	response_del(rps);
	return ret;
}
Пример #13
0
/*
 * Get the verify code image form the server
 */
static gint get_vc_image(QQInfo *info)
{
	if(info -> vc_type == NULL || info -> vc_type -> len <=0){
		g_warning("Need vc_type!!(%s, %d)", __FILE__, __LINE__);
		return PARAMETER_ERR;
	}
	gint ret = 0;
	gchar params[500];
	gint res = 0;

	Request *req = request_new();
	Response *rps = NULL;
	request_set_method(req, "GET");
	request_set_version(req, "HTTP/1.1");
	g_sprintf(params, IMAGEPATH"?aid="APPID"&r=%.16f&uin=%s&vc_type=%s"
			, g_random_double(), info -> me -> uin -> str
			, info -> vc_type -> str);
	request_set_uri(req, params);
	request_set_default_headers(req);
	request_add_header(req, "Host", IMAGEHOST);

	Connection *con = connect_to_host(IMAGEHOST, 80);
	if(con == NULL){
		g_warning("Can NOT connect to server!(%s, %d)"
				, __FILE__, __LINE__);
		request_del(req);
		return NETWORK_ERR;
	}

	send_request(con, req);
	res = rcv_response(con, &rps);
	close_con(con);
	connection_free(con);
	const gchar *retstatus = rps -> status -> str;
	if(g_strstr_len(retstatus, -1, "200") == NULL){
		g_warning("Server status %s (%s, %d)", retstatus
				, __FILE__, __LINE__);
		ret = NETWORK_ERR;
		goto error;
	}

	info -> vc_image_data = g_string_new(NULL);
	g_string_append_len(info -> vc_image_data, rps -> msg -> str
				, rps -> msg -> len);
    info -> vc_image_size = rps -> msg -> len;

	gchar *ct = response_get_header_chars(rps, "Content-Type");
	gchar *vc_ftype = g_strstr_len(ct, -1, "image/");
	g_debug("vc content type: %s(%s, %d)", vc_ftype, __FILE__, __LINE__);
	if(vc_ftype == NULL){
		g_warning("Unknown verify code image file type!(%s, %d)"
				, __FILE__, __LINE__);
		g_string_free(info -> vc_image_data, TRUE);
		info -> vc_image_data = NULL;
		ret = NETWORK_ERR;
		goto error;

	}
	vc_ftype += (sizeof("image/") - 1);
	g_debug("Verify code image file type: %s len %d (%s, %d)", vc_ftype
                    , info -> vc_image_size, __FILE__, __LINE__);
	g_strstrip(vc_ftype);
	info -> vc_image_type = g_string_new(vc_ftype);

error:
	request_del(req);
	response_del(rps);
	return ret;
}