avatar.c
changeset 6 a0231d43ae53
parent 3 c920fcf835c7
child 9 a838a4ecf834
equal deleted inserted replaced
5:f7a9dc93bc73 6:a0231d43ae53
    48 #define NS_AVATAR_METADATA        ( "urn:xmpp:avatar:metadata"        )
    48 #define NS_AVATAR_METADATA        ( "urn:xmpp:avatar:metadata"        )
    49 #define NS_AVATAR_METADATA_NOTIFY ( "urn:xmpp:avatar:metadata+notify" )
    49 #define NS_AVATAR_METADATA_NOTIFY ( "urn:xmpp:avatar:metadata+notify" )
    50 
    50 
    51 static guint avatar_cid = 0;
    51 static guint avatar_cid = 0;
    52 
    52 
    53 GSList *reply_handlers = NULL;
    53 static GSList *reply_handlers = NULL;
       
    54 
       
    55 static LmMessageHandler *avatar_metadata_reply_handler = NULL;
       
    56 
       
    57 // predeclarations
       
    58 
       
    59 static LmHandlerResult avatar_retrieve_data_reply_handler (LmMessageHandler *handler, LmConnection *connection, LmMessage *message, gpointer userdata);
    54 
    60 
    55 // png stuff
    61 // png stuff
    56 
    62 
    57 static png_voidp png_glib_malloc (png_structp ignore, png_size_t size)
    63 static png_voidp png_glib_malloc (png_structp ignore, png_size_t size)
    58 {
    64 {
   461 		scr_LogPrint (LPRINT_LOGNORM, "avatar: Cannot symlink jid-file to avatar: %s.", strerror (errno));
   467 		scr_LogPrint (LPRINT_LOGNORM, "avatar: Cannot symlink jid-file to avatar: %s.", strerror (errno));
   462 }
   468 }
   463 
   469 
   464 // reply handler for metadata publish request
   470 // reply handler for metadata publish request
   465 // just prints error message if unsuccessful
   471 // just prints error message if unsuccessful
   466 LmHandlerResult avatar_publish_metadata_reply_handler (LmMessageHandler *handler, LmConnection *connection, LmMessage *message, gpointer userdata)
   472 static LmHandlerResult avatar_publish_metadata_reply_handler (LmMessageHandler *handler, LmConnection *connection, LmMessage *message, gpointer userdata)
   467 {
   473 {
   468 	reply_handlers = g_slist_remove (reply_handlers, handler);
       
   469 
       
   470 	switch (lm_message_get_sub_type (message)) {
   474 	switch (lm_message_get_sub_type (message)) {
   471 	case LM_MESSAGE_SUB_TYPE_RESULT:
   475 	case LM_MESSAGE_SUB_TYPE_RESULT:
   472 		break;
   476 		break;
   473 
   477 
   474 	case LM_MESSAGE_SUB_TYPE_ERROR:
   478 	case LM_MESSAGE_SUB_TYPE_ERROR:
   498 	return LM_HANDLER_RESULT_REMOVE_MESSAGE;
   502 	return LM_HANDLER_RESULT_REMOVE_MESSAGE;
   499 }
   503 }
   500 
   504 
   501 // reply handler for data publish request
   505 // reply handler for data publish request
   502 // sends metadata update request or prints error message
   506 // sends metadata update request or prints error message
   503 LmHandlerResult avatar_publish_data_reply_handler (LmMessageHandler *handler, LmConnection *connection, LmMessage *message, gpointer userdata)
   507 static LmHandlerResult avatar_publish_data_reply_handler (LmMessageHandler *handler, LmConnection *connection, LmMessage *message, gpointer userdata)
   504 {
   508 {
   505 	LmMessage *request = (LmMessage *) userdata;
   509 	LmMessage *request = (LmMessage *) userdata;
   506 
   510 
   507 	reply_handlers = g_slist_remove (reply_handlers, handler);
   511 	reply_handlers = g_slist_remove (reply_handlers, handler);
   508 	
   512 	
   509 	switch (lm_message_get_sub_type (message)) {
   513 	switch (lm_message_get_sub_type (message)) {
   510 	case LM_MESSAGE_SUB_TYPE_RESULT:
   514 	case LM_MESSAGE_SUB_TYPE_RESULT:
   511 
   515 
   512 		{
   516 		lm_connection_send_with_reply (connection, request, avatar_metadata_reply_handler, NULL);
   513 			// XXX we may use only one instance of this...
   517 		lm_message_unref (request);
   514 			LmMessageHandler *mhandler = lm_message_handler_new (avatar_publish_metadata_reply_handler, NULL, NULL);
       
   515 
       
   516 			reply_handlers = g_slist_append (reply_handlers, mhandler);
       
   517 
       
   518 			lm_connection_send_with_reply (connection, request, mhandler, NULL);
       
   519 
       
   520 			lm_message_handler_unref (mhandler);
       
   521 			lm_message_unref (request);
       
   522 		}
       
   523 
   518 
   524 		break;
   519 		break;
   525 
   520 
   526 	case LM_MESSAGE_SUB_TYPE_ERROR:
   521 	case LM_MESSAGE_SUB_TYPE_ERROR:
   527 
   522 
   564 
   559 
   565 	{ // check if file exists to not trigger unnecessary error messages
   560 	{ // check if file exists to not trigger unnecessary error messages
   566 		struct stat buf;
   561 		struct stat buf;
   567 
   562 
   568 		if (stat (file, &buf) == -1) {
   563 		if (stat (file, &buf) == -1) {
   569 			gchar *bjid = jidtodisp (jid);
   564 			gchar            *bjid = jidtodisp (jid);
   570 
   565 			LmMessage        *request;
   571 			scr_WriteIncomingMessage (bjid, "No avatar for this buddy yet.", 0, HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG, 0); // NO conversion from utf-8
   566 			LmMessageNode    *node;
   572 
   567 			LmMessageHandler *dhandler;
   573 			g_free (bjid);
   568 
   574 
   569 			scr_WriteIncomingMessage (bjid, "No avatar for this buddy yet, sending request.", 0, HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG, 0); // NO conversion from utf-8
       
   570 
       
   571 			// create data request
       
   572 			request = lm_message_new_with_sub_type (bjid, LM_MESSAGE_TYPE_IQ, LM_MESSAGE_SUB_TYPE_GET);
       
   573 			node = lm_message_get_node (request);
       
   574 			lm_message_node_set_attribute (node, "from", lm_connection_get_jid (lconnection));
       
   575 
       
   576 			node = lm_message_node_add_child (node, "pubsub", NULL);
       
   577 			lm_message_node_set_attribute (node, "xmlns", NS_PUBSUB);
       
   578 
       
   579 			node = lm_message_node_add_child (node, "items", NULL);
       
   580 			lm_message_node_set_attribute (node, "node", NS_AVATAR_DATA);
       
   581 
       
   582 			node = lm_message_node_add_child (node, "item", NULL);
       
   583 
       
   584 			// create handler
       
   585 			dhandler = lm_message_handler_new (avatar_retrieve_data_reply_handler, bjid, g_free);
       
   586 			reply_handlers = g_slist_append (reply_handlers, dhandler);
       
   587 
       
   588 			// send
       
   589 			lm_connection_send_with_reply (lconnection, request, dhandler, NULL);
       
   590 
       
   591 			lm_message_handler_unref (dhandler);
       
   592 			lm_message_unref (request);
       
   593 			// bjid will be freed on handler destruction
   575 			return TRUE;
   594 			return TRUE;
   576 		}
   595 		}
   577 	}
   596 	}
   578 
   597 
   579 	{
   598 	{
   650 	return TRUE;
   669 	return TRUE;
   651 }
   670 }
   652 
   671 
   653 // reply handler for image/png data request
   672 // reply handler for image/png data request
   654 // saves image and prints it to buddy buffer
   673 // saves image and prints it to buddy buffer
   655 LmHandlerResult avatar_retrieve_data_reply_handler (LmMessageHandler *handler, LmConnection *connection, LmMessage *message, gpointer userdata)
   674 static LmHandlerResult avatar_retrieve_data_reply_handler (LmMessageHandler *handler, LmConnection *connection, LmMessage *message, gpointer userdata)
   656 {
   675 {
   657 	gchar *from = (gchar *) userdata;
   676 	gchar *from = (gchar *) userdata;
   658 
   677 
   659 	reply_handlers = g_slist_remove (reply_handlers, handler);
   678 	reply_handlers = g_slist_remove (reply_handlers, handler);
   660 	
   679 	
   822 
   841 
   823 		node = lm_message_node_add_child (node, "info", NULL);
   842 		node = lm_message_node_add_child (node, "info", NULL);
   824 		lm_message_node_set_attributes (node, "bytes", bytes, "id", id, "type", "image/png", NULL);
   843 		lm_message_node_set_attributes (node, "bytes", bytes, "id", id, "type", "image/png", NULL);
   825 
   844 
   826 		g_free (bytes);
   845 		g_free (bytes);
   827 	}
   846 
   828 
   847 		// create handler
   829 	// create handler
   848 		LmMessageHandler *handler = lm_message_handler_new (avatar_publish_data_reply_handler, (gpointer) datarequest, (GDestroyNotify) lm_message_unref /* custom, remove from queue? */);
   830 	if (len) 
   849 		reply_handlers = g_slist_append (reply_handlers, handler);
   831 		handler = lm_message_handler_new (avatar_publish_data_reply_handler, (gpointer) datarequest, (GDestroyNotify) lm_message_unref /* custom, remove from queue? */);
   850 
   832 	else 
   851 		// send
   833 		handler = lm_message_handler_new (avatar_publish_metadata_reply_handler, NULL, NULL);
   852 		lm_connection_send_with_reply (lconnection, request, handler, NULL);
   834 	reply_handlers = g_slist_append (reply_handlers, handler);
   853 
   835 
   854 		lm_message_handler_unref (handler);
   836 	// send
   855 	} else 
   837 	lm_connection_send_with_reply (lconnection, request, handler, NULL);
   856 		// send
   838 
   857 		lm_connection_send_with_reply (lconnection, request, avatar_metadata_reply_handler, NULL);
   839 	lm_message_handler_unref (handler);
   858 
   840 	lm_message_unref (request);
   859 	lm_message_unref (request);
   841 }
   860 }
   842 
   861 
   843 // pep node handler
   862 // pep node handler
   844 // if avatar is not yet saved, sends data request, else updates jid's symlink
   863 // if avatar is not yet saved, sends data request, else updates jid's symlink
  1015 
  1034 
  1016 static void avatar_free_reply_handlers (void)
  1035 static void avatar_free_reply_handlers (void)
  1017 {
  1036 {
  1018 	GSList *hel;
  1037 	GSList *hel;
  1019 
  1038 
  1020 	// let's hope, that after invalidation, lm will remove and free unreffed by us handler
       
  1021 	for (hel = reply_handlers; hel; hel = hel->next) {
  1039 	for (hel = reply_handlers; hel; hel = hel->next) {
  1022 		LmMessageHandler *handler = (LmMessageHandler *) hel->data;
  1040 		LmMessageHandler *handler = (LmMessageHandler *) hel->data;
  1023 		lm_message_handler_invalidate (handler);
  1041 		lm_message_handler_invalidate (handler);
       
  1042 		// it is already unreffed
  1024 	}
  1043 	}
  1025 
  1044 
  1026 	g_slist_free (reply_handlers);
  1045 	g_slist_free (reply_handlers);
  1027 	reply_handlers = NULL;
  1046 	reply_handlers = NULL;
  1028 }
  1047 }
  1041 }
  1060 }
  1042 
  1061 
  1043 const gchar *g_module_check_init (GModule *module)
  1062 const gchar *g_module_check_init (GModule *module)
  1044 {
  1063 {
  1045 	pep_register_xmlns_handler (NS_AVATAR_METADATA, avatar_handler, NULL, NULL);
  1064 	pep_register_xmlns_handler (NS_AVATAR_METADATA, avatar_handler, NULL, NULL);
       
  1065 	avatar_metadata_reply_handler = lm_message_handler_new (avatar_publish_metadata_reply_handler, NULL, NULL);
  1046 
  1066 
  1047 	cmd_add ("avatar", "", COMPL_FILENAME, 0, do_avatar, NULL);
  1067 	cmd_add ("avatar", "", COMPL_FILENAME, 0, do_avatar, NULL);
  1048 	
  1068 	
  1049 	hk_add_handler (avatar_hh, HOOK_INTERNAL, NULL);
  1069 	hk_add_handler (avatar_hh, HOOK_INTERNAL, NULL);
  1050 
  1070 
  1054 	return NULL;
  1074 	return NULL;
  1055 }
  1075 }
  1056 
  1076 
  1057 void g_module_unload (GModule *module)
  1077 void g_module_unload (GModule *module)
  1058 {
  1078 {
  1059 	pep_unregister_xmlns_handler (NS_AVATAR_METADATA);
       
  1060 
       
  1061 	avatar_free_reply_handlers ();
       
  1062 
       
  1063 	hk_del_handler (avatar_hh, NULL);
       
  1064 
       
  1065 	cmd_del ("avatar");
       
  1066 
       
  1067 	xmpp_del_feature (NS_AVATAR_METADATA);
  1079 	xmpp_del_feature (NS_AVATAR_METADATA);
  1068 	xmpp_del_feature (NS_AVATAR_METADATA_NOTIFY);
  1080 	xmpp_del_feature (NS_AVATAR_METADATA_NOTIFY);
  1069 }
  1081 
  1070 
  1082 	hk_del_handler (avatar_hh, NULL);
  1071 /* vim: se ts=4: */
  1083 
       
  1084 	cmd_del ("avatar");
       
  1085 
       
  1086 	pep_unregister_xmlns_handler (NS_AVATAR_METADATA);
       
  1087 
       
  1088 	avatar_free_reply_handlers ();
       
  1089 
       
  1090 	if (avatar_metadata_reply_handler) {
       
  1091 		lm_message_handler_invalidate (avatar_metadata_reply_handler);
       
  1092 		lm_message_handler_unref (avatar_metadata_reply_handler);
       
  1093 	}
       
  1094 }
       
  1095 
       
  1096 /* vim: se ts=4 sw=4: */