00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <string.h>
00021 #include <unistd.h>
00022 #include <stdlib.h>
00023 #include <errno.h>
00024
00025 #include "../../dprint.h"
00026
00027 #include "purple.h"
00028 #include "purplepipe.h"
00029 #include "purple_sip.h"
00030 #include "clientpipe.h"
00031 #include "mapping.h"
00032 #include "hashtable.h"
00033 #include "clientaccount.h"
00034 #include "utils.h"
00035
00036 #include <libpurple/account.h>
00037 #include <libpurple/accountopt.h>
00038 #include <libpurple/conversation.h>
00039 #include <libpurple/connection.h>
00040 #include <libpurple/core.h>
00041 #include <libpurple/debug.h>
00042 #include <libpurple/eventloop.h>
00043 #include <libpurple/ft.h>
00044 #include <libpurple/log.h>
00045 #include <libpurple/notify.h>
00046 #include <libpurple/plugin.h>
00047 #include <libpurple/prefs.h>
00048 #include <libpurple/prpl.h>
00049 #include <libpurple/pounce.h>
00050 #include <libpurple/savedstatuses.h>
00051 #include <libpurple/sound.h>
00052 #include <libpurple/status.h>
00053 #include <libpurple/util.h>
00054 #include <libpurple/whiteboard.h>
00055 #include <libpurple/xmlnode.h>
00056
00057 static void pipe_handle_message(struct purple_message *message) {
00058 LM_DBG("handling message cmd\n");
00059 PurpleAccount *account = NULL;
00060 extern_account_t *accounts = NULL;
00061 extern_user_t *users = NULL;
00062 int naccounts = 0, nusers = 0;
00063 int i, j;
00064
00065 PurpleConversation *conv = NULL;
00066 LM_DBG("calling find_accounts(\"%s\", &naccounts)\n", message->from);
00067 accounts = find_accounts(message->from, &naccounts);
00068 LM_DBG("found %d extra account(s) for <%s>", naccounts, message->from);
00069
00070 LM_DBG("calling find_users(\"%s\", &nusers)\n", message->to);
00071 users = find_users(message->to, &nusers);
00072 LM_DBG("found %d extra user(s) for <%s>", nusers, message->to);
00073
00074 for (i = 0; i < naccounts; i++) {
00075 LM_DBG("calling client_find_account(\"%s\")\n", accounts[i].username);
00076 account = client_find_account(&accounts[i]);
00077 if ((account) && purple_account_is_connected(account)) {
00078
00079 for (j = 0; j < nusers; j++) {
00080 if (!strcmp(accounts[i].protocol, users[j].protocol)) {
00081 LM_DBG("mathing protocol found: %s\n", accounts[i].protocol);
00082 conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, users[j].username, account);
00083 if (conv == NULL)
00084 conv = purple_conversation_new(PURPLE_CONV_TYPE_IM, account, users[j].username);
00085 purple_conv_im_send(purple_conversation_get_im_data(conv), message->body);
00086 break;
00087 }
00088 }
00089 }
00090 else if (account == NULL)
00091 LM_DBG("not account found neither created\n");
00092 else if (purple_account_is_disconnected(account))
00093 LM_DBG("account is disconnected cannot send message\n");
00094 }
00095 if (accounts)
00096 extern_account_free(accounts, naccounts);
00097 if (users)
00098 extern_user_free(users, nusers);
00099
00100 }
00101
00102 static void pipe_handle_publish(struct purple_publish *publish) {
00103 PurpleAccount *account = NULL;
00104 extern_account_t *accounts = NULL;
00105 int naccounts = 0;
00106 int i;
00107
00108 LM_DBG("calling find_accounts(\"%s\", &naccoutns)\n", publish->from);
00109 accounts = find_accounts(publish->from, &naccounts);
00110 LM_DBG("found %d extra account(s) for <%s>", naccounts, publish->from);
00111
00112 for (i = 0; i < naccounts; i++) {
00113 LM_DBG("calling client_find_account(\"%s\")\n", accounts[i].username);
00114 account = client_find_account(&accounts[i]);
00115 if (account) {
00116
00117 if (publish->basic == PURPLE_BASIC_OPEN) {
00118 client_enable_account(account);
00119 LM_DBG("basic = open, setting up new status... %s,%d,%s\n", account[i].username, publish->primitive, publish->note);
00120 PurpleStatusType *type = purple_account_get_status_type_with_primitive(account, publish->primitive);
00121 if (purple_status_type_get_attr(type, "message")) {
00122 purple_account_set_status(account, purple_status_type_get_id(type), TRUE, "message", publish->note, NULL);
00123 } else {
00124 purple_account_set_status(account, purple_status_type_get_id(type), TRUE, NULL);
00125 }
00126 }
00127
00128 else if (publish->basic == PURPLE_BASIC_CLOSED){
00129 LM_DBG("basic = closed, setting up new status to offline... %s\n", account[i].username);
00130 PurpleStatusType *type = purple_account_get_status_type_with_primitive(account, PURPLE_STATUS_OFFLINE);
00131 purple_account_set_status(account, purple_status_type_get_id(type), TRUE, NULL);
00132 }
00133
00134 }
00135 }
00136
00137 if (accounts)
00138 extern_account_free(accounts, naccounts);
00139
00140 }
00141
00142 static void pipe_handle_subscribe(struct purple_subscribe *subscribe) {
00143 PurpleAccount *account = NULL;
00144 extern_account_t *accounts = NULL;
00145 extern_user_t *users = NULL;
00146 int naccounts = 0, nusers = 0;
00147 int i, j;
00148 PurpleBuddy *buddy = NULL;
00149
00150 int d = 0;
00151
00152 const char *note;
00153 enum purple_publish_basic basic;
00154 enum purple_publish_activity activity;
00155
00156 LM_DBG("calling find_accounts(\"%s\", &naccounts)\n", subscribe->from);
00157 accounts = find_accounts(subscribe->from, &naccounts);
00158 LM_DBG("found %d extra account(s) for <%s>", naccounts, subscribe->from);
00159
00160 LM_DBG("calling find_users(\"%s\", &nusers)\n", subscribe->to);
00161 users = find_users(subscribe->to, &nusers);
00162 LM_DBG("found %d extra user(s) for <%s>", nusers, subscribe->to);
00163
00164 for (i = 0; i < naccounts; i++) {
00165 LM_DBG("calling client_find_account(\"%s\")\n", accounts[i].username);
00166 account = client_find_account(&accounts[i]);
00167
00168 if (account) {
00169 for (j = 0; j < nusers; j++) {
00170 if (!strcmp(accounts[i].protocol, users[j].protocol)) {
00171 LM_DBG("found matching protocol: %s\n", accounts[i].protocol);
00172
00173 LM_DBG("subscribe expires : %d\n", subscribe->expires);
00174 if (subscribe->expires == 0)
00175 d = hashtable_dec_counter(users[j].username);
00176 else
00177 d = hashtable_inc_counter(users[j].username);
00178
00179 LM_DBG("<%s> is now referenced %d times\n", users[j].username, d);
00180 if (d == 0) {
00181 LM_DBG("<%s> is no more referenced, removing presence...\n", users[j].username);
00182 if (purple_send_sip_publish(subscribe->to, users[j].username, PURPLE_BASIC_CLOSED, 0, NULL) < 0)
00183 LM_ERR("error sending presence for %s", subscribe->to);
00184 else
00185 LM_DBG("presence message sent successfully\n");
00186 }
00187
00188 else {
00189
00190 buddy = purple_find_buddy(account, users[j].username);
00191 if (buddy == NULL) {
00192 LM_DBG("<%s> not found in <%s> buddy list, adding\n", users[j].username, accounts[i].username);
00193 buddy = purple_buddy_new(account, users[j].username, users[j].username);
00194
00195 purple_account_add_buddy(account, buddy);
00196 }
00197 else {
00198 LM_DBG("<%s> found in <%s> buddy list, sending publish\n", users[j].username, accounts[i].username);
00199 PurplePresence *presence = purple_buddy_get_presence(buddy);
00200 PurpleStatus *status = purple_presence_get_active_status(presence);
00201 PurpleStatusType *type = purple_status_get_type(status);
00202 PurpleStatusPrimitive primitive = purple_status_type_get_primitive(type);
00203 note = purple_status_get_attr_string(status, "message");
00204 primitive_parse(primitive, &basic, &activity);
00205
00206 if (purple_send_sip_publish(subscribe->to, users[j].username, basic, activity, note) < 0)
00207 LM_ERR("error sending presence for %s", subscribe->to);
00208 else
00209 LM_DBG("presence message sent successfully\n");
00210
00211 }
00212
00213 }
00214
00215 break;
00216 }
00217 }
00218 }
00219 }
00220 if (accounts)
00221 extern_account_free(accounts, naccounts);
00222 if (users)
00223 extern_user_free(users, nusers);
00224
00225 }
00226
00227 void pipe_reader(gpointer data, gint fd, PurpleInputCondition condition) {
00228 struct purple_cmd *cmd;
00229 if (read(fd, &cmd, sizeof(cmd)) != sizeof(cmd)) {
00230 LM_ERR("failed to read from command pipe: %s\n", strerror(errno));
00231 return;
00232 }
00233
00234 switch (cmd->type) {
00235 case PURPLE_MESSAGE_CMD:
00236 LM_DBG("received message cmd via pipe from <%s> to <%s>\n", cmd->message.from, cmd->message.to);
00237 pipe_handle_message(&cmd->message);
00238 break;
00239
00240 case PURPLE_SUBSCRIBE_CMD:
00241 LM_DBG("received subscribe cmd via pipe from <%s> to <%s>\n", cmd->subscribe.from, cmd->subscribe.to);
00242 pipe_handle_subscribe(&cmd->subscribe);
00243 break;
00244
00245 case PURPLE_PUBLISH_CMD:
00246 LM_DBG("received publish cmd via pipe from <%s>\n", cmd->publish.from);
00247 pipe_handle_publish(&cmd->publish);
00248 break;
00249
00250 default:
00251 LM_ERR("unknown cmd type 0x%x\n", cmd->type);
00252 }
00253 purple_free_cmd(cmd);
00254 }
00255
00256