From: <sid...@us...> - 2010-08-13 20:15:52
|
Revision: 381 http://libyahoo2.svn.sourceforge.net/libyahoo2/?rev=381&view=rev Author: siddheshp Date: 2010-08-13 20:15:45 +0000 (Fri, 13 Aug 2010) Log Message: ----------- Merge libyahoo2 chatroom code Conflicts: libyahoo2/src/libyahoo2.c libyahoo2/src/sample_client.c libyahoo2/src/yahoo2.h libyahoo2/src/yahoo2_callbacks.h libyahoo2/src/yahoo2_types.h libyahoo2/src/yahoo_httplib.c Modified Paths: -------------- trunk/libyahoo2/src/libyahoo2.c trunk/libyahoo2/src/sample_client.c trunk/libyahoo2/src/yahoo2.h trunk/libyahoo2/src/yahoo2_callbacks.h trunk/libyahoo2/src/yahoo2_types.h trunk/libyahoo2/src/yahoo_httplib.c Added Paths: ----------- trunk/libyahoo2/doc/ymsg-chatroom.txt Added: trunk/libyahoo2/doc/ymsg-chatroom.txt =================================================================== --- trunk/libyahoo2/doc/ymsg-chatroom.txt (rev 0) +++ trunk/libyahoo2/doc/ymsg-chatroom.txt 2010-08-13 20:15:45 UTC (rev 381) @@ -0,0 +1,169 @@ +Yahoo Messenger Protocol -- Chat Room +---------------------------------------- + +The YMSG protocol used in chat room. +Seven types of messages used here: +1) Chat Online +2) Chat Join : Messages send when joining the chat room. +3) Chat Comment : Send comment to server or Receive comments from others from server +4) Chat Join : When a user joined the chat room, will receive a message from the server +5) Chat Logout : When a user left the chat room, will receive a message from the server +6) Chat Exit : Left the chat room, send a message to tell the server +7) Ignore User : Ignore/Unignore a specified user, and the server will not send the user's comments any more + + +1.Chat Online + +Service: Chat Online (150 0×96) + +Client –> Server : + +109 : username +1 : username +6 : abcde +98 : us +445 : en-us +135 : ym10.0.0.1258 + +Server –> Client : + +1 : username +6 : abcde +98 : us +109 : username +135 : ym10.0.0.1258 +445 : en-us +302 : 10019 +10019 : username +303 : 10019 + +2. Chat Join + +Service: Chat Join (152 0×98) + +Client –> Server : + +1 : username +104 : #ChatRoom(China : 1) +129 : (Chat Room ID) +62 : 2 + +Server –> Client : + +13 : 1 +104 : #ChatRoom(China : 1) +105 : To help preven spam … … +109 : username +302 : 10019 +10019 : username +303 : 10019 +109 : Yahoo +141 : Messenger Chat Admin + +Now client receives the URL of the image for verification. Libyahoo2 will be in charge of extracting the URL and handle it to client to display the image. + +Server –> Client + +13 : 1 +104 : #ChatRoom(China : 1) +105 : (Information from the chat room) +108 : (Number of members in this package) +126 : 328704 +128 : 1032 +129 : (Chat Room ID) +130 : (Some Unrecognizable characters to show the first join) +302 : 10019 +10019 : username +303 : 10019 +#For all the users in the chat room: +109 : user name +110 : 0 +111 : (sex) neuter/male/female +113 : (number) +141 : (nick name ?) james +142 : (country) New Zealand + +Special Situation : Disconnect. Maybe the chat room is full + +Server –> Client : +Status : Disconnected(4294967295) +114 : -35 + +3. Chat Comment + +Service : Comment(168 0xa8) + +Client –> Server + +1 : username +104: #ChatRoom(China:1) +124 : (Message Type) +117 : (Content) + +Server –> Client + +104 : #ChatRoom(China:1) +109 : (From) Yahoo/username +117 : (Content) +124 : (Message Type) + +4. Chat Join + +Service : Chat Join (152 0×98) + +Server –> Client : + +104 : #ChatRoom(China : 1) +105 : (Information from the chat room) +108 : 1 +109 : username(who is joining) +113 : (number) + +5. Chat Exit + +Service : Chat Exit(155 0×9b) + +Server –> Client + +104 : #ChatRoom(China:1) +108 : 1 +109 : username(who is leaving) +113 : (number) + +6. Chat Logout + +Service : Chat Logout (160 0xa0) + +Client –> Server + +1 : username +1005 : (number) + +Server –> Client + +1 : username +1005 : (number) <same with the number sent to server> +302 : 10019 +10019 : username +303 : 10019 + +7. Ignore user + +Service : Ignore Contact (133 0x85) + +Client -->Server + +1 : my username +13 : 1 if ignore a user / 2 if unignore a user +302 : 319 +300 : 319 +7 : user to be ignored +301 : 319 +303 : 319 + +Server --> Client + +0 : user to be ignored +1 : my username +13 : 1 if ignore a user / 2 if unignore a user +66 : 0 Modified: trunk/libyahoo2/src/libyahoo2.c =================================================================== --- trunk/libyahoo2/src/libyahoo2.c 2010-08-05 03:36:23 UTC (rev 380) +++ trunk/libyahoo2/src/libyahoo2.c 2010-08-13 20:15:45 UTC (rev 381) @@ -93,6 +93,11 @@ struct yahoo_callbacks *yc = NULL; +struct yahoo_post_data { + struct yahoo_input_data *yid; + char *data; +}; + void yahoo_register_callbacks(struct yahoo_callbacks *tyc) { yc = tyc; @@ -103,6 +108,7 @@ static int yahoo_send_data(void *fd, void *data, int len); static void _yahoo_http_connected(int id, void *fd, int error, void *data); static void yahoo_connected(void *fd, int error, void *data); +static void _yahoo_http_post_connected(int id, void *fd, int error, void *data); int yahoo_log_message(char *fmt, ...) { @@ -204,6 +210,7 @@ YList *txqueues; int write_tag; + int chat_room_id; }; struct yahoo_server_settings { @@ -465,6 +472,51 @@ } } +/* Free chat room list */ +static void yahoo_free_chat_room_list(YList *list) +{ + YList *lobby, *templ; + while(list != NULL) { + FREE(((yahoo_chatroom_info *)list->data)->type); + FREE(((yahoo_chatroom_info *)list->data)->topic); + FREE(((yahoo_chatroom_info *)list->data)->name); + lobby = list->prev; + while(lobby != NULL) { + templ = lobby->prev; + FREE(lobby->data); + FREE(lobby); + lobby = templ; + } + list = list->next; + } + y_list_free(list); +} +/* +static void yahoo_free_chat_cat_list(YList *list) +{ + YList *ptr = list->next; + free_chat_cat_list(list->next); + FREE(list); +} +*/ +static void yahoo_free_chat_cat_list(YList *list) +{ + FREE(((yahoo_chatroom_category *)list->data)->name); + + if(((yahoo_chatroom_category *)(list->data))->room_list) + yahoo_free_chat_room_list(((yahoo_chatroom_category *)list->data)->room_list); + + if (list->prev) { + yahoo_free_chat_cat_list(list->prev); + } + if (list->next) { + yahoo_free_chat_cat_list(list->next); + } + + FREE(list->data); + FREE(list); +} + /* Free webcam data */ static void yahoo_free_webcam(struct yahoo_webcam *wcm) { @@ -1052,6 +1104,12 @@ int membercount = 0; int chaterr = 0; YList *l; + char *end, *head; + char content[256], vcode[8]; + int length; + struct yahoo_post_data *yad; + struct yahoo_input_data *new_yid; + static int verify_image = 1; yahoo_dump_unhandled(pkt); for (l = pkt->hash; l; l = l->next) { @@ -1163,6 +1221,42 @@ WARNING(("Got more than 1 member on a normal join")); } /* this should only ever have one, but just in case */ + + /* skip the message "To help prevent spam ..." to the url of the image for verification + the URL is in the first message server send to client + if what user input is wrong, new image URL will be send in form of HTTP*/ + if (verify_image == 1) { + verify_image = 0; + end = strstr(topic, ".jpg"); + end[4] = '\0'; + + /* find the URL of the image, the SECOND "http://" in the string */ + head = strstr(topic, "http://"); + topic = head + 7; /*skip the first "http://" */ + head = strstr(topic, "http://"); + + /* handle the URL to client to show the image and get the code in the image*/ + YAHOO_CALLBACK(ext_yahoo_chat_verify)(head, vcode); + + /* construct a HTTP post message to send the verification code to the server*/ + length = snprintf(content, sizeof(content), "question=%s" + "&answer=%s" + "&.intl=us&.lang=en-US", + head, vcode); + + new_yid = y_new0(struct yahoo_input_data, 1); + new_yid->type = YAHOO_CONNECTION_CAPTCHA; + new_yid->yd = yid->yd; + + yad = y_new0(struct yahoo_post_data, 1); + yad->yid = new_yid; + yad->data = strdup(content); + yahoo_http_post(yid->yd->client_id, "http://captcha.chat.yahoo.com/captcha1", + NULL, length, _yahoo_http_post_connected, yad); + break; + } + + /* The second time receive the message of this type, it will contain all the members in the chat room*/ while (members) { YList *n = members->next; currentmember = members->data; @@ -1850,7 +1944,7 @@ yahoo_packet_hash(packet, 2, "1"); yahoo_packet_hash(packet, 59, yd->cookie_b); yahoo_packet_hash(packet, 98, "us"); /* TODO Put country code */ - yahoo_packet_hash(packet, 135, "9.0.0.2152"); + yahoo_packet_hash(packet, 135, YMSG_VERSION); yahoo_send_packet(yid, packet, 0); @@ -2955,18 +3049,261 @@ } } -static void yahoo_process_chatcat_connection(struct yahoo_input_data *yid, - int over) +static void traverse_cat_list(YList *list, int level) { + int i; + for(i=0; i<level; i++) + putchar('\t'); + printf("%d - %s\n", ((yahoo_chatroom_category *)list->data)->id, ((yahoo_chatroom_category *)list->data)->name); + if(list->prev) + traverse_cat_list(list->prev, level+1); + if(list->next) + traverse_cat_list(list->next, level); +} + +static void traverse_room_list(YList *list) +{ + YList *lobby; + + while(list != NULL) { + lobby = list->prev; + while(lobby != NULL) { + printf("%d - %s %d [%d] [w%d]\n", + ((yahoo_chatroom_info *)list->data)->id, ((yahoo_chatroom_info *)list->data)->name, + ((yahoo_lobby_info *)lobby->data)->count, ((yahoo_lobby_info *)lobby->data)->users, + ((yahoo_lobby_info *)lobby->data)->webcams); + lobby = lobby->prev; + } + list = list->next; + } +} + +static YList *find_room_category(YList *list, int cat_id) +{ + YList *cat_pos = NULL; + if (((yahoo_chatroom_category *)(list->data))->id == cat_id) { + return list; + } + + if(list->prev) + cat_pos = find_room_category(list->prev, cat_id); + if(list->next && !cat_pos) + cat_pos = find_room_category(list->next, cat_id); + + return cat_pos; +} + +static char *get_xml_chatroom_info(char *content, char *pattern) +{ + char *header, *tailer, *info; + header = strstr(content, pattern); + header += strlen(pattern); + tailer = strchr(header, '"'); + *tailer = '\0'; + info = y_new0(char, tailer - header + 1); + strcpy(info, header); + *tailer = '"'; + return info; +} + +static void parse_chat_cat_xml(int id, const char *xml) +{ + struct yahoo_data *yd = find_conn_by_id(id); + struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_CHATCAT); + char *content = strdup(xml), *header, *tailer; + int child_mode = 0; + YList *room_list; + YList *list_ptr; + YList *cat_stack[5]; + int stack_ptr = 0; + YList *temp, *child, *tail, *category; + + room_list = y_new0(struct _YList, 1); + list_ptr = room_list; + content = strstr(content, "<category"); /* Find the first category */ + + if (content == NULL) { + category = find_room_category(yd->chat_room_list, yid->chat_room_id); + + content = strdup(xml); + content = strstr(content, "<chatRooms>"); + if (content == NULL) { + printf("Error : Cannot find anything!\n"); + return ; + } + + content += strlen("<chatRooms>"); + + content = strchr(content, '<'); + while(*(content + 1) != '/') { + /* find all the fields of a chat room */ + temp = y_new0(struct _YList, 1); + temp->data = y_new0(struct yahoo_chatroom, 1); + tail = temp; + + ((yahoo_chatroom_info *)(temp->data))->type = get_xml_chatroom_info(content, "type=\""); + ((yahoo_chatroom_info *)(temp->data))->id = atoi(get_xml_chatroom_info(content, "id=\"")); + ((yahoo_chatroom_info *)(temp->data))->name = get_xml_chatroom_info(content, "name=\""); + ((yahoo_chatroom_info *)(temp->data))->topic = get_xml_chatroom_info(content, "topic=\""); + + /* find all lobbys of a chat room */ + + content = strchr(content+1, '<'); + while(*(content + 1) != '/') { + child = y_new0(struct _YList, 1); + child->data = y_new0(struct yahoo_lobby, 1); + + ((yahoo_lobby_info *)(child->data))->count = atoi(get_xml_chatroom_info(content, "count=\"")); + ((yahoo_lobby_info *)(child->data))->users = atoi(get_xml_chatroom_info(content, "users=\"")); + ((yahoo_lobby_info *)(child->data))->voices = atoi(get_xml_chatroom_info(content, "voices=\"")); + ((yahoo_lobby_info *)(child->data))->webcams = atoi(get_xml_chatroom_info(content, "webcams=\"")); + + /* prev is used as a pointer to the the lobby*/ + tail->prev = child; + tail = child; + + content = strchr(content+1, '<'); + } + + list_ptr->next = temp; + list_ptr = temp; + + content = strchr(content+1, '<'); + } + + ((yahoo_chatroom_category *)(category->data))->room_list = room_list->next; + + } else { + while(stack_ptr >= 0) { + /* prev is used as a pointer linked with its child categories */ + + /* Find the id */ + temp = y_new0(struct _YList, 1); + temp->data = y_new0(struct yahoo_chatroom_category, 1); + header = strchr(content, '"'); + tailer = strchr(header+1, '"'); + *tailer = '\0'; + ((yahoo_chatroom_category *)(temp->data))->id = atoi(strdup(header + 1)); + + /* Find the name*/ + header = strchr(tailer+1, '"'); + tailer = strchr(header+1, '"'); + *tailer = '\0'; + ((yahoo_chatroom_category *)(temp->data))->name = strdup(header + 1); + ((yahoo_chatroom_category *)(temp->data))->room_list = NULL; + + content = strchr(tailer+1, '>'); + if(child_mode == 1) { + list_ptr->prev = temp; + list_ptr = temp; + cat_stack[stack_ptr] = temp; + child_mode = 0; + } else { + list_ptr->next = temp; + list_ptr = temp; + cat_stack[stack_ptr] = temp; + } + + if (*(content-1) != '/') { + stack_ptr ++; + child_mode = 1; + } + + /* find the next category */ + content = strchr(content, '<'); + while (*(content+1) == '/' && stack_ptr >= 0) { + stack_ptr --; + list_ptr = cat_stack[stack_ptr]; + content = strchr(content + 1, '<'); + } + } + + yd->chat_room_list = room_list->next; + } + FREE(room_list); /* free the head node */ +} + +static void yahoo_process_chatcat_connection(struct yahoo_input_data *yid, int over) +{ if (over) return; - if (strstr((char *)yid->rxqueue + (yid->rxlen - 20), "</content>")) { + if (strstr((char *)yid->rxqueue, "</content>")) { + parse_chat_cat_xml(yid->yd->client_id, (char *)yid->rxqueue); + + /* ext_yahoo_chat_cat_xml() needs to be deprecated in future releases */ YAHOO_CALLBACK(ext_yahoo_chat_cat_xml) (yid->yd->client_id, (char *)yid->rxqueue); } } +static void yahoo_process_captcha_connection(struct yahoo_input_data *yid, int over) +{ + char content[256], vcode[8]; + char *url, *location; + int length; + struct yahoo_post_data *yad; + struct yahoo_input_data *new_yid; + struct yahoo_packet *pkt; + struct yahoo_data *yd = yid->yd; + int id = yd->client_id; + char *judge; + http_data data; + + if (over) + return; + + yahoo_set_http_data((char *)yid->rxqueue, yid->rxlen, &data); + location = yahoo_http_get_header_value(data, "Location"); + + /*location = strstr((char *)yid->rxqueue, "Location:");*/ + if (location == NULL) { + return ; /* Do not found the content, must have error*/ + } + + judge = strstr(location, "tryagain=1"); + if (judge == NULL) { + judge = strstr(location, "close"); + if (judge != NULL) { + /* Successfully logged in*/ + printf("Successfully Logged in\n"); + } else { + printf("Error in captcha process\n"); + } + yahoo_input_close(yid); + return ; + } else { + location = judge; + /* Find the end of the URL*/ + url = strstr(location, ".jpg"); + url[4] = '\0'; + + /* Find the head of the URL*/ + url = strstr(location, "http://"); + + /* handle the URL to client to show the image and get the code in the image*/ + YAHOO_CALLBACK(ext_yahoo_chat_verify)(url, vcode); + + /* construct a HTTP post message to send the verification code to the server*/ + length = snprintf(content, sizeof(content), "question=%s" + "&answer=%s" + "&.intl=us&.lang=en-US", + url, vcode); + + new_yid = y_new0(struct yahoo_input_data, 1); + new_yid->type = YAHOO_CONNECTION_CAPTCHA; + new_yid->yd = yid->yd; + + yad = y_new0(struct yahoo_post_data, 1); + yad->yid = new_yid; + yad->data = strdup(content); + yahoo_input_close(yid); + yahoo_http_post(new_yid->yd->client_id, "http://captcha.chat.yahoo.com/captcha1", + NULL, length, _yahoo_http_post_connected, yad); + } + yahoo_free_http_data(&data); +} + static void yahoo_process_yab_connection(struct yahoo_input_data *yid, int over) { struct yahoo_data *yd = yid->yd; @@ -3508,12 +3845,15 @@ static void (*yahoo_process_connection[]) (struct yahoo_input_data *, int over) = { -yahoo_process_pager_connection, yahoo_process_ft_connection, + yahoo_process_pager_connection, + yahoo_process_ft_connection, yahoo_process_yab_connection, yahoo_process_webcam_master_connection, yahoo_process_webcam_connection, yahoo_process_chatcat_connection, - yahoo_process_search_connection, yahoo_process_auth_connection}; + yahoo_process_search_connection, + yahoo_process_auth_connection, + yahoo_process_captcha_connection}; int yahoo_read_ready(int id, void *fd, void *data) { @@ -3581,6 +3921,8 @@ yd->current_status = -1; yd->client_id = ++last_id; + + yd->chat_room_list = NULL; add_to_list(yd); @@ -3891,11 +4233,6 @@ _yahoo_http_connected, yid); } -struct yahoo_post_data { - struct yahoo_input_data *yid; - char *data; -}; - static void _yahoo_http_post_connected(int id, void *fd, int error, void *data) { struct yahoo_post_data *yad = data; @@ -4400,6 +4737,7 @@ struct yahoo_input_data *yid; char url[1024]; char buff[1024]; + YList *category; if (!yd) return; @@ -4407,11 +4745,22 @@ yid = y_new0(struct yahoo_input_data, 1); yid->yd = yd; yid->type = YAHOO_CONNECTION_CHATCAT; + yid->chat_room_id = chatroomid; if (chatroomid == 0) { + if (yd->chat_room_list) { + yahoo_free_chat_cat_list(yd->chat_room_list); + yd->chat_room_list = NULL; + } snprintf(url, 1024, "http://insider.msg.yahoo.com/ycontent/?chatcat=0"); } else { + if (!(yd->chat_room_list)) { + return; + } + category = find_room_category(yd->chat_room_list, chatroomid); + if(((yahoo_chatroom_category *)(category->data))->room_list) + yahoo_free_chat_room_list(((yahoo_chatroom_category *)(category->data))->room_list); snprintf(url, 1024, "http://insider.msg.yahoo.com/ycontent/?chatroom_%d=0", chatroomid); @@ -4421,12 +4770,12 @@ inputs = y_list_prepend(inputs, yid); - yahoo_http_get(yid->yd->client_id, url, buff, 0, 0, + yahoo_http_get(yid->yd->client_id, url, buff, 1, 0, _yahoo_http_connected, yid); } void yahoo_chat_logon(int id, const char *from, const char *room, - const char *roomid) + const char *roomid, const char *country, const char *language) { struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); @@ -4438,17 +4787,27 @@ yd = yid->yd; + /* First, send a CHAT ONLINE message*/ pkt = yahoo_packet_new(YAHOO_SERVICE_CHATONLINE, YPACKET_STATUS_DEFAULT, yd->session_id); yahoo_packet_hash(pkt, 1, (from ? from : yd->user)); yahoo_packet_hash(pkt, 109, yd->user); yahoo_packet_hash(pkt, 6, "abcde"); + if(country && language) { + yahoo_packet_hash(pkt, 98, country); + yahoo_packet_hash(pkt, 445, language); + } else { + yahoo_packet_hash(pkt, 98, "us"); + yahoo_packet_hash(pkt, 445, "en-us"); + } + yahoo_packet_hash(pkt, 135, YMSG_VERSION); yahoo_send_packet(yid, pkt, 0); yahoo_packet_free(pkt); - + + /* Second, Send a CHAT JOIN message*/ pkt = yahoo_packet_new(YAHOO_SERVICE_CHATJOIN, YPACKET_STATUS_DEFAULT, yd->session_id); @@ -4494,12 +4853,44 @@ yahoo_packet_free(pkt); } +void yahoo_chat_ignore(int id, const char *from, const char *user, int ignore) +/*ignore = 1 means we are trying to ignore the user + ignore = 0 means we have already ignored the user and don't want to ignore him any more*/ +{ + struct yahoo_input_data *yid = + find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); + struct yahoo_data *yd; + struct yahoo_packet *pkt; + + yd = yid->yd; + + pkt = yahoo_packet_new(YAHOO_SERVICE_IGNORECONTACT, YPACKET_STATUS_DEFAULT, + yd->session_id); + + yahoo_packet_hash(pkt, 1, (from ? from : yd->user)); + if(ignore) + yahoo_packet_hash(pkt, 13, "1"); + else + yahoo_packet_hash(pkt, 13, "2"); + yahoo_packet_hash(pkt, 302, "319"); + yahoo_packet_hash(pkt, 300, "319"); + yahoo_packet_hash(pkt, 7, user); + yahoo_packet_hash(pkt, 301, "319"); + yahoo_packet_hash(pkt, 303, "319"); + + yahoo_send_packet(yid, pkt, 0); + + yahoo_packet_free(pkt); +} + void yahoo_chat_logoff(int id, const char *from) { struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); struct yahoo_data *yd; struct yahoo_packet *pkt; + char c1005[8] = "12345678"; + /* Any value of the field 1005 will cause not much difference, just use a hard-coding value */ if (!yid) return; @@ -4510,6 +4901,7 @@ yd->session_id); yahoo_packet_hash(pkt, 1, (from ? from : yd->user)); + yahoo_packet_hash(pkt, 1005, c1005); yahoo_send_packet(yid, pkt, 0); @@ -5483,6 +5875,25 @@ return yd->buddies; } +const YList *yahoo_get_chat_room_list(int id, int roomid, void *ext_data) +{ + struct yahoo_data *yd = find_conn_by_id(id); + YList *category; + + if (!yd) + return NULL; + if(roomid == 0) + return yd->chat_room_list; + else { + if(yd->chat_room_list) { + category = find_room_category(yd->chat_room_list, roomid); + return ((yahoo_chatroom_category *)(category->data))->room_list; + } else { + return NULL; + } + } +} + const YList *yahoo_get_ignorelist(int id) { struct yahoo_data *yd = find_conn_by_id(id); Modified: trunk/libyahoo2/src/sample_client.c =================================================================== --- trunk/libyahoo2/src/sample_client.c 2010-08-05 03:36:23 UTC (rev 380) +++ trunk/libyahoo2/src/sample_client.c 2010-08-13 20:15:45 UTC (rev 381) @@ -463,9 +463,173 @@ printf(" Location: %s", ycm->location); } +static void ext_yahoo_chat_verify(const char *url, char *vcode) +{ + printf("%s\n", url); + printf("Please input the verification code:"); + scanf("%s", vcode); +} + +static void traverse_cat_list(YList *list, int level) +{ + int i; + for(i=0; i<level; i++) + putchar('\t'); + printf("%d - %s\n", ((yahoo_chatroom_category *)list->data)->id, ((yahoo_chatroom_category *)list->data)->name); + if(list->prev) + traverse_cat_list(list->prev, level+1); + if(list->next) + traverse_cat_list(list->next, level); +} + +static void traverse_room_list(YList *list) +{ + YList *lobby; + + while(list != NULL) { + lobby = list->prev; + while(lobby != NULL) { + printf("%d - %s %d [%d] [w%d]\n", + ((yahoo_chatroom_info *)list->data)->id, ((yahoo_chatroom_info *)list->data)->name, + ((yahoo_lobby_info *)lobby->data)->count, ((yahoo_lobby_info *)lobby->data)->users, + ((yahoo_lobby_info *)lobby->data)->webcams); + lobby = lobby->prev; + } + list = list->next; + } +} + +static char *get_xml_chatroom_info(char *content, char *pattern) +{ + char *header, *tailer, *info; + header = strstr(content, pattern); + header += strlen(pattern); + tailer = strchr(header, '"'); + *tailer = '\0'; + info = malloc(tailer - header + 1); + strcpy(info, header); + *tailer = '"'; + return info; +} + static void ext_yahoo_chat_cat_xml(int id, const char *xml) { - print_message(("%s", xml)); + char *content = strdup(xml), *header, *tailer; + int child_mode = 0; + YList *room_list; + YList *list_ptr; + YList *cat_stack[5]; + int stack_ptr = 0; + YList *temp, *child, *tail; + + content = strstr(content, "<category"); /* Find the first category*/ + + if (content == NULL) { + room_list = calloc(1, sizeof(YList)); + list_ptr = room_list; + + content = strdup(xml); + content = strstr(content, "<chatRooms>"); + if (content == NULL) { + printf("Error : Cannot find anything!\n"); + return ; + } + + content += strlen("<chatRooms>"); + + content = strchr(content, '<'); + while(*(content + 1) != '/') { + + /* find all the fields of a chat room */ + temp = calloc(1, sizeof(YList)); + temp->data = calloc(1, sizeof(yahoo_chatroom_info)); + tail = temp; + + ((yahoo_chatroom_info *)(temp->data))->type = get_xml_chatroom_info(content, "type=\""); + ((yahoo_chatroom_info *)(temp->data))->id = atoi(get_xml_chatroom_info(content, "id=\"")); + ((yahoo_chatroom_info *)(temp->data))->name = get_xml_chatroom_info(content, "name=\""); + ((yahoo_chatroom_info *)(temp->data))->topic = get_xml_chatroom_info(content, "topic=\""); + + /* find all lobbys of a chat room */ + + content = strchr(content+1, '<'); + while(*(content + 1) != '/') { + child = calloc(1, sizeof(YList)); + child->data = calloc(1, sizeof(yahoo_lobby_info)); + + ((yahoo_lobby_info *)child->data)->count = atoi(get_xml_chatroom_info(content, "count=\"")); + ((yahoo_lobby_info *)child->data)->users = atoi(get_xml_chatroom_info(content, "users=\"")); + ((yahoo_lobby_info *)child->data)->voices = atoi(get_xml_chatroom_info(content, "voices=\"")); + ((yahoo_lobby_info *)child->data)->webcams = atoi(get_xml_chatroom_info(content, "webcams=\"")); + + /* prev is used as a pointer to the the lobby*/ + tail->prev = child; + tail = child; + + content = strchr(content+1, '<'); + } + + list_ptr->next = temp; + list_ptr = temp; + + content = strchr(content+1, '<'); + } + + /* Traverse the structure and print them out */ + traverse_room_list(room_list->next); + + } else { + /* Create a head node */ + room_list = calloc(1, sizeof(YList)); + list_ptr = room_list; + + while(stack_ptr >= 0) { + /* prev is used as a pointer linked with its child categories */ + + /* Find the id */ + temp = calloc(1, sizeof(YList)); + temp->data = calloc(1, sizeof(yahoo_chatroom_category)); + header = strchr(content, '"'); + tailer = strchr(header+1, '"'); + *tailer = '\0'; + ((yahoo_chatroom_category *)temp->data)->id = atoi(strdup(header + 1)); + + /* Find the name*/ + header = strchr(tailer+1, '"'); + tailer = strchr(header+1, '"'); + *tailer = '\0'; + ((yahoo_chatroom_category *)temp->data)->name = strdup(header + 1); + ((yahoo_chatroom_category *)temp->data)->room_list = NULL; + + content = strchr(tailer+1, '>'); + if(child_mode == 1) { + list_ptr->prev = temp; + list_ptr = temp; + cat_stack[stack_ptr] = temp; + child_mode = 0; + } else { + list_ptr->next = temp; + list_ptr = temp; + cat_stack[stack_ptr] = temp; + } + + if (*(content-1) != '/') { + stack_ptr ++; + child_mode = 1; + } + + /* find the next category */ + content = strchr(content, '<'); + while (*(content+1) == '/' && stack_ptr >= 0) { + stack_ptr --; + list_ptr = cat_stack[stack_ptr]; + content = strchr(content + 1, '<'); + } + } + + /* Traverse the structure and print them out */ + traverse_cat_list(room_list->next, 0); + } } static void ext_yahoo_chat_join(int id, const char *me, const char *room, const char * topic, YList *members, void *fd) @@ -1444,8 +1608,23 @@ int roomid; roomid = atoi(copy); yahoo_get_chatrooms(ylad->id, roomid); + } else if(!strncasecmp(cmd, "CHR", strlen("CHR"))) { + int roomid; + void *ext_data; + roomid = atoi(copy); + YList *list = yahoo_get_chat_room_list(ylad->id, roomid, ext_data); + if(list) { + if(roomid == 0) + traverse_cat_list(list, 0); + else + traverse_room_list(list); + } + } else if(!strncasecmp(cmd, "CHJ", strlen("CHJ"))) { + /* Command Format "CHJ roomid roomname" */ char *roomid, *roomname; + char country[] = "us"; + char language[] = "en-us"; /* Linux, FreeBSD, Solaris:1 */ /* 1600326591 */ roomid = copy; @@ -1456,24 +1635,38 @@ } roomname = copy; if(roomid && roomname) { - yahoo_chat_logon(ylad->id, NULL, roomname, roomid); + yahoo_chat_logon(ylad->id, NULL, roomname, roomid, country, language); } } else if(!strncasecmp(cmd, "CHM", strlen("CHM"))) { + /* Command Format "CHM roomname msg" */ char *msg, *roomname; roomname = copy; - tmp = strstr(copy, " "); + tmp = strchr(copy, ' '); if(tmp) { *tmp = '\0'; - copy = tmp+2; + copy = tmp+1; } msg = copy; if(roomname && msg) { yahoo_chat_message(ylad->id, NULL, roomname, msg, 1, 0); } + } else if(!strncasecmp(cmd, "CHI", strlen("CHI"))) { + /* Ignore a member in the chat room, Command Format "CHI user_to_be_ignored" */ + char *user; + user = copy; + yahoo_chat_ignore(ylad->id, NULL, user, 1); + + } else if(!strncasecmp(cmd, "CHU", strlen("CHU"))) { + /* Unignore a member in the chat room, Command Format "CHI user_to_be_ignored" */ + char *user; + user = copy; + yahoo_chat_ignore(ylad->id, NULL, user, 0); + } else if(!strncasecmp(cmd, "CHX", strlen("CHX"))) { yahoo_chat_logoff(ylad->id, NULL); + } else if(!strncasecmp(cmd, "STA", strlen("STA"))) { if(isdigit(copy[0])) { state = (enum yahoo_status)atoi(copy); @@ -1853,6 +2046,7 @@ yc.ext_yahoo_conf_userjoin = ext_yahoo_conf_userjoin; yc.ext_yahoo_conf_userleave = ext_yahoo_conf_userleave; yc.ext_yahoo_conf_message = ext_yahoo_conf_message; + yc.ext_yahoo_chat_verify = ext_yahoo_chat_verify; yc.ext_yahoo_chat_cat_xml = ext_yahoo_chat_cat_xml; yc.ext_yahoo_chat_join = ext_yahoo_chat_join; yc.ext_yahoo_chat_userjoin = ext_yahoo_chat_userjoin; Modified: trunk/libyahoo2/src/yahoo2.h =================================================================== --- trunk/libyahoo2/src/yahoo2.h 2010-08-05 03:36:23 UTC (rev 380) +++ trunk/libyahoo2/src/yahoo2.h 2010-08-13 20:15:45 UTC (rev 381) @@ -139,10 +139,12 @@ void yahoo_get_chatrooms(int id, int chatroomid); /* join room with specified roomname and roomid */ void yahoo_chat_logon(int id, const char *from, const char *room, - const char *roomid); + const char *roomid, const char *country, const char *language); /* Send message "msg" to room with specified roomname, msgtype is 1-normal message or 2-/me mesage */ void yahoo_chat_message(int id, const char *from, const char *room, const char *msg, const int msgtype, const int utf8); +/* Ignore a contact in the chat room, ignore = 1 represents ignore and ignore = 0 represents unignore */ + void yahoo_chat_ignore(int id, const char *from, const char *user, int ignore); /* Log off chat */ void yahoo_chat_logoff(int id, const char *from); Modified: trunk/libyahoo2/src/yahoo2_callbacks.h =================================================================== --- trunk/libyahoo2/src/yahoo2_callbacks.h 2010-08-05 03:36:23 UTC (rev 380) +++ trunk/libyahoo2/src/yahoo2_callbacks.h 2010-08-13 20:15:45 UTC (rev 381) @@ -238,6 +238,16 @@ const char *me, const char *who, const char *room); /* + * Name: ext_yahoo_chat_cat_verify + * Called when user log into chat room, client will receive a image + * while user needs to type in the characters in the image to verify + * Params: + * url - the URL of the image for verification + * vcode - the characters which is typed in by the user + */ + void YAHOO_CALLBACK_TYPE(ext_yahoo_chat_verify) (const char *url, char *vcode); + +/* * Name: ext_yahoo_chat_cat_xml * Called when ? * Params: Modified: trunk/libyahoo2/src/yahoo2_types.h =================================================================== --- trunk/libyahoo2/src/yahoo2_types.h 2010-08-05 03:36:23 UTC (rev 380) +++ trunk/libyahoo2/src/yahoo2_types.h 2010-08-13 20:15:45 UTC (rev 381) @@ -28,6 +28,8 @@ extern "C" { #endif +#define YMSG_VERSION "9.0.0.2152" + enum yahoo_service { /* these are easier to see in hex */ YAHOO_SERVICE_LOGON = 1, YAHOO_SERVICE_LOGOFF, @@ -229,7 +231,8 @@ YAHOO_CONNECTION_WEBCAM, YAHOO_CONNECTION_CHATCAT, YAHOO_CONNECTION_SEARCH, - YAHOO_CONNECTION_AUTH + YAHOO_CONNECTION_AUTH, + YAHOO_CONNECTION_CAPTCHA }; enum yahoo_webcam_direction_type { @@ -302,6 +305,8 @@ void *server_settings; struct yahoo_process_status_entry *half_user; + + YList *chat_room_list; }; struct yab { @@ -324,6 +329,26 @@ struct yab *yab_entry; }; + typedef struct yahoo_chatroom_category{ + int id; + char *name; + YList *room_list; + } yahoo_chatroom_category; + + typedef struct yahoo_chatroom{ + char *type; + int id; + char *name; + char *topic; + } yahoo_chatroom_info; + + typedef struct yahoo_lobby{ + int count; + int users; + int voices; + int webcams; + } yahoo_lobby_info; + enum yahoo_search_type { YAHOO_SEARCH_KEYWORD = 0, YAHOO_SEARCH_YID, @@ -390,6 +415,19 @@ int f213; /* 213 state */ }; + typedef struct pair{ + char *name; + char *value; + }namevalue_pair; + + typedef struct{ + char *http_version; + char *status_code; + YList *headers; + char *content; + }http_data; + + #ifdef __cplusplus } #endif Modified: trunk/libyahoo2/src/yahoo_httplib.c =================================================================== --- trunk/libyahoo2/src/yahoo_httplib.c 2010-08-05 03:36:23 UTC (rev 380) +++ trunk/libyahoo2/src/yahoo_httplib.c 2010-08-13 20:15:45 UTC (rev 381) @@ -61,6 +61,83 @@ extern enum yahoo_log_level log_level; +char *yahoo_http_get_header_value(http_data data, char *field) +{ + YList *ptr = data.headers; + while(ptr != NULL) { + if(!strcmp(field, ((struct pair *)(ptr->data))->name)) + return ((struct pair *)(ptr->data))->value; + ptr = ptr->next; + } + return NULL; +} + +void yahoo_get_http_data(http_data data) +{ + YList *ptr = data.headers; + printf("%s, %s\n", data.http_version, data.status_code); + while(ptr != NULL) { + printf("%s : %s\n", ((struct pair *)(ptr->data))->name, ((struct pair *)(ptr->data))->value); + ptr = ptr->next; + } + printf("%s\n", data.content); +} + +void yahoo_set_http_data(char *input, int length, http_data *struct_packet) +{ + char *head, *tail; + char *raw_packet = strdup(input); + namevalue_pair *temp_header; + YList *temp_ylist; + + struct_packet->headers = NULL; + + /* Get HTTP version and the status code */ + struct_packet->http_version = y_new(char, 4); + struct_packet->status_code = y_new(char, 4); + sscanf(raw_packet, "%*[^/]/%s %s", struct_packet->http_version, struct_packet->status_code); + + head = strstr(raw_packet, "\r\n"); + head = head + 2; + while(*head != '\r' || *(head+1) != '\n') { + temp_header = y_new(struct pair, 1); + temp_ylist = y_new(struct _YList, 1); + + tail = strchr(head, ':'); + *tail = '\0'; + temp_header->name = strdup(head); + + head = tail+2; + tail = strstr(head, "\r\n"); + *tail = '\0'; + temp_header->value = strdup(head); + + struct_packet->headers = y_list_append(struct_packet->headers, temp_header); + + head = tail+2; + } + head += 2; + tail = raw_packet + length; + *tail = '\0'; + struct_packet->content = strdup(head); +} + +void yahoo_free_http_data(http_data *http_pkt) +{ + YList *rm; + FREE(http_pkt->http_version); + FREE(http_pkt->status_code); + + while(http_pkt->headers) { + rm = http_pkt->headers; + FREE(((namevalue_pair *)(http_pkt->headers->data))->name); + FREE(((namevalue_pair *)(http_pkt->headers->data))->value); + FREE(http_pkt->headers->data); + http_pkt->headers = y_list_remove_link(http_pkt->headers, http_pkt->headers); + y_list_free_1(rm); + } +} + int yahoo_tcp_readline(char *ptr, int maxlen, void *fd) { int n, rc; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |