diff options
| -rw-r--r-- | protocols/yahoo/libyahoo2.c | 2997 | ||||
| -rw-r--r-- | protocols/yahoo/yahoo.c | 111 | ||||
| -rw-r--r-- | protocols/yahoo/yahoo2.h | 15 | ||||
| -rw-r--r-- | protocols/yahoo/yahoo2_callbacks.h | 128 | ||||
| -rw-r--r-- | protocols/yahoo/yahoo2_types.h | 539 | ||||
| -rw-r--r-- | protocols/yahoo/yahoo_httplib.c | 337 | ||||
| -rw-r--r-- | protocols/yahoo/yahoo_httplib.h | 26 | ||||
| -rw-r--r-- | protocols/yahoo/yahoo_list.h | 2 | 
8 files changed, 2170 insertions, 1985 deletions
| diff --git a/protocols/yahoo/libyahoo2.c b/protocols/yahoo/libyahoo2.c index c376a2de..bd111654 100644 --- a/protocols/yahoo/libyahoo2.c +++ b/protocols/yahoo/libyahoo2.c @@ -107,7 +107,9 @@ void yahoo_register_callbacks(struct yahoo_callbacks *tyc)  #define YAHOO_CALLBACK(x)	x  #endif -static int yahoo_send_data(int fd, void *data, int len); +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);  int yahoo_log_message(char *fmt, ...)  { @@ -139,9 +141,15 @@ int yahoo_set_log_level(enum yahoo_log_level level)  }  /* default values for servers */ -static char pager_host[] = "scs.msg.yahoo.com";  +static char *default_pager_hosts[] = {	"scs.msg.yahoo.com", +					"scsa.msg.yahoo.com", +					"scsb.msg.yahoo.com", +					"scsc.msg.yahoo.com", +					NULL}; +  static int pager_port = 5050;  static int fallback_ports[] = { 23, 25, 80, 20, 119, 8001, 8002, 5050, 0 }; +  static char filetransfer_host[] = "filetransfer.msg.yahoo.com";  static int filetransfer_port = 80;  static char webcam_host[] = "webcam.yahoo.com"; @@ -152,84 +160,11 @@ static int conn_type = Y_WCM_DSL;  static char profile_url[] = "http://profiles.yahoo.com/"; -enum yahoo_service { /* these are easier to see in hex */ -	YAHOO_SERVICE_LOGON = 1, -	YAHOO_SERVICE_LOGOFF, -	YAHOO_SERVICE_ISAWAY, -	YAHOO_SERVICE_ISBACK, -	YAHOO_SERVICE_IDLE, /* 5 (placemarker) */ -	YAHOO_SERVICE_MESSAGE, -	YAHOO_SERVICE_IDACT, -	YAHOO_SERVICE_IDDEACT, -	YAHOO_SERVICE_MAILSTAT, -	YAHOO_SERVICE_USERSTAT, /* 0xa */ -	YAHOO_SERVICE_NEWMAIL, -	YAHOO_SERVICE_CHATINVITE, -	YAHOO_SERVICE_CALENDAR, -	YAHOO_SERVICE_NEWPERSONALMAIL, -	YAHOO_SERVICE_NEWCONTACT, -	YAHOO_SERVICE_ADDIDENT, /* 0x10 */ -	YAHOO_SERVICE_ADDIGNORE, -	YAHOO_SERVICE_PING, -	YAHOO_SERVICE_GOTGROUPRENAME, /* < 1, 36(old), 37(new) */ -	YAHOO_SERVICE_SYSMESSAGE = 0x14, -	YAHOO_SERVICE_SKINNAME = 0x15, -	YAHOO_SERVICE_PASSTHROUGH2 = 0x16, -	YAHOO_SERVICE_CONFINVITE = 0x18, -	YAHOO_SERVICE_CONFLOGON, -	YAHOO_SERVICE_CONFDECLINE, -	YAHOO_SERVICE_CONFLOGOFF, -	YAHOO_SERVICE_CONFADDINVITE, -	YAHOO_SERVICE_CONFMSG, -	YAHOO_SERVICE_CHATLOGON, -	YAHOO_SERVICE_CHATLOGOFF, -	YAHOO_SERVICE_CHATMSG = 0x20, -	YAHOO_SERVICE_GAMELOGON = 0x28, -	YAHOO_SERVICE_GAMELOGOFF, -	YAHOO_SERVICE_GAMEMSG = 0x2a, -	YAHOO_SERVICE_FILETRANSFER = 0x46, -	YAHOO_SERVICE_VOICECHAT = 0x4A, -	YAHOO_SERVICE_NOTIFY, -	YAHOO_SERVICE_VERIFY, -	YAHOO_SERVICE_P2PFILEXFER, -	YAHOO_SERVICE_PEERTOPEER = 0x4F,	/* Checks if P2P possible */ -	YAHOO_SERVICE_WEBCAM, -	YAHOO_SERVICE_AUTHRESP = 0x54, -	YAHOO_SERVICE_LIST, -	YAHOO_SERVICE_AUTH = 0x57, -	YAHOO_SERVICE_AUTHBUDDY = 0x6d, -	YAHOO_SERVICE_ADDBUDDY = 0x83, -	YAHOO_SERVICE_REMBUDDY, -	YAHOO_SERVICE_IGNORECONTACT,	/* > 1, 7, 13 < 1, 66, 13, 0*/ -	YAHOO_SERVICE_REJECTCONTACT, -	YAHOO_SERVICE_GROUPRENAME = 0x89, /* > 1, 65(new), 66(0), 67(old) */ -	YAHOO_SERVICE_Y7_PING = 0x8A, /* 0 - id and that's it?? */ -	YAHOO_SERVICE_CHATONLINE = 0x96, /* > 109(id), 1, 6(abcde) < 0,1*/ -	YAHOO_SERVICE_CHATGOTO, -	YAHOO_SERVICE_CHATJOIN,	/* > 1 104-room 129-1600326591 62-2 */ -	YAHOO_SERVICE_CHATLEAVE, -	YAHOO_SERVICE_CHATEXIT = 0x9b, -	YAHOO_SERVICE_CHATADDINVITE = 0x9d, -	YAHOO_SERVICE_CHATLOGOUT = 0xa0, -	YAHOO_SERVICE_CHATPING, -	YAHOO_SERVICE_COMMENT = 0xa8, -	YAHOO_SERVICE_STEALTH = 0xb9, -	YAHOO_SERVICE_PICTURE_CHECKSUM = 0xbd, -	YAHOO_SERVICE_PICTURE = 0xbe, -	YAHOO_SERVICE_PICTURE_UPDATE = 0xc1, -	YAHOO_SERVICE_PICTURE_UPLOAD = 0xc2, -	YAHOO_SERVICE_Y6_VISIBILITY = 0xc5, -	YAHOO_SERVICE_Y6_STATUS_UPDATE = 0xc6, -	YAHOO_PHOTOSHARE_INIT = 0xd2,	 -	YAHOO_SERVICE_CONTACT_YMSG13 = 0xd6, -	YAHOO_PHOTOSHARE_PREV = 0xd7, -	YAHOO_PHOTOSHARE_KEY = 0xd8, -	YAHOO_PHOTOSHARE_TRANS = 0xda, -	YAHOO_FILE_TRANSFER_INIT_YMSG13 = 0xdc, -	YAHOO_FILE_TRANSFER_GET_YMSG13 = 0xdd, -	YAHOO_FILE_TRANSFER_PUT_YMSG13 = 0xde, -	YAHOO_SERVICE_YMSG15_STATUS = 0xf0, -	YAHOO_SERVICE_YMSG15_BUDDY_LIST = 0xf1, +struct connect_callback_data { +	struct yahoo_data *yd; +	int tag; +	int i; +	int server_i;  };  struct yahoo_pair { @@ -267,9 +202,9 @@ struct yahoo_input_data {  	struct yahoo_webcam_data *wcd;  	struct yahoo_search_state *ys; -	int fd; +	void *fd;  	enum yahoo_connection_type type; -	 +  	unsigned char *rxqueue;  	int rxlen;  	int read_tag; @@ -288,13 +223,31 @@ struct yahoo_server_settings {  	char *webcam_description;  	char *local_host;  	int conn_type; +	char **pager_host_list;  }; +static void yahoo_process_ft_connection(struct yahoo_input_data *yid, int over); + +static void yahoo_process_filetransfer(struct yahoo_input_data *yid, +	struct yahoo_packet *pkt); +static void yahoo_process_filetransferinfo(struct yahoo_input_data *yid, +	struct yahoo_packet *pkt); +static void yahoo_process_filetransferaccept(struct yahoo_input_data *yid, +	struct yahoo_packet *pkt); + +static void yahoo_https_auth(struct yahoo_input_data *yid, const char *seed, const char *sn); +  static void *_yahoo_default_server_settings()  { -	struct yahoo_server_settings *yss = y_new0(struct yahoo_server_settings, 1); +	struct yahoo_server_settings *yss = +		y_new0(struct yahoo_server_settings, 1); + +	/* Give preference to the default host list +	 * Make sure that only one of the two is set at any time  +	 */ +	yss->pager_host = NULL; +	yss->pager_host_list = default_pager_hosts; -	yss->pager_host = strdup(pager_host);  	yss->pager_port = pager_port;  	yss->filetransfer_host = strdup(filetransfer_host);  	yss->filetransfer_port = filetransfer_port; @@ -313,6 +266,7 @@ static void *_yahoo_assign_server_settings(va_list ap)  	char *key;  	char *svalue;  	int nvalue; +	char **pvalue;  	while (1) {  		key = va_arg(ap, char *); @@ -323,6 +277,12 @@ static void *_yahoo_assign_server_settings(va_list ap)  			svalue = va_arg(ap, char *);  			free(yss->pager_host);  			yss->pager_host = strdup(svalue); +			yss->pager_host_list = NULL; +		} else if (!strcmp(key, "pager_host_list")) { +			pvalue = va_arg(ap, char **); +			yss->pager_host_list = pvalue; +			free(yss->pager_host); +			yss->pager_host = NULL;  		} else if (!strcmp(key, "pager_port")) {  			nvalue = va_arg(ap, int);  			yss->pager_port = nvalue; @@ -383,6 +343,7 @@ static void add_to_list(struct yahoo_data *yd)  {  	conns = y_list_prepend(conns, yd);  } +  static struct yahoo_data *find_conn_by_id(int id)  {  	YList *l; @@ -393,13 +354,15 @@ static struct yahoo_data *find_conn_by_id(int id)  	}  	return NULL;  } +  static void del_from_list(struct yahoo_data *yd)  {  	conns = y_list_remove(conns, yd);  }  /* call repeatedly to get the next one */ -static struct yahoo_input_data *find_input_by_id(int id) +/* +static struct yahoo_input_data * find_input_by_id(int id)  {  	YList *l;  	for(l = inputs; l; l = y_list_next(l)) { @@ -409,23 +372,27 @@ static struct yahoo_input_data *find_input_by_id(int id)  	}  	return NULL;  } +*/ -static struct yahoo_input_data *find_input_by_id_and_webcam_user(int id, const char *who) +static struct yahoo_input_data *find_input_by_id_and_webcam_user(int id, +	const char *who)  {  	YList *l;  	LOG(("find_input_by_id_and_webcam_user"));  	for (l = inputs; l; l = y_list_next(l)) {  		struct yahoo_input_data *yid = l->data; -		if (yid->type == YAHOO_CONNECTION_WEBCAM && yid->yd->client_id == id  -				&& yid->wcm &&  -				((who && yid->wcm->user && !strcmp(who, yid->wcm->user)) || -				 !(yid->wcm->user && !who))) +		if (yid->type == YAHOO_CONNECTION_WEBCAM +			&& yid->yd->client_id == id && yid->wcm && ((who +					&& yid->wcm->user +					&& !strcmp(who, yid->wcm->user)) +				|| !(yid->wcm->user && !who)))  			return yid;  	}  	return NULL;  } -static struct yahoo_input_data *find_input_by_id_and_type(int id, enum yahoo_connection_type type) +static struct yahoo_input_data *find_input_by_id_and_type(int id, +	enum yahoo_connection_type type)  {  	YList *l;  	LOG(("find_input_by_id_and_type")); @@ -437,7 +404,7 @@ static struct yahoo_input_data *find_input_by_id_and_type(int id, enum yahoo_con  	return NULL;  } -static struct yahoo_input_data *find_input_by_id_and_fd(int id, int fd) +static struct yahoo_input_data *find_input_by_id_and_fd(int id, void *fd)  {  	YList *l;  	LOG(("find_input_by_id_and_fd")); @@ -463,7 +430,6 @@ static int count_inputs_with_id(int id)  	return c;  } -  extern char *yahoo_crypt(char *, char *);  /* Free a buddy list */ @@ -527,6 +493,7 @@ static void yahoo_free_data(struct yahoo_data *yd)  	FREE(yd->password);  	FREE(yd->cookie_y);  	FREE(yd->cookie_t); +	FREE(yd->cookie_b);  	FREE(yd->cookie_c);  	FREE(yd->login_cookie);  	FREE(yd->login_id); @@ -542,8 +509,8 @@ static void yahoo_free_data(struct yahoo_data *yd)  #define YAHOO_PACKET_HDRLEN (4 + 2 + 2 + 2 + 2 + 4 + 4) -static struct yahoo_packet *yahoo_packet_new(enum yahoo_service service,  -		enum yahoo_status status, int id) +static struct yahoo_packet *yahoo_packet_new(enum yahoo_service service, +	enum ypacket_status status, int id)  {  	struct yahoo_packet *pkt = y_new0(struct yahoo_packet, 1); @@ -554,7 +521,8 @@ static struct yahoo_packet *yahoo_packet_new(enum yahoo_service service,  	return pkt;  } -static void yahoo_packet_hash(struct yahoo_packet *pkt, int key, const char *value) +static void yahoo_packet_hash(struct yahoo_packet *pkt, int key, +	const char *value)  {  	struct yahoo_pair *pair = y_new0(struct yahoo_pair, 1);  	pair->key = key; @@ -599,7 +567,8 @@ static int yahoo_packet_length(struct yahoo_packet *pkt)  			 (((*((buf)+2))&0xff)<< 8) + \  			 (((*((buf)+3))&0xff))) -static void yahoo_packet_read(struct yahoo_packet *pkt, unsigned char *data, int len) +static void yahoo_packet_read(struct yahoo_packet *pkt, unsigned char *data, +	int len)  {  	int pos = 0; @@ -652,7 +621,8 @@ static void yahoo_packet_read(struct yahoo_packet *pkt, unsigned char *data, int  			pair->value = strdup(value);  			FREE(value);  			pkt->hash = y_list_append(pkt->hash, pair); -			DEBUG_MSG(("Key: %d  \tValue: %s", pair->key, pair->value)); +			DEBUG_MSG(("Key: %d  \tValue: %s", pair->key, +					pair->value));  		} else {  			FREE(pair);  		} @@ -787,18 +757,18 @@ static void yahoo_packet_free(struct yahoo_packet *pkt)  	FREE(pkt);  } -static int yahoo_send_data(int fd, void *data, int len) +static int yahoo_send_data(void *fd, void *data, int len)  {  	int ret;  	int e; -	if (fd < 0) +	if (fd == NULL)  		return -1;  	yahoo_packet_dump(data, len);  	do { -		ret = write(fd, data, len); +		ret = YAHOO_CALLBACK(ext_yahoo_write) (fd, data, len);  	} while (ret == -1 && errno == EINTR);  	e = errno; @@ -837,7 +807,7 @@ static void yahoo_input_close(struct yahoo_input_data *yid)  		yid->write_tag);  	yid->read_tag = yid->write_tag = 0;  	if (yid->fd) -		close(yid->fd); +		YAHOO_CALLBACK(ext_yahoo_close) (yid->fd);  	yid->fd = 0;  	FREE(yid->rxqueue);  	if (count_inputs_with_id(yid->yd->client_id) == 0) { @@ -941,7 +911,7 @@ static void yahoo_process_notify(struct yahoo_input_data *yid,  			from, stat);  	else if (!strncasecmp(msg, "GAME", strlen("GAME")))  		YAHOO_CALLBACK(ext_yahoo_game_notify) (yd->client_id, to, from, -			stat); +			stat, ind);  	else if (!strncasecmp(msg, "WEBCAMINVITE", strlen("WEBCAMINVITE"))) {  		if (!strcmp(ind, " ")) {  			YAHOO_CALLBACK(ext_yahoo_webcam_invite) (yd->client_id, @@ -958,63 +928,8 @@ static void yahoo_process_notify(struct yahoo_input_data *yid,  		LOG(("Got unknown notification: %s", msg));  } -static void yahoo_process_filetransfer(struct yahoo_input_data *yid, struct yahoo_packet *pkt) -{ -	struct yahoo_data *yd = yid->yd; -	char *from = NULL; -	char *to = NULL; -	char *msg = NULL; -	char *url = NULL; -	long expires = 0; - -	char *service = NULL; - -	char *filename = NULL; -	unsigned long filesize = 0L; - -	YList *l; -	for (l = pkt->hash; l; l = l->next) { -		struct yahoo_pair *pair = l->data; -		if (pair->key == 4) -			from = pair->value; -		if (pair->key == 5) -			to = pair->value; -		if (pair->key == 14) -			msg = pair->value; -		if (pair->key == 20) -			url = pair->value; -		if (pair->key == 38) -			expires = atol(pair->value); - -		if (pair->key == 27) -			filename = pair->value; -		if (pair->key == 28) -			filesize = atol(pair->value); - -		if (pair->key == 49) -			service = pair->value; -	} - -	if (pkt->service == YAHOO_SERVICE_P2PFILEXFER) { -		if (strcmp("FILEXFER", service) != 0) { -			WARNING(("unhandled service 0x%02x", pkt->service)); -			yahoo_dump_unhandled(pkt); -			return; -		} -	} - -	if (msg) { -		char *tmp; -		tmp = strchr(msg, '\006'); -		if (tmp) -			*tmp = '\0'; -	} -	if (url && from) -		YAHOO_CALLBACK(ext_yahoo_got_file) (yd->client_id, to, from, url, expires, msg, filename, filesize); - -} - -static void yahoo_process_conference(struct yahoo_input_data *yid, struct yahoo_packet *pkt) +static void yahoo_process_conference(struct yahoo_input_data *yid, +	struct yahoo_packet *pkt)  {  	struct yahoo_data *yd = yid->yd;  	char *msg = NULL; @@ -1089,10 +1004,9 @@ static void yahoo_process_conference(struct yahoo_input_data *yid, struct yahoo_  				E_CONFNOTAVAIL);  		break;  	case YAHOO_SERVICE_CONFADDINVITE: -		if (pkt->status == 2) -			; -		else -			YAHOO_CALLBACK(ext_yahoo_got_conf_invite) (yd->client_id, id, host, room, msg, members); +		if (pkt->status == 1) +			YAHOO_CALLBACK(ext_yahoo_got_conf_invite) (yd-> +				client_id, id, host, room, msg, members);  		break;  	case YAHOO_SERVICE_CONFDECLINE:  		if (who) @@ -1133,7 +1047,7 @@ static void yahoo_process_chat(struct yahoo_input_data *yid,  	int membercount = 0;  	int chaterr = 0;  	YList *l; -	 +  	yahoo_dump_unhandled(pkt);  	for (l = pkt->hash; l; l = l->next) {  		struct yahoo_pair *pair = l->data; @@ -1284,6 +1198,7 @@ static void yahoo_process_message(struct yahoo_input_data *yid,  		long tm;  		char *msg;  		int utf8; +		char *gunk;  	} *message = y_new0(struct m, 1);  	for (l = pkt->hash; l; l = l->next) { @@ -1297,7 +1212,10 @@ static void yahoo_process_message(struct yahoo_input_data *yid,  			message->tm = strtol(pair->value, NULL, 10);  		else if (pair->key == 97)  			message->utf8 = atoi(pair->value); -			/* user message */  /* sys message */ +		/* This comes when the official client sends us a message */ +		else if (pair->key == 429) +			message->gunk = pair->value; +		/* user message *//* sys message */  		else if (pair->key == 14 || pair->key == 16)  			message->msg = pair->value;  		else if (pair->key == 31) { @@ -1317,18 +1235,66 @@ static void yahoo_process_message(struct yahoo_input_data *yid,  	for (l = messages; l; l = l->next) {  		message = l->data;  		if (pkt->service == YAHOO_SERVICE_SYSMESSAGE) { -			YAHOO_CALLBACK(ext_yahoo_system_message) (yd->client_id, message->msg); +			YAHOO_CALLBACK(ext_yahoo_system_message) (yd->client_id, +				message->to, message->from, message->msg);  		} else if (pkt->status <= 2 || pkt->status == 5) { -			YAHOO_CALLBACK(ext_yahoo_got_im) (yd->client_id, message->to, message->from, message->msg, message->tm, pkt->status, message->utf8); +			/* Confirm message receipt if we got the gunk */ +			if(message->gunk) { +				struct yahoo_packet *outpkt; +                         +				outpkt = yahoo_packet_new(YAHOO_SERVICE_MESSAGE_CONFIRM, +					YPACKET_STATUS_DEFAULT, 0); +				yahoo_packet_hash(outpkt, 1, yd->user); +				yahoo_packet_hash(outpkt, 5, message->from); +				yahoo_packet_hash(outpkt, 302, "430"); +				yahoo_packet_hash(outpkt, 430, message->gunk); +				yahoo_packet_hash(outpkt, 303, "430"); +				yahoo_packet_hash(outpkt, 450, "0"); +				yahoo_send_packet(yid, outpkt, 0); +                         +				yahoo_packet_free(outpkt); +			} + +			if (!strcmp(message->msg, "<ding>")) +				YAHOO_CALLBACK(ext_yahoo_got_buzz) (yd->client_id, +					message->to, message->from, message->tm); +			else +				YAHOO_CALLBACK(ext_yahoo_got_im) (yd->client_id, +					message->to, message->from, message->msg, +					message->tm, pkt->status, message->utf8);  		} else if (pkt->status == 0xffffffff) { -			YAHOO_CALLBACK(ext_yahoo_error) (yd->client_id, message->msg, 0, E_SYSTEM); +			YAHOO_CALLBACK(ext_yahoo_error) (yd->client_id, +				message->msg, 0, E_SYSTEM);  		} -		free(message); +		FREE(message);  	}  	y_list_free(messages);  } +/* + * Here's what multi-level packets look like. Data in brackets is the value. + * + * 3 level: + * ======= + *  + * 302 (318) - Beginning level 1 + * 	300 (318) - Begin level 2 + * 	302 (319) - End level 2 header + * 		300 (319) - Begin level 3 + * 		301 (319) - End level 3 + * 	303 (319) - End level 2 + * 303 (318) - End level 1 + * + * 2 level: + * ======= + * + * 302 (315) - Beginning level 1 + * 	300 (315) - Begin level 2 + * 	301 (315) - End level 2 + * 303 (315) - End level 1 + * + */  static void yahoo_process_status(struct yahoo_input_data *yid,  	struct yahoo_packet *pkt)  { @@ -1720,564 +1686,65 @@ static void yahoo_process_picture_upload(struct yahoo_input_data *yid,  	YList *l;  	char *url = NULL; -	if ( pkt->status != 1 ) +	if (pkt->status != 1)  		return;		/* something went wrong */ -	 -	for (l = pkt->hash; l; l = l->next) -	{ + +	for (l = pkt->hash; l; l = l->next) {  		struct yahoo_pair *pair = l->data; -		switch(pair->key) -		{ -			case 5:		/* we */ -				break; -			case 20:		/* url */ -				url = pair->value; -				break; -			case 27:		/* local filename */ -				break; -			case 38:		/* time */ -				break; +		switch (pair->key) { +		case 5:	/* we */ +			break; +		case 20:	/* url */ +			url = pair->value; +			break; +		case 27:	/* local filename */ +			break; +		case 38:	/* time */ +			break;  		}  	}  	YAHOO_CALLBACK(ext_yahoo_buddyicon_uploaded) (yd->client_id, url);  } -static void yahoo_process_auth_pre_0x0b(struct yahoo_input_data *yid,  -		const char *seed, const char *sn) +void yahoo_login(int id, int initial)  { -	struct yahoo_data *yd = yid->yd; -	 -	/* So, Yahoo has stopped supporting its older clients in India, and  -	 * undoubtedly will soon do so in the rest of the world. -	 *  -	 * The new clients use this authentication method.  I warn you in  -	 * advance, it's bizzare, convoluted, inordinately complicated.   -	 * It's also no more secure than crypt() was.  The only purpose this  -	 * scheme could serve is to prevent third part clients from connecting  -	 * to their servers. -	 * -	 * Sorry, Yahoo. -	 */ - -	struct yahoo_packet *pack; -	 -	md5_byte_t result[16]; -	md5_state_t ctx; -	char *crypt_result; -	unsigned char *password_hash = malloc(25); -	unsigned char *crypt_hash = malloc(25); -	unsigned char *hash_string_p = malloc(50 + strlen(sn)); -	unsigned char *hash_string_c = malloc(50 + strlen(sn)); -	 -	char checksum; -	 -	int sv; -	 -	unsigned char *result6 = malloc(25); -	unsigned char *result96 = malloc(25); +	struct yahoo_data *yd = find_conn_by_id(id); +	struct connect_callback_data *ccd; +	struct yahoo_server_settings *yss; +	int tag; -	sv = seed[15]; -	sv = (sv % 8) % 5; +	char *host; -	md5_init(&ctx); -	md5_append(&ctx, (md5_byte_t *)yd->password, strlen(yd->password)); -	md5_finish(&ctx, result); -	to_y64(password_hash, result, 16); -	 -	md5_init(&ctx); -	crypt_result = yahoo_crypt(yd->password, "$1$_2S43d5f$");   -	md5_append(&ctx, (md5_byte_t *)crypt_result, strlen(crypt_result)); -	md5_finish(&ctx, result); -	to_y64(crypt_hash, result, 16); -	free(crypt_result); - -	switch (sv) { -	case 0: -		checksum = seed[seed[7] % 16]; -		snprintf((char *)hash_string_p, strlen(sn) + 50, -			"%c%s%s%s", checksum, password_hash, yd->user, seed); -		snprintf((char *)hash_string_c, strlen(sn) + 50, -			"%c%s%s%s", checksum, crypt_hash, yd->user, seed); -		break; -	case 1: -		checksum = seed[seed[9] % 16]; -		snprintf((char *)hash_string_p, strlen(sn) + 50, -			"%c%s%s%s", checksum, yd->user, seed, password_hash); -		snprintf((char *)hash_string_c, strlen(sn) + 50, -			"%c%s%s%s", checksum, yd->user, seed, crypt_hash); -		break; -	case 2: -		checksum = seed[seed[15] % 16]; -		snprintf((char *)hash_string_p, strlen(sn) + 50, -			"%c%s%s%s", checksum, seed, password_hash, yd->user); -		snprintf((char *)hash_string_c, strlen(sn) + 50, -			"%c%s%s%s", checksum, seed, crypt_hash, yd->user); -		break; -	case 3: -		checksum = seed[seed[1] % 16]; -		snprintf((char *)hash_string_p, strlen(sn) + 50, -			"%c%s%s%s", checksum, yd->user, password_hash, seed); -		snprintf((char *)hash_string_c, strlen(sn) + 50, -			"%c%s%s%s", checksum, yd->user, crypt_hash, seed); -		break; -	case 4: -		checksum = seed[seed[3] % 16]; -		snprintf((char *)hash_string_p, strlen(sn) + 50, -			"%c%s%s%s", checksum, password_hash, seed, yd->user); -		snprintf((char *)hash_string_c, strlen(sn) + 50, -			"%c%s%s%s", checksum, crypt_hash, seed, yd->user); -		break; -	} -		 -	md5_init(&ctx);   -	md5_append(&ctx, (md5_byte_t *)hash_string_p, strlen((char *)hash_string_p)); -	md5_finish(&ctx, result); -	to_y64(result6, result, 16); - -	md5_init(&ctx);   -	md5_append(&ctx, (md5_byte_t *)hash_string_c, strlen((char *)hash_string_c)); -	md5_finish(&ctx, result); -	to_y64(result96, result, 16); +	struct yahoo_input_data *yid = y_new0(struct yahoo_input_data, 1); +	yid->yd = yd; +	yid->type = YAHOO_CONNECTION_PAGER; +	inputs = y_list_prepend(inputs, yid); -	pack = yahoo_packet_new(YAHOO_SERVICE_AUTHRESP, yd->initial_status, yd->session_id); -	yahoo_packet_hash(pack, 0, yd->user); -	yahoo_packet_hash(pack, 6, (char *)result6); -	yahoo_packet_hash(pack, 96, (char *)result96); -	yahoo_packet_hash(pack, 1, yd->user); -		 -	yahoo_send_packet(yid, pack, 0); -		 -	FREE(result6); -	FREE(result96); -	FREE(password_hash); -	FREE(crypt_hash); -	FREE(hash_string_p); -	FREE(hash_string_c); +	yd->initial_status = initial; +	yss = yd->server_settings; -	yahoo_packet_free(pack); +	ccd = y_new0(struct connect_callback_data, 1); +	ccd->yd = yd; -} +	host = yss->pager_host; -/* - * New auth protocol cracked by Cerulean Studios and sent in to Gaim - */ -static void yahoo_process_auth_0x0b(struct yahoo_input_data *yid, const char *seed, const char *sn) -{ -	struct yahoo_packet *pack = NULL; -	struct yahoo_data *yd = yid->yd; +	if (!host) +		host = yss->pager_host_list[0]; -	md5_byte_t         result[16]; -	md5_state_t        ctx; - -	sha1_state_t       ctx1; -	sha1_state_t       ctx2; - -	char *alphabet1 = "FBZDWAGHrJTLMNOPpRSKUVEXYChImkwQ"; -	char *alphabet2 = "F0E1D2C3B4A59687abcdefghijklmnop"; - -	char *challenge_lookup = "qzec2tb3um1olpar8whx4dfgijknsvy5"; -	char *operand_lookup = "+|&%/*^-"; -	char *delimit_lookup = ",;"; - -	unsigned char *password_hash = malloc(25); -	unsigned char *crypt_hash = malloc(25); -	char *crypt_result = NULL; -	unsigned char pass_hash_xor1[64]; -	unsigned char pass_hash_xor2[64]; -	unsigned char crypt_hash_xor1[64]; -	unsigned char crypt_hash_xor2[64]; -	unsigned char chal[7]; -	char resp_6[100]; -	char resp_96[100]; - -	unsigned char digest1[20]; -	unsigned char digest2[20]; -	unsigned char magic_key_char[4]; -	const unsigned char *magic_ptr; - -	unsigned int magic[64]; -	unsigned int magic_work = 0; - -	char comparison_src[20]; - -	int x, j, i; -	int cnt = 0; -	int magic_cnt = 0; -	int magic_len; -	int depth =0, table =0; - -	memset(&pass_hash_xor1, 0, 64); -	memset(&pass_hash_xor2, 0, 64); -	memset(&crypt_hash_xor1, 0, 64); -	memset(&crypt_hash_xor2, 0, 64); -	memset(&digest1, 0, 20); -	memset(&digest2, 0, 20); -	memset(&magic, 0, 64); -	memset(&resp_6, 0, 100); -	memset(&resp_96, 0, 100); -	memset(&magic_key_char, 0, 4); +	tag = YAHOO_CALLBACK(ext_yahoo_connect_async) (yd->client_id, +		host, yss->pager_port, yahoo_connected, ccd, 0); -	/*  -	 * Magic: Phase 1.  Generate what seems to be a 30  -	 * byte value (could change if base64 -	 * ends up differently?  I don't remember and I'm  -	 * tired, so use a 64 byte buffer. +	/* +	 * if tag <= 0, then callback has already been called +	 * so ccd will have been freed  	 */ - -	magic_ptr = (unsigned char *)seed; - -	while (*magic_ptr != 0) { -		char *loc; - -		/* Ignore parentheses.  */ - -		if (*magic_ptr == '(' || *magic_ptr == ')') { -			magic_ptr++; -			continue; -		} - -		/* Characters and digits verify against  -		   the challenge lookup. -		*/ - -		if (isalpha(*magic_ptr) || isdigit(*magic_ptr)) { -			loc = strchr(challenge_lookup, *magic_ptr); -			if (!loc) { -				/* This isn't good */ -				continue; -			} - -			/* Get offset into lookup table and lsh 3. */ - -			magic_work = loc - challenge_lookup; -			magic_work <<= 3; - -			magic_ptr++; -			continue; -		} else { -			unsigned int local_store; - -			loc = strchr(operand_lookup, *magic_ptr); -			if (!loc) { -				/* Also not good. */ -				continue; -			} - -			local_store = loc - operand_lookup; - -			/* Oops; how did this happen? */ -			if (magic_cnt >= 64)  -				break; - -			magic[magic_cnt++] = magic_work | local_store; -			magic_ptr++; -			continue; -		} -	} - -	magic_len = magic_cnt; -	magic_cnt = 0; - -	/* Magic: Phase 2.  Take generated magic value and  -	 * sprinkle fairy dust on the values. */ - -	for (magic_cnt = magic_len-2; magic_cnt >= 0; magic_cnt--) { -		unsigned char byte1; -		unsigned char byte2; - -		/* Bad.  Abort. -		 */ -		if (magic_cnt >= magic_len) { -			WARNING(("magic_cnt(%d)  magic_len(%d)", magic_cnt, magic_len)) -			break; -		} - -		byte1 = magic[magic_cnt]; -		byte2 = magic[magic_cnt+1]; - -		byte1 *= 0xcd; -		byte1 ^= byte2; - -		magic[magic_cnt+1] = byte1; -	} - -	/* Magic: Phase 3.  This computes 20 bytes.  The first 4 bytes are used as our magic  -	 * key (and may be changed later); the next 16 bytes are an MD5 sum of the magic key  -	 * plus 3 bytes.  The 3 bytes are found by looping, and they represent the offsets  -	 * into particular functions we'll later call to potentially alter the magic key.  -	 *  -	 * %-)  -	 */  -	 -	magic_cnt = 1;  -	x = 0;  -	 -	do {  -		unsigned int bl = 0;   -		unsigned int cl = magic[magic_cnt++];  -		 -		if (magic_cnt >= magic_len)  -			break;  -		 -		if (cl > 0x7F) {  -			if (cl < 0xe0)   -				bl = cl = (cl & 0x1f) << 6;   -			else {  -				bl = magic[magic_cnt++];   -                              cl = (cl & 0x0f) << 6;   -                              bl = ((bl & 0x3f) + cl) << 6;   -			}   -			 -			cl = magic[magic_cnt++];   -			bl = (cl & 0x3f) + bl;   -		} else  -			bl = cl;   -		 -		comparison_src[x++] = (bl & 0xff00) >> 8;   -		comparison_src[x++] = bl & 0xff;   -	} while (x < 20);  - -	/* Dump magic key into a char for SHA1 action. */ -	 -		 -	for (x = 0; x < 4; x++)  -		magic_key_char[x] = comparison_src[x]; - -	/* Compute values for recursive function table! */ -	memcpy( chal, magic_key_char, 4 ); -        x = 1; -	for ( i = 0; i < 0xFFFF && x; i++ ) -	{ -		for ( j = 0; j < 5 && x; j++ ) -		{ -			chal[4] = i; -			chal[5] = i >> 8; -			chal[6] = j; -			md5_init( &ctx ); -			md5_append( &ctx, chal, 7 ); -			md5_finish( &ctx, result ); -			if ( memcmp( comparison_src + 4, result, 16 ) == 0 ) -			{ -				depth = i; -				table = j; -				x = 0; -			} -		} -	} - -	/* Transform magic_key_char using transform table */ -	x = magic_key_char[3] << 24  | magic_key_char[2] << 16  -		| magic_key_char[1] << 8 | magic_key_char[0]; -	x = yahoo_xfrm( table, depth, x ); -	x = yahoo_xfrm( table, depth, x ); -	magic_key_char[0] = x & 0xFF; -	magic_key_char[1] = x >> 8 & 0xFF; -	magic_key_char[2] = x >> 16 & 0xFF; -	magic_key_char[3] = x >> 24 & 0xFF; - -	/* Get password and crypt hashes as per usual. */ -	md5_init(&ctx); -	md5_append(&ctx, (md5_byte_t *)yd->password,  strlen(yd->password)); -	md5_finish(&ctx, result); -	to_y64(password_hash, result, 16); - -	md5_init(&ctx); -	crypt_result = yahoo_crypt(yd->password, "$1$_2S43d5f$");   -	md5_append(&ctx, (md5_byte_t *)crypt_result, strlen(crypt_result)); -	md5_finish(&ctx, result); -	to_y64(crypt_hash, result, 16); -	free(crypt_result); - -	/* Our first authentication response is based off  -	 * of the password hash. */ - -	for (x = 0; x < (int)strlen((char *)password_hash); x++)  -		pass_hash_xor1[cnt++] = password_hash[x] ^ 0x36; - -	if (cnt < 64)  -		memset(&(pass_hash_xor1[cnt]), 0x36, 64-cnt); - -	cnt = 0; - -	for (x = 0; x < (int)strlen((char *)password_hash); x++)  -		pass_hash_xor2[cnt++] = password_hash[x] ^ 0x5c; - -	if (cnt < 64)  -		memset(&(pass_hash_xor2[cnt]), 0x5c, 64-cnt); - -	sha1_init(&ctx1); -	sha1_init(&ctx2); - -	/* The first context gets the password hash XORed  -	 * with 0x36 plus a magic value -	 * which we previously extrapolated from our  -	 * challenge. */ - -	sha1_append(&ctx1, pass_hash_xor1, 64); -	if (j >= 3 ) -		ctx1.Length_Low = 0x1ff; -	sha1_append(&ctx1, magic_key_char, 4); -	sha1_finish(&ctx1, digest1); - -	 /* The second context gets the password hash XORed  -	  * with 0x5c plus the SHA-1 digest -	  * of the first context. */ - -	sha1_append(&ctx2, pass_hash_xor2, 64); -	sha1_append(&ctx2, digest1, 20); -	sha1_finish(&ctx2, digest2); - -	/* Now that we have digest2, use it to fetch  -	 * characters from an alphabet to construct -	 * our first authentication response. */ - -	for (x = 0; x < 20; x += 2) { -		unsigned int val = 0; -		unsigned int lookup = 0; -		char byte[6]; - -		memset(&byte, 0, 6); - -		/* First two bytes of digest stuffed  -		 *  together. -		 */ - -		val = digest2[x]; -		val <<= 8; -		val += digest2[x+1]; - -		lookup = (val >> 0x0b); -		lookup &= 0x1f; -		if (lookup >= strlen(alphabet1)) -			break; -		sprintf(byte, "%c", alphabet1[lookup]); -		strcat(resp_6, byte); -		strcat(resp_6, "="); - -		lookup = (val >> 0x06); -		lookup &= 0x1f; -		if (lookup >= strlen(alphabet2)) -			break; -		sprintf(byte, "%c", alphabet2[lookup]); -		strcat(resp_6, byte); - -		lookup = (val >> 0x01); -		lookup &= 0x1f; -		if (lookup >= strlen(alphabet2)) -			break; -		sprintf(byte, "%c", alphabet2[lookup]); -		strcat(resp_6, byte); - -		lookup = (val & 0x01); -		if (lookup >= strlen(delimit_lookup)) -			break; -		sprintf(byte, "%c", delimit_lookup[lookup]); -		strcat(resp_6, byte); -	} - -	/* Our second authentication response is based off  -	 * of the crypto hash. */ - -	cnt = 0; -	memset(&digest1, 0, 20); -	memset(&digest2, 0, 20); - -	for (x = 0; x < (int)strlen((char *)crypt_hash); x++)  -		crypt_hash_xor1[cnt++] = crypt_hash[x] ^ 0x36; - -	if (cnt < 64)  -		memset(&(crypt_hash_xor1[cnt]), 0x36, 64-cnt); - -	cnt = 0; - -	for (x = 0; x < (int)strlen((char *)crypt_hash); x++)  -		crypt_hash_xor2[cnt++] = crypt_hash[x] ^ 0x5c; - -	if (cnt < 64)  -		memset(&(crypt_hash_xor2[cnt]), 0x5c, 64-cnt); - -	sha1_init(&ctx1); -	sha1_init(&ctx2); - -	/* The first context gets the password hash XORed  -	 * with 0x36 plus a magic value -	 * which we previously extrapolated from our  -	 * challenge. */ - -	sha1_append(&ctx1, crypt_hash_xor1, 64); -	if (j >= 3 ) -		ctx1.Length_Low = 0x1ff; -	sha1_append(&ctx1, magic_key_char, 4); -	sha1_finish(&ctx1, digest1); - -	/* The second context gets the password hash XORed  -	 * with 0x5c plus the SHA-1 digest -	 * of the first context. */ - -	sha1_append(&ctx2, crypt_hash_xor2, 64); -	sha1_append(&ctx2, digest1, 20); -	sha1_finish(&ctx2, digest2); - -	/* Now that we have digest2, use it to fetch  -	 * characters from an alphabet to construct -	 * our first authentication response.  */ - -	for (x = 0; x < 20; x += 2) { -		unsigned int val = 0; -		unsigned int lookup = 0; - -		char byte[6]; - -		memset(&byte, 0, 6); - -		/* First two bytes of digest stuffed  -		 *  together. */ - -		val = digest2[x]; -		val <<= 8; -		val += digest2[x+1]; - -		lookup = (val >> 0x0b); -		lookup &= 0x1f; -		if (lookup >= strlen(alphabet1)) -			break; -		sprintf(byte, "%c", alphabet1[lookup]); -		strcat(resp_96, byte); -		strcat(resp_96, "="); - -		lookup = (val >> 0x06); -		lookup &= 0x1f; -		if (lookup >= strlen(alphabet2)) -			break; -		sprintf(byte, "%c", alphabet2[lookup]); -		strcat(resp_96, byte); - -		lookup = (val >> 0x01); -		lookup &= 0x1f; -		if (lookup >= strlen(alphabet2)) -			break; -		sprintf(byte, "%c", alphabet2[lookup]); -		strcat(resp_96, byte); - -		lookup = (val & 0x01); -		if (lookup >= strlen(delimit_lookup)) -			break; -		sprintf(byte, "%c", delimit_lookup[lookup]); -		strcat(resp_96, byte); -	} - -	pack = yahoo_packet_new(YAHOO_SERVICE_AUTHRESP, yd->initial_status, yd->session_id); -	yahoo_packet_hash(pack, 0, sn); -	yahoo_packet_hash(pack, 6, resp_6); -	yahoo_packet_hash(pack, 96, resp_96); -	yahoo_packet_hash(pack, 1, sn); -	yahoo_send_packet(yid, pack, 0); -	yahoo_packet_free(pack); - -	free(password_hash); -	free(crypt_hash); +	if (tag > 0) +		ccd->tag = tag; +	else if (tag < 0) +		YAHOO_CALLBACK(ext_yahoo_login_response) (yd->client_id, +			YAHOO_LOGIN_SOCK, NULL);  }  struct yahoo_https_auth_data @@ -2327,7 +1794,7 @@ static enum yahoo_status yahoo_https_status_parse(int code)  	}  } -static void yahoo_process_auth_0x10(struct yahoo_input_data *yid, const char *seed, const char *sn) +static void yahoo_https_auth(struct yahoo_input_data *yid, const char *seed, const char *sn)  {  	struct yahoo_https_auth_data *had = g_new0(struct yahoo_https_auth_data, 1); @@ -2478,52 +1945,53 @@ fail:  	g_free(had);  } -static void yahoo_process_auth(struct yahoo_input_data *yid, struct yahoo_packet *pkt) +static void yahoo_process_auth(struct yahoo_input_data *yid, +	struct yahoo_packet *pkt)  {  	char *seed = NULL; -	char *sn   = NULL; +	char *sn = NULL;  	YList *l = pkt->hash;  	int m = 0; +	struct yahoo_data *yd = yid->yd;  	while (l) {  		struct yahoo_pair *pair = l->data; -		if (pair->key == 94) + +		switch (pair->key) { +		case 94:  			seed = pair->value; -		if (pair->key == 1) +			break; +		case 1:  			sn = pair->value; -		if (pair->key == 13) +			break; +		case 13:  			m = atoi(pair->value); +			break; +		}  		l = l->next;  	} -	if (!seed)  +	if (!seed)  		return; -	switch (m) { -		case 0: -			yahoo_process_auth_pre_0x0b(yid, seed, sn); -			break; -		case 1: -			yahoo_process_auth_0x0b(yid, seed, sn); -			break; -		case 2: -			yahoo_process_auth_0x10(yid, seed, sn); -			break; -		default: -			/* call error */ -			WARNING(("unknown auth type %d", m)); -			yahoo_process_auth_0x0b(yid, seed, sn); -			break; +	if (m==2) +		yahoo_https_auth(yid, seed, sn); +	else { +		/* call error */ +		WARNING(("unknown auth type %d", m)); +		YAHOO_CALLBACK(ext_yahoo_login_response) (yd->client_id, +			YAHOO_LOGIN_UNKNOWN, NULL);  	}  } -static void yahoo_process_auth_resp(struct yahoo_input_data *yid, struct yahoo_packet *pkt) +static void yahoo_process_auth_resp(struct yahoo_input_data *yid, +	struct yahoo_packet *pkt)  {  	struct yahoo_data *yd = yid->yd;  	char *login_id;  	char *handle;  	char *url = NULL; -	int login_status = 0; +	int login_status = -1;  	YList *l; @@ -2539,9 +2007,10 @@ static void yahoo_process_auth_resp(struct yahoo_input_data *yid, struct yahoo_p  			login_status = atoi(pair->value);  	} -	if (pkt->status == 0xffffffff) { -		YAHOO_CALLBACK(ext_yahoo_login_response) (yd->client_id, login_status, url); -	/*	yahoo_logoff(yd->client_id);*/ +	if (pkt->status == YPACKET_STATUS_DISCONNECTED) { +		YAHOO_CALLBACK(ext_yahoo_login_response) (yd->client_id, +			login_status, url); +		/*      yahoo_logoff(yd->client_id); */  	}  } @@ -2579,6 +2048,37 @@ static void yahoo_process_mail(struct yahoo_input_data *yid,  			NULL, count);  } +static void yahoo_process_new_contact(struct yahoo_input_data *yid, +	struct yahoo_packet *pkt) +{ +	struct yahoo_data *yd = yid->yd; +	char *me = NULL; +	char *who = NULL; +	char *msg = NULL; +	int online = -1; + +	YList *l; + +	for (l = pkt->hash; l; l = l->next) { +		struct yahoo_pair *pair = l->data; +		if (pair->key == 4) +			who = pair->value; +		else if (pair->key == 5) +			me = pair->value; +		else if (pair->key == 14) +			msg = pair->value; +		else if (pair->key == 13) +			online = strtol(pair->value, NULL, 10); +	} + +	if (who && online < 0) +		YAHOO_CALLBACK(ext_yahoo_contact_added) (yd->client_id, me, who, +			msg); +	else if (online == 2) +		YAHOO_CALLBACK(ext_yahoo_rejected) (yd->client_id, who, msg); +} + +/* UNUSED? */  static void yahoo_process_contact(struct yahoo_input_data *yid,  	struct yahoo_packet *pkt)  { @@ -2660,41 +2160,21 @@ static void yahoo_process_buddyadd(struct yahoo_input_data *yid,  	if (!where)  		where = "Unknown"; -	/* status: 0 == Successful, 1 == Error (does not exist), 2 == Already in list */ -	if ( status == 0 ) { -		bud = y_new0(struct yahoo_buddy, 1); -		bud->id = strdup(who); -		bud->group = strdup(where); -		bud->real_name = NULL; -		 -		yd->buddies = y_list_append(yd->buddies, bud); -	 -		/* Possibly called already, but at least the call above doesn't -		   seem to happen every time (not anytime I tried). */ -		YAHOO_CALLBACK(ext_yahoo_contact_added) (yd->client_id, me, who, NULL); -	} +	bud = y_new0(struct yahoo_buddy, 1); +	bud->id = strdup(who); +	bud->group = strdup(where); +	bud->real_name = NULL; -/*	YAHOO_CALLBACK(ext_yahoo_status_changed) (yd->client_id, who, status, NULL, (status==YAHOO_STATUS_AVAILABLE?0:1)); */ -} +	yd->buddies = y_list_append(yd->buddies, bud); -static void yahoo_process_contact_ymsg13(struct yahoo_input_data *yid, struct yahoo_packet *pkt) -{ -	char* who = NULL; -	char* me = NULL;	 -	char* msg = NULL; -	YList *l; -	for (l = pkt->hash; l; l = l->next) { -		struct yahoo_pair *pair = l->data; -		if (pair->key == 4) -			who = pair->value; -		else if (pair->key == 5) -			me = pair->value; -		else -			DEBUG_MSG(("unknown key: %d = %s", pair->key, pair->value)); +	/* A non-zero status (i've seen 2) seems to mean the buddy is already  +	 * added and is online */ +	if (status) { +		LOG(("Setting online see packet for info")); +		yahoo_dump_unhandled(pkt); +		YAHOO_CALLBACK(ext_yahoo_status_changed) (yd->client_id, who, +			YAHOO_STATUS_AVAILABLE, NULL, 0, 0, 0);  	} - -	if (pkt->status==3) -		YAHOO_CALLBACK(ext_yahoo_contact_auth_request) (yid->yd->client_id, me, who, msg);  }  static void yahoo_process_buddydel(struct yahoo_input_data *yid, @@ -2782,7 +2262,7 @@ static void yahoo_process_ignore(struct yahoo_input_data *yid,  	 */  /*	if(status) -		YAHOO_CALLBACK(ext_yahoo_error) (yd->client_id, who, 0, status); +		YAHOO_CALLBACK(ext_yahoo_error)(yd->client_id, who, 0, status);  */  } @@ -2836,7 +2316,32 @@ static void yahoo_process_ping(struct yahoo_input_data *yid,  	YAHOO_CALLBACK(ext_yahoo_got_ping) (yid->yd->client_id, errormsg);  } -static void _yahoo_webcam_get_server_connected(int fd, int error, void *d) +static void yahoo_process_buddy_change_group(struct yahoo_input_data *yid, +	struct yahoo_packet *pkt) +{ +	YList *l; +	char *me = NULL; +	char *who = NULL; +	char *old_group = NULL; +	char *new_group = NULL; + +	for (l = pkt->hash; l; l = l->next) { +		struct yahoo_pair *pair = l->data; +		if (pair->key == 1) +			me = pair->value; +		if (pair->key == 7) +			who = pair->value; +		if (pair->key == 224) +			old_group = pair->value; +		if (pair->key == 264) +			new_group = pair->value; +	} + +	YAHOO_CALLBACK(ext_yahoo_got_buddy_change_group) (yid->yd->client_id, +		me, who, old_group, new_group); +} + +static void _yahoo_webcam_get_server_connected(void *fd, int error, void *d)  {  	struct yahoo_input_data *yid = d;  	char *who = yid->wcm->user; @@ -2847,7 +2352,7 @@ static void _yahoo_webcam_get_server_connected(int fd, int error, void *d)  	unsigned int len = 0;  	unsigned int pos = 0; -	if (error || fd <= 0) { +	if (error || !fd) {  		FREE(who);  		FREE(yid);  		return; @@ -2904,7 +2409,7 @@ static void yahoo_webcam_get_server(struct yahoo_input_data *y, char *who,  	YAHOO_CALLBACK(ext_yahoo_connect_async) (yid->yd->client_id,  		yss->webcam_host, yss->webcam_port, -		_yahoo_webcam_get_server_connected, yid); +		_yahoo_webcam_get_server_connected, yid, 0);  } @@ -2951,7 +2456,7 @@ static void yahoo_packet_process(struct yahoo_input_data *yid,  	case YAHOO_SERVICE_IDACT:  	case YAHOO_SERVICE_IDDEACT:  	case YAHOO_SERVICE_Y6_STATUS_UPDATE: -	case YAHOO_SERVICE_YMSG15_STATUS: +	case YAHOO_SERVICE_Y8_STATUS:  		yahoo_process_status(yid, pkt);  		break;  	case YAHOO_SERVICE_NOTIFY: @@ -2965,7 +2470,9 @@ static void yahoo_packet_process(struct yahoo_input_data *yid,  	case YAHOO_SERVICE_NEWMAIL:  		yahoo_process_mail(yid, pkt);  		break; -	case YAHOO_SERVICE_REJECTCONTACT: +	case YAHOO_SERVICE_Y7_AUTHORIZATION: +		yahoo_process_new_contact(yid, pkt); +		break;  	case YAHOO_SERVICE_NEWCONTACT:  		yahoo_process_contact(yid, pkt);  		break; @@ -3000,15 +2507,18 @@ static void yahoo_packet_process(struct yahoo_input_data *yid,  		yahoo_process_chat(yid, pkt);  		break;  	case YAHOO_SERVICE_P2PFILEXFER: -	case YAHOO_SERVICE_FILETRANSFER: +	case YAHOO_SERVICE_Y7_FILETRANSFER:  		yahoo_process_filetransfer(yid, pkt);  		break; +	case YAHOO_SERVICE_Y7_FILETRANSFERINFO: +		yahoo_process_filetransferinfo(yid, pkt); +		break; +	case YAHOO_SERVICE_Y7_FILETRANSFERACCEPT: +		yahoo_process_filetransferaccept(yid, pkt); +		break;  	case YAHOO_SERVICE_ADDBUDDY:  		yahoo_process_buddyadd(yid, pkt);  		break; -	case YAHOO_SERVICE_CONTACT_YMSG13: -		yahoo_process_contact_ymsg13(yid,pkt); -		break;  	case YAHOO_SERVICE_REMBUDDY:  		yahoo_process_buddydel(yid, pkt);  		break; @@ -3024,6 +2534,9 @@ static void yahoo_packet_process(struct yahoo_input_data *yid,  	case YAHOO_SERVICE_PING:  		yahoo_process_ping(yid, pkt);  		break; +	case YAHOO_SERVICE_Y7_CHANGE_GROUP: +		yahoo_process_buddy_change_group(yid, pkt); +		break;  	case YAHOO_SERVICE_IDLE:  	case YAHOO_SERVICE_MAILSTAT:  	case YAHOO_SERVICE_CHATINVITE: @@ -3037,6 +2550,7 @@ static void yahoo_packet_process(struct yahoo_input_data *yid,  	case YAHOO_SERVICE_CHATLOGON:  	case YAHOO_SERVICE_CHATLOGOFF:  	case YAHOO_SERVICE_CHATMSG: +	case YAHOO_SERVICE_REJECTCONTACT:  	case YAHOO_SERVICE_PEERTOPEER:  		WARNING(("unhandled service 0x%02x", pkt->service));  		yahoo_dump_unhandled(pkt); @@ -3049,9 +2563,10 @@ static void yahoo_packet_process(struct yahoo_input_data *yid,  		break;  	case YAHOO_SERVICE_PICTURE_UPLOAD:  		yahoo_process_picture_upload(yid, pkt); -		break;	 -	case YAHOO_SERVICE_YMSG15_BUDDY_LIST:	/* Buddy List */ +		break; +	case YAHOO_SERVICE_Y8_LIST:	/* Buddy List */  		yahoo_process_buddy_list(yid, pkt); +		break;  	default:  		WARNING(("unknown service 0x%02x", pkt->service));  		yahoo_dump_unhandled(pkt); @@ -3386,90 +2901,92 @@ static int yahoo_get_webcam_data(struct yahoo_input_data *yid)  			yid->wcd->data_size));  	/* find out what kind of packet we got */ -	switch (yid->wcd->packet_type) -	{ -		case 0x00: -			/* user requests to view webcam (uploading) */ -			if (yid->wcd->data_size && -				yid->wcm->direction == YAHOO_WEBCAM_UPLOAD) { -				end = begin; -				while (end <= yid->rxlen && -					yid->rxqueue[end++] != 13); -				if (end > begin) -				{ -					who = y_memdup(yid->rxqueue + begin, end - begin); -					who[end - begin - 1] = 0; -					YAHOO_CALLBACK(ext_yahoo_webcam_viewer) (yd->client_id, who + 2, 2); -					FREE(who); -				} +	switch (yid->wcd->packet_type) { +	case 0x00: +		/* user requests to view webcam (uploading) */ +		if (yid->wcd->data_size && +			yid->wcm->direction == YAHOO_WEBCAM_UPLOAD) { +			end = begin; +			while (end <= yid->rxlen && yid->rxqueue[end++] != 13) ; +			if (end > begin) { +				who = y_memdup(yid->rxqueue + begin, +					end - begin); +				who[end - begin - 1] = 0; +				YAHOO_CALLBACK(ext_yahoo_webcam_viewer) (yd-> +					client_id, who + 2, 2); +				FREE(who);  			} +		} -			if (yid->wcm->direction == YAHOO_WEBCAM_DOWNLOAD) { -				/* timestamp/status field */ -				/* 0 = declined viewing permission */ -				/* 1 = accepted viewing permission */ -				if (yid->wcd->timestamp == 0) { -					YAHOO_CALLBACK(ext_yahoo_webcam_closed) (yd->client_id, yid->wcm->user, 3); -				} +		if (yid->wcm->direction == YAHOO_WEBCAM_DOWNLOAD) { +			/* timestamp/status field */ +			/* 0 = declined viewing permission */ +			/* 1 = accepted viewing permission */ +			if (yid->wcd->timestamp == 0) { +				YAHOO_CALLBACK(ext_yahoo_webcam_closed) (yd-> +					client_id, yid->wcm->user, 3);  			} +		} +		break; +	case 0x01:		/* status packets?? */ +		/* timestamp contains status info */ +		/* 00 00 00 01 = we have data?? */ +		break; +	case 0x02:		/* image data */ +		YAHOO_CALLBACK(ext_yahoo_got_webcam_image) (yd->client_id, +			yid->wcm->user, yid->rxqueue + begin, +			yid->wcd->data_size, pos - begin, yid->wcd->timestamp); +		break; +	case 0x05:		/* response packets when uploading */ +		if (!yid->wcd->data_size) { +			YAHOO_CALLBACK(ext_yahoo_webcam_data_request) (yd-> +				client_id, yid->wcd->timestamp); +		} +		break; +	case 0x07:		/* connection is closing */ +		switch (reason) { +		case 0x01:	/* user closed connection */ +			closed = 1;  			break; -		case 0x01: /* status packets?? */ -			/* timestamp contains status info */ -			/* 00 00 00 01 = we have data?? */ -			break; -		case 0x02: /* image data */ -			YAHOO_CALLBACK(ext_yahoo_got_webcam_image) (yd->client_id,  -					yid->wcm->user, yid->rxqueue + begin, -					yid->wcd->data_size, pos - begin, -					yid->wcd->timestamp); -			break; -		case 0x05: /* response packets when uploading */ -			if (!yid->wcd->data_size) { -				YAHOO_CALLBACK(ext_yahoo_webcam_data_request) (yd->client_id, yid->wcd->timestamp); -			} -			break; -		case 0x07: /* connection is closing */ -			switch(reason) -			{ -				case 0x01: /* user closed connection */ -					closed = 1; -					break; -				case 0x0F: /* user cancelled permission */ -					closed = 2; -					break; -			} -			YAHOO_CALLBACK(ext_yahoo_webcam_closed) (yd->client_id, yid->wcm->user, closed); -			break; -		case 0x0C: /* user connected */ -		case 0x0D: /* user disconnected */ -			if (yid->wcd->data_size) { -				who = y_memdup(yid->rxqueue + begin, pos - begin + 1); -				who[pos - begin] = 0; -				if (yid->wcd->packet_type == 0x0C) -					connect = 1; -				else -					connect = 0; -				YAHOO_CALLBACK(ext_yahoo_webcam_viewer) (yd->client_id, who, connect); -				FREE(who); -			} -			break; -		case 0x13: /* user data */ -			/* i = user_ip (ip of the user we are viewing) */ -			/* j = user_ext_ip (external ip of the user we */ - 			/*                are viewing) */ -			break; -		case 0x17: /* ?? */ +		case 0x0F:	/* user cancelled permission */ +			closed = 2;  			break; +		} +		YAHOO_CALLBACK(ext_yahoo_webcam_closed) (yd->client_id, +			yid->wcm->user, closed); +		break; +	case 0x0C:		/* user connected */ +	case 0x0D:		/* user disconnected */ +		if (yid->wcd->data_size) { +			who = y_memdup(yid->rxqueue + begin, pos - begin + 1); +			who[pos - begin] = 0; +			if (yid->wcd->packet_type == 0x0C) +				connect = 1; +			else +				connect = 0; +			YAHOO_CALLBACK(ext_yahoo_webcam_viewer) (yd->client_id, +				who, connect); +			FREE(who); +		} +		break; +	case 0x13:		/* user data */ +		/* i=user_ip (ip of the user we are viewing) */ +		/* j=user_ext_ip (external ip of the user we */ +		/*                are viewing) */ +		break; +	case 0x17:		/* ?? */ +		break;  	}  	yid->wcd->to_read -= pos - begin;  	yid->rxlen -= pos;  	DEBUG_MSG(("rxlen == %d, rxqueue == %p", yid->rxlen, yid->rxqueue)); -	if (yid->rxlen>0) { +	if (yid->rxlen > 0) {  		unsigned char *tmp = y_memdup(yid->rxqueue + pos, yid->rxlen);  		FREE(yid->rxqueue);  		yid->rxqueue = tmp; -		DEBUG_MSG(("new rxlen == %d, rxqueue == %p", yid->rxlen, yid->rxqueue)); +		DEBUG_MSG(("new rxlen == %d, rxqueue == %p", yid->rxlen, +				yid->rxqueue));  	} else {  		DEBUG_MSG(("freed rxqueue == %p", yid->rxqueue));  		FREE(yid->rxqueue); @@ -3482,16 +2999,16 @@ static int yahoo_get_webcam_data(struct yahoo_input_data *yid)  	return 0;  } -int yahoo_write_ready(int id, int fd, void *data) +int yahoo_write_ready(int id, void *fd, void *data)  {  	struct yahoo_input_data *yid = data;  	int len;  	struct data_queue *tx; -	LOG(("write callback: id=%d fd=%d data=%p", id, fd, data)); -	if (!yid || !yid->txqueues || !find_conn_by_id(id)) +	LOG(("write callback: id=%d fd=%p data=%p", id, fd, data)); +	if (!yid || !yid->txqueues)  		return -2; -	 +  	tx = yid->txqueues->data;  	LOG(("writing %d bytes", tx->len));  	len = yahoo_send_data(fd, tx->queue, MIN(1024, tx->len)); @@ -3507,10 +3024,12 @@ int yahoo_write_ready(int id, int fd, void *data)  			tx = l->data;  			free(tx->queue);  			free(tx); -			yid->txqueues = y_list_remove_link(yid->txqueues, yid->txqueues); +			yid->txqueues = +				y_list_remove_link(yid->txqueues, +				yid->txqueues);  			y_list_free_1(l);  		} -		LOG(("yahoo_write_ready(%d, %d) len < 0", id, fd)); +		LOG(("yahoo_write_ready(%d, %p) len < 0", id, fd));  		YAHOO_CALLBACK(ext_yahoo_remove_handler) (id, yid->write_tag);  		yid->write_tag = 0;  		errno = e; @@ -3527,15 +3046,17 @@ int yahoo_write_ready(int id, int fd, void *data)  		YList *l = yid->txqueues;  		free(tx->queue);  		free(tx); -		yid->txqueues = y_list_remove_link(yid->txqueues, yid->txqueues); +		yid->txqueues = +			y_list_remove_link(yid->txqueues, yid->txqueues);  		y_list_free_1(l);  		/* -		if (!yid->txqueues)  -			LOG(("yahoo_write_ready(%d, %d) !yxqueues", id, fd)); -		*/ +		   if(!yid->txqueues)  +		   LOG(("yahoo_write_ready(%d, %d) !yxqueues", id, fd)); +		 */  		if (!yid->txqueues) { -			LOG(("yahoo_write_ready(%d, %d) !yxqueues", id, fd)); -			YAHOO_CALLBACK(ext_yahoo_remove_handler) (id, yid->write_tag); +			LOG(("yahoo_write_ready(%d, %p) !txqueues", id, fd)); +			YAHOO_CALLBACK(ext_yahoo_remove_handler) (id, +				yid->write_tag);  			yid->write_tag = 0;  		}  	} @@ -3543,7 +3064,8 @@ int yahoo_write_ready(int id, int fd, void *data)  	return 1;  } -static void yahoo_process_pager_connection(struct yahoo_input_data *yid, int over) +static void yahoo_process_pager_connection(struct yahoo_input_data *yid, +	int over)  {  	struct yahoo_packet *pkt;  	struct yahoo_data *yd = yid->yd; @@ -3552,8 +3074,8 @@ static void yahoo_process_pager_connection(struct yahoo_input_data *yid, int ove  	if (over)  		return; -	while (find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER)  -			&& (pkt = yahoo_getdata(yid)) != NULL) { +	while (find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER) +		&& (pkt = yahoo_getdata(yid)) != NULL) {  		yahoo_packet_process(yid, pkt); @@ -3561,17 +3083,15 @@ static void yahoo_process_pager_connection(struct yahoo_input_data *yid, int ove  	}  } -static void yahoo_process_ft_connection(struct yahoo_input_data *yid, int over) -{ -} - -static void yahoo_process_chatcat_connection(struct yahoo_input_data *yid, int over) +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>")) { -		YAHOO_CALLBACK(ext_yahoo_chat_cat_xml) (yid->yd->client_id, (char*)yid->rxqueue); +	if (strstr((char *)yid->rxqueue + (yid->rxlen - 20), "</content>")) { +		YAHOO_CALLBACK(ext_yahoo_chat_cat_xml) (yid->yd->client_id, +			(char *)yid->rxqueue);  	}  } @@ -3582,48 +3102,70 @@ static void yahoo_process_yab_connection(struct yahoo_input_data *yid, int over)  	YList *buds;  	int changed = 0;  	int id = yd->client_id; +	int yab_used = 0; + +	LOG(("Got data for YAB"));  	if (over)  		return; -	while (find_input_by_id_and_type(id, YAHOO_CONNECTION_YAB)  -			&& (yab = yahoo_getyab(yid)) != NULL) { +	while (find_input_by_id_and_type(id, YAHOO_CONNECTION_YAB) +		&& (yab = yahoo_getyab(yid)) != NULL) {  		if (!yab->id)  			continue; +  		changed = 1; +		yab_used = 0;  		for (buds = yd->buddies; buds; buds = buds->next) {  			struct yahoo_buddy *bud = buds->data;  			if (!strcmp(bud->id, yab->id)) { +				yab_used = 1;  				bud->yab_entry = yab;  				if (yab->nname) {  					bud->real_name = strdup(yab->nname);  				} else if (yab->fname && yab->lname) { -					bud->real_name = y_new0(char,  -							strlen(yab->fname)+ -							strlen(yab->lname)+2 -							); +					bud->real_name = y_new0(char, +						strlen(yab->fname) + +						strlen(yab->lname) + 2);  					sprintf(bud->real_name, "%s %s", -							yab->fname, yab->lname); +						yab->fname, yab->lname);  				} else if (yab->fname) {  					bud->real_name = strdup(yab->fname);  				} -				break; /* for */ +				break;	/* for */  			}  		} + +		if (!yab_used) { +			FREE(yab->fname); +			FREE(yab->lname); +			FREE(yab->nname); +			FREE(yab->id); +			FREE(yab->email); +			FREE(yab->hphone); +			FREE(yab->wphone); +			FREE(yab->mphone); +			FREE(yab); +		} +  	}  	if (changed) -		YAHOO_CALLBACK(ext_yahoo_got_buddies) (yd->client_id, yd->buddies); +		YAHOO_CALLBACK(ext_yahoo_got_buddies) (yd->client_id, +			yd->buddies);  } -static void yahoo_process_search_connection(struct yahoo_input_data *yid, int over) +static void yahoo_process_search_connection(struct yahoo_input_data *yid, +	int over)  {  	struct yahoo_found_contact *yct = NULL;  	char *p = (char *)yid->rxqueue, *np, *cp;  	int k, n; -	int start = 0, found=0, total=0; +	int start = 0, found = 0, total = 0;  	YList *contacts = NULL; -	struct yahoo_input_data *pyid = find_input_by_id_and_type(yid->yd->client_id, YAHOO_CONNECTION_PAGER); +	struct yahoo_input_data *pyid = +		find_input_by_id_and_type(yid->yd->client_id, +		YAHOO_CONNECTION_PAGER);  	if (!over || !pyid)  		return; @@ -3634,10 +3176,16 @@ static void yahoo_process_search_connection(struct yahoo_input_data *yid, int ov  		for (k = 0; (p = strchr(p, 4)) && (k < 4); k++) {  			p++;  			n = atoi(p); -			switch(k) { -				case 0: found = pyid->ys->lsearch_nfound = n; break; -				case 2: start = pyid->ys->lsearch_nstart = n; break; -				case 3: total = pyid->ys->lsearch_ntotal = n; break; +			switch (k) { +			case 0: +				found = pyid->ys->lsearch_nfound = n; +				break; +			case 2: +				start = pyid->ys->lsearch_nstart = n; +				break; +			case 3: +				total = pyid->ys->lsearch_ntotal = n; +				break;  			}  		} @@ -3652,37 +3200,41 @@ static void yahoo_process_search_connection(struct yahoo_input_data *yid, int ov  			if (!np)  				break;  			*np = 0; -			p = np+1; - -			switch(k++) { -				case 1: -					if (strlen(cp) > 2 && y_list_length(contacts) < total) { -						yct = y_new0(struct yahoo_found_contact, 1); -						contacts = y_list_append(contacts, yct); -						yct->id = cp+2; -					} else { -						*p = 0; -					} -					break; -				case 2:  -					yct->online = !strcmp(cp, "2") ? 1 : 0; -					break; -				case 3:  -					yct->gender = cp; -					break; -				case 4:  -					yct->age = atoi(cp); -					break; -				case 5:  -					if (strcmp(cp, "5") != 0) -						yct->location = cp; -					k = 0; -					break; +			p = np + 1; + +			switch (k++) { +			case 1: +				if (strlen(cp) > 2 +					&& y_list_length(contacts) < total) { +					yct = y_new0(struct yahoo_found_contact, +						1); +					contacts = y_list_append(contacts, yct); +					yct->id = cp + 2; +				} else { +					*p = 0; +				} +				break; +			case 2: +				yct->online = !strcmp(cp, "2") ? 1 : 0; +				break; +			case 3: +				yct->gender = cp; +				break; +			case 4: +				yct->age = atoi(cp); +				break; +			case 5: +				/* not worth the context switch for strcmp */ +				if (cp[0] != '\005' || cp[1] != '\000') +					yct->location = cp; +				k = 0; +				break;  			}  		}  	} -	YAHOO_CALLBACK(ext_yahoo_got_search_result) (yid->yd->client_id, found, start, total, contacts); +	YAHOO_CALLBACK(ext_yahoo_got_search_result) (yid->yd->client_id, found, +		start, total, contacts);  	while (contacts) {  		YList *node = contacts; @@ -3692,7 +3244,7 @@ static void yahoo_process_search_connection(struct yahoo_input_data *yid, int ov  	}  } -static void _yahoo_webcam_connected(int fd, int error, void *d) +static void _yahoo_webcam_connected(void *fd, int error, void *d)  {  	struct yahoo_input_data *yid = d;  	struct yahoo_webcam *wcm = yid->wcm; @@ -3700,12 +3252,12 @@ static void _yahoo_webcam_connected(int fd, int error, void *d)  	char conn_type[100];  	char *data = NULL;  	char *packet = NULL; -	unsigned char magic_nr[] = {1, 0, 0, 0, 1}; +	unsigned char magic_nr[] = { 1, 0, 0, 0, 1 };  	unsigned header_len = 0;  	unsigned int len = 0;  	unsigned int pos = 0; -	if (error || fd <= 0) { +	if (error || !fd) {  		FREE(yid);  		return;  	} @@ -3715,74 +3267,70 @@ static void _yahoo_webcam_connected(int fd, int error, void *d)  	LOG(("Connected"));  	/* send initial packet */ -	switch (wcm->direction) -	{ -		case YAHOO_WEBCAM_DOWNLOAD: -			data = strdup("<REQIMG>"); -			break; -		case YAHOO_WEBCAM_UPLOAD:	 -			data = strdup("<SNDIMG>"); -			break; -		default: -			return; +	switch (wcm->direction) { +	case YAHOO_WEBCAM_DOWNLOAD: +		data = strdup("<REQIMG>"); +		break; +	case YAHOO_WEBCAM_UPLOAD: +		data = strdup("<SNDIMG>"); +		break; +	default: +		return;  	}  	yahoo_add_to_send_queue(yid, data, strlen(data));  	FREE(data);  	/* send data */ -	switch (wcm->direction) -	{ -		case YAHOO_WEBCAM_DOWNLOAD: -			header_len = 8; -			data = strdup("a=2\r\nc=us\r\ne=21\r\nu="); -			data = y_string_append(data, yd->user); -			data = y_string_append(data, "\r\nt="); -			data = y_string_append(data, wcm->key); -			data = y_string_append(data, "\r\ni="); -			data = y_string_append(data, wcm->my_ip); -			data = y_string_append(data, "\r\ng="); -			data = y_string_append(data, wcm->user); -			data = y_string_append(data, "\r\no=w-2-5-1\r\np="); -			snprintf(conn_type, sizeof(conn_type), "%d", wcm->conn_type); -			data = y_string_append(data, conn_type); -			data = y_string_append(data, "\r\n"); -			break; -		case YAHOO_WEBCAM_UPLOAD: -			header_len = 13; -			data = strdup("a=2\r\nc=us\r\nu="); -			data = y_string_append(data, yd->user); -			data = y_string_append(data, "\r\nt="); -			data = y_string_append(data, wcm->key); -			data = y_string_append(data, "\r\ni="); -			data = y_string_append(data, wcm->my_ip); -			data = y_string_append(data, "\r\no=w-2-5-1\r\np="); -			snprintf(conn_type, sizeof(conn_type), "%d", wcm->conn_type); -			data = y_string_append(data, conn_type); -			data = y_string_append(data, "\r\nb="); -			data = y_string_append(data, wcm->description); -			data = y_string_append(data, "\r\n"); -			break; +	switch (wcm->direction) { +	case YAHOO_WEBCAM_DOWNLOAD: +		header_len = 8; +		data = strdup("a=2\r\nc=us\r\ne=21\r\nu="); +		data = y_string_append(data, yd->user); +		data = y_string_append(data, "\r\nt="); +		data = y_string_append(data, wcm->key); +		data = y_string_append(data, "\r\ni="); +		data = y_string_append(data, wcm->my_ip); +		data = y_string_append(data, "\r\ng="); +		data = y_string_append(data, wcm->user); +		data = y_string_append(data, "\r\no=w-2-5-1\r\np="); +		snprintf(conn_type, sizeof(conn_type), "%d", wcm->conn_type); +		data = y_string_append(data, conn_type); +		data = y_string_append(data, "\r\n"); +		break; +	case YAHOO_WEBCAM_UPLOAD: +		header_len = 13; +		data = strdup("a=2\r\nc=us\r\nu="); +		data = y_string_append(data, yd->user); +		data = y_string_append(data, "\r\nt="); +		data = y_string_append(data, wcm->key); +		data = y_string_append(data, "\r\ni="); +		data = y_string_append(data, wcm->my_ip); +		data = y_string_append(data, "\r\no=w-2-5-1\r\np="); +		snprintf(conn_type, sizeof(conn_type), "%d", wcm->conn_type); +		data = y_string_append(data, conn_type); +		data = y_string_append(data, "\r\nb="); +		data = y_string_append(data, wcm->description); +		data = y_string_append(data, "\r\n"); +		break;  	}  	len = strlen(data);  	packet = y_new0(char, header_len + len);  	packet[pos++] = header_len;  	packet[pos++] = 0; -	switch (wcm->direction) -	{ -		case YAHOO_WEBCAM_DOWNLOAD: -			packet[pos++] = 1; -			packet[pos++] = 0; -			break; -		case YAHOO_WEBCAM_UPLOAD: -			packet[pos++] = 5; -			packet[pos++] = 0; -			break; +	switch (wcm->direction) { +	case YAHOO_WEBCAM_DOWNLOAD: +		packet[pos++] = 1; +		packet[pos++] = 0; +		break; +	case YAHOO_WEBCAM_UPLOAD: +		packet[pos++] = 5; +		packet[pos++] = 0; +		break;  	}  	pos += yahoo_put32(packet + pos, len); -	if (wcm->direction == YAHOO_WEBCAM_UPLOAD) -	{ +	if (wcm->direction == YAHOO_WEBCAM_UPLOAD) {  		memcpy(packet + pos, magic_nr, sizeof(magic_nr));  		pos += sizeof(magic_nr);  	} @@ -3791,7 +3339,9 @@ static void _yahoo_webcam_connected(int fd, int error, void *d)  	FREE(packet);  	FREE(data); -	yid->read_tag = YAHOO_CALLBACK(ext_yahoo_add_handler) (yid->yd->client_id, yid->fd, YAHOO_INPUT_READ, yid); +	yid->read_tag = +		YAHOO_CALLBACK(ext_yahoo_add_handler) (yid->yd->client_id, +		yid->fd, YAHOO_INPUT_READ, yid);  }  static void yahoo_webcam_connect(struct yahoo_input_data *y) @@ -3816,14 +3366,15 @@ static void yahoo_webcam_connect(struct yahoo_input_data *y)  	yid->wcd = y_new0(struct yahoo_webcam_data, 1);  	LOG(("Connecting to: %s:%d", wcm->server, wcm->port)); -	YAHOO_CALLBACK(ext_yahoo_connect_async) (y->yd->client_id, wcm->server, wcm->port, -			_yahoo_webcam_connected, yid); +	YAHOO_CALLBACK(ext_yahoo_connect_async) (y->yd->client_id, wcm->server, +		wcm->port, _yahoo_webcam_connected, yid, 0);  } -static void yahoo_process_webcam_master_connection(struct yahoo_input_data *yid, int over) +static void yahoo_process_webcam_master_connection(struct yahoo_input_data *yid, +	int over)  { -	char* server; +	char *server;  	struct yahoo_server_settings *yss;  	if (over) @@ -3831,8 +3382,7 @@ static void yahoo_process_webcam_master_connection(struct yahoo_input_data *yid,  	server = yahoo_getwebcam_master(yid); -	if (server) -	{ +	if (server) {  		yss = yid->yd->server_settings;  		yid->wcm->server = strdup(server);  		yid->wcm->port = yss->webcam_port; @@ -3845,45 +3395,44 @@ static void yahoo_process_webcam_master_connection(struct yahoo_input_data *yid,  	}  } -static void yahoo_process_webcam_connection(struct yahoo_input_data *yid, int over) +static void yahoo_process_webcam_connection(struct yahoo_input_data *yid, +	int over)  {  	int id = yid->yd->client_id; -	int fd = yid->fd; +	void *fd = yid->fd;  	if (over)  		return;  	/* as long as we still have packets available keep processing them */ -	while (find_input_by_id_and_fd(id, fd)  -			&& yahoo_get_webcam_data(yid) == 1); -} - -static void (*yahoo_process_connection[])(struct yahoo_input_data *, int over) = { -	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, -}; +	while (find_input_by_id_and_fd(id, fd) +		&& yahoo_get_webcam_data(yid) == 1) ; +} + +static void (*yahoo_process_connection[]) (struct yahoo_input_data *, +	int over) = { +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}; -int yahoo_read_ready(int id, int fd, void *data) +int yahoo_read_ready(int id, void *fd, void *data)  {  	struct yahoo_input_data *yid = data;  	char buf[1024];  	int len; -	LOG(("read callback: id=%d fd=%d data=%p", id, fd, data)); +	LOG(("read callback: id=%d fd=%p data=%p", id, fd, data));  	if (!yid)  		return -2; -	  	do { -		len = read(fd, buf, sizeof(buf)); +		len = YAHOO_CALLBACK(ext_yahoo_read) (fd, buf, sizeof(buf));  	} while (len == -1 && errno == EINTR); -	if (len == -1 && (errno == EAGAIN||errno == EINTR))	/* we'll try again later */ +	if (len == -1 && (errno == EAGAIN || errno == EINTR))	/* we'll try again later */  		return 1;  	if (len <= 0) { @@ -3891,10 +3440,11 @@ int yahoo_read_ready(int id, int fd, void *data)  		DEBUG_MSG(("len == %d (<= 0)", len));  		if (yid->type == YAHOO_CONNECTION_PAGER) { -			YAHOO_CALLBACK(ext_yahoo_error) (yid->yd->client_id, "Connection closed by server", 1, E_CONNECTION); +			YAHOO_CALLBACK(ext_yahoo_login_response) (yid->yd-> +				client_id, YAHOO_LOGIN_SOCK, NULL);  		} -		yahoo_process_connection[yid->type](yid, 1); +		yahoo_process_connection[yid->type] (yid, 1);  		yahoo_input_close(yid);  		/* no need to return an error, because we've already fixed it */ @@ -3906,11 +3456,13 @@ int yahoo_read_ready(int id, int fd, void *data)  		return -1;  	} -	yid->rxqueue = y_renew(unsigned char, yid->rxqueue, len + yid->rxlen); +	yid->rxqueue = +		y_renew(unsigned char, yid->rxqueue, len + yid->rxlen + 1);  	memcpy(yid->rxqueue + yid->rxlen, buf, len);  	yid->rxlen += len; +	yid->rxqueue[yid->rxlen] = 0; -	yahoo_process_connection[yid->type](yid, 0); +	yahoo_process_connection[yid->type] (yid, 0);  	return len;  } @@ -3947,13 +3499,7 @@ int yahoo_init(const char *username, const char *password)  	return yahoo_init_with_attributes(username, password, NULL);  } -struct connect_callback_data { -	struct yahoo_data *yd; -	int tag; -	int i; -}; - -static void yahoo_connected(int fd, int error, void *data) +static void yahoo_connected(void *fd, int error, void *data)  {  	struct connect_callback_data *ccd = data;  	struct yahoo_data *yd = ccd->yd; @@ -3962,86 +3508,84 @@ static void yahoo_connected(int fd, int error, void *data)  	struct yahoo_server_settings *yss = yd->server_settings;  	if (error) { +		int tag;  		if (fallback_ports[ccd->i]) { -			int tag; +			char *host = yss->pager_host; + +			if (!host) +				host = yss->pager_host_list[ccd->server_i]; +  			yss->pager_port = fallback_ports[ccd->i++]; -			tag = YAHOO_CALLBACK(ext_yahoo_connect_async) (yd->client_id, yss->pager_host, -					yss->pager_port, yahoo_connected, ccd); +			tag = YAHOO_CALLBACK(ext_yahoo_connect_async) (yd-> +				client_id, host, yss->pager_port, +				yahoo_connected, ccd, 0);  			if (tag > 0)  				ccd->tag = tag; +		} else if (yss->pager_host_list +				&& yss->pager_host_list[ccd->server_i]) { + +			/* Get back to the default port */ +			yss->pager_port = pager_port; +			ccd->server_i++; +			LOG(("Fallback: Connecting to %s:%d", yss->pager_host_list[ccd->server_i], yss->pager_port)); + +			ccd->i = 0; +			tag = YAHOO_CALLBACK(ext_yahoo_connect_async) (yd->client_id, +				yss->pager_host_list[ccd->server_i], yss->pager_port, +				yahoo_connected, ccd, 0);  		} else {  			FREE(ccd); -			YAHOO_CALLBACK(ext_yahoo_login_response) (yd->client_id, YAHOO_LOGIN_SOCK, NULL); +			YAHOO_CALLBACK(ext_yahoo_login_response) (yd->client_id, +				YAHOO_LOGIN_SOCK, NULL);  		}  		return;  	}  	FREE(ccd); -	/* fd < 0 && error == 0 means connect was cancelled */ -	if (fd < 0) +	/* fd == NULL && error == 0 means connect was cancelled */ +	if (!fd)  		return; -	pkt = yahoo_packet_new(YAHOO_SERVICE_AUTH, YAHOO_STATUS_AVAILABLE, yd->session_id); +	pkt = yahoo_packet_new(YAHOO_SERVICE_AUTH, YPACKET_STATUS_DEFAULT, +		yd->session_id);  	NOTICE(("Sending initial packet"));  	yahoo_packet_hash(pkt, 1, yd->user); -	yid = y_new0(struct yahoo_input_data, 1); -	yid->yd = yd; +	yid = find_input_by_id_and_type(yd->client_id, YAHOO_CONNECTION_PAGER);  	yid->fd = fd; -	inputs = y_list_prepend(inputs, yid);  	yahoo_send_packet(yid, pkt, 0);  	yahoo_packet_free(pkt); -	yid->read_tag = YAHOO_CALLBACK(ext_yahoo_add_handler) (yid->yd->client_id, yid->fd, YAHOO_INPUT_READ, yid); -} - -void yahoo_login(int id, int initial) -{ -	struct yahoo_data *yd = find_conn_by_id(id); -	struct connect_callback_data *ccd; -	struct yahoo_server_settings *yss; -	int tag; - -	if (!yd) -		return; - -	yss = yd->server_settings; - -	yd->initial_status = initial; - -	ccd = y_new0(struct connect_callback_data, 1); -	ccd->yd = yd; -	tag = YAHOO_CALLBACK(ext_yahoo_connect_async) (yd->client_id, yss->pager_host, yss->pager_port,  -			yahoo_connected, ccd); - -	/* -	 * if tag <= 0, then callback has already been called -	 * so ccd will have been freed -	 */ -	if (tag > 0) -		ccd->tag = tag; -	else if (tag < 0) -		YAHOO_CALLBACK(ext_yahoo_login_response) (yd->client_id, YAHOO_LOGIN_SOCK, NULL); +	yid->read_tag = +		YAHOO_CALLBACK(ext_yahoo_add_handler) (yid->yd->client_id, +		yid->fd, YAHOO_INPUT_READ, yid);  } - -int yahoo_get_fd(int id) +void *yahoo_get_fd(int id)  { -	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); +	struct yahoo_input_data *yid = +		find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);  	if (!yid)  		return 0;  	else  		return yid->fd;  } -void yahoo_send_im(int id, const char *from, const char *who, const char *what, int utf8, int picture) +void yahoo_send_buzz(int id, const char *from, const char *who) +{ +	yahoo_send_im(id, from, who, "<ding>", 1, 0); +} + +void yahoo_send_im(int id, const char *from, const char *who, const char *what, +	int utf8, int picture)  { -	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); +	struct yahoo_input_data *yid = +		find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);  	struct yahoo_packet *pkt = NULL;  	struct yahoo_data *yd;  	char pic_str[10]; @@ -4051,13 +3595,14 @@ void yahoo_send_im(int id, const char *from, const char *who, const char *what,  	yd = yid->yd; -	pkt = yahoo_packet_new(YAHOO_SERVICE_MESSAGE, YAHOO_STATUS_OFFLINE, yd->session_id); +	pkt = yahoo_packet_new(YAHOO_SERVICE_MESSAGE, YAHOO_STATUS_OFFLINE, +		yd->session_id);  	snprintf(pic_str, sizeof(pic_str), "%d", picture); -	 +  	if (from && strcmp(from, yd->user))  		yahoo_packet_hash(pkt, 0, yd->user); -	yahoo_packet_hash(pkt, 1, from?from:yd->user); +	yahoo_packet_hash(pkt, 1, from ? from : yd->user);  	yahoo_packet_hash(pkt, 5, who);  	yahoo_packet_hash(pkt, 14, what); @@ -4068,7 +3613,6 @@ void yahoo_send_im(int id, const char *from, const char *who, const char *what,  	yahoo_packet_hash(pkt, 64, "0");  	yahoo_packet_hash(pkt, 206, pic_str); -  	yahoo_send_packet(yid, pkt, 0);  	yahoo_packet_free(pkt); @@ -4076,17 +3620,19 @@ void yahoo_send_im(int id, const char *from, const char *who, const char *what,  void yahoo_send_typing(int id, const char *from, const char *who, int typ)  { -	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); +	struct yahoo_input_data *yid = +		find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);  	struct yahoo_data *yd;  	struct yahoo_packet *pkt = NULL;  	if (!yid)  		return;  	yd = yid->yd; -	pkt = yahoo_packet_new(YAHOO_SERVICE_NOTIFY, YAHOO_STATUS_NOTIFY, yd->session_id); +	pkt = yahoo_packet_new(YAHOO_SERVICE_NOTIFY, YPACKET_STATUS_NOTIFY, +		yd->session_id);  	yahoo_packet_hash(pkt, 5, who); -	yahoo_packet_hash(pkt, 1, from?from:yd->user); +	yahoo_packet_hash(pkt, 1, from ? from : yd->user);  	yahoo_packet_hash(pkt, 14, " ");  	yahoo_packet_hash(pkt, 13, typ ? "1" : "0");  	yahoo_packet_hash(pkt, 49, "TYPING"); @@ -4098,7 +3644,8 @@ void yahoo_send_typing(int id, const char *from, const char *who, int typ)  void yahoo_set_away(int id, enum yahoo_status state, const char *msg, int away)  { -	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); +	struct yahoo_input_data *yid = +		find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);  	struct yahoo_data *yd;  	struct yahoo_packet *pkt = NULL;  	int old_status; @@ -4108,12 +3655,14 @@ void yahoo_set_away(int id, enum yahoo_status state, const char *msg, int away)  		return;  	yd = yid->yd; +  	old_status = yd->current_status;  	yd->current_status = state;  	/* Thank you libpurple :) */  	if (yd->current_status == YAHOO_STATUS_INVISIBLE) { -		pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_VISIBILITY, YAHOO_STATUS_AVAILABLE, 0); +		pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_VISIBLE_TOGGLE, +			YAHOO_STATUS_AVAILABLE, 0);  		yahoo_packet_hash(pkt, 13, "2");  		yahoo_send_packet(yid, pkt, 0);  		yahoo_packet_free(pkt); @@ -4121,7 +3670,8 @@ void yahoo_set_away(int id, enum yahoo_status state, const char *msg, int away)  		return;  	} -	pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_STATUS_UPDATE, yd->current_status, yd->session_id); +	pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_STATUS_UPDATE, +		yd->current_status, yd->session_id);  	snprintf(s, sizeof(s), "%d", yd->current_status);  	yahoo_packet_hash(pkt, 10, s);  	yahoo_packet_hash(pkt, 19, msg && state == YAHOO_STATUS_CUSTOM ? msg : ""); @@ -4130,7 +3680,8 @@ void yahoo_set_away(int id, enum yahoo_status state, const char *msg, int away)  	yahoo_packet_free(pkt);  	if (old_status == YAHOO_STATUS_INVISIBLE) { -		pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_VISIBILITY, YAHOO_STATUS_AVAILABLE, 0); +		pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_VISIBLE_TOGGLE, +			YAHOO_STATUS_AVAILABLE, 0);  		yahoo_packet_hash(pkt, 13, "1");  		yahoo_send_packet(yid, pkt, 0);  		yahoo_packet_free(pkt); @@ -4139,7 +3690,8 @@ void yahoo_set_away(int id, enum yahoo_status state, const char *msg, int away)  void yahoo_logoff(int id)  { -	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); +	struct yahoo_input_data *yid = +		find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);  	struct yahoo_data *yd;  	struct yahoo_packet *pkt = NULL; @@ -4153,7 +3705,8 @@ void yahoo_logoff(int id)  		/* Meh. Don't send this. The event handlers are not going to  		   get to do this so it'll just leak memory. And the TCP  		   connection reset will hopefully be clear enough. */ -		pkt = yahoo_packet_new(YAHOO_SERVICE_LOGOFF, YAHOO_STATUS_AVAILABLE, yd->session_id); +		pkt = yahoo_packet_new(YAHOO_SERVICE_LOGOFF, +			YPACKET_STATUS_DEFAULT, yd->session_id);  		yd->current_status = -1;  		if (pkt) { @@ -4162,14 +3715,16 @@ void yahoo_logoff(int id)  		}  	} -	do { +/*	do {  		yahoo_input_close(yid); -	} while ((yid = find_input_by_id(id))); +	} while((yid = find_input_by_id(id)));*/ +  }  void yahoo_get_list(int id)  { -	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); +	struct yahoo_input_data *yid = +		find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);  	struct yahoo_data *yd;  	struct yahoo_packet *pkt = NULL; @@ -4177,7 +3732,8 @@ void yahoo_get_list(int id)  		return;  	yd = yid->yd; -	pkt = yahoo_packet_new(YAHOO_SERVICE_LIST, YAHOO_STATUS_AVAILABLE, yd->session_id); +	pkt = yahoo_packet_new(YAHOO_SERVICE_LIST, YPACKET_STATUS_DEFAULT, +		yd->session_id);  	yahoo_packet_hash(pkt, 1, yd->user);  	if (pkt) {  		yahoo_send_packet(yid, pkt, 0); @@ -4185,25 +3741,28 @@ void yahoo_get_list(int id)  	}  } -static void _yahoo_http_connected(int id, int fd, int error, void *data) +static void _yahoo_http_connected(int id, void *fd, int error, void *data)  {  	struct yahoo_input_data *yid = data; -	if (fd <= 0) { +	if (fd == NULL || error) {  		inputs = y_list_remove(inputs, yid);  		FREE(yid);  		return;  	}  	yid->fd = fd; -	yid->read_tag = YAHOO_CALLBACK(ext_yahoo_add_handler) (yid->yd->client_id, fd, YAHOO_INPUT_READ, yid); +	yid->read_tag = +		YAHOO_CALLBACK(ext_yahoo_add_handler) (yid->yd->client_id, fd, +		YAHOO_INPUT_READ, yid);  } +/* FIXME Get address book from address.yahoo.com instead */  void yahoo_get_yab(int id)  {  	struct yahoo_data *yd = find_conn_by_id(id);  	struct yahoo_input_data *yid;  	char url[1024]; -	char buff[1024]; +	char buff[2048];  	if (!yd)  		return; @@ -4212,25 +3771,58 @@ void yahoo_get_yab(int id)  	yid->yd = yd;  	yid->type = YAHOO_CONNECTION_YAB; -	snprintf(url, 1024, "http://insider.msg.yahoo.com/ycontent/?ab2=0"); +	LOG(("Sending request for Address Book")); + +	snprintf(url, 1024, +		"http://address.yahoo.com/yab/us?v=XM&prog=ymsgr&.intl=us" +		"&diffs=1&t=0&tags=short&rt=0&prog-ver=8.1.0.249&useutf8=1&legenc=codepage-1252"); -	snprintf(buff, sizeof(buff), "Y=%s; T=%s", -			yd->cookie_y, yd->cookie_t); +	snprintf(buff, sizeof(buff), "Y=%s; T=%s", yd->cookie_y, yd->cookie_t);  	inputs = y_list_prepend(inputs, yid); -	yahoo_http_get(yid->yd->client_id, url, buff,  -			_yahoo_http_connected, yid); +	yahoo_http_get(yid->yd->client_id, url, buff, 0, 0, +		_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; +	struct yahoo_input_data *yid = yad->yid; +	char *buff = yad->data; + +	if (!fd) { +		inputs = y_list_remove(inputs, yid); +		FREE(yid); +		return; +	} + +	YAHOO_CALLBACK(ext_yahoo_write) (fd, buff, strlen(buff)); + +	yid->fd = fd; +	yid->read_tag = +		YAHOO_CALLBACK(ext_yahoo_add_handler) (yid->yd->client_id, fd, +		YAHOO_INPUT_READ, yid); + +	FREE(buff); +	FREE(yad);  } +/* FIXME This is also likely affected */  void yahoo_set_yab(int id, struct yab *yab)  { +	struct yahoo_post_data *yad = y_new0(struct yahoo_post_data, 1);  	struct yahoo_data *yd = find_conn_by_id(id);  	struct yahoo_input_data *yid;  	char url[1024];  	char buff[1024]; -	char *temp; -	int size = sizeof(url)-1; +	char post[1024]; +	int size = 0;  	if (!yd)  		return; @@ -4239,76 +3831,37 @@ void yahoo_set_yab(int id, struct yab *yab)  	yid->type = YAHOO_CONNECTION_YAB;  	yid->yd = yd; -	strncpy(url, "http://insider.msg.yahoo.com/ycontent/?addab2=0", size); - -	if (yab->dbid) { -		/* change existing yab */ -		char tmp[32]; -		strncat(url, "&ee=1&ow=1&id=", size - strlen(url)); -		snprintf(tmp, sizeof(tmp), "%d", yab->dbid); -		strncat(url, tmp, size - strlen(url)); -	} - -	if (yab->fname) { -		strncat(url, "&fn=", size - strlen(url)); -		temp = yahoo_urlencode(yab->fname); -		strncat(url, temp, size - strlen(url)); -		free(temp); -	} -	if (yab->lname) { -		strncat(url, "&ln=", size - strlen(url)); -		temp = yahoo_urlencode(yab->lname); -		strncat(url, temp, size - strlen(url)); -		free(temp); -	} -	strncat(url, "&yid=", size - strlen(url)); -	temp = yahoo_urlencode(yab->id); -	strncat(url, temp, size - strlen(url)); -	free(temp); -	if (yab->nname) { -		strncat(url, "&nn=", size - strlen(url)); -		temp = yahoo_urlencode(yab->nname); -		strncat(url, temp, size - strlen(url)); -		free(temp); -	} -	if (yab->email) { -		strncat(url, "&e=", size - strlen(url)); -		temp = yahoo_urlencode(yab->email); -		strncat(url, temp, size - strlen(url)); -		free(temp); -	} -	if (yab->hphone) { -		strncat(url, "&hp=", size - strlen(url)); -		temp = yahoo_urlencode(yab->hphone); -		strncat(url, temp, size - strlen(url)); -		free(temp); -	} -	if (yab->wphone) { -		strncat(url, "&wp=", size - strlen(url)); -		temp = yahoo_urlencode(yab->wphone); -		strncat(url, temp, size - strlen(url)); -		free(temp); -	} -	if (yab->mphone) { -		strncat(url, "&mp=", size - strlen(url)); -		temp = yahoo_urlencode(yab->mphone); -		strncat(url, temp, size - strlen(url)); -		free(temp); -	} -	strncat(url, "&pp=0", size - strlen(url)); - -	snprintf(buff, sizeof(buff), "Y=%s; T=%s", -			yd->cookie_y, yd->cookie_t); +	if(yab->yid) +		size = snprintf(post, sizeof(post), "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +			"<ab k=\"%s\" cc=\"%d\">" +			"<ct id=\"%d\" e=\"1\" yi=\"%s\" nn=\"%s\" />" +			"</ab>", yd->user, 9, yab->yid,	/* Don't know why */ +			yab->id, yab->nname?yab->nname:""); +	else +		size = snprintf(post, sizeof(post), "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +			"<ab k=\"%s\" cc=\"%d\">" +			"<ct a=\"1\" yi=\"%s\" nn=\"%s\" />" +			"</ab>", yd->user, 1,	/* Don't know why */ +			yab->id, yab->nname?yab->nname:""); + +	yad->yid = yid; +	yad->data = strdup(post); + +	strcpy(url, "http://address.yahoo.com/yab/us?v=XM&prog=ymsgr&.intl=us" +		"&sync=1&tags=short&noclear=1&useutf8=1&legenc=codepage-1252"); + +	snprintf(buff, sizeof(buff), "Y=%s; T=%s", yd->cookie_y, yd->cookie_t);  	inputs = y_list_prepend(inputs, yid); -	yahoo_http_get(yid->yd->client_id, url, buff,  -			_yahoo_http_connected, yid); +	yahoo_http_post(yid->yd->client_id, url, buff, size, +		_yahoo_http_post_connected, yad);  }  void yahoo_set_identity_status(int id, const char *identity, int active)  { -	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); +	struct yahoo_input_data *yid = +		find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);  	struct yahoo_data *yd;  	struct yahoo_packet *pkt = NULL; @@ -4316,8 +3869,8 @@ void yahoo_set_identity_status(int id, const char *identity, int active)  		return;  	yd = yid->yd; -	pkt = yahoo_packet_new(active?YAHOO_SERVICE_IDACT:YAHOO_SERVICE_IDDEACT, -			YAHOO_STATUS_AVAILABLE, yd->session_id); +	pkt = yahoo_packet_new(active ? YAHOO_SERVICE_IDACT : +		YAHOO_SERVICE_IDDEACT, YPACKET_STATUS_DEFAULT, yd->session_id);  	yahoo_packet_hash(pkt, 3, identity);  	if (pkt) {  		yahoo_send_packet(yid, pkt, 0); @@ -4327,7 +3880,8 @@ void yahoo_set_identity_status(int id, const char *identity, int active)  void yahoo_refresh(int id)  { -	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); +	struct yahoo_input_data *yid = +		find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);  	struct yahoo_data *yd;  	struct yahoo_packet *pkt = NULL; @@ -4335,7 +3889,8 @@ void yahoo_refresh(int id)  		return;  	yd = yid->yd; -	pkt = yahoo_packet_new(YAHOO_SERVICE_USERSTAT, YAHOO_STATUS_AVAILABLE, yd->session_id); +	pkt = yahoo_packet_new(YAHOO_SERVICE_USERSTAT, YPACKET_STATUS_DEFAULT, +		yd->session_id);  	if (pkt) {  		yahoo_send_packet(yid, pkt, 0);  		yahoo_packet_free(pkt); @@ -4344,37 +3899,43 @@ void yahoo_refresh(int id)  void yahoo_keepalive(int id)  { -	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); +	struct yahoo_input_data *yid = +		find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);  	struct yahoo_data *yd;  	struct yahoo_packet *pkt = NULL;  	if (!yid)  		return;  	yd = yid->yd; -	pkt = yahoo_packet_new(YAHOO_SERVICE_PING, YAHOO_STATUS_AVAILABLE, yd->session_id); +	pkt = yahoo_packet_new(YAHOO_SERVICE_PING, YPACKET_STATUS_DEFAULT, +		yd->session_id);  	yahoo_send_packet(yid, pkt, 0);  	yahoo_packet_free(pkt);  } -void yahoo_chat_keepalive (int id) +void yahoo_chat_keepalive(int id)  { -	struct yahoo_input_data *yid = find_input_by_id_and_type (id, YAHOO_CONNECTION_PAGER); +	struct yahoo_input_data *yid = +		find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);  	struct yahoo_data *yd;  	struct yahoo_packet *pkt = NULL;  	if (!yid) -	    return; +		return;  	yd = yid->yd; -	pkt = yahoo_packet_new (YAHOO_SERVICE_CHATPING, YAHOO_STATUS_AVAILABLE, yd->session_id); -	yahoo_send_packet (yid, pkt, 0); -	yahoo_packet_free (pkt); +	pkt = yahoo_packet_new(YAHOO_SERVICE_CHATPING, YPACKET_STATUS_DEFAULT, +		yd->session_id); +	yahoo_send_packet(yid, pkt, 0); +	yahoo_packet_free(pkt);  } -void yahoo_add_buddy(int id, const char *who, const char *group, const char *msg) +void yahoo_add_buddy(int id, const char *who, const char *group, +	const char *msg)  { -	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); +	struct yahoo_input_data *yid = +		find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);  	struct yahoo_data *yd;  	struct yahoo_packet *pkt; @@ -4385,13 +3946,12 @@ void yahoo_add_buddy(int id, const char *who, const char *group, const char *msg  	if (!yd->logged_in)  		return; -	pkt = yahoo_packet_new(YAHOO_SERVICE_ADDBUDDY, YPACKET_STATUS_DEFAULT, yd->session_id); - -	if (msg != NULL) /* add message/request "it's me add me" */ +	pkt = yahoo_packet_new(YAHOO_SERVICE_ADDBUDDY, YPACKET_STATUS_DEFAULT, +		yd->session_id); +	if (msg != NULL)	/* add message/request "it's me add me" */  		yahoo_packet_hash(pkt, 14, msg);  	else -		yahoo_packet_hash(pkt,14,""); - +		yahoo_packet_hash(pkt, 14, "");  	yahoo_packet_hash(pkt, 65, group);  	yahoo_packet_hash(pkt, 97, "1");  	yahoo_packet_hash(pkt, 1, yd->user); @@ -4401,15 +3961,14 @@ void yahoo_add_buddy(int id, const char *who, const char *group, const char *msg  	yahoo_packet_hash(pkt, 334, "0");  	yahoo_packet_hash(pkt, 301, "319");  	yahoo_packet_hash(pkt, 303, "319"); - -  	yahoo_send_packet(yid, pkt, 0);  	yahoo_packet_free(pkt);  }  void yahoo_remove_buddy(int id, const char *who, const char *group)  { -	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); +	struct yahoo_input_data *yid = +		find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);  	struct yahoo_data *yd;  	struct yahoo_packet *pkt = NULL; @@ -4417,7 +3976,8 @@ void yahoo_remove_buddy(int id, const char *who, const char *group)  		return;  	yd = yid->yd; -	pkt = yahoo_packet_new(YAHOO_SERVICE_REMBUDDY, YAHOO_STATUS_AVAILABLE, yd->session_id); +	pkt = yahoo_packet_new(YAHOO_SERVICE_REMBUDDY, YPACKET_STATUS_DEFAULT, +		yd->session_id);  	yahoo_packet_hash(pkt, 1, yd->user);  	yahoo_packet_hash(pkt, 7, who); @@ -4426,52 +3986,10 @@ void yahoo_remove_buddy(int id, const char *who, const char *group)  	yahoo_packet_free(pkt);  } -void yahoo_accept_buddy_ymsg13(int id,const char* me,const char* who){ -	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); -	struct yahoo_data *yd; - -	if (!yid) -		return; -	yd = yid->yd; - -	struct yahoo_packet* pkt = NULL; -	pkt= yahoo_packet_new(YAHOO_SERVICE_CONTACT_YMSG13,YAHOO_STATUS_AVAILABLE,0); - -	yahoo_packet_hash(pkt,1,me ?: yd->user);	 -	yahoo_packet_hash(pkt,5,who); -	yahoo_packet_hash(pkt,13,"1"); -	yahoo_packet_hash(pkt,334,"0"); -	yahoo_send_packet(yid, pkt, 0); -	yahoo_packet_free(pkt); -} - -void yahoo_reject_buddy_ymsg13(int id,const char* me,const char* who,const char* msg){ -	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); -	struct yahoo_data *yd; - -	if (!yid) -		return; -	yd = yid->yd; - -	struct yahoo_packet* pkt = NULL; -	pkt= yahoo_packet_new(YAHOO_SERVICE_CONTACT_YMSG13,YAHOO_STATUS_AVAILABLE,0); - -	yahoo_packet_hash(pkt,1,me ?: yd->user);	 -	yahoo_packet_hash(pkt,5,who); -//	yahoo_packet_hash(pkt,241,YAHOO_PROTO_VER); -	yahoo_packet_hash(pkt,13,"2"); -	yahoo_packet_hash(pkt,334,"0"); -	yahoo_packet_hash(pkt,97,"1"); -	yahoo_packet_hash(pkt,14,msg?:""); - -	yahoo_send_packet(yid, pkt, 0); -	yahoo_packet_free(pkt); - -} - -void yahoo_reject_buddy(int id, const char *who, const char *msg) +void yahoo_confirm_buddy(int id, const char *who, int reject, const char *msg)  { -	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); +	struct yahoo_input_data *yid = +		find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);  	struct yahoo_data *yd;  	struct yahoo_packet *pkt; @@ -4482,17 +4000,32 @@ void yahoo_reject_buddy(int id, const char *who, const char *msg)  	if (!yd->logged_in)  		return; -	pkt = yahoo_packet_new(YAHOO_SERVICE_REJECTCONTACT, YAHOO_STATUS_AVAILABLE, yd->session_id); +	pkt = yahoo_packet_new(YAHOO_SERVICE_Y7_AUTHORIZATION, +		YPACKET_STATUS_DEFAULT, yd->session_id);  	yahoo_packet_hash(pkt, 1, yd->user); -	yahoo_packet_hash(pkt, 7, who); -	yahoo_packet_hash(pkt, 14, msg); +	yahoo_packet_hash(pkt, 5, who); +	if (reject) +		yahoo_packet_hash(pkt, 13, "2"); +	else { +		yahoo_packet_hash(pkt, 241, "0"); +		yahoo_packet_hash(pkt, 13, "1"); +	} + +	yahoo_packet_hash(pkt, 334, "0"); + +	if (reject) { +		yahoo_packet_hash(pkt, 14, msg ? msg : ""); +		yahoo_packet_hash(pkt, 97, "1"); +	} +  	yahoo_send_packet(yid, pkt, 0);  	yahoo_packet_free(pkt);  }  void yahoo_ignore_buddy(int id, const char *who, int unignore)  { -	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); +	struct yahoo_input_data *yid = +		find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);  	struct yahoo_data *yd;  	struct yahoo_packet *pkt; @@ -4503,17 +4036,19 @@ void yahoo_ignore_buddy(int id, const char *who, int unignore)  	if (!yd->logged_in)  		return; -	pkt = yahoo_packet_new(YAHOO_SERVICE_IGNORECONTACT, YAHOO_STATUS_AVAILABLE, yd->session_id); +	pkt = yahoo_packet_new(YAHOO_SERVICE_IGNORECONTACT, +		YPACKET_STATUS_DEFAULT, yd->session_id);  	yahoo_packet_hash(pkt, 1, yd->user);  	yahoo_packet_hash(pkt, 7, who); -	yahoo_packet_hash(pkt, 13, unignore?"2":"1"); +	yahoo_packet_hash(pkt, 13, unignore ? "2" : "1");  	yahoo_send_packet(yid, pkt, 0);  	yahoo_packet_free(pkt);  }  void yahoo_stealth_buddy(int id, const char *who, int unstealth)  { -	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); +	struct yahoo_input_data *yid = +		find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);  	struct yahoo_data *yd;  	struct yahoo_packet *pkt; @@ -4524,18 +4059,21 @@ void yahoo_stealth_buddy(int id, const char *who, int unstealth)  	if (!yd->logged_in)  		return; -	pkt = yahoo_packet_new(YAHOO_SERVICE_STEALTH, YAHOO_STATUS_AVAILABLE, yd->session_id); +	pkt = yahoo_packet_new(YAHOO_SERVICE_STEALTH_PERM, +		YPACKET_STATUS_DEFAULT, yd->session_id);  	yahoo_packet_hash(pkt, 1, yd->user);  	yahoo_packet_hash(pkt, 7, who); -	yahoo_packet_hash(pkt, 31, unstealth?"2":"1"); +	yahoo_packet_hash(pkt, 31, unstealth ? "2" : "1");  	yahoo_packet_hash(pkt, 13, "2");  	yahoo_send_packet(yid, pkt, 0);  	yahoo_packet_free(pkt);  } -void yahoo_change_buddy_group(int id, const char *who, const char *old_group, const char *new_group) +void yahoo_change_buddy_group(int id, const char *who, const char *old_group, +	const char *new_group)  { -	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); +	struct yahoo_input_data *yid = +		find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);  	struct yahoo_data *yd;  	struct yahoo_packet *pkt = NULL; @@ -4543,26 +4081,25 @@ void yahoo_change_buddy_group(int id, const char *who, const char *old_group, co  		return;  	yd = yid->yd; -	pkt = yahoo_packet_new(YAHOO_SERVICE_ADDBUDDY, YAHOO_STATUS_AVAILABLE, yd->session_id); +	pkt = yahoo_packet_new(YAHOO_SERVICE_Y7_CHANGE_GROUP, +		YPACKET_STATUS_DEFAULT, yd->session_id);  	yahoo_packet_hash(pkt, 1, yd->user); +	yahoo_packet_hash(pkt, 302, "240"); +	yahoo_packet_hash(pkt, 300, "240");  	yahoo_packet_hash(pkt, 7, who); -	yahoo_packet_hash(pkt, 65, new_group); -	yahoo_packet_hash(pkt, 14, " "); - -	yahoo_send_packet(yid, pkt, 0); -	yahoo_packet_free(pkt); +	yahoo_packet_hash(pkt, 224, old_group); +	yahoo_packet_hash(pkt, 264, new_group); +	yahoo_packet_hash(pkt, 301, "240"); +	yahoo_packet_hash(pkt, 303, "240"); -	pkt = yahoo_packet_new(YAHOO_SERVICE_REMBUDDY, YAHOO_STATUS_AVAILABLE, yd->session_id); -	yahoo_packet_hash(pkt, 1, yd->user); -	yahoo_packet_hash(pkt, 7, who); -	yahoo_packet_hash(pkt, 65, old_group);  	yahoo_send_packet(yid, pkt, 0);  	yahoo_packet_free(pkt);  }  void yahoo_group_rename(int id, const char *old_group, const char *new_group)  { -	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); +	struct yahoo_input_data *yid = +		find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);  	struct yahoo_data *yd;  	struct yahoo_packet *pkt = NULL; @@ -4570,7 +4107,8 @@ void yahoo_group_rename(int id, const char *old_group, const char *new_group)  		return;  	yd = yid->yd; -	pkt = yahoo_packet_new(YAHOO_SERVICE_GROUPRENAME, YAHOO_STATUS_AVAILABLE, yd->session_id); +	pkt = yahoo_packet_new(YAHOO_SERVICE_GROUPRENAME, +		YPACKET_STATUS_DEFAULT, yd->session_id);  	yahoo_packet_hash(pkt, 1, yd->user);  	yahoo_packet_hash(pkt, 65, old_group);  	yahoo_packet_hash(pkt, 67, new_group); @@ -4579,19 +4117,22 @@ void yahoo_group_rename(int id, const char *old_group, const char *new_group)  	yahoo_packet_free(pkt);  } -void yahoo_conference_addinvite(int id, const char *from, const char *who, const char *room, const YList *members, const char *msg) +void yahoo_conference_addinvite(int id, const char *from, const char *who, +	const char *room, const YList *members, const char *msg)  { -	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); +	struct yahoo_input_data *yid = +		find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);  	struct yahoo_data *yd;  	struct yahoo_packet *pkt; -		 +  	if (!yid)  		return;  	yd = yid->yd; -	pkt = yahoo_packet_new(YAHOO_SERVICE_CONFADDINVITE, YAHOO_STATUS_AVAILABLE, yd->session_id); +	pkt = yahoo_packet_new(YAHOO_SERVICE_CONFADDINVITE, +		YPACKET_STATUS_DEFAULT, yd->session_id); -	yahoo_packet_hash(pkt, 1, (from?from:yd->user)); +	yahoo_packet_hash(pkt, 1, (from ? from : yd->user));  	yahoo_packet_hash(pkt, 51, who);  	yahoo_packet_hash(pkt, 57, room);  	yahoo_packet_hash(pkt, 58, msg); @@ -4607,19 +4148,22 @@ void yahoo_conference_addinvite(int id, const char *from, const char *who, const  	yahoo_packet_free(pkt);  } -void yahoo_conference_invite(int id, const char *from, YList *who, const char *room, const char *msg) +void yahoo_conference_invite(int id, const char *from, YList *who, +	const char *room, const char *msg)  { -	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); +	struct yahoo_input_data *yid = +		find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);  	struct yahoo_data *yd;  	struct yahoo_packet *pkt; -		 +  	if (!yid)  		return;  	yd = yid->yd; -	pkt = yahoo_packet_new(YAHOO_SERVICE_CONFINVITE, YAHOO_STATUS_AVAILABLE, yd->session_id); +	pkt = yahoo_packet_new(YAHOO_SERVICE_CONFINVITE, YPACKET_STATUS_DEFAULT, +		yd->session_id); -	yahoo_packet_hash(pkt, 1, (from?from:yd->user)); +	yahoo_packet_hash(pkt, 1, (from ? from : yd->user));  	yahoo_packet_hash(pkt, 50, yd->user);  	for (; who; who = who->next) {  		yahoo_packet_hash(pkt, 52, (char *)who->data); @@ -4633,45 +4177,51 @@ void yahoo_conference_invite(int id, const char *from, YList *who, const char *r  	yahoo_packet_free(pkt);  } -void yahoo_conference_logon(int id, const char *from, YList *who, const char *room) +void yahoo_conference_logon(int id, const char *from, YList *who, +	const char *room)  { -	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); +	struct yahoo_input_data *yid = +		find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);  	struct yahoo_data *yd;  	struct yahoo_packet *pkt; -		 +  	if (!yid)  		return;  	yd = yid->yd; -	pkt = yahoo_packet_new(YAHOO_SERVICE_CONFLOGON, YAHOO_STATUS_AVAILABLE, yd->session_id); +	pkt = yahoo_packet_new(YAHOO_SERVICE_CONFLOGON, YPACKET_STATUS_DEFAULT, +		yd->session_id); -	yahoo_packet_hash(pkt, 1, (from?from:yd->user)); -	for (; who; who = who->next) { -		yahoo_packet_hash(pkt, 3, (char *)who->data); -	} +	yahoo_packet_hash(pkt, 1, (from ? from : yd->user)); +	yahoo_packet_hash(pkt, 3, (from ? from : yd->user));  	yahoo_packet_hash(pkt, 57, room); +	for (; who; who = who->next) +		yahoo_packet_hash(pkt, 3, (char *)who->data);  	yahoo_send_packet(yid, pkt, 0);  	yahoo_packet_free(pkt);  } -void yahoo_conference_decline(int id, const char *from, YList *who, const char *room, const char *msg) +void yahoo_conference_decline(int id, const char *from, YList *who, +	const char *room, const char *msg)  { -	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); +	struct yahoo_input_data *yid = +		find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);  	struct yahoo_data *yd;  	struct yahoo_packet *pkt; -		 +  	if (!yid)  		return;  	yd = yid->yd; -	pkt = yahoo_packet_new(YAHOO_SERVICE_CONFDECLINE, YAHOO_STATUS_AVAILABLE, yd->session_id); +	pkt = yahoo_packet_new(YAHOO_SERVICE_CONFDECLINE, +		YPACKET_STATUS_DEFAULT, yd->session_id); -	yahoo_packet_hash(pkt, 1, (from?from:yd->user)); -	for (; who; who = who->next) { +	yahoo_packet_hash(pkt, 1, (from ? from : yd->user)); +	yahoo_packet_hash(pkt, 3, (from ? from : yd->user)); +	for (; who; who = who->next)  		yahoo_packet_hash(pkt, 3, (char *)who->data); -	}  	yahoo_packet_hash(pkt, 57, room);  	yahoo_packet_hash(pkt, 14, msg); @@ -4680,22 +4230,26 @@ void yahoo_conference_decline(int id, const char *from, YList *who, const char *  	yahoo_packet_free(pkt);  } -void yahoo_conference_logoff(int id, const char *from, YList *who, const char *room) +void yahoo_conference_logoff(int id, const char *from, YList *who, +	const char *room)  { -	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); +	struct yahoo_input_data *yid = +		find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);  	struct yahoo_data *yd;  	struct yahoo_packet *pkt; -		 +  	if (!yid)  		return;  	yd = yid->yd; -	pkt = yahoo_packet_new(YAHOO_SERVICE_CONFLOGOFF, YAHOO_STATUS_AVAILABLE, yd->session_id); +	pkt = yahoo_packet_new(YAHOO_SERVICE_CONFLOGOFF, YPACKET_STATUS_DEFAULT, +		yd->session_id); -	yahoo_packet_hash(pkt, 1, (from?from:yd->user)); -	for (; who; who = who->next) { +	yahoo_packet_hash(pkt, 1, (from ? from : yd->user)); +	yahoo_packet_hash(pkt, 3, (from ? from : yd->user)); +	for (; who; who = who->next)  		yahoo_packet_hash(pkt, 3, (char *)who->data); -	} +  	yahoo_packet_hash(pkt, 57, room);  	yahoo_send_packet(yid, pkt, 0); @@ -4703,22 +4257,26 @@ void yahoo_conference_logoff(int id, const char *from, YList *who, const char *r  	yahoo_packet_free(pkt);  } -void yahoo_conference_message(int id, const char *from, YList *who, const char *room, const char *msg, int utf8) +void yahoo_conference_message(int id, const char *from, YList *who, +	const char *room, const char *msg, int utf8)  { -	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); +	struct yahoo_input_data *yid = +		find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);  	struct yahoo_data *yd;  	struct yahoo_packet *pkt; -		 +  	if (!yid)  		return;  	yd = yid->yd; -	pkt = yahoo_packet_new(YAHOO_SERVICE_CONFMSG, YAHOO_STATUS_AVAILABLE, yd->session_id); +	pkt = yahoo_packet_new(YAHOO_SERVICE_CONFMSG, YPACKET_STATUS_DEFAULT, +		yd->session_id); -	yahoo_packet_hash(pkt, 1, (from?from:yd->user)); -	for (; who; who = who->next) { +	yahoo_packet_hash(pkt, 1, (from ? from : yd->user)); +	yahoo_packet_hash(pkt, 53, (from ? from : yd->user)); +	for (; who; who = who->next)  		yahoo_packet_hash(pkt, 53, (char *)who->data); -	} +  	yahoo_packet_hash(pkt, 57, room);  	yahoo_packet_hash(pkt, 14, msg); @@ -4745,32 +4303,39 @@ void yahoo_get_chatrooms(int id, int chatroomid)  	yid->type = YAHOO_CONNECTION_CHATCAT;  	if (chatroomid == 0) { -		snprintf(url, 1024, "http://insider.msg.yahoo.com/ycontent/?chatcat=0"); +		snprintf(url, 1024, +			"http://insider.msg.yahoo.com/ycontent/?chatcat=0");  	} else { -		snprintf(url, 1024, "http://insider.msg.yahoo.com/ycontent/?chatroom_%d=0",chatroomid); +		snprintf(url, 1024, +			"http://insider.msg.yahoo.com/ycontent/?chatroom_%d=0", +			chatroomid);  	}  	snprintf(buff, sizeof(buff), "Y=%s; T=%s", yd->cookie_y, yd->cookie_t);  	inputs = y_list_prepend(inputs, yid); -	yahoo_http_get(yid->yd->client_id, url, buff, _yahoo_http_connected, yid); +	yahoo_http_get(yid->yd->client_id, url, buff, 0, 0, +		_yahoo_http_connected, yid);  } -void yahoo_chat_logon(int id, const char *from, const char *room, const char *roomid) +void yahoo_chat_logon(int id, const char *from, const char *room, +	const char *roomid)  { -	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); +	struct yahoo_input_data *yid = +		find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);  	struct yahoo_data *yd;  	struct yahoo_packet *pkt; -		 +  	if (!yid)  		return;  	yd = yid->yd; -	pkt = yahoo_packet_new(YAHOO_SERVICE_CHATONLINE, YAHOO_STATUS_AVAILABLE, yd->session_id); +	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, 1, (from ? from : yd->user));  	yahoo_packet_hash(pkt, 109, yd->user);  	yahoo_packet_hash(pkt, 6, "abcde"); @@ -4778,37 +4343,40 @@ void yahoo_chat_logon(int id, const char *from, const char *room, const char *ro  	yahoo_packet_free(pkt); -	pkt = yahoo_packet_new(YAHOO_SERVICE_CHATJOIN, YAHOO_STATUS_AVAILABLE, yd->session_id); +	pkt = yahoo_packet_new(YAHOO_SERVICE_CHATJOIN, YPACKET_STATUS_DEFAULT, +		yd->session_id); -	yahoo_packet_hash(pkt, 1, (from?from:yd->user)); +	yahoo_packet_hash(pkt, 1, (from ? from : yd->user));  	yahoo_packet_hash(pkt, 104, room);  	yahoo_packet_hash(pkt, 129, roomid); -	yahoo_packet_hash(pkt, 62, "2"); /* ??? */ +	yahoo_packet_hash(pkt, 62, "2");	/* ??? */  	yahoo_send_packet(yid, pkt, 0);  	yahoo_packet_free(pkt);  } - -void  yahoo_chat_message(int id, const char *from, const char *room, const char *msg, const int msgtype, const int utf8) +void yahoo_chat_message(int id, const char *from, const char *room, +	const char *msg, const int msgtype, const int utf8)  { -	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); +	struct yahoo_input_data *yid = +		find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);  	struct yahoo_data *yd;  	struct yahoo_packet *pkt;  	char buf[2]; -		 +  	if (!yid)  		return;  	yd = yid->yd; -	pkt = yahoo_packet_new(YAHOO_SERVICE_COMMENT, YAHOO_STATUS_AVAILABLE, yd->session_id); +	pkt = yahoo_packet_new(YAHOO_SERVICE_COMMENT, YPACKET_STATUS_DEFAULT, +		yd->session_id); -	yahoo_packet_hash(pkt, 1, (from?from:yd->user)); +	yahoo_packet_hash(pkt, 1, (from ? from : yd->user));  	yahoo_packet_hash(pkt, 104, room);  	yahoo_packet_hash(pkt, 117, msg); -	 +  	snprintf(buf, sizeof(buf), "%d", msgtype);  	yahoo_packet_hash(pkt, 124, buf); @@ -4820,21 +4388,22 @@ void  yahoo_chat_message(int id, const char *from, const char *room, const char  	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_input_data *yid = +		find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);  	struct yahoo_data *yd;  	struct yahoo_packet *pkt; -		 +  	if (!yid)  		return;  	yd = yid->yd; -	pkt = yahoo_packet_new(YAHOO_SERVICE_CHATLOGOUT, YAHOO_STATUS_AVAILABLE, yd->session_id); +	pkt = yahoo_packet_new(YAHOO_SERVICE_CHATLOGOUT, YPACKET_STATUS_DEFAULT, +		yd->session_id); -	yahoo_packet_hash(pkt, 1, (from?from:yd->user)); +	yahoo_packet_hash(pkt, 1, (from ? from : yd->user));  	yahoo_send_packet(yid, pkt, 0); @@ -4843,16 +4412,18 @@ void yahoo_chat_logoff(int id, const char *from)  void yahoo_buddyicon_request(int id, const char *who)  { -	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); +	struct yahoo_input_data *yid = +		find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);  	struct yahoo_data *yd;  	struct yahoo_packet *pkt; -	if ( !yid ) +	if (!yid)  		return;  	yd = yid->yd; -	 -	pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE, YAHOO_STATUS_AVAILABLE, 0); + +	pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE, YPACKET_STATUS_DEFAULT, +		0);  	yahoo_packet_hash(pkt, 4, yd->user);  	yahoo_packet_hash(pkt, 5, who);  	yahoo_packet_hash(pkt, 13, "1"); @@ -4861,21 +4432,24 @@ void yahoo_buddyicon_request(int id, const char *who)  	yahoo_packet_free(pkt);  } -void yahoo_send_picture_info(int id, const char *who, const char *url, int checksum) +void yahoo_send_picture_info(int id, const char *who, const char *url, +	int checksum)  { -	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); +	struct yahoo_input_data *yid = +		find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);  	struct yahoo_data *yd;  	struct yahoo_packet *pkt;  	char checksum_str[10]; -	if ( !yid ) +	if (!yid)  		return;  	yd = yid->yd;  	snprintf(checksum_str, sizeof(checksum_str), "%d", checksum); -	pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE, YAHOO_STATUS_AVAILABLE, 0); +	pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE, YPACKET_STATUS_DEFAULT, +		0);  	yahoo_packet_hash(pkt, 1, yd->user);  	yahoo_packet_hash(pkt, 4, yd->user);  	yahoo_packet_hash(pkt, 5, who); @@ -4889,19 +4463,21 @@ void yahoo_send_picture_info(int id, const char *who, const char *url, int check  void yahoo_send_picture_update(int id, const char *who, int type)  { -	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); +	struct yahoo_input_data *yid = +		find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);  	struct yahoo_data *yd;  	struct yahoo_packet *pkt;  	char type_str[10]; -	if ( !yid ) +	if (!yid)  		return;  	yd = yid->yd;  	snprintf(type_str, sizeof(type_str), "%d", type); -	pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE_UPDATE, YAHOO_STATUS_AVAILABLE, 0); +	pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE_UPDATE, +		YPACKET_STATUS_DEFAULT, 0);  	yahoo_packet_hash(pkt, 1, yd->user);  	yahoo_packet_hash(pkt, 5, who);  	yahoo_packet_hash(pkt, 206, type_str); @@ -4912,21 +4488,23 @@ void yahoo_send_picture_update(int id, const char *who, int type)  void yahoo_send_picture_checksum(int id, const char *who, int checksum)  { -	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); +	struct yahoo_input_data *yid = +		find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);  	struct yahoo_data *yd;  	struct yahoo_packet *pkt;  	char checksum_str[10]; -	if ( !yid ) +	if (!yid)  		return;  	yd = yid->yd; -	 +  	snprintf(checksum_str, sizeof(checksum_str), "%d", checksum); -	pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE_CHECKSUM, YAHOO_STATUS_AVAILABLE, 0); +	pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE_CHECKSUM, +		YPACKET_STATUS_DEFAULT, 0);  	yahoo_packet_hash(pkt, 1, yd->user); -	if ( who != 0 ) +	if (who != 0)  		yahoo_packet_hash(pkt, 5, who);  	yahoo_packet_hash(pkt, 192, checksum_str);  	yahoo_packet_hash(pkt, 212, "1"); @@ -4937,7 +4515,8 @@ void yahoo_send_picture_checksum(int id, const char *who, int checksum)  void yahoo_webcam_close_feed(int id, const char *who)  { -	struct yahoo_input_data *yid = find_input_by_id_and_webcam_user(id, who); +	struct yahoo_input_data *yid = +		find_input_by_id_and_webcam_user(id, who);  	if (yid)  		yahoo_input_close(yid); @@ -4945,10 +4524,11 @@ void yahoo_webcam_close_feed(int id, const char *who)  void yahoo_webcam_get_feed(int id, const char *who)  { -	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); +	struct yahoo_input_data *yid = +		find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);  	struct yahoo_data *yd;  	struct yahoo_packet *pkt; -		 +  	if (!yid)  		return; @@ -4959,11 +4539,12 @@ void yahoo_webcam_get_feed(int id, const char *who)  	 * order that we request them.  	 * The queue is popped in yahoo_process_webcam_key  	 */ -	webcam_queue = y_list_append(webcam_queue, who?strdup(who):NULL); +	webcam_queue = y_list_append(webcam_queue, who ? strdup(who) : NULL);  	yd = yid->yd; -	pkt = yahoo_packet_new(YAHOO_SERVICE_WEBCAM, YAHOO_STATUS_AVAILABLE, yd->session_id); +	pkt = yahoo_packet_new(YAHOO_SERVICE_WEBCAM, YPACKET_STATUS_DEFAULT, +		yd->session_id);  	yahoo_packet_hash(pkt, 1, yd->user);  	if (who != NULL) @@ -4973,9 +4554,11 @@ void yahoo_webcam_get_feed(int id, const char *who)  	yahoo_packet_free(pkt);  } -void yahoo_webcam_send_image(int id, unsigned char *image, unsigned int length, unsigned int timestamp) +void yahoo_webcam_send_image(int id, unsigned char *image, unsigned int length, +	unsigned int timestamp)  { -	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_WEBCAM); +	struct yahoo_input_data *yid = +		find_input_by_id_and_type(id, YAHOO_CONNECTION_WEBCAM);  	unsigned char *packet;  	unsigned char header_len = 13;  	unsigned int pos = 0; @@ -4987,10 +4570,10 @@ void yahoo_webcam_send_image(int id, unsigned char *image, unsigned int length,  	packet[pos++] = header_len;  	packet[pos++] = 0; -	packet[pos++] = 5; /* version byte?? */ +	packet[pos++] = 5;	/* version byte?? */  	packet[pos++] = 0;  	pos += yahoo_put32(packet + pos, length); -	packet[pos++] = 2; /* packet type, image */ +	packet[pos++] = 2;	/* packet type, image */  	pos += yahoo_put32(packet + pos, timestamp);  	yahoo_add_to_send_queue(yid, packet, header_len);  	FREE(packet); @@ -4999,9 +4582,10 @@ void yahoo_webcam_send_image(int id, unsigned char *image, unsigned int length,  		yahoo_add_to_send_queue(yid, image, length);  } -void yahoo_webcam_accept_viewer(int id, const char* who, int accept) +void yahoo_webcam_accept_viewer(int id, const char *who, int accept)  { -	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_WEBCAM); +	struct yahoo_input_data *yid = +		find_input_by_id_and_type(id, YAHOO_CONNECTION_WEBCAM);  	char *packet = NULL;  	char *data = NULL;  	unsigned char header_len = 13; @@ -5012,17 +4596,17 @@ void yahoo_webcam_accept_viewer(int id, const char* who, int accept)  		return;  	data = strdup("u="); -	data = y_string_append(data, (char*)who); +	data = y_string_append(data, (char *)who);  	data = y_string_append(data, "\r\n");  	len = strlen(data);  	packet = y_new0(char, header_len + len);  	packet[pos++] = header_len;  	packet[pos++] = 0; -	packet[pos++] = 5; /* version byte?? */ +	packet[pos++] = 5;	/* version byte?? */  	packet[pos++] = 0;  	pos += yahoo_put32(packet + pos, len); -	packet[pos++] = 0; /* packet type */ +	packet[pos++] = 0;	/* packet type */  	pos += yahoo_put32(packet + pos, accept);  	memcpy(packet + pos, data, len);  	FREE(data); @@ -5032,13 +4616,15 @@ void yahoo_webcam_accept_viewer(int id, const char* who, int accept)  void yahoo_webcam_invite(int id, const char *who)  { -	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); +	struct yahoo_input_data *yid = +		find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);  	struct yahoo_packet *pkt; -		 +  	if (!yid)  		return; -	pkt = yahoo_packet_new(YAHOO_SERVICE_NOTIFY, YAHOO_STATUS_NOTIFY, yid->yd->session_id); +	pkt = yahoo_packet_new(YAHOO_SERVICE_NOTIFY, YPACKET_STATUS_NOTIFY, +		yid->yd->session_id);  	yahoo_packet_hash(pkt, 49, "WEBCAMINVITE");  	yahoo_packet_hash(pkt, 14, " "); @@ -5050,7 +4636,8 @@ void yahoo_webcam_invite(int id, const char *who)  	yahoo_packet_free(pkt);  } -static void yahoo_search_internal(int id, int t, const char *text, int g, int ar, int photo, int yahoo_only, int startpos, int total) +static void yahoo_search_internal(int id, int t, const char *text, int g, +	int ar, int photo, int yahoo_only, int startpos, int total)  {  	struct yahoo_data *yd = find_conn_by_id(id);  	struct yahoo_input_data *yid; @@ -5066,32 +4653,37 @@ static void yahoo_search_internal(int id, int t, const char *text, int g, int ar  	yid->type = YAHOO_CONNECTION_SEARCH;  	/* -	age range -	.ar=1 - 13-18, 2 - 18-25, 3 - 25-35, 4 - 35-50, 5 - 50-70, 6 - 70+ -	*/ +	   age range +	   .ar=1 - 13-18, 2 - 18-25, 3 - 25-35, 4 - 35-50, 5 - 50-70, 6 - 70+ +	 */ -	snprintf(buff, sizeof(buff), "&.sq=%%20&.tt=%d&.ss=%d", total, startpos); +	snprintf(buff, sizeof(buff), "&.sq=%%20&.tt=%d&.ss=%d", total, +		startpos);  	ctext = strdup(text);  	while ((p = strchr(ctext, ' ')))  		*p = '+'; -	snprintf(url, 1024, "http://members.yahoo.com/interests?.oc=m&.kw=%s&.sb=%d&.g=%d&.ar=0%s%s%s", -			ctext, t, g, photo ? "&.p=y" : "", yahoo_only ? "&.pg=y" : "", -			startpos ? buff : ""); +	snprintf(url, 1024, +		"http://members.yahoo.com/interests?.oc=m&.kw=%s&.sb=%d&.g=%d&.ar=0%s%s%s", +		ctext, t, g, photo ? "&.p=y" : "", yahoo_only ? "&.pg=y" : "", +		startpos ? buff : "");  	FREE(ctext);  	snprintf(buff, sizeof(buff), "Y=%s; T=%s", yd->cookie_y, yd->cookie_t);  	inputs = y_list_prepend(inputs, yid); -	yahoo_http_get(yid->yd->client_id, url, buff, _yahoo_http_connected, yid); +	yahoo_http_get(yid->yd->client_id, url, buff, 0, 0, +		_yahoo_http_connected, yid);  } -void yahoo_search(int id, enum yahoo_search_type t, const char *text, enum yahoo_search_gender g, enum yahoo_search_agerange ar,  -		int photo, int yahoo_only) +void yahoo_search(int id, enum yahoo_search_type t, const char *text, +	enum yahoo_search_gender g, enum yahoo_search_agerange ar, int photo, +	int yahoo_only)  { -	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); +	struct yahoo_input_data *yid = +		find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);  	struct yahoo_search_state *yss;  	if (!yid) @@ -5115,7 +4707,8 @@ void yahoo_search(int id, enum yahoo_search_type t, const char *text, enum yahoo  void yahoo_search_again(int id, int start)  { -	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); +	struct yahoo_input_data *yid = +		find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);  	struct yahoo_search_state *yss;  	if (!yid || !yid->ys) @@ -5126,201 +4719,644 @@ void yahoo_search_again(int id, int start)  	if (start == -1)  		start = yss->lsearch_nstart + yss->lsearch_nfound; -	yahoo_search_internal(id, yss->lsearch_type, yss->lsearch_text,  -			yss->lsearch_gender, yss->lsearch_agerange,  -			yss->lsearch_photo, yss->lsearch_yahoo_only,  -			start, yss->lsearch_ntotal); +	yahoo_search_internal(id, yss->lsearch_type, yss->lsearch_text, +		yss->lsearch_gender, yss->lsearch_agerange, +		yss->lsearch_photo, yss->lsearch_yahoo_only, +		start, yss->lsearch_ntotal);  } +void yahoo_send_picture(int id, const char *name, unsigned long size, +	yahoo_get_fd_callback callback, void *data) +{ +	/* Not Implemented */ +} + +/* File Transfer */ +static YList *active_file_transfers = NULL; + +enum { +	FT_STATE_HEAD = 1, +	FT_STATE_RECV, +	FT_STATE_RECV_START, +	FT_STATE_SEND +}; +  struct send_file_data { -	struct yahoo_packet *pkt; +	int client_id; +	char *id; +	char *who; +	char *filename; +	char *ip_addr; +	char *token; +	int size; + +	struct yahoo_input_data *yid; +	int state; +  	yahoo_get_fd_callback callback; -	void *user_data; +	void *data;  }; -static void _yahoo_send_picture_connected(int id, int fd, int error, void *data) +static char *yahoo_get_random(void) +{ +	int i = 0; +	int r = 0; +	int c = 0; +	char out[25]; + +	out[24] = '\0'; +	out[23] = '$'; +	out[22] = '$'; +	 +	for (i = 0; i < 22; i++) { +		if(r == 0) +			r = rand(); + +		c = r%61; + +		if(c<26) +			out[i] = c + 'a'; +		else if (c<52) +			out[i] = c - 26 + 'A'; +		else +			out[i] = c - 52 + '0'; + +		r /= 61; +	} + +	return strdup(out); +} + +static int _are_same_id(const void *sfd1, const void *id) +{ +	return strcmp(((struct send_file_data *)sfd1)->id, (char *)id); +} + +static int _are_same_yid(const void *sfd1, const void *yid) +{ +	if(((struct send_file_data *)sfd1)->yid == yid) +		return 0; +	else +		return 1; +} + +static struct send_file_data *yahoo_get_active_transfer(char *id) +{ +	YList *l = y_list_find_custom(active_file_transfers, id, +		_are_same_id); + +	if(l) +		return (struct send_file_data *)l->data; +	 +	return NULL; +} + +static struct send_file_data *yahoo_get_active_transfer_with_yid(void *yid) +{ +	YList *l = y_list_find_custom(active_file_transfers, yid, +		_are_same_yid); + +	if(l) +		return (struct send_file_data *)l->data; +	 +	return NULL; +} + +static void yahoo_add_active_transfer(struct send_file_data *sfd) +{ +	active_file_transfers = y_list_prepend(active_file_transfers, sfd); +} + +static void yahoo_remove_active_transfer(struct send_file_data *sfd) +{ +	active_file_transfers = y_list_remove(active_file_transfers, sfd); +	free(sfd->id); +	free(sfd->who); +	free(sfd->filename); +	free(sfd->ip_addr); +	FREE(sfd); +} + +static void _yahoo_ft_upload_connected(int id, void *fd, int error, void *data)  { -	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_FT);  	struct send_file_data *sfd = data; -	struct yahoo_packet *pkt = sfd->pkt; -	unsigned char buff[1024]; +	struct yahoo_input_data *yid = sfd->yid; -	if (fd <= 0) { -		sfd->callback(id, fd, error, sfd->user_data); -		FREE(sfd); -		yahoo_packet_free(pkt); +	if (!fd) {  		inputs = y_list_remove(inputs, yid);  		FREE(yid);  		return;  	} +	sfd->callback(id, fd, error, sfd->data); +  	yid->fd = fd; -	yahoo_send_packet(yid, pkt, 8); -	yahoo_packet_free(pkt); +	yid->read_tag = +		YAHOO_CALLBACK(ext_yahoo_add_handler) (yid->yd->client_id, fd, +		YAHOO_INPUT_READ, yid); +} -	snprintf((char *)buff, sizeof(buff), "29"); -	buff[2] = 0xc0; -	buff[3] = 0x80; -	 -	write(yid->fd, buff, 4); +static void yahoo_file_transfer_upload(struct yahoo_data *yd, +	struct send_file_data *sfd) +{ +	char url[256]; +	char buff[4096]; +	char *sender_enc = NULL, *recv_enc = NULL, *token_enc = NULL; -	/*	YAHOO_CALLBACK(ext_yahoo_add_handler) (nyd->fd, YAHOO_INPUT_READ); */ +	struct yahoo_input_data *yid = y_new0(struct yahoo_input_data, 1); -	sfd->callback(id, fd, error, sfd->user_data); -	FREE(sfd); -	inputs = y_list_remove(inputs, yid); -	/* -	while (yahoo_tcp_readline(buff, sizeof(buff), nyd->fd) > 0) { -	if (!strcmp(buff, "")) -	break; +	yid->yd = yd; +	yid->type = YAHOO_CONNECTION_FT; + +	inputs = y_list_prepend(inputs, yid); +	sfd->yid = yid; +	sfd->state = FT_STATE_SEND; + +	token_enc = yahoo_urlencode(sfd->token); +	sender_enc = yahoo_urlencode(yd->user); +	recv_enc = yahoo_urlencode(sfd->who); + +	snprintf(url, sizeof(url),  +		"http://%s/relay?token=%s&sender=%s&recver=%s", sfd->ip_addr, +		token_enc, sender_enc, recv_enc); + +	snprintf(buff, sizeof(buff), "T=%s; Y=%s", yd->cookie_t, yd->cookie_y); + +	yahoo_http_post(yd->client_id, url, buff, sfd->size, +		_yahoo_ft_upload_connected, sfd); + +	FREE(token_enc); +	FREE(sender_enc); +	FREE(recv_enc); +} + +static void yahoo_init_ft_recv(struct yahoo_data *yd, +	struct send_file_data *sfd) +{ +	char url[256]; +	char buff[1024]; +	char *sender_enc = NULL, *recv_enc = NULL, *token_enc = NULL; + +	struct yahoo_input_data *yid = y_new0(struct yahoo_input_data, 1); + +	yid->yd = yd; +	yid->type = YAHOO_CONNECTION_FT; + +	inputs = y_list_prepend(inputs, yid); +	sfd->yid = yid; +	sfd->state = FT_STATE_HEAD; + +	token_enc = yahoo_urlencode(sfd->token); +	sender_enc = yahoo_urlencode(sfd->who); +	recv_enc = yahoo_urlencode(yd->user); + +	snprintf(url, sizeof(url),  +		"http://%s/relay?token=%s&sender=%s&recver=%s", sfd->ip_addr, +		token_enc, sender_enc, recv_enc); + +	snprintf(buff, sizeof(buff), "Y=%s; T=%s", yd->cookie_y, yd->cookie_t); + +	yahoo_http_head(yid->yd->client_id, url, buff, 0, NULL, +		_yahoo_http_connected, yid); + +	FREE(token_enc); +	FREE(sender_enc); +	FREE(recv_enc);  } -	*/ -	yahoo_input_close(yid); +static void yahoo_file_transfer_accept(struct yahoo_input_data *yid, +	struct send_file_data *sfd) +{ +	struct yahoo_packet *pkt; + +	pkt = yahoo_packet_new(YAHOO_SERVICE_Y7_FILETRANSFERACCEPT, +		YPACKET_STATUS_DEFAULT, yid->yd->session_id); + +	yahoo_packet_hash(pkt, 1, yid->yd->user); +	yahoo_packet_hash(pkt, 5, sfd->who); +	yahoo_packet_hash(pkt, 265, sfd->id); +	yahoo_packet_hash(pkt, 27, sfd->filename); +	yahoo_packet_hash(pkt, 249, "3"); +	yahoo_packet_hash(pkt, 251, sfd->token); + +	yahoo_send_packet(yid, pkt, 0); + +	yahoo_packet_free(pkt); + +	yahoo_init_ft_recv(yid->yd, sfd);  } -void yahoo_send_picture(int id, const char *name, unsigned long size, -							yahoo_get_fd_callback callback, void *data) +static void yahoo_process_filetransferaccept(struct yahoo_input_data *yid, +	struct yahoo_packet *pkt)  { -	struct yahoo_data *yd = find_conn_by_id(id); -	struct yahoo_input_data *yid; -	struct yahoo_server_settings *yss; -	struct yahoo_packet *pkt = NULL; -	char size_str[10]; -	char expire_str[10]; -	long content_length = 0; -	unsigned char buff[1024]; -	char url[255]; +	YList *l;  	struct send_file_data *sfd; +	char *who = NULL; +	char *filename = NULL; +	char *id = NULL; +	char *token = NULL; -	if (!yd) -		return; +	for (l = pkt->hash; l; l = l->next) { +		struct yahoo_pair *pair = l->data; +		switch (pair->key) { +		case 4: +			who = pair->value; +			break; +		case 5: +			/* Me... don't care */ +			break; +		case 249: +			break; +		case 265: +			id = pair->value; +			break; +		case 251: +			token = pair->value; +			break; +		case 27: +			filename = pair->value; +			break; +		} +	} -	yss = yd->server_settings; +	sfd = yahoo_get_active_transfer(id); -	yid = y_new0(struct yahoo_input_data, 1); -	yid->yd = yd; -	yid->type = YAHOO_CONNECTION_FT; +	if (sfd) { +		sfd->token = strdup(token); -	pkt = yahoo_packet_new(YAHOO_SERVICE_PICTURE_UPLOAD, YAHOO_STATUS_AVAILABLE, yd->session_id); +		yahoo_file_transfer_upload(yid->yd, sfd); +	} +	else { +		YAHOO_CALLBACK(ext_yahoo_file_transfer_done) +			(yid->yd->client_id, YAHOO_FILE_TRANSFER_UNKNOWN, +			sfd->data); -	snprintf(size_str, sizeof(size_str), "%ld", size); -	snprintf(expire_str, sizeof(expire_str), "%ld", (long)604800); +		yahoo_remove_active_transfer(sfd); +	} +} -	yahoo_packet_hash(pkt, 0, yd->user); -	yahoo_packet_hash(pkt, 1, yd->user); -	yahoo_packet_hash(pkt, 14, ""); -	yahoo_packet_hash(pkt, 27, name); -	yahoo_packet_hash(pkt, 28, size_str); -	yahoo_packet_hash(pkt, 38, expire_str); -	 +static void yahoo_process_filetransferinfo(struct yahoo_input_data *yid, +	struct yahoo_packet *pkt) +{ +	YList *l; +	char *who = NULL; +	char *filename = NULL; +	char *id = NULL; +	char *token = NULL; +	char *ip_addr = NULL; -	content_length = YAHOO_PACKET_HDRLEN + yahoo_packet_length(pkt); +	struct send_file_data *sfd; -	snprintf(url, sizeof(url), "http://%s:%d/notifyft", -				yss->filetransfer_host, yss->filetransfer_port); -	snprintf((char *)buff, sizeof(buff), "Y=%s; T=%s", -				 yd->cookie_y, yd->cookie_t); -	inputs = y_list_prepend(inputs, yid); +	for (l = pkt->hash; l; l = l->next) { +		struct yahoo_pair *pair = l->data; +		switch (pair->key) { +		case 1: +		case 4: +			who = pair->value; +			break; +		case 5: +			/* Me... don't care */ +			break; +		case 249: +			break; +		case 265: +			id = pair->value; +			break; +		case 250: +			ip_addr = pair->value; +			break; +		case 251: +			token = pair->value; +			break; +		case 27: +			filename = pair->value; +			break; +		} +	} -	sfd = y_new0(struct send_file_data, 1); -	sfd->pkt = pkt; -	sfd->callback = callback; -	sfd->user_data = data; -	yahoo_http_post(yid->yd->client_id, url, (char *)buff, content_length+4+size, -						_yahoo_send_picture_connected, sfd); +	sfd = yahoo_get_active_transfer(id); + +	if (sfd) { +		sfd->token = strdup(token); +		sfd->ip_addr = strdup(ip_addr); + +		yahoo_file_transfer_accept(yid, sfd); +	} +	else { +		YAHOO_CALLBACK(ext_yahoo_file_transfer_done) +			(yid->yd->client_id, YAHOO_FILE_TRANSFER_UNKNOWN, +			sfd->data); + +		yahoo_remove_active_transfer(sfd); +	}  } -static void _yahoo_send_file_connected(int id, int fd, int error, void *data) +static void yahoo_send_filetransferinfo(struct yahoo_data *yd, +	struct send_file_data *sfd)  { -	struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_FT); -	struct send_file_data *sfd = data; -	struct yahoo_packet *pkt = sfd->pkt; -	unsigned char buff[1024]; +	struct yahoo_input_data *yid; +	struct yahoo_packet *pkt; + +	yid = find_input_by_id_and_type(yd->client_id, YAHOO_CONNECTION_PAGER); +	sfd->ip_addr = YAHOO_CALLBACK(ext_yahoo_get_ip_addr)("relay.yahoo.com"); + +	if (!sfd->ip_addr) { +		YAHOO_CALLBACK(ext_yahoo_file_transfer_done) +			(yd->client_id, YAHOO_FILE_TRANSFER_RELAY, sfd->data); + +		yahoo_remove_active_transfer(sfd); -	if (fd <= 0) { -		sfd->callback(id, fd, error, sfd->user_data); -		FREE(sfd); -		yahoo_packet_free(pkt); -		inputs = y_list_remove(inputs, yid); -		FREE(yid);  		return;  	} -	yid->fd = fd; -	yahoo_send_packet(yid, pkt, 8); +	pkt = yahoo_packet_new(YAHOO_SERVICE_Y7_FILETRANSFERINFO, +		YPACKET_STATUS_DEFAULT, yd->session_id); + +	yahoo_packet_hash(pkt, 1, yd->user); +	yahoo_packet_hash(pkt, 5, sfd->who); +	yahoo_packet_hash(pkt, 265, sfd->id); +	yahoo_packet_hash(pkt, 27, sfd->filename); +	yahoo_packet_hash(pkt, 249, "3"); +	yahoo_packet_hash(pkt, 250, sfd->ip_addr); + +	yahoo_send_packet(yid, pkt, 0); +  	yahoo_packet_free(pkt); +} -	snprintf((char *)buff, sizeof(buff), "29"); -	buff[2] = 0xc0; -	buff[3] = 0x80; -	 -	write(yid->fd, buff, 4); +static void yahoo_process_filetransfer(struct yahoo_input_data *yid, +	struct yahoo_packet *pkt) +{ +	YList *l; +	char *who = NULL; +	char *filename = NULL; +	char *msg = NULL; +	char *id = NULL; +	int action = 0; +	int size = 0; +	struct yahoo_data *yd = yid->yd; -/*	YAHOO_CALLBACK(ext_yahoo_add_handler) (nyd->fd, YAHOO_INPUT_READ); */ +	struct send_file_data *sfd; -	sfd->callback(id, fd, error, sfd->user_data); -	FREE(sfd); -	inputs = y_list_remove(inputs, yid); -	/* -	while (yahoo_tcp_readline(buff, sizeof(buff), nyd->fd) > 0) { -		if (!strcmp(buff, "")) +	for (l = pkt->hash; l; l = l->next) { +		struct yahoo_pair *pair = l->data; +		switch (pair->key) { +		case 4: +			who = pair->value; +			break; +		case 5: +			/* Me... don't care */ +			break; +		case 222: +			action = atoi(pair->value); +			break; +		case 265: +			id = pair->value; +			break; +		case 266: /* Don't know */ +			break; +		case 302: /* Start Data? */  			break; +		case 300: +			break; +		case 27: +			filename = pair->value; +			break; +		case 28: +			size = atoi(pair->value); +			break; +		case 14: +			msg = pair->value; +		case 301: /* End Data? */ +			break; +		case 303: +			break; + +		}  	} -	*/ -	yahoo_input_close(yid); +	if (action == YAHOO_FILE_TRANSFER_INIT) { +		/* Received a FT request from buddy */ +		sfd = y_new0(struct send_file_data, 1); +         +		sfd->client_id = yd->client_id; +		sfd->id = strdup(id); +		sfd->who = strdup(who); +		sfd->filename = strdup(filename); +		sfd->size = size; +         +		yahoo_add_active_transfer(sfd); + +		YAHOO_CALLBACK(ext_yahoo_got_file) (yd->client_id, yd->user, +			who, msg, filename, size, sfd->id); +	} +	else { +		/* Response to our request */ +		sfd = yahoo_get_active_transfer(id); + +		if (sfd && action == YAHOO_FILE_TRANSFER_ACCEPT) { +			yahoo_send_filetransferinfo(yd, sfd); +		} +		else if (!sfd || action == YAHOO_FILE_TRANSFER_REJECT) { +			YAHOO_CALLBACK(ext_yahoo_file_transfer_done) +				(yd->client_id, YAHOO_FILE_TRANSFER_REJECT, +				sfd->data); + +			yahoo_remove_active_transfer(sfd); +		} +	}  } -void yahoo_send_file(int id, const char *who, const char *msg,  -		const char *name, unsigned long size,  -		yahoo_get_fd_callback callback, void *data) +void yahoo_send_file(int id, const char *who, const char *msg, +	const char *name, unsigned long size, +	yahoo_get_fd_callback callback, void *data)  { -	struct yahoo_data *yd = find_conn_by_id(id); -	struct yahoo_input_data *yid; -	struct yahoo_server_settings *yss;  	struct yahoo_packet *pkt = NULL;  	char size_str[10]; -	long content_length = 0; -	unsigned char buff[1024]; -	char url[255]; +	struct yahoo_input_data *yid; +	struct yahoo_data *yd;  	struct send_file_data *sfd; +	 +	yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); +	yd = find_conn_by_id(id); +	sfd = y_new0(struct send_file_data, 1); -	if (!yd) -		return; +	sfd->client_id = id; +	sfd->id = yahoo_get_random(); +	sfd->who = strdup(who); +	sfd->filename = strdup(name); +	sfd->size = size; +	sfd->callback = callback; +	sfd->data = data; -	yss = yd->server_settings; +	yahoo_add_active_transfer(sfd); -	yid = y_new0(struct yahoo_input_data, 1); -	yid->yd = yd; -	yid->type = YAHOO_CONNECTION_FT; +	if (!yd) +		return; -	pkt = yahoo_packet_new(YAHOO_SERVICE_FILETRANSFER, YAHOO_STATUS_AVAILABLE, yd->session_id); +	pkt = yahoo_packet_new(YAHOO_SERVICE_Y7_FILETRANSFER, +		YPACKET_STATUS_DEFAULT, yd->session_id);  	snprintf(size_str, sizeof(size_str), "%ld", size); -	yahoo_packet_hash(pkt, 0, yd->user); +	yahoo_packet_hash(pkt, 1, yd->user);  	yahoo_packet_hash(pkt, 5, who); -	yahoo_packet_hash(pkt, 14, msg); +	yahoo_packet_hash(pkt, 265, sfd->id); +	yahoo_packet_hash(pkt, 222, "1"); +	yahoo_packet_hash(pkt, 266, "1"); +	yahoo_packet_hash(pkt, 302, "268"); +	yahoo_packet_hash(pkt, 300, "268");  	yahoo_packet_hash(pkt, 27, name);  	yahoo_packet_hash(pkt, 28, size_str); +	yahoo_packet_hash(pkt, 301, "268"); +	yahoo_packet_hash(pkt, 303, "268"); -	content_length = YAHOO_PACKET_HDRLEN + yahoo_packet_length(pkt); +	yahoo_send_packet(yid, pkt, 0); -	snprintf(url, sizeof(url), "http://%s:%d/notifyft",  -			yss->filetransfer_host, yss->filetransfer_port); -	snprintf((char *)buff, sizeof(buff), "Y=%s; T=%s", -			yd->cookie_y, yd->cookie_t); -	inputs = y_list_prepend(inputs, yid); +	yahoo_packet_free(pkt); +} -	sfd = y_new0(struct send_file_data, 1); -	sfd->pkt = pkt; -	sfd->callback = callback; -	sfd->user_data = data; -	yahoo_http_post(yid->yd->client_id, url, (char *)buff, content_length+4+size, -			_yahoo_send_file_connected, sfd); +void yahoo_send_file_transfer_response(int client_id, int response, char *id, void *data) +{ +	struct yahoo_packet *pkt = NULL; +	char resp[2]; +	struct yahoo_input_data *yid; +	 +	struct send_file_data *sfd = yahoo_get_active_transfer(id); + +	sfd->data = data; + +	yid = find_input_by_id_and_type(client_id, YAHOO_CONNECTION_PAGER); + +	pkt = yahoo_packet_new(YAHOO_SERVICE_Y7_FILETRANSFER, +		YPACKET_STATUS_DEFAULT, yid->yd->session_id); + +	snprintf(resp, sizeof(resp), "%d", response); + +	yahoo_packet_hash(pkt, 1, yid->yd->user); +	yahoo_packet_hash(pkt, 5, sfd->who); +	yahoo_packet_hash(pkt, 265, sfd->id); +	yahoo_packet_hash(pkt, 222, resp); + +	yahoo_send_packet(yid, pkt, 0); + +	yahoo_packet_free(pkt); + +	if(response == YAHOO_FILE_TRANSFER_REJECT) +		yahoo_remove_active_transfer(sfd);  } +static void yahoo_process_ft_connection(struct yahoo_input_data *yid, int over) +{ +	struct send_file_data *sfd; +	struct yahoo_data *yd = yid->yd; +	 +	sfd = yahoo_get_active_transfer_with_yid(yid); + +	if (!sfd) { +		LOG(("Something funny happened. yid %p has no sfd.\n", yid)); +		return; +	} + +	/*  +	 * We want to handle only the complete data with HEAD since we don't +	 * want a situation where both the GET and HEAD are active. +	 * With SEND, we really can't do much with partial response +	 */ +	if ((sfd->state == FT_STATE_HEAD || sfd->state == FT_STATE_SEND)  +			&& !over) +		return; + +	if (sfd->state == FT_STATE_HEAD) { +		/* Do a GET */ +		char url[256]; +		char buff[1024]; +		char *sender_enc = NULL, *recv_enc = NULL, *token_enc = NULL; + +		struct yahoo_input_data *yid_ft =  +			y_new0(struct yahoo_input_data, 1); +         +		yid_ft->yd = yid->yd; +		yid_ft->type = YAHOO_CONNECTION_FT; +         +		inputs = y_list_prepend(inputs, yid_ft); +		sfd->yid = yid_ft; +		sfd->state = FT_STATE_RECV; + +		token_enc = yahoo_urlencode(sfd->token); +		sender_enc = yahoo_urlencode(sfd->who); +		recv_enc = yahoo_urlencode(yd->user); +         +		snprintf(url, sizeof(url),  +			"http://%s/relay?token=%s&sender=%s&recver=%s", sfd->ip_addr, +			token_enc, sender_enc, recv_enc); + +		snprintf(buff, sizeof(buff), "Y=%s; T=%s", yd->cookie_y, +			yd->cookie_t); + + +		yahoo_http_get(yd->client_id, url, buff, 1, 1, +			_yahoo_http_connected, yid_ft); + +		FREE(token_enc); +		FREE(sender_enc); +		FREE(recv_enc); +	} +	else if (sfd->state == FT_STATE_RECV ||  +		sfd->state == FT_STATE_RECV_START) { + +		unsigned char *data_begin = NULL; + +		if (yid->rxlen == 0) +			yahoo_remove_active_transfer(sfd); + +		if (sfd->state != FT_STATE_RECV_START && +			(data_begin =  +				(unsigned char *)strstr((char *)yid->rxqueue, +				"\r\n\r\n"))) { + +			sfd->state = FT_STATE_RECV_START; + +			yid->rxlen -= 4+(data_begin-yid->rxqueue)/sizeof(char); +			data_begin += 4; + +			if (yid->rxlen > 0) +				YAHOO_CALLBACK(ext_yahoo_got_ft_data)  +					(yd->client_id, data_begin, +					yid->rxlen, sfd->data); +		} +		else if (sfd->state == FT_STATE_RECV_START) +			YAHOO_CALLBACK(ext_yahoo_got_ft_data) (yd->client_id, +				yid->rxqueue, yid->rxlen, sfd->data); + +		FREE(yid->rxqueue); +		yid->rxqueue = NULL; +		yid->rxlen = 0; +	} +	else if (sfd->state == FT_STATE_SEND) { +		/* Sent file completed */ +		int len = 0; +		char *off = strstr((char *)yid->rxqueue, "Content-Length: "); + +		if (off) { +			off += 16; +			len = atoi(off); +		} + +		if (len < sfd->size) +			YAHOO_CALLBACK(ext_yahoo_file_transfer_done) +				(yd->client_id, +				YAHOO_FILE_TRANSFER_FAILED, sfd->data); +		else +			YAHOO_CALLBACK(ext_yahoo_file_transfer_done) +				(yd->client_id, +				YAHOO_FILE_TRANSFER_DONE, sfd->data); + +		yahoo_remove_active_transfer(sfd); +	} +} + +/* End File Transfer */  enum yahoo_status yahoo_current_status(int id)  { @@ -5361,6 +5397,8 @@ const char *yahoo_get_cookie(int id, const char *which)  		return NULL;  	if (!strncasecmp(which, "y", 1))  		return yd->cookie_y; +	if (!strncasecmp(which, "b", 1)) +		return yd->cookie_b;  	if (!strncasecmp(which, "t", 1))  		return yd->cookie_t;  	if (!strncasecmp(which, "c", 1)) @@ -5370,18 +5408,7 @@ const char *yahoo_get_cookie(int id, const char *which)  	return NULL;  } -void yahoo_get_url_handle(int id, const char *url,  -		yahoo_get_url_handle_callback callback, void *data) -{ -	struct yahoo_data *yd = find_conn_by_id(id); -	if (!yd) -		return; - -	yahoo_get_url_fd(id, url, yd, callback, data); -} - -const char *yahoo_get_profile_url( void ) +const char *yahoo_get_profile_url(void)  {  	return profile_url;  } - diff --git a/protocols/yahoo/yahoo.c b/protocols/yahoo/yahoo.c index bf577496..7a856254 100644 --- a/protocols/yahoo/yahoo.c +++ b/protocols/yahoo/yahoo.c @@ -1,7 +1,7 @@  /*   * libyahoo2 wrapper to BitlBee   * - * Mostly Copyright 2004 Wilmer van der Gaast <wilmer@gaast.net> + * Mostly Copyright 2004-2010 Wilmer van der Gaast <wilmer@gaast.net>   *   * This program is free software; you can redistribute it and/or modify   * it under the terms of the GNU General Public License as published by @@ -338,16 +338,20 @@ static struct groupchat *byahoo_chat_with( struct im_connection *ic, char *who )  static void byahoo_auth_allow( struct im_connection *ic, const char *who )  { +	/*  	struct byahoo_data *yd = (struct byahoo_data *) ic->proto_data;  	yahoo_accept_buddy_ymsg13( yd->y2_id, NULL, who ); +	*/  }  static void byahoo_auth_deny( struct im_connection *ic, const char *who )  { +	/*  	struct byahoo_data *yd = (struct byahoo_data *) ic->proto_data;  	yahoo_reject_buddy_ymsg13( yd->y2_id, NULL, who, NULL ); +	*/  }  void byahoo_initmodule( ) @@ -420,7 +424,7 @@ void byahoo_connect_callback( gpointer data, gint source, b_input_condition cond  		return;  	} -	d->callback( d->fd, 0, d->data ); +	d->callback( NULL + d->fd, 0, d->data );  	g_free( d );  } @@ -440,7 +444,7 @@ gboolean byahoo_read_ready_callback( gpointer data, gint source, b_input_conditi  		/* WTF doesn't libyahoo clean this up? */  		return FALSE; -	yahoo_read_ready( d->id, d->fd, d->data ); +	yahoo_read_ready( d->id, NULL + d->fd, d->data );  	return TRUE;  } @@ -457,7 +461,7 @@ gboolean byahoo_write_ready_callback( gpointer data, gint source, b_input_condit  {  	struct byahoo_write_ready_data *d = data; -	return yahoo_write_ready( d->id, d->fd, d->data ); +	return yahoo_write_ready( d->id, NULL + d->fd, d->data );  }  void ext_yahoo_login_response( int id, int succ, const char *url ) @@ -605,9 +609,6 @@ void ext_yahoo_status_changed( int id, const char *who, int stat, const char *ms  		state_string = "Offline";  		flags = 0;  		break; -	case YAHOO_STATUS_NOTIFY: -		state_string = "Notify"; -		break;  	}  	imcb_buddy_status( ic, who, flags, state_string, msg ); @@ -616,6 +617,10 @@ void ext_yahoo_status_changed( int id, const char *who, int stat, const char *ms  		imcb_buddy_times( ic, who, 0, idle );  } +void ext_yahoo_got_buzz( int id, const char *me, const char *who, long tm ) +{ +} +  void ext_yahoo_got_im( int id, const char *me, const char *who, const char *msg, long tm, int stat, int utf8 )  {  	struct im_connection *ic = byahoo_get_ic_by_id( id ); @@ -629,15 +634,22 @@ void ext_yahoo_got_im( int id, const char *me, const char *who, const char *msg,  	}  } -void ext_yahoo_got_file( int id, -                         const char *ignored, -                         const char *who, const char *url, long expires, const char *msg, const char *fname, unsigned long fesize ) +void ext_yahoo_got_file( int id, const char *ignored, const char *who, const char *msg, +                         const char *fname, unsigned long fesize, char *trid )  {  	struct im_connection *ic = byahoo_get_ic_by_id( id );  	imcb_log( ic, "Got a file transfer (file = %s) from %s. Ignoring for now due to lack of support.", fname, who );  } +void ext_yahoo_got_ft_data( int id, const unsigned char *in, int len, void *data ) +{ +} + +void ext_yahoo_file_transfer_done( int id, int result, void *data ) +{ +} +  void ext_yahoo_typing_notify( int id, const char *ignored, const char *who, int stat )  {  	struct im_connection *ic = byahoo_get_ic_by_id( id ); @@ -648,7 +660,7 @@ void ext_yahoo_typing_notify( int id, const char *ignored, const char *who, int  		imcb_buddy_typing( ic, (char*) who, 0 );  } -void ext_yahoo_system_message( int id, const char *msg ) +void ext_yahoo_system_message( int id, const char *me, const char *who, const char *msg )  {  	struct im_connection *ic = byahoo_get_ic_by_id( id ); @@ -670,9 +682,10 @@ void ext_yahoo_error( int id, const char *err, int fatal, int num )  }  /* TODO: Clear up the mess of inp and d structures */ -int ext_yahoo_add_handler( int id, int fd, yahoo_input_condition cond, void *data ) +int ext_yahoo_add_handler( int id, void *fd_, yahoo_input_condition cond, void *data )  {  	struct byahoo_input_data *inp = g_new0( struct byahoo_input_data, 1 ); +	int fd = (int) fd_;  	if( cond == YAHOO_INPUT_READ )  	{ @@ -699,12 +712,12 @@ int ext_yahoo_add_handler( int id, int fd, yahoo_input_condition cond, void *dat  	else  	{  		g_free( inp ); -		return( -1 ); +		return -1;  		/* Panic... */  	}  	byahoo_inputs = g_slist_append( byahoo_inputs, inp ); -	return( inp->h ); +	return inp->h;  }  void ext_yahoo_remove_handler( int id, int tag ) @@ -728,7 +741,7 @@ void ext_yahoo_remove_handler( int id, int tag )  	b_event_remove( tag );  } -int ext_yahoo_connect_async( int id, const char *host, int port, yahoo_connect_callback callback, void *data ) +int ext_yahoo_connect_async( int id, const char *host, int port, yahoo_connect_callback callback, void *data, int use_ssl )  {  	struct byahoo_connect_callback_data *d;  	int fd; @@ -744,48 +757,38 @@ int ext_yahoo_connect_async( int id, const char *host, int port, yahoo_connect_c  	d->data = data;  	d->id = id; -	return( fd ); +	return fd;  } -/* Because we don't want asynchronous connects in BitlBee, and because -   libyahoo doesn't seem to use this one anyway, this one is now defunct. */ -int ext_yahoo_connect(const char *host, int port) +char *ext_yahoo_get_ip_addr( const char *domain )  { -#if 0 -	struct sockaddr_in serv_addr; -	static struct hostent *server; -	static char last_host[256]; -	int servfd; -	char **p; +	return NULL; +} -	if(last_host[0] || g_strcasecmp(last_host, host)!=0) { -		if(!(server = gethostbyname(host))) { -			return -1; -		} -		strncpy(last_host, host, 255); -	} +int ext_yahoo_write( void *fd, char *buf, int len ) +{ +	return write( (int) fd, buf, len ); +} -	if((servfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { -		return -1; -	} +int ext_yahoo_read( void *fd, char *buf, int len ) +{ +	return read( (int) fd, buf, len ); +} -	for (p = server->h_addr_list; *p; p++) -	{ -		memset(&serv_addr, 0, sizeof(serv_addr)); -		serv_addr.sin_family = AF_INET; -		memcpy(&serv_addr.sin_addr.s_addr, *p, server->h_length); -		serv_addr.sin_port = htons(port); - -		if(connect(servfd, (struct sockaddr *) &serv_addr,  -					sizeof(serv_addr)) == -1) { -			return -1; -		} else { -			return servfd; -		} -	} +void ext_yahoo_close( void *fd ) +{ +	close( (int) fd ); +} + +void ext_yahoo_got_buddy_change_group( int id, const char *me, const char *who, +                                       const char *old_group, const char *new_group ) +{ +}                                 -	closesocket(servfd); -#endif +/* Because we don't want asynchronous connects in BitlBee, and because +   libyahoo doesn't seem to use this one anyway, this one is now defunct. */ +int ext_yahoo_connect(const char *host, int port) +{  	return -1;  } @@ -897,7 +900,7 @@ void ext_yahoo_chat_cat_xml( int id, const char *xml )  {  } -void ext_yahoo_chat_join( int id, const char *who, const char *room, const char *topic, YList *members, int fd ) +void ext_yahoo_chat_join( int id, const char *who, const char *room, const char *topic, YList *members, void *fd )  {  } @@ -927,9 +930,7 @@ void ext_yahoo_chat_yahooerror( int id, const char *me )  void ext_yahoo_contact_auth_request( int id, const char *myid, const char *who, const char *msg )  { -	struct im_connection *ic = byahoo_get_ic_by_id( id ); -	 -	imcb_ask_auth( ic, who, NULL ); +	/* Apparently no longer implemented.. */  }  void ext_yahoo_contact_added( int id, const char *myid, const char *who, const char *msg ) @@ -943,7 +944,7 @@ void ext_yahoo_rejected( int id, const char *who, const char *msg )  {  } -void ext_yahoo_game_notify( int id, const char *me, const char *who, int stat ) +void ext_yahoo_game_notify( int id, const char *me, const char *who, int stat, const char *msg )  {  } diff --git a/protocols/yahoo/yahoo2.h b/protocols/yahoo/yahoo2.h index ba42b39e..589aaa5a 100644 --- a/protocols/yahoo/yahoo2.h +++ b/protocols/yahoo/yahoo2.h @@ -50,13 +50,13 @@ extern "C" {  #include "yahoo2_types.h" -/* returns the socket descriptor for a given pager connection. shouldn't be needed */ -int  yahoo_get_fd(int id); +/* returns the socket descriptor object for a given pager connection. shouldn't be needed */ +	void *yahoo_get_fd(int id);  /* says how much logging to do */  /* see yahoo2_types.h for the different values */ -int  yahoo_set_log_level(enum yahoo_log_level level); -enum yahoo_log_level  yahoo_get_log_level( void ); +	int yahoo_set_log_level(enum yahoo_log_level level); +	enum yahoo_log_level yahoo_get_log_level(void);  /* these functions should be self explanatory */  /* who always means the buddy you're acting on */ @@ -221,8 +221,8 @@ enum yahoo_log_level  yahoo_get_log_level( void );  /* these should be called when input is available on a fd */  /* registered by ext_yahoo_add_handler */  /* if these return negative values, errno may be set */ -int  yahoo_read_ready(int id, int fd, void *data); -int  yahoo_write_ready(int id, int fd, void *data); +	int yahoo_read_ready(int id, void *fd, void *data); +	int yahoo_write_ready(int id, void *fd, void *data);  /* utility functions. these do not hit the server */  	enum yahoo_status yahoo_current_status(int id); @@ -239,9 +239,6 @@ int  yahoo_write_ready(int id, int fd, void *data);  	void yahoo_buddyicon_request(int id, const char *who); -	void yahoo_accept_buddy_ymsg13(int,const char*, const char*); -	void yahoo_reject_buddy_ymsg13(int,const char*, const char*, const char*); -  #include "yahoo_httplib.h"  #ifdef __cplusplus diff --git a/protocols/yahoo/yahoo2_callbacks.h b/protocols/yahoo/yahoo2_callbacks.h index 19060a22..0dccf188 100644 --- a/protocols/yahoo/yahoo2_callbacks.h +++ b/protocols/yahoo/yahoo2_callbacks.h @@ -54,15 +54,16 @@ extern "C" {   * A callback function called when an asynchronous connect completes.   *    * Params: - *     fd    - The file descriptor that has been connected, or -1 on error + *     fd    - The file descriptor object that has been connected, or NULL on  + *             error   *     error - The value of errno set by the call to connect or 0 if no error   *	       Set both fd and error to 0 if the connect was cancelled by the   *	       user   *     callback_data - the callback_data passed to the ext_yahoo_connect_async   *	       function   */ -typedef void (*yahoo_connect_callback)(int fd, int error, void *callback_data); - +	typedef void (*yahoo_connect_callback) (void *fd, int error, +		void *callback_data);  /*   * The following functions need to be implemented in the client @@ -261,10 +262,10 @@ struct yahoo_callbacks {   * 	topic   - the topic of the room, freed by library after call   *	members - the initial members of the chatroom (null terminated YList    *	          of yahoo_chat_member's) Must be freed by the client - *	fd	- the socket where the connection is coming from (for tracking) + *	fd	- the object where the connection is coming from (for tracking)   */  	void YAHOO_CALLBACK_TYPE(ext_yahoo_chat_join) (int id, const char *me, -		const char *room, const char *topic, YList *members, int fd); +		const char *room, const char *topic, YList *members, void *fd);  /*   * Name: ext_yahoo_chat_userjoin @@ -363,26 +364,42 @@ struct yahoo_callbacks {   * 	id   - the id that identifies the server connection   * 	me   - the identity the file was sent to   * 	who  - the user who sent the file - * 	url  - the file url - * 	expires  - the expiry date of the file on the server (timestamp)   * 	msg  - the message   * 	fname- the file name if direct transfer   * 	fsize- the file size if direct transfer + * 	trid - transfer id. Unique for this transfer + * + * NOTE: Subsequent callbacks for file transfer do not send all of this + * information again since it is wasteful. Implementations are expected to + * save this information and supply it as callback data when the file or + * confirmation is sent   */ -void YAHOO_CALLBACK_TYPE(ext_yahoo_got_file)(int id, const char *me, const char *who, const char *url, long expires, const char *msg, const char *fname, unsigned long fesize); - +	void YAHOO_CALLBACK_TYPE(ext_yahoo_got_file) (int id, const char *me, +		const char *who, const char *msg, const char *fname, +		unsigned long fesize, char *trid);  /* - * Name: ext_yahoo_contact_auth_request - * 	Called when a contact wants to add you to his/her contact list + * Name: ext_yahoo_got_ft_data + * 	Called multiple times when parts of the file are received   * Params:   * 	id   - the id that identifies the server connection - * 	myid - the identity s/he added - * 	who  - who did it - * 	msg  - any message sent + * 	in   - The data + * 	len  - Length of the data + * 	data - callback data   */ -void YAHOO_CALLBACK_TYPE(ext_yahoo_contact_auth_request)(int id, const char *myid, const char *who, const char *msg); +	void YAHOO_CALLBACK_TYPE(ext_yahoo_got_ft_data) (int id, +		const unsigned char *in, int len, void *data); +/* + * Name: ext_yahoo_file_transfer_done + * 	File transfer is done + * Params: + * 	id     - the id that identifies the server connection + * 	result - To notify if it finished successfully or with a failure + * 	data   - callback data + */ +	void YAHOO_CALLBACK_TYPE(ext_yahoo_file_transfer_done) (int id, +		int result, void *data);  /*   * Name: ext_yahoo_contact_added @@ -427,9 +444,10 @@ void YAHOO_CALLBACK_TYPE(ext_yahoo_contact_auth_request)(int id, const char *myi   * 	me   - the handle of the identity the notification is sent to   * 	who  - the handle of the remote user   * 	stat - 1 if game, 0 if stopped gaming + * 	msg  - game description and/or other text   */ -void YAHOO_CALLBACK_TYPE(ext_yahoo_game_notify)(int id, const char *me, const char *who, int stat); - +	void YAHOO_CALLBACK_TYPE(ext_yahoo_game_notify) (int id, const char *me, +		const char *who, int stat, const char *msg);  /*   * Name: ext_yahoo_mail_notify @@ -448,9 +466,12 @@ void YAHOO_CALLBACK_TYPE(ext_yahoo_game_notify)(int id, const char *me, const ch   * 	System message   * Params:   * 	id   - the id that identifies the server connection + * 	me   - the handle of the identity the notification is sent to + * 	who  - the source of the system message (there are different types)   * 	msg  - the message   */ -void YAHOO_CALLBACK_TYPE(ext_yahoo_system_message)(int id, const char *msg); +	void YAHOO_CALLBACK_TYPE(ext_yahoo_system_message) (int id, +		const char *me, const char *who, const char *msg);  /*   * Name: ext_yahoo_got_buddyicon @@ -629,13 +650,13 @@ void YAHOO_CALLBACK_TYPE(ext_yahoo_system_message)(int id, const char *msg);   * 	when a YAHOO_INPUT_WRITE fd is ready.   * Params:   * 	id   - the id that identifies the server connection - * 	fd   - the fd on which to listen + * 	fd   - the fd object on which to listen   * 	cond - the condition on which to call the callback   * 	data - callback data to pass to yahoo_*_ready   * 	   * Returns: a tag to be used when removing the handler   */ -	int YAHOO_CALLBACK_TYPE(ext_yahoo_add_handler) (int id, int fd, +	int YAHOO_CALLBACK_TYPE(ext_yahoo_add_handler) (int id, void *fd,  		yahoo_input_condition cond, void *data);  /* @@ -673,12 +694,74 @@ void YAHOO_CALLBACK_TYPE(ext_yahoo_system_message)(int id, const char *msg);   * 	port - the port to connect on   * 	callback - function to call when connect completes   * 	callback_data - data to pass to the callback function + * 	use_ssl - Whether we need an SSL connection   * Returns: - * 	a unix file descriptor to the socket + * 	a tag signifying the connection attempt   */  	int YAHOO_CALLBACK_TYPE(ext_yahoo_connect_async) (int id,  		const char *host, int port, yahoo_connect_callback callback, -		void *callback_data); +		void *callback_data, int use_ssl); + +/* + * Name: ext_yahoo_get_ip_addr + * 	get IP Address for a domain name + * Params: + * 	domain - Domain name + * Returns: + * 	Newly allocated string containing the IP Address in IPv4 notation + */ +	char *YAHOO_CALLBACK_TYPE(ext_yahoo_get_ip_addr) (const char *domain); + +/* + * Name: ext_yahoo_write + * 	Write data from the buffer into the socket for the specified connection + * Params: + * 	fd  - the file descriptor object that identifies this connection + * 	buf - Buffer to write the data from + * 	len - Length of the data + * Returns: + * 	Number of bytes written or -1 for error + */ +	int YAHOO_CALLBACK_TYPE(ext_yahoo_write) (void *fd, char *buf, int len); + +/* + * Name: ext_yahoo_read + * 	Read data into a buffer from socket for the specified connection + * Params: + * 	fd  - the file descriptor object that identifies this connection + * 	buf - Buffer to read the data into + * 	len - Max length to read + * Returns: + * 	Number of bytes read or -1 for error + */ +	int YAHOO_CALLBACK_TYPE(ext_yahoo_read) (void *fd, char *buf, int len); + +/* + * Name: ext_yahoo_close + * 	Close the file descriptor object and free its resources. Libyahoo2 will not + * 	use this object again. + * Params: + * 	fd  - the file descriptor object that identifies this connection + * Returns: + * 	Nothing + */ +	void YAHOO_CALLBACK_TYPE(ext_yahoo_close) (void *fd); + +/* + * Name: ext_yahoo_got_buddy_change_group + * 	Acknowledgement of buddy changing group + * Params: + * 	id: client id + * 	me: The user + * 	who: Buddy name + * 	old_group: Old group name + * 	new_group: New group name + * Returns: + * 	Nothing + */ +	void YAHOO_CALLBACK_TYPE(ext_yahoo_got_buddy_change_group) (int id, +		const char *me, const char *who, const char *old_group, +		const char *new_group);  #ifdef USE_STRUCT_CALLBACKS  }; @@ -698,4 +781,3 @@ void yahoo_register_callbacks(struct yahoo_callbacks *tyc);  #endif  #endif - diff --git a/protocols/yahoo/yahoo2_types.h b/protocols/yahoo/yahoo2_types.h index 0f6d7aab..bbade5d8 100644 --- a/protocols/yahoo/yahoo2_types.h +++ b/protocols/yahoo/yahoo2_types.h @@ -28,74 +28,175 @@  extern "C" {  #endif -enum yahoo_status { -	YAHOO_STATUS_DISCONNECTED = -1, -	YAHOO_STATUS_AVAILABLE = 0, -	YAHOO_STATUS_BRB, -	YAHOO_STATUS_BUSY, -	YAHOO_STATUS_NOTATHOME, -	YAHOO_STATUS_NOTATDESK, -	YAHOO_STATUS_NOTINOFFICE, -	YAHOO_STATUS_ONPHONE, -	YAHOO_STATUS_ONVACATION, -	YAHOO_STATUS_OUTTOLUNCH, -	YAHOO_STATUS_STEPPEDOUT, -	YAHOO_STATUS_INVISIBLE = 12, -	YAHOO_STATUS_CUSTOM = 99, -	YAHOO_STATUS_IDLE = 999, -	YAHOO_STATUS_WEBLOGIN = 0x5a55aa55, -	YAHOO_STATUS_OFFLINE = 0x5a55aa56, /* don't ask */ -	YAHOO_STATUS_NOTIFY = 0x16 /* TYPING */ -}; -#define YAHOO_STATUS_GAME	0x2 		/* Games don't fit into the regular status model */ - -enum yahoo_login_status { -	YAHOO_LOGIN_OK = 0, -	YAHOO_LOGIN_LOGOFF = 2, -	YAHOO_LOGIN_UNAME = 3, -	YAHOO_LOGIN_PASSWD = 13, -	YAHOO_LOGIN_LOCK = 14, -	YAHOO_LOGIN_DUPL = 99, -	YAHOO_LOGIN_SOCK = -1, -}; - -enum ypacket_status { -	YPACKET_STATUS_DISCONNECTED = -1, -	YPACKET_STATUS_DEFAULT = 0, -	YPACKET_STATUS_SERVERACK = 1, -	YPACKET_STATUS_GAME     = 0x2, -	YPACKET_STATUS_AWAY     = 0x4, -	YPACKET_STATUS_CONTINUED = 0x5, -	YPACKET_STATUS_INVISIBLE = 12, -	YPACKET_STATUS_NOTIFY = 0x16, /* TYPING */ -	YPACKET_STATUS_WEBLOGIN = 0x5a55aa55, -	YPACKET_STATUS_OFFLINE = 0x5a55aa56 -}; - -enum yahoo_error { -	E_UNKNOWN = -1, -	E_CONNECTION = -2, -	E_SYSTEM = -3, -	E_CUSTOM = 0, - -	/* responses from ignore buddy */ -	E_IGNOREDUP = 2, -	E_IGNORENONE = 3, -	E_IGNORECONF = 12, -	 -	/* conference */ -	E_CONFNOTAVAIL = 20 -}; - -enum yahoo_log_level { -	YAHOO_LOG_NONE = 0, -	YAHOO_LOG_FATAL, -	YAHOO_LOG_ERR, -	YAHOO_LOG_WARNING, -	YAHOO_LOG_NOTICE, -	YAHOO_LOG_INFO, -	YAHOO_LOG_DEBUG -}; +	enum yahoo_service {	/* these are easier to see in hex */ +		YAHOO_SERVICE_LOGON = 1, +		YAHOO_SERVICE_LOGOFF, +		YAHOO_SERVICE_ISAWAY, +		YAHOO_SERVICE_ISBACK, +		YAHOO_SERVICE_IDLE,	/* 5 (placemarker) */ +		YAHOO_SERVICE_MESSAGE, +		YAHOO_SERVICE_IDACT, +		YAHOO_SERVICE_IDDEACT, +		YAHOO_SERVICE_MAILSTAT, +		YAHOO_SERVICE_USERSTAT,	/* 0xa */ +		YAHOO_SERVICE_NEWMAIL, +		YAHOO_SERVICE_CHATINVITE, +		YAHOO_SERVICE_CALENDAR, +		YAHOO_SERVICE_NEWPERSONALMAIL, +		YAHOO_SERVICE_NEWCONTACT, +		YAHOO_SERVICE_ADDIDENT,	/* 0x10 */ +		YAHOO_SERVICE_ADDIGNORE, +		YAHOO_SERVICE_PING, +		YAHOO_SERVICE_GOTGROUPRENAME,	/* < 1, 36(old), 37(new) */ +		YAHOO_SERVICE_SYSMESSAGE = 0x14, +		YAHOO_SERVICE_SKINNAME = 0x15, +		YAHOO_SERVICE_PASSTHROUGH2 = 0x16, +		YAHOO_SERVICE_CONFINVITE = 0x18, +		YAHOO_SERVICE_CONFLOGON, +		YAHOO_SERVICE_CONFDECLINE, +		YAHOO_SERVICE_CONFLOGOFF, +		YAHOO_SERVICE_CONFADDINVITE, +		YAHOO_SERVICE_CONFMSG, +		YAHOO_SERVICE_CHATLOGON, +		YAHOO_SERVICE_CHATLOGOFF, +		YAHOO_SERVICE_CHATMSG = 0x20, +		YAHOO_SERVICE_GAMELOGON = 0x28, +		YAHOO_SERVICE_GAMELOGOFF, +		YAHOO_SERVICE_GAMEMSG = 0x2a, +		YAHOO_SERVICE_FILETRANSFER = 0x46, +		YAHOO_SERVICE_VOICECHAT = 0x4A, +		YAHOO_SERVICE_NOTIFY, +		YAHOO_SERVICE_VERIFY, +		YAHOO_SERVICE_P2PFILEXFER, +		YAHOO_SERVICE_PEERTOPEER = 0x4F,	/* Checks if P2P possible */ +		YAHOO_SERVICE_WEBCAM, +		YAHOO_SERVICE_AUTHRESP = 0x54, +		YAHOO_SERVICE_LIST, +		YAHOO_SERVICE_AUTH = 0x57, +		YAHOO_SERVICE_AUTHBUDDY = 0x6d, +		YAHOO_SERVICE_ADDBUDDY = 0x83, +		YAHOO_SERVICE_REMBUDDY, +		YAHOO_SERVICE_IGNORECONTACT,	/* > 1, 7, 13 < 1, 66, 13, 0 */ +		YAHOO_SERVICE_REJECTCONTACT, +		YAHOO_SERVICE_GROUPRENAME = 0x89,	/* > 1, 65(new), 66(0), 67(old) */ +		YAHOO_SERVICE_Y7_PING = 0x8A, +		YAHOO_SERVICE_CHATONLINE = 0x96,	/* > 109(id), 1, 6(abcde) < 0,1 */ +		YAHOO_SERVICE_CHATGOTO, +		YAHOO_SERVICE_CHATJOIN,	/* > 1 104-room 129-1600326591 62-2 */ +		YAHOO_SERVICE_CHATLEAVE, +		YAHOO_SERVICE_CHATEXIT = 0x9b, +		YAHOO_SERVICE_CHATADDINVITE = 0x9d, +		YAHOO_SERVICE_CHATLOGOUT = 0xa0, +		YAHOO_SERVICE_CHATPING, +		YAHOO_SERVICE_COMMENT = 0xa8, +		YAHOO_SERVICE_GAME_INVITE = 0xb7, +		YAHOO_SERVICE_STEALTH_PERM = 0xb9, +		YAHOO_SERVICE_STEALTH_SESSION = 0xba, +		YAHOO_SERVICE_AVATAR = 0xbc, +		YAHOO_SERVICE_PICTURE_CHECKSUM = 0xbd, +		YAHOO_SERVICE_PICTURE = 0xbe, +		YAHOO_SERVICE_PICTURE_UPDATE = 0xc1, +		YAHOO_SERVICE_PICTURE_UPLOAD = 0xc2, +		YAHOO_SERVICE_YAB_UPDATE = 0xc4, +		YAHOO_SERVICE_Y6_VISIBLE_TOGGLE = 0xc5,	/* YMSG13, key 13: 2 = invisible, 1 = visible */ +		YAHOO_SERVICE_Y6_STATUS_UPDATE = 0xc6,	/* YMSG13 */ +		YAHOO_SERVICE_PICTURE_STATUS = 0xc7,	/* YMSG13, key 213: 0 = none, 1 = avatar, 2 = picture */ +		YAHOO_SERVICE_VERIFY_ID_EXISTS = 0xc8, +		YAHOO_SERVICE_AUDIBLE = 0xd0, +		YAHOO_SERVICE_Y7_PHOTO_SHARING = 0xd2, +		YAHOO_SERVICE_Y7_CONTACT_DETAILS = 0xd3,	/* YMSG13 */ +		YAHOO_SERVICE_Y7_CHAT_SESSION = 0xd4, +		YAHOO_SERVICE_Y7_AUTHORIZATION = 0xd6,	/* YMSG13 */ +		YAHOO_SERVICE_Y7_FILETRANSFER = 0xdc,	/* YMSG13 */ +		YAHOO_SERVICE_Y7_FILETRANSFERINFO,	/* YMSG13 */ +		YAHOO_SERVICE_Y7_FILETRANSFERACCEPT,	/* YMSG13 */ +		YAHOO_SERVICE_Y7_MINGLE = 0xe1,	/* YMSG13 */ +		YAHOO_SERVICE_Y7_CHANGE_GROUP = 0xe7,	/* YMSG13 */ +		YAHOO_SERVICE_MYSTERY = 0xef,	/* Don't know what this is for */ +		YAHOO_SERVICE_Y8_STATUS = 0xf0,	/* YMSG15 */ +		YAHOO_SERVICE_Y8_LIST = 0Xf1,	/* YMSG15 */ +		YAHOO_SERVICE_MESSAGE_CONFIRM = 0xfb, +		YAHOO_SERVICE_WEBLOGIN = 0x0226, +		YAHOO_SERVICE_SMS_MSG = 0x02ea +	}; + +	enum yahoo_status { +		YAHOO_STATUS_AVAILABLE = 0, +		YAHOO_STATUS_BRB, +		YAHOO_STATUS_BUSY, +		YAHOO_STATUS_NOTATHOME, +		YAHOO_STATUS_NOTATDESK, +		YAHOO_STATUS_NOTINOFFICE, +		YAHOO_STATUS_ONPHONE, +		YAHOO_STATUS_ONVACATION, +		YAHOO_STATUS_OUTTOLUNCH, +		YAHOO_STATUS_STEPPEDOUT, +		YAHOO_STATUS_INVISIBLE = 12, +		YAHOO_STATUS_CUSTOM = 99, +		YAHOO_STATUS_IDLE = 999, +		YAHOO_STATUS_OFFLINE = 0x5a55aa56	/* don't ask */ +	}; + +	enum ypacket_status { +		YPACKET_STATUS_DISCONNECTED = -1, +		YPACKET_STATUS_DEFAULT = 0, +		YPACKET_STATUS_SERVERACK = 1, +		YPACKET_STATUS_GAME = 0x2, +		YPACKET_STATUS_AWAY = 0x4, +		YPACKET_STATUS_CONTINUED = 0x5, +		YPACKET_STATUS_INVISIBLE = 12, +		YPACKET_STATUS_NOTIFY = 0x16,	/* TYPING */ +		YPACKET_STATUS_WEBLOGIN = 0x5a55aa55, +		YPACKET_STATUS_OFFLINE = 0x5a55aa56 +	}; + +#define YAHOO_STATUS_GAME	0x2	/* Games don't fit into the regular status model */ + +	enum yahoo_login_status { +		YAHOO_LOGIN_OK = 0, +		YAHOO_LOGIN_LOGOFF = 1, +		YAHOO_LOGIN_UNAME = 3, +		YAHOO_LOGIN_PASSWD = 13, +		YAHOO_LOGIN_LOCK = 14, +		YAHOO_LOGIN_DUPL = 99, +		YAHOO_LOGIN_SOCK = -1, +		YAHOO_LOGIN_UNKNOWN = 999 +	}; + +	enum yahoo_error { +		E_UNKNOWN = -1, +		E_CONNECTION = -2, +		E_SYSTEM = -3, +		E_CUSTOM = 0, + +		/* responses from ignore buddy */ +		E_IGNOREDUP = 2, +		E_IGNORENONE = 3, +		E_IGNORECONF = 12, + +		/* conference */ +		E_CONFNOTAVAIL = 20 +	}; + +	enum yahoo_log_level { +		YAHOO_LOG_NONE = 0, +		YAHOO_LOG_FATAL, +		YAHOO_LOG_ERR, +		YAHOO_LOG_WARNING, +		YAHOO_LOG_NOTICE, +		YAHOO_LOG_INFO, +		YAHOO_LOG_DEBUG +	}; + +	enum yahoo_file_transfer { +		YAHOO_FILE_TRANSFER_INIT = 1, +		YAHOO_FILE_TRANSFER_ACCEPT = 3, +		YAHOO_FILE_TRANSFER_REJECT = 4, +		YAHOO_FILE_TRANSFER_DONE = 5, +		YAHOO_FILE_TRANSFER_RELAY, +		YAHOO_FILE_TRANSFER_FAILED, +		YAHOO_FILE_TRANSFER_UNKNOWN +	};  #define YAHOO_PROTO_VER 0x0010 @@ -120,172 +221,176 @@ enum yahoo_log_level {  #define YAHOO_STYLE_URLON "\033[lm"  #define YAHOO_STYLE_URLOFF "\033[xlm" -enum yahoo_connection_type { -	YAHOO_CONNECTION_PAGER=0, -	YAHOO_CONNECTION_FT, -	YAHOO_CONNECTION_YAB, -	YAHOO_CONNECTION_WEBCAM_MASTER, -	YAHOO_CONNECTION_WEBCAM, -	YAHOO_CONNECTION_CHATCAT, -	YAHOO_CONNECTION_SEARCH, -	YAHOO_CONNECTION_AUTH, -}; - -enum yahoo_webcam_direction_type { -        YAHOO_WEBCAM_DOWNLOAD=0, -        YAHOO_WEBCAM_UPLOAD -}; - -enum yahoo_stealth_visibility_type { -	YAHOO_STEALTH_DEFAULT = 0, -  	YAHOO_STEALTH_ONLINE, -  	YAHOO_STEALTH_PERM_OFFLINE -}; +	enum yahoo_connection_type { +		YAHOO_CONNECTION_PAGER = 0, +		YAHOO_CONNECTION_FT, +		YAHOO_CONNECTION_YAB, +		YAHOO_CONNECTION_WEBCAM_MASTER, +		YAHOO_CONNECTION_WEBCAM, +		YAHOO_CONNECTION_CHATCAT, +		YAHOO_CONNECTION_SEARCH, +		YAHOO_CONNECTION_AUTH +	}; + +	enum yahoo_webcam_direction_type { +		YAHOO_WEBCAM_DOWNLOAD = 0, +		YAHOO_WEBCAM_UPLOAD +	}; + +	enum yahoo_stealth_visibility_type { +		YAHOO_STEALTH_DEFAULT = 0, +		YAHOO_STEALTH_ONLINE, +		YAHOO_STEALTH_PERM_OFFLINE +	};  /* chat member attribs */  #define YAHOO_CHAT_MALE 0x8000  #define YAHOO_CHAT_FEMALE 0x10000 +#define YAHOO_CHAT_FEMALE 0x10000  #define YAHOO_CHAT_DUNNO 0x400  #define YAHOO_CHAT_WEBCAM 0x10 -enum yahoo_webcam_conn_type { Y_WCM_DIALUP, Y_WCM_DSL, Y_WCM_T1 }; - -struct yahoo_webcam { -	int direction;     /* Uploading or downloading */ -	int conn_type;     /* 0=Dialup, 1=DSL/Cable, 2=T1/Lan */ - -	char *user;        /* user we are viewing */ -	char *server;      /* webcam server to connect to */ -	int   port;        /* webcam port to connect on */ -	char *key;         /* key to connect to the server with */ -	char *description; /* webcam description */ -	char *my_ip;       /* own ip number */ -}; - -struct yahoo_webcam_data { -	unsigned int data_size; -	unsigned int to_read; -	unsigned int timestamp; -	unsigned char packet_type; -}; - -struct yahoo_data { -	char  *user; -	char  *password; - -	char  *cookie_y; -	char  *cookie_t; -	char  *cookie_c; -	char  *login_cookie; - -	YList *buddies; -	YList *ignore; -	YList *identities; -	char  *login_id; - -	int   current_status; -	int   initial_status; -	int   logged_in; - -	int   session_id; - -	int   client_id; - -	char  *rawbuddylist; -	char  *ignorelist; - -	void  *server_settings; -	 -	struct yahoo_process_status_entry *half_user; -}; - -struct yab { -	int yid; -	char *id; -	char *fname; -	char *lname; -	char *nname; -	char *email; -	char *hphone; -	char *wphone; -	char *mphone; -	int  dbid; -}; - -struct yahoo_buddy { -	char *group; -	char *id; -	char *real_name; -	struct yab *yab_entry; -}; - -enum yahoo_search_type { -	YAHOO_SEARCH_KEYWORD = 0, -	YAHOO_SEARCH_YID, -	YAHOO_SEARCH_NAME -}; - -enum yahoo_search_gender { -	YAHOO_GENDER_NONE = 0, -	YAHOO_GENDER_MALE, -	YAHOO_GENDER_FEMALE -}; - -enum yahoo_search_agerange { -	YAHOO_AGERANGE_NONE = 0 -}; - -struct yahoo_found_contact { -	char *id; -	char *gender; -	char *location; -	int age; -	int online; -}; +	enum yahoo_webcam_conn_type { Y_WCM_DIALUP, Y_WCM_DSL, Y_WCM_T1 }; + +	struct yahoo_webcam { +		int direction;	/* Uploading or downloading */ +		int conn_type;	/* 0=Dialup, 1=DSL/Cable, 2=T1/Lan */ + +		char *user;	/* user we are viewing */ +		char *server;	/* webcam server to connect to */ +		int port;	/* webcam port to connect on */ +		char *key;	/* key to connect to the server with */ +		char *description;	/* webcam description */ +		char *my_ip;	/* own ip number */ +	}; + +	struct yahoo_webcam_data { +		unsigned int data_size; +		unsigned int to_read; +		unsigned int timestamp; +		unsigned char packet_type; +	}; + +	struct yahoo_data { +		char *user; +		char *password; + +		char *cookie_y; +		char *cookie_t; +		char *cookie_c; +		char *cookie_b; +		char *login_cookie; +		char *crumb; +		char *seed; + +		YList *buddies; +		YList *ignore; +		YList *identities; +		char *login_id; + +		int current_status; +		int initial_status; +		int logged_in; + +		int session_id; + +		int client_id; + +		char *rawbuddylist; +		char *ignorelist; + +		void *server_settings; + +		struct yahoo_process_status_entry *half_user; +	}; + +	struct yab { +		int yid; +		char *id; +		char *fname; +		char *lname; +		char *nname; +		char *email; +		char *hphone; +		char *wphone; +		char *mphone; +		int dbid; +	}; + +	struct yahoo_buddy { +		char *group; +		char *id; +		char *real_name; +		struct yab *yab_entry; +	}; + +	enum yahoo_search_type { +		YAHOO_SEARCH_KEYWORD = 0, +		YAHOO_SEARCH_YID, +		YAHOO_SEARCH_NAME +	}; + +	enum yahoo_search_gender { +		YAHOO_GENDER_NONE = 0, +		YAHOO_GENDER_MALE, +		YAHOO_GENDER_FEMALE +	}; + +	enum yahoo_search_agerange { +		YAHOO_AGERANGE_NONE = 0 +	}; + +	struct yahoo_found_contact { +		char *id; +		char *gender; +		char *location; +		int age; +		int online; +	};  /*   * Function pointer to be passed to http get/post and send file   */ -typedef void (*yahoo_get_fd_callback)(int id, int fd, int error, void *data); +	typedef void (*yahoo_get_fd_callback) (int id, void *fd, int error, +		void *data);  /*   * Function pointer to be passed to yahoo_get_url_handle   */ -typedef void (*yahoo_get_url_handle_callback)(int id, int fd, int error, -		const char *filename, unsigned long size, void *data); - - -struct yahoo_chat_member { -	char *id; -	int  age; -	int  attribs; -	char *alias; -	char *location; -}; - -struct yahoo_process_status_entry { -	char *name;	/* 7      name */ -	int state;	/* 10     state */ -	int flags;	/* 13     flags, bit 0 = pager, bit 1 = chat, bit 2 = game */ -	int mobile;	/* 60     mobile */ -	char *msg;	/* 19     custom status message */ -	int away;	/* 47     away (or invisible) */ -	int buddy_session; /* 11  state */ -	int f17;	/* 17     in chat? then what about flags? */ -	int idle;	/* 137    seconds idle */ -	int f138;	/* 138    state */ -	char *f184;	/* 184    state */ -	int f192;	/* 192    state */ -	int f10001;	/* 10001  state */ -	int f10002;	/* 10002  state */ -	int f198;	/* 198    state */ -	char *f197;	/* 197    state */ -	char *f205;	/* 205    state */ -	int f213;	/* 213    state */ -}; +	typedef void (*yahoo_get_url_handle_callback) (int id, void *fd, +		int error, const char *filename, unsigned long size, +		void *data); + +	struct yahoo_chat_member { +		char *id; +		int age; +		int attribs; +		char *alias; +		char *location; +	}; + +	struct yahoo_process_status_entry {  +		char *name;     /* 7      name */  +		int state;      /* 10     state */  +		int flags;      /* 13     flags, bit 0 = pager, bit 1 = chat, bit 2 = game */  +		int mobile;     /* 60     mobile */  +		char *msg;      /* 19     custom status message */  +		int away;       /* 47     away (or invisible) */  +		int buddy_session; /* 11  state */  +		int f17;        /* 17     in chat? then what about flags? */  +		int idle;       /* 137    seconds idle */  +		int f138;       /* 138    state */  +		char *f184;     /* 184    state */  +		int f192;       /* 192    state */  +		int f10001;     /* 10001  state */  +		int f10002;     /* 10002  state */  +		int f198;       /* 198    state */  +		char *f197;     /* 197    state */  +		char *f205;     /* 205    state */  +		int f213;       /* 213    state */  +	};  #ifdef __cplusplus  }  #endif -  #endif diff --git a/protocols/yahoo/yahoo_httplib.c b/protocols/yahoo/yahoo_httplib.c index 1b084992..6bb8923d 100644 --- a/protocols/yahoo/yahoo_httplib.c +++ b/protocols/yahoo/yahoo_httplib.c @@ -29,14 +29,13 @@  #  define strchr index  #  define strrchr rindex  # endif -char *strchr (), *strrchr (); +char *strchr(), *strrchr();  # if !HAVE_MEMCPY  #  define memcpy(d, s, n) bcopy ((s), (d), (n))  #  define memmove(d, s, n) bcopy ((s), (d), (n))  # endif  #endif -  #include <errno.h>  #ifndef _WIN32  #include <unistd.h> @@ -62,7 +61,7 @@ extern struct yahoo_callbacks *yc;  extern enum yahoo_log_level log_level; -int yahoo_tcp_readline(char *ptr, int maxlen, int fd) +int yahoo_tcp_readline(char *ptr, int maxlen, void *fd)  {  	int n, rc;  	char c; @@ -70,11 +69,11 @@ int yahoo_tcp_readline(char *ptr, int maxlen, int fd)  	for (n = 1; n < maxlen; n++) {  		do { -			rc = read(fd, &c, 1); -		} while(rc == -1 && (errno == EINTR || errno == EAGAIN)); /* this is bad - it should be done asynchronously */ +			rc = YAHOO_CALLBACK(ext_yahoo_read) (fd, &c, 1); +		} while (rc == -1 && (errno == EINTR || errno == EAGAIN));	/* this is bad - it should be done asynchronously */  		if (rc == 1) { -			if(c == '\r')			/* get rid of \r */ +			if (c == '\r')	/* get rid of \r */  				continue;  			*ptr = c;  			if (c == '\n') @@ -82,9 +81,9 @@ int yahoo_tcp_readline(char *ptr, int maxlen, int fd)  			ptr++;  		} else if (rc == 0) {  			if (n == 1) -				return (0);		/* EOF, no data */ +				return (0);	/* EOF, no data */  			else -				break;			/* EOF, w/ data */ +				break;	/* EOF, w/ data */  		} else {  			return -1;  		} @@ -95,12 +94,12 @@ int yahoo_tcp_readline(char *ptr, int maxlen, int fd)  }  static int url_to_host_port_path(const char *url, -		char *host, int *port, char *path) +	char *host, int *port, char *path, int *ssl)  { -	char *urlcopy=NULL; -	char *slash=NULL; -	char *colon=NULL; -	 +	char *urlcopy = NULL; +	char *slash = NULL; +	char *colon = NULL; +  	/*  	 * http://hostname  	 * http://hostname/ @@ -110,10 +109,14 @@ static int url_to_host_port_path(const char *url,  	 * http://hostname:port/  	 * http://hostname:port/path  	 * http://hostname:port/path:foo +	 * and https:// variants of the above  	 */ -	if(strstr(url, "http://") == url) { -		urlcopy = strdup(url+7); +	if (strstr(url, "http://") == url) { +		urlcopy = strdup(url + 7); +	} else if (strstr(url, "https://") == url) { +		urlcopy = strdup(url + 8); +		*ssl = 1;  	} else {  		WARNING(("Weird url - unknown protocol: %s", url));  		return 0; @@ -122,14 +125,17 @@ static int url_to_host_port_path(const char *url,  	slash = strchr(urlcopy, '/');  	colon = strchr(urlcopy, ':'); -	if(!colon || (slash && slash < colon)) { -		*port = 80; +	if (!colon || (slash && slash < colon)) { +		if (*ssl) +			*port = 443; +		else +			*port = 80;  	} else {  		*colon = 0; -		*port = atoi(colon+1); +		*port = atoi(colon + 1);  	} -	if(!slash) { +	if (!slash) {  		strcpy(path, "/");  	} else {  		strcpy(path, slash); @@ -137,7 +143,7 @@ static int url_to_host_port_path(const char *url,  	}  	strcpy(host, urlcopy); -	 +  	FREE(urlcopy);  	return 1; @@ -145,135 +151,135 @@ static int url_to_host_port_path(const char *url,  static int isurlchar(unsigned char c)  { -	return (isalnum(c) || '-' == c || '_' == c); +	return (isalnum(c));  }  char *yahoo_urlencode(const char *instr)  { -	int ipos=0, bpos=0; +	int ipos = 0, bpos = 0;  	char *str = NULL;  	int len = strlen(instr); -	if(!(str = y_new(char, 3*len + 1) )) -		return ""; +	if (!(str = y_new(char, 3 *len + 1))) +		 return ""; -	while(instr[ipos]) { -		while(isurlchar(instr[ipos])) +	while (instr[ipos]) { +		while (isurlchar(instr[ipos]))  			str[bpos++] = instr[ipos++]; -		if(!instr[ipos]) +		if (!instr[ipos])  			break; -		 -		snprintf(&str[bpos], 4, "%%%.2x", instr[ipos]); -		bpos+=3; + +		snprintf(&str[bpos], 4, "%%%02x", instr[ipos] & 0xff); +		bpos += 3;  		ipos++;  	} -	str[bpos]='\0'; +	str[bpos] = '\0';  	/* free extra alloc'ed mem. */  	len = strlen(str); -	str = y_renew(char, str, len+1); +	str = y_renew(char, str, len + 1);  	return (str);  }  char *yahoo_urldecode(const char *instr)  { -	int ipos=0, bpos=0; +	int ipos = 0, bpos = 0;  	char *str = NULL; -	char entity[3]={0,0,0}; +	char entity[3] = { 0, 0, 0 };  	unsigned dec;  	int len = strlen(instr); -	if(!(str = y_new(char, len+1) )) -		return ""; +	if (!(str = y_new(char, len + 1))) +		 return ""; -	while(instr[ipos]) { -		while(instr[ipos] && instr[ipos]!='%') -			if(instr[ipos]=='+') { -				str[bpos++]=' '; +	while (instr[ipos]) { +		while (instr[ipos] && instr[ipos] != '%') +			if (instr[ipos] == '+') { +				str[bpos++] = ' ';  				ipos++;  			} else  				str[bpos++] = instr[ipos++]; -		if(!instr[ipos]) +		if (!instr[ipos])  			break; -		 -		if(instr[ipos+1] && instr[ipos+2]) { + +		if (instr[ipos + 1] && instr[ipos + 2]) {  			ipos++; -			entity[0]=instr[ipos++]; -			entity[1]=instr[ipos++]; +			entity[0] = instr[ipos++]; +			entity[1] = instr[ipos++];  			sscanf(entity, "%2x", &dec);  			str[bpos++] = (char)dec;  		} else {  			str[bpos++] = instr[ipos++];  		}  	} -	str[bpos]='\0'; +	str[bpos] = '\0';  	/* free extra alloc'ed mem. */  	len = strlen(str); -	str = y_renew(char, str, len+1); +	str = y_renew(char, str, len + 1);  	return (str);  }  char *yahoo_xmldecode(const char *instr)  { -	int ipos=0, bpos=0, epos=0; +	int ipos = 0, bpos = 0, epos = 0;  	char *str = NULL; -	char entity[4]={0,0,0,0}; -	char *entitymap[5][2]={ -		{"amp;",  "&"},  +	char entity[4] = { 0, 0, 0, 0 }; +	char *entitymap[5][2] = { +		{"amp;", "&"},  		{"quot;", "\""}, -		{"lt;",   "<"},  -		{"gt;",   "<"},  +		{"lt;", "<"}, +		{"gt;", "<"},  		{"nbsp;", " "}  	};  	unsigned dec;  	int len = strlen(instr); -	if(!(str = y_new(char, len+1) )) -		return ""; +	if (!(str = y_new(char, len + 1))) +		 return ""; -	while(instr[ipos]) { -		while(instr[ipos] && instr[ipos]!='&') -			if(instr[ipos]=='+') { -				str[bpos++]=' '; +	while (instr[ipos]) { +		while (instr[ipos] && instr[ipos] != '&') +			if (instr[ipos] == '+') { +				str[bpos++] = ' ';  				ipos++;  			} else  				str[bpos++] = instr[ipos++]; -		if(!instr[ipos] || !instr[ipos+1]) +		if (!instr[ipos] || !instr[ipos + 1])  			break;  		ipos++; -		if(instr[ipos] == '#') { +		if (instr[ipos] == '#') {  			ipos++; -			epos=0; -			while(instr[ipos] != ';') -				entity[epos++]=instr[ipos++]; +			epos = 0; +			while (instr[ipos] != ';') +				entity[epos++] = instr[ipos++];  			sscanf(entity, "%u", &dec);  			str[bpos++] = (char)dec;  			ipos++;  		} else {  			int i; -			for (i=0; i<5; i++)  -				if(!strncmp(instr+ipos, entitymap[i][0],  -					       strlen(entitymap[i][0]))) { -				       	str[bpos++] = entitymap[i][1][0]; +			for (i = 0; i < 5; i++) +				if (!strncmp(instr + ipos, entitymap[i][0], +						strlen(entitymap[i][0]))) { +					str[bpos++] = entitymap[i][1][0];  					ipos += strlen(entitymap[i][0]);  					break;  				}  		}  	} -	str[bpos]='\0'; +	str[bpos] = '\0';  	/* free extra alloc'ed mem. */  	len = strlen(str); -	str = y_renew(char, str, len+1); +	str = y_renew(char, str, len + 1);  	return (str);  } -typedef void (*http_connected)(int id, int fd, int error); +typedef void (*http_connected) (int id, void *fd, int error);  struct callback_data {  	int id; @@ -282,150 +288,117 @@ struct callback_data {  	void *user_data;  }; -static void connect_complete(int fd, int error, void *data) +static void connect_complete(void *fd, int error, void *data)  {  	struct callback_data *ccd = data; -	if(error == 0 && fd > 0) -		write(fd, ccd->request, strlen(ccd->request)); -	FREE(ccd->request); +	if (error == 0) +		YAHOO_CALLBACK(ext_yahoo_write) (fd, ccd->request, +			strlen(ccd->request)); +	free(ccd->request);  	ccd->callback(ccd->id, fd, error, ccd->user_data);  	FREE(ccd);  } -static void yahoo_send_http_request(int id, char *host, int port, char *request,  -		yahoo_get_fd_callback callback, void *data) +static void yahoo_send_http_request(int id, char *host, int port, char *request, +	yahoo_get_fd_callback callback, void *data, int use_ssl)  { -	struct callback_data *ccd=y_new0(struct callback_data, 1); +	struct callback_data *ccd = y_new0(struct callback_data, 1);  	ccd->callback = callback;  	ccd->id = id;  	ccd->request = strdup(request);  	ccd->user_data = data; -	 -	YAHOO_CALLBACK(ext_yahoo_connect_async)(id, host, port, connect_complete, ccd); + +	YAHOO_CALLBACK(ext_yahoo_connect_async) (id, host, port, +		connect_complete, ccd, use_ssl);  } -void yahoo_http_post(int id, const char *url, const char *cookies, long content_length, -		yahoo_get_fd_callback callback, void *data) +void yahoo_http_post(int id, const char *url, const char *cookies, +	long content_length, yahoo_get_fd_callback callback, void *data)  {  	char host[255];  	int port = 80;  	char path[255];  	char buff[1024]; -	 -	if(!url_to_host_port_path(url, host, &port, path)) -		return; +	int ssl = 0; -	snprintf(buff, sizeof(buff),  -			"POST %s HTTP/1.0\r\n" -			"Content-length: %ld\r\n" -			"User-Agent: Mozilla/4.5 [en] (" PACKAGE "/" VERSION ")\r\n" -			"Host: %s:%d\r\n" -			"Cookie: %s\r\n" -			"\r\n", -			path, content_length,  -			host, port, -			cookies); +	if (!url_to_host_port_path(url, host, &port, path, &ssl)) +		return; -	yahoo_send_http_request(id, host, port, buff, callback, data); +	/* thanks to kopete dumpcap */ +	snprintf(buff, sizeof(buff), +		"POST %s HTTP/1.1\r\n" +		"Cookie: %s\r\n" +		"User-Agent: Mozilla/5.0\r\n" +		"Host: %s\r\n" +		"Content-Length: %ld\r\n" +		"Cache-Control: no-cache\r\n" +		"\r\n", path, cookies, host, content_length); + +	yahoo_send_http_request(id, host, port, buff, callback, data, ssl);  } -void yahoo_http_get(int id, const char *url, const char *cookies, -		yahoo_get_fd_callback callback, void *data) +void yahoo_http_get(int id, const char *url, const char *cookies, int http11, +	int keepalive, yahoo_get_fd_callback callback, void *data)  {  	char host[255];  	int port = 80;  	char path[255]; -	char buff[1024]; -	 -	if(!url_to_host_port_path(url, host, &port, path)) -		return; +	char buff[2048]; +	char cookiebuff[1024]; +	int ssl = 0; -	snprintf(buff, sizeof(buff),  -			"GET %s HTTP/1.0\r\n" -			"Host: %s:%d\r\n" -			"User-Agent: Mozilla/4.5 [en] (" PACKAGE "/" VERSION ")\r\n" -			"Cookie: %s\r\n" -			"\r\n", -			path, host, port, cookies); +	if (!url_to_host_port_path(url, host, &port, path, &ssl)) +		return; -	yahoo_send_http_request(id, host, port, buff, callback, data); +	/* Allow cases when we don't need to send a cookie */ +	if (cookies) +		snprintf(cookiebuff, sizeof(cookiebuff), "Cookie: %s\r\n", +			cookies); +	else +		cookiebuff[0] = '\0'; + +	snprintf(buff, sizeof(buff), +		"GET %s HTTP/1.%s\r\n" +		"%sHost: %s\r\n" +		"User-Agent: Mozilla/4.5 [en] (" PACKAGE "/" VERSION ")\r\n" +		"Accept: */*\r\n" +		"%s" "\r\n", path, http11?"1":"0", cookiebuff, host, +		keepalive? "Connection: Keep-Alive\r\n":"Connection: close\r\n"); + +	yahoo_send_http_request(id, host, port, buff, callback, data, ssl);  } -struct url_data { -	yahoo_get_url_handle_callback callback; -	void *user_data; -}; - -static void yahoo_got_url_fd(int id, int fd, int error, void *data) +void yahoo_http_head(int id, const char *url, const char *cookies, int len, +	char *payload, yahoo_get_fd_callback callback, void *data)  { -	char *tmp=NULL; -	char buff[1024]; -	unsigned long filesize=0; -	char *filename=NULL; -	int n; - -	struct url_data *ud = data; +	char host[255]; +	int port = 80; +	char path[255]; +	char buff[2048]; +	char cookiebuff[1024]; +	int ssl = 0; -	if(error || fd < 0) { -		ud->callback(id, fd, error, filename, filesize, ud->user_data); -		FREE(ud); +	if (!url_to_host_port_path(url, host, &port, path, &ssl))  		return; -	} - -	while((n=yahoo_tcp_readline(buff, sizeof(buff), fd)) > 0) { -		LOG(("Read:%s:\n", buff)); -		if(!strcmp(buff, "")) -			break; - -		if( !strncasecmp(buff, "Content-length:",  -				strlen("Content-length:")) ) { -			tmp = strrchr(buff, ' '); -			if(tmp) -				filesize = atol(tmp); -		} - -		if( !strncasecmp(buff, "Content-disposition:",  -				strlen("Content-disposition:")) ) { -			tmp = strstr(buff, "name="); -			if(tmp) { -				tmp+=strlen("name="); -				if(tmp[0] == '"') { -					char *tmp2; -					tmp++; -					tmp2 = strchr(tmp, '"'); -					if(tmp2) -						*tmp2 = '\0'; -				} else { -					char *tmp2; -					tmp2 = strchr(tmp, ';'); -					if(!tmp2) -						tmp2 = strchr(tmp, '\r'); -					if(!tmp2) -						tmp2 = strchr(tmp, '\n'); -					if(tmp2) -						*tmp2 = '\0'; -				} -				filename = strdup(tmp); -			} -		} -	} - -	LOG(("n == %d\n", n)); -	LOG(("Calling callback, filename:%s, size: %ld\n", filename, filesize)); -	ud->callback(id, fd, error, filename, filesize, ud->user_data); -	FREE(ud); -	FREE(filename); -} - -void yahoo_get_url_fd(int id, const char *url, const struct yahoo_data *yd, -		yahoo_get_url_handle_callback callback, void *data) -{ -	char buff[1024]; -	struct url_data *ud = y_new0(struct url_data, 1); -	snprintf(buff, sizeof(buff), "Y=%s; T=%s", yd->cookie_y, yd->cookie_t); -	ud->callback = callback; -	ud->user_data = data; -	yahoo_http_get(id, url, buff, yahoo_got_url_fd, ud); +	/* Allow cases when we don't need to send a cookie */ +	if (cookies) +		snprintf(cookiebuff, sizeof(cookiebuff), "Cookie: %s\r\n", +			cookies); +	else +		cookiebuff[0] = '\0'; + +	snprintf(buff, sizeof(buff), +		"HEAD %s HTTP/1.0\r\n" +		"Accept: */*\r\n" +		"Host: %s:%d\r\n" +		"User-Agent: Mozilla/4.5 [en] (" PACKAGE "/" VERSION ")\r\n" +		"%s" +		"Content-Length: %d\r\n" +		"Cache-Control: no-cache\r\n" +		"\r\n%s", path, host, port, cookiebuff, len, +		payload?payload:""); + +	yahoo_send_http_request(id, host, port, buff, callback, data, ssl);  } diff --git a/protocols/yahoo/yahoo_httplib.h b/protocols/yahoo/yahoo_httplib.h index fd28ad48..ab699b20 100644 --- a/protocols/yahoo/yahoo_httplib.h +++ b/protocols/yahoo/yahoo_httplib.h @@ -28,21 +28,21 @@ extern "C" {  #include "yahoo2_types.h" -char *yahoo_urlencode(const char *instr); -char *yahoo_urldecode(const char *instr); -char *yahoo_xmldecode(const char *instr); - -int yahoo_tcp_readline(char *ptr, int maxlen, int fd); -void yahoo_http_post(int id, const char *url, const char *cookies, long size, -		yahoo_get_fd_callback callback, void *data); -void yahoo_http_get(int id, const char *url, const char *cookies, -		yahoo_get_fd_callback callback, void *data); -void yahoo_get_url_fd(int id, const char *url, const struct yahoo_data *yd, -		yahoo_get_url_handle_callback callback, void *data); - +	char *yahoo_urlencode(const char *instr); +	char *yahoo_urldecode(const char *instr); +	char *yahoo_xmldecode(const char *instr); + +	int yahoo_tcp_readline(char *ptr, int maxlen, void *fd); +	void yahoo_http_post(int id, const char *url, const char *cookies, +		long size, yahoo_get_fd_callback callback, void *data); +	void yahoo_http_get(int id, const char *url, const char *cookies, +		int http11, int keepalive, yahoo_get_fd_callback callback, +		void *data); +	void yahoo_http_head(int id, const char *url, const char *cookies, +		int size, char *payload, yahoo_get_fd_callback callback, +		void *data);  #ifdef __cplusplus  }  #endif -  #endif diff --git a/protocols/yahoo/yahoo_list.h b/protocols/yahoo/yahoo_list.h index 0d335acd..c2e5ad18 100644 --- a/protocols/yahoo/yahoo_list.h +++ b/protocols/yahoo/yahoo_list.h @@ -23,7 +23,7 @@  #ifndef __YLIST_H__  #define __YLIST_H__ -/* GLib has linked list already, so I don't see why libyahoo2 has to copy this... */ +/* BitlBee already uses GLib so use it. */  typedef GList YList; | 
