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; }
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; }
/* * 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; }
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; }
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); }
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; } }
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; }
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; }
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; }
/* * 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; }
/* * 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; }
/* * 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; }
/* * 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; }