/***************************************************************************\ * * * BitlBee - An IRC to IM gateway * * Jabber module - SI packets * * * * Copyright 2007 Uli Meis * * * * 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 * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License along * * with this program; if not, write to the Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * * \***************************************************************************/ #include "jabber.h" #include "sha1.h" void jabber_si_answer_request(file_transfer_t *ft); int jabber_si_send_request(struct im_connection *ic, char *who, struct jabber_transfer *tf); /* file_transfer free() callback */ void jabber_si_free_transfer(file_transfer_t *ft) { struct jabber_transfer *tf = ft->data; struct jabber_data *jd = tf->ic->proto_data; if (tf->watch_in) { b_event_remove(tf->watch_in); tf->watch_in = 0; } jd->filetransfers = g_slist_remove(jd->filetransfers, tf); if (tf->fd != -1) { closesocket(tf->fd); tf->fd = -1; } if (tf->disco_timeout) { b_event_remove(tf->disco_timeout); } g_free(tf->ini_jid); g_free(tf->tgt_jid); g_free(tf->iq_id); g_free(tf->sid); g_free(tf); } /* file_transfer canceled() callback */ void jabber_si_canceled(file_transfer_t *ft, char *reason) { struct jabber_transfer *tf = ft->data; struct xt_node *reply, *iqnode; if (tf->accepted) { return; } iqnode = jabber_make_packet("iq", "error", tf->ini_jid, NULL); xt_add_attr(iqnode, "id", tf->iq_id); reply = jabber_make_error_packet(iqnode, "forbidden", "cancel", "403"); xt_free_node(iqnode); if (!jabber_write_packet(tf->ic, reply)) { imcb_log(tf->ic, "WARNING: Error generating reply to file transfer request"); } xt_free_node(reply); } int jabber_si_check_features(struct jabber_transfer *tf, GSList *features) { int foundft = FALSE, foundbt = FALSE, foundsi = FALSE; while (features) { if (!strcmp(features->data, XMLNS_FILETRANSFER)) { foundft = TRUE; } if (!strcmp(features->data, XMLNS_BYTESTREAMS)) { foundbt = TRUE; } if (!strcmp(features->data, XMLNS_SI)) { foundsi = TRUE; } features = g_slist_next(features); } if (!foundft) { imcb_file_canceled(tf->ic, tf->ft, "Buddy's client doesn't feature file transfers"); } else if (!foundbt) { imcb_file_canceled(tf->ic, tf->ft, "Buddy's client doesn't feature byte streams (required)"); } else if (!foundsi) { imcb_file_canceled(tf->ic, tf->ft, "Buddy's client doesn't feature stream initiation (required)"); } return foundft && foundbt && foundsi; } void jabber_si_transfer_start(struct jabber_transfer *tf) { if (!jabber_si_check_features(tf, tf->bud->features)) { return; } /* send the request to our buddy */ jabber_si_send_request(tf->ic, tf->bud->full_jid, tf); /* and start the receive logic */ imcb_file_recv_start(tf->ic, tf->ft); } gboolean jabber_si_waitfor_disco(gpointer data, gint fd, b_input_condition cond) { struct jabber_transfer *tf = data; struct jabber_data *jd = tf->ic->proto_data; tf->disco_timeout_fired++; if (tf->bud->features && jd->have_streamhosts == 1) { tf->disco_timeout = 0; jabber_si_transfer_start(tf); return FALSE; } /* 8 seconds should be enough for server and buddy to respond */ if (tf->disco_timeout_fired < 16) { return TRUE; } if (!tf->bud->features && jd->have_streamhosts != 1) { imcb_log(tf->ic, "Couldn't get buddy's features nor discover all services of the server"); } else if (!tf->bud->features) { imcb_log(tf->ic, "Couldn't get buddy's features"); } else { imcb_log(tf->ic, "Couldn't discover some of the server's services"); } tf->disco_timeout = 0; jabber_si_transfer_start(tf); return FALSE; } void jabber_si_transfer_request(struct im_connection *ic, file_transfer_t *ft, char *who) { struct jabber_transfer *tf; struct jabber_data *jd = ic->proto_data; struct jabber_buddy *bud; char *server = jd->server, *s; if ((s = strchr(who, '=')) && jabber_chat_by_jid(ic, s + 1)) { bud = jabber_buddy_by_ext_jid(ic, who, 0); } else { bud = jabber_buddy_by_jid(ic, who, 0); } if (bud == NULL) { imcb_file_canceled(ic, ft, "Couldn't find buddy (BUG?)"); return; } imcb_log(ic, "Trying to send %s(%zd bytes) to %s", ft->file_name, ft->file_size, who); tf = g_new0(struct jabber_transfer, 1); tf->ic = ic; tf->ft = ft; tf->fd = -1; tf->ft->data = tf; tf->ft->free = jabber_si_free_transfer; tf->bud = bud; ft->write = jabber_bs_send_write; jd->filetransfers = g_slist_prepend(jd->filetransfers, tf); /* query buddy's features and server's streaming proxies if necessary */ if (!tf->bud->features) { jabber_iq_query_features(ic, bud->full_jid); } /* If is not set don't check for proxies */ if ((jd->have_streamhosts != 1) && (jd->streamhosts == NULL) && (strstr(set_getstr(&ic->acc->set, "proxy"), "") != NULL)) { jd->have_streamhosts = 0; jabber_iq_query_server(ic, server, XMLNS_DISCO_ITEMS); } else if (jd->streamhosts != NULL) { jd->have_streamhosts = 1; } /* if we had to do a query, wait for the result. * Otherwise fire away. */ if (!tf->bud->features || jd->have_streamhosts != 1) { tf->disco_timeout = b_timeout_add(500, jabber_si_waitfor_disco, tf); } else { jabber_si_transfer_start(tf); } } /* * First function that gets called when a file transfer request comes in. * A lot to parse. * * We choose a stream type from the options given by the initiator.
/***************************************************************************\
*                                                                           *
*  BitlBee - An IRC to IM gateway                                           *
*  Simple module to facilitate twitter functionality.                       *
*                                                                           *
*  Copyright 2009 Geert Mulders <g.c.w.m.mulders@gmail.com>                 *
*                                                                           *
*  This library is free software; you can redistribute it and/or            *
*  modify it under the terms of the GNU Lesser General Public               *
*  License as published by the Free Software Foundation, version            *
*  2.1.                                                                     *
*                                                                           *
*  This library is distributed in the hope that it will be useful,          *
*  but WITHOUT ANY WARRANTY; without even the implied warranty of           *
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU        *
*  Lesser General Public License for more details.                          *
*                                                                           *
*  You should have received a copy of the GNU Lesser General Public License *
*  along with this library; if not, write to the Free Software Foundation,  *
*  Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA           *
*                                                                           *
****************************************************************************/


#ifndef _TWITTER_LIB_H
#define _TWITTER_LIB_H

#include "nogaim.h"
#include "twitter_http.h"

#define TWITTER_API_URL "https://api.twitter.com/1.1"
#define IDENTICA_API_URL "https://identi.ca/api"

/* Status URLs */
#define TWITTER_STATUS_UPDATE_URL "/statuses/update.json"
#define TWITTER_STATUS_SHOW_URL "/statuses/show/"
#define TWITTER_STATUS_DESTROY_URL "/statuses/destroy/"
#define TWITTER_STATUS_RETWEET_URL "/statuses/retweet/"

/* Timeline URLs */
#define TWITTER_PUBLIC_TIMELINE_URL "/statuses/public_timeline.json"
#define TWITTER_FEATURED_USERS_URL "/statuses/featured.json"
#define TWITTER_FRIENDS_TIMELINE_URL "/statuses/friends_timeline.json"
#define TWITTER_HOME_TIMELINE_URL "/statuses/home_timeline.json"
#define TWITTER_MENTIONS_URL "/statuses/mentions_timeline.json"
#define TWITTER_USER_TIMELINE_URL "/statuses/user_timeline.json"

/* Users URLs */
#define TWITTER_USERS_LOOKUP_URL "/users/lookup.json"

/* Direct messages URLs */
#define TWITTER_DIRECT_MESSAGES_URL "/direct_messages.json"
#define TWITTER_DIRECT_MESSAGES_NEW_URL "/direct_messages/new.json"
#define TWITTER_DIRECT_MESSAGES_SENT_URL "/direct_messages/sent.json"
#define TWITTER_DIRECT_MESSAGES_DESTROY_URL "/direct_messages/destroy/"

/* Friendships URLs */
#define TWITTER_FRIENDSHIPS_CREATE_URL "/friendships/create.json"
#define TWITTER_FRIENDSHIPS_DESTROY_URL "/friendships/destroy.json"
#define TWITTER_FRIENDSHIPS_SHOW_URL "/friendships/show.json"

/* Social graphs URLs */
#define TWITTER_FRIENDS_IDS_URL "/friends/ids.json"
#define TWITTER_FOLLOWERS_IDS_URL "/followers/ids.json"

/* Account URLs */
#define TWITTER_ACCOUNT_RATE