Changes in / [d304445:c720890]


Ignore:
Files:
21 edited

Legend:

Unmodified
Added
Removed
  • configure

    rd304445 rc720890  
    8282                replace="\1+$timestamp+$branch+\2-\3-git"
    8383
    84                 BITLBEE_VERSION=$(cd $srcdir; git describe --long --tags | sed -r "s/$search/$replace/")
     84                BITLBEE_VERSION=$(cd $srcdir; git describe --long --tags | sed -r "s#$search#$replace#")
    8585
    8686                unset timestamp branch search replace
  • debian/control

    rd304445 rc720890  
    2222Architecture: any
    2323Depends: ${misc:Depends}, ${shlibs:Depends}, debianutils (>= 1.16), bitlbee-common (= ${source:Version})
    24 Provides: bitlbee
     24Provides: bitlbee (= ${source:Version})
    2525Conflicts: bitlbee
    2626Replaces: bitlbee
  • doc/user-guide/commands.xml

    rd304445 rc720890  
    10171017                <description>
    10181018                        <para>
    1019                                 Some protocols (MSN, Yahoo!) can notify via IM about new e-mail. Since most people use their Hotmail/Yahoo! addresses as a spam-box, this is disabled default. If you want these notifications, you can enable this setting.
     1019                                Some protocols (MSN, Yahoo!, GTalk) can notify via IM about new e-mail. Since most people use their Hotmail/Yahoo! addresses as a spam-box, this is disabled default. If you want these notifications, you can enable this setting.
     1020                        </para>
     1021                </description>
     1022
     1023        </bitlbee-setting>
     1024
     1025        <bitlbee-setting name="mail_notifications_handle" type="string" scope="account">
     1026                <default>empty</default>
     1027
     1028                <description>
     1029                        <para>
     1030                                This setting is available for protocols with e-mail notification functionality. If set to empty all e-mail notifications will go to control channel, if set to some string - this will be the name of a contact who will PRIVMSG you on every new notification.
    10201031                        </para>
    10211032                </description>
  • irc.h

    rd304445 rc720890  
    147147        IRC_CHANNEL_TEMP = 2,   /* Erase the channel when the user leaves,
    148148                                   and don't save it. */
     149
     150        /* Show a placeholder of the channel in listings, but don't save it */
     151        IRC_CHANNEL_KEEP_PLACEHOLDER = 4,
    149152
    150153        /* Hack: Set this flag right before jumping into IM when we expect
  • irc_channel.c

    rd304445 rc720890  
    276276                if (ic->irc->status & USTATUS_SHUTDOWN) {
    277277                        /* Don't do anything fancy when we're shutting down anyway. */
    278                 } else if (ic->flags & IRC_CHANNEL_TEMP) {
     278                } else if (ic->flags & IRC_CHANNEL_TEMP && !(ic->flags & IRC_CHANNEL_KEEP_PLACEHOLDER)) {
    279279                        irc_channel_free_soon(ic);
    280280                } else {
  • irc_im.c

    rd304445 rc720890  
    576576        ic->data = c;
    577577
    578         topic = g_strdup_printf(
    579                 "BitlBee groupchat: \"%s\". Please keep in mind that root-commands won't work here. Have fun!",
    580                 c->title);
    581         irc_channel_set_topic(ic, topic, irc->root);
    582         g_free(topic);
     578        if (ic->topic == NULL) {
     579                /* New channel with no preset topic - make up a generic one */
     580                topic = g_strdup_printf(
     581                        "BitlBee groupchat: \"%s\". Please keep in mind that root-commands won't work here. Have fun!",
     582                        c->title);
     583                irc_channel_set_topic(ic, topic, irc->root);
     584        } else {
     585                /* Preset topic from the channel we picked */
     586                topic = g_strdup(ic->topic);
     587        }
     588
     589        g_free(c->topic);
     590        c->topic = topic;         /* Let groupchat borrow this pointer */
    583591
    584592        return TRUE;
     
    600608        c->ui_data = NULL;
    601609        irc_channel_del_user(ic, ic->irc->user, IRC_CDU_KICK, "Chatroom closed by server");
     610
     611        return TRUE;
     612}
     613
     614static gboolean bee_irc_chat_placeholder_new(bee_t *bee, struct im_connection *ic, const char *handle,
     615                                             const char *name, const char *topic)
     616{
     617        irc_t *irc = bee->ui_data;
     618        irc_channel_t *ircc;
     619        char *full_name = irc_channel_name_gen(irc, name);
     620
     621        ircc = irc_channel_new(irc, full_name);
     622
     623        set_setstr(&ircc->set, "type", "chat");
     624        set_setstr(&ircc->set, "chat_type", "placeholder");
     625        set_setstr(&ircc->set, "account", ic->acc->tag);
     626        set_setstr(&ircc->set, "room", (char *) handle);
     627
     628        irc_channel_set_topic(ircc, topic, NULL);
     629
     630        g_free(full_name);
    602631
    603632        return TRUE;
     
    826855static gboolean bee_irc_channel_chat_join(irc_channel_t *ic)
    827856{
    828         char *acc_s, *room;
     857        char *acc_s, *room, *chat_type;
    829858        account_t *acc;
    830859
    831         if (strcmp(set_getstr(&ic->set, "chat_type"), "room") != 0) {
     860        chat_type = set_getstr(&ic->set, "chat_type");
     861
     862        if (strcmp(chat_type, "room") != 0 && strcmp(chat_type, "placeholder") != 0) {
    832863                return TRUE;
    833864        }
     
    9851016        struct irc_channel *ic = set->data;
    9861017
     1018        ic->flags &= ~(IRC_CHANNEL_TEMP | IRC_CHANNEL_KEEP_PLACEHOLDER);
     1019
    9871020        if (strcmp(value, "groupchat") == 0) {
    9881021                ic->flags |= IRC_CHANNEL_TEMP;
    9891022        } else if (strcmp(value, "room") == 0) {
    990                 ic->flags &= ~IRC_CHANNEL_TEMP;
     1023                // beep boop
     1024        } else if (strcmp(value, "placeholder") == 0) {
     1025                ic->flags |= IRC_CHANNEL_TEMP | IRC_CHANNEL_KEEP_PLACEHOLDER;
    9911026        } else {
    9921027                return NULL;
     
    10721107        bee_irc_chat_new,
    10731108        bee_irc_chat_free,
     1109        bee_irc_chat_placeholder_new,
    10741110        bee_irc_chat_log,
    10751111        bee_irc_chat_msg,
  • nick.c

    rd304445 rc720890  
    368368
    369369        if (tab['A'] == 0) {
     370                /* initialize table so nonchars are mapped to themselves */
     371                for (i = 0; i < sizeof(tab); i++) {
     372                        tab[i] = i;
     373                }
     374                /* replace uppercase chars with lowercase chars */
    370375                for (i = 0; nick_lc_chars[i]; i++) {
    371376                        tab[(int) nick_uc_chars[i]] = nick_lc_chars[i];
    372                         tab[(int) nick_lc_chars[i]] = nick_lc_chars[i];
    373377                }
    374378        }
  • protocols/bee.h

    rd304445 rc720890  
    115115        gboolean (*chat_new)(bee_t *bee, struct groupchat *c);
    116116        gboolean (*chat_free)(bee_t *bee, struct groupchat *c);
     117        gboolean (*chat_placeholder_new)(bee_t *bee, struct im_connection *ic, const char *handle,
     118                                         const char *name, const char *topic);
    117119        /* System messages of any kind. */
    118120        gboolean (*chat_log)(bee_t *bee, struct groupchat *c, const char *text);
     
    156158G_MODULE_EXPORT void imcb_buddy_msg(struct im_connection *ic, const char *handle, const char *msg, guint32 flags,
    157159                                    time_t sent_at);
     160G_MODULE_EXPORT void imcb_notify_email(struct im_connection *ic, char *format, ...) G_GNUC_PRINTF(2, 3);
    158161
    159162/* bee_chat.c */
     
    165168 *   user, too. */
    166169G_MODULE_EXPORT struct groupchat *imcb_chat_new(struct im_connection *ic, const char *handle);
     170G_MODULE_EXPORT void imcb_chat_placeholder_new(struct im_connection *ic, const char *handle, const char *name,
     171                                               const char *topic);
    167172G_MODULE_EXPORT void imcb_chat_name_hint(struct groupchat *c, const char *name);
    168173G_MODULE_EXPORT void imcb_chat_free(struct groupchat *c);
  • protocols/bee_chat.c

    rd304445 rc720890  
    5454}
    5555
     56void imcb_chat_placeholder_new(struct im_connection *ic, const char *handle, const char *name, const char *topic)
     57{
     58        bee_t *bee = ic->bee;
     59
     60        if (bee->ui->chat_placeholder_new) {
     61                bee->ui->chat_placeholder_new(bee, ic, handle, name, topic);
     62        }
     63}
     64
    5665void imcb_chat_name_hint(struct groupchat *c, const char *name)
    5766{
  • protocols/bee_user.c

    rd304445 rc720890  
    271271}
    272272
     273void imcb_notify_email(struct im_connection *ic, char *format, ...)
     274{
     275        const char *handle;
     276        va_list params;
     277        char *msg;
     278
     279        if (!set_getbool(&ic->acc->set, "mail_notifications")) {
     280                return;
     281        }
     282
     283        va_start(params, format);
     284        msg = g_strdup_vprintf(format, params);
     285        va_end(params);
     286
     287        /* up to the protocol to set_add this if they want to use this */
     288        handle = set_getstr(&ic->acc->set, "mail_notifications_handle");
     289
     290        if (handle != NULL) {
     291                imcb_buddy_msg(ic, handle, msg, 0, 0);
     292        } else {
     293                imcb_log(ic, "%s", msg);
     294        }
     295
     296        g_free(msg);
     297}
     298
    273299void imcb_buddy_typing(struct im_connection *ic, const char *handle, uint32_t flags)
    274300{
  • protocols/jabber/conference.c

    rd304445 rc720890  
    354354        struct xt_node *subject = xt_find_node(node->children, "subject");
    355355        struct xt_node *body = xt_find_node(node->children, "body");
    356         struct groupchat *chat = bud ? jabber_chat_by_jid(ic, bud->bare_jid) : NULL;
    357         struct jabber_chat *jc = chat ? chat->data : NULL;
    358         char *s;
     356        struct groupchat *chat = NULL;
     357        struct jabber_chat *jc = NULL;
     358        char *from = NULL;
     359        char *nick = NULL;
     360        char *final_from = NULL;
     361        char *bare_jid = NULL;
     362
     363        from = (bud) ? bud->full_jid : xt_find_attr(node, "from");
     364
     365        if (from) {
     366                nick = strchr(from, '/');
     367                if (nick) {
     368                        *nick = 0;
     369                }
     370                chat = jabber_chat_by_jid(ic, from);
     371                if (nick) {
     372                        *nick = '/';
     373                        nick++;
     374                }
     375        }
     376
     377        jc = (chat) ? chat->data : NULL;
     378
     379        if (!bud) {
     380                struct xt_node *c;
     381                char *s;
     382
     383                /* Try some clever stuff to find out the real JID here */
     384                c = xt_find_node_by_attr(node->children, "delay", "xmlns", XMLNS_DELAY);
     385
     386                if (c && ((s = xt_find_attr(c, "from")) ||
     387                          (s = xt_find_attr(c, "from_jid")))) {
     388                        /* This won't be useful if it's the MUC JID */
     389                        if (!(jc && jabber_compare_jid(s, jc->name))) {
     390                                /* Hopefully this one makes more sense! */
     391                                bud = jabber_buddy_by_jid(ic, s, GET_BUDDY_FIRST | GET_BUDDY_CREAT);
     392                        }
     393                }
     394
     395        }
    359396
    360397        if (subject && chat) {
    361                 s = (bud && bud->ext_jid) ? strchr(bud->ext_jid, '/') : NULL;
    362                 if (s) {
    363                         *s = 0;
    364                 }
    365                 imcb_chat_topic(chat, bud ? bud->ext_jid : NULL, subject->text_len > 0 ?
    366                                 subject->text : NULL, jabber_get_timestamp(node));
    367                 if (s) {
    368                         *s = '/';
    369                 }
    370         }
    371 
    372         if (bud == NULL || (jc && ~jc->flags & JCFLAG_MESSAGE_SENT && bud == jc->me)) {
    373                 char *nick;
    374 
    375                 if (body == NULL || body->text_len == 0) {
    376                         /* Meh. Empty messages aren't very interesting, no matter
    377                            how much some servers love to send them. */
    378                         return;
    379                 }
    380 
    381                 s = xt_find_attr(node, "from");   /* pkt_message() already NULL-checked this one. */
    382                 nick = strchr(s, '/');
    383                 if (nick) {
    384                         /* If this message included a resource/nick we don't know,
    385                            we might still know the groupchat itself. */
    386                         *nick = 0;
    387                         chat = jabber_chat_by_jid(ic, s);
    388                         *nick = '/';
    389 
    390                         nick++;
     398                char *subject_text = subject->text_len > 0 ? subject->text : NULL;
     399                if (g_strcmp0(chat->topic, subject_text) != 0) {
     400                        bare_jid = (bud) ? jabber_get_bare_jid(bud->ext_jid) : NULL;
     401                        imcb_chat_topic(chat, bare_jid, subject_text,
     402                                        jabber_get_timestamp(node));
     403                        g_free(bare_jid);
     404                }
     405        }
     406
     407        if (body == NULL || body->text_len == 0) {
     408                /* Meh. Empty messages aren't very interesting, no matter
     409                   how much some servers love to send them. */
     410                return;
     411        }
     412
     413        if (chat == NULL) {
     414                if (nick == NULL) {
     415                        imcb_log(ic, "System message from unknown groupchat %s: %s", from, body->text);
    391416                } else {
    392                         /* message.c uses the EXACT_JID option, so bud should
    393                            always be NULL here for bare JIDs. */
    394                         chat = jabber_chat_by_jid(ic, s);
    395                 }
    396 
    397                 if (nick == NULL) {
    398                         /* This is fine, the groupchat itself isn't in jd->buddies. */
    399                         if (chat) {
    400                                 imcb_chat_log(chat, "From conference server: %s", body->text);
    401                         } else {
    402                                 imcb_log(ic, "System message from unknown groupchat %s: %s", s, body->text);
    403                         }
    404                 } else {
    405                         /* This can happen too, at least when receiving a backlog when
    406                            just joining a channel. */
    407                         if (chat) {
    408                                 imcb_chat_log(chat, "Message from unknown participant %s: %s", nick, body->text);
    409                         } else {
    410                                 imcb_log(ic, "Groupchat message from unknown JID %s: %s", s, body->text);
    411                         }
     417                        imcb_log(ic, "Groupchat message from unknown JID %s: %s", from, body->text);
    412418                }
    413419
    414420                return;
    415         } else if (chat == NULL) {
    416                 /* How could this happen?? We could do kill( self, 11 )
    417                    now or just wait for the OS to do it. :-) */
     421        } else if (chat != NULL && bud == NULL && nick == NULL) {
     422                imcb_chat_log(chat, "From conference server: %s", body->text);
    418423                return;
    419         }
    420         if (body && body->text_len > 0) {
    421                 s = (bud->ext_jid) ? strchr(bud->ext_jid, '/') : NULL;
    422                 if (s) {
    423                         *s = 0;
    424                 }
    425                 imcb_chat_msg(chat, bud->ext_jid, body->text, 0, jabber_get_timestamp(node));
    426                 if (s) {
    427                         *s = '/';
    428                 }
    429         }
    430 }
     424        } else if (jc && jc->flags & JCFLAG_MESSAGE_SENT && bud == jc->me) {
     425                /* exclude self-messages since they would get filtered out
     426                 * but not the ones in the backlog */
     427                return;
     428        }
     429
     430        if (bud && jc && bud != jc->me) {
     431                bare_jid = jabber_get_bare_jid(bud->ext_jid ? bud->ext_jid : bud->full_jid);
     432                final_from = bare_jid;
     433        } else {
     434                final_from = nick;
     435        }
     436
     437        imcb_chat_msg(chat, final_from, body->text, 0, jabber_get_timestamp(node));
     438
     439        g_free(bare_jid);
     440}
  • protocols/jabber/hipchat.c

    rd304445 rc720890  
    2727{
    2828        struct jabber_data *jd = ic->proto_data;
    29         char *sep, *jid;
     29        char *sep, *jid, *muc_host;
    3030
    3131        jid = xt_find_attr(node, "jid");
     32        muc_host = xt_find_attr(node, "muc_host");
    3233
    3334        sep = strchr(jid, '/');
     
    4849        if (!jabber_get_roster(ic) ||
    4950            !jabber_iq_disco_server(ic) ||
    50             !jabber_get_hipchat_profile(ic)) {
     51            !jabber_get_hipchat_profile(ic) ||
     52            !jabber_iq_disco_muc(ic, muc_host)) {
    5153                return XT_ABORT;
    5254        }
     
    9294
    9395}
     96
     97int jabber_iq_disco_muc(struct im_connection *ic, char *muc_server)
     98{
     99        struct xt_node *node;
     100        int st;
     101
     102        imcb_log(ic, "Fetching MUC list");
     103
     104        node = xt_new_node("query", NULL, NULL);
     105        xt_add_attr(node, "xmlns", XMLNS_DISCO_ITEMS);
     106        node = jabber_make_packet("iq", "get", muc_server, node);
     107
     108        jabber_cache_add(ic, node, jabber_parse_muc_list);
     109        st = jabber_write_packet(ic, node);
     110
     111        return st;
     112}
     113
     114xt_status jabber_parse_muc_list(struct im_connection *ic, struct xt_node *node, struct xt_node *orig)
     115{
     116        struct xt_node *query, *c;
     117
     118        if (!(query = xt_find_node(node->children, "query"))) {
     119                imcb_log(ic, "Warning: Received NULL MUC list packet");
     120                return XT_HANDLED;
     121        }
     122
     123        c = query->children;
     124        while ((c = xt_find_node(c, "item"))) {
     125                struct xt_node *c2;
     126                char *topic = NULL;
     127                char *jid = xt_find_attr(c, "jid");
     128                char *name = xt_find_attr(c, "name");
     129
     130                imcb_log(ic, "Debug: adding MUC to channel list: %s - '%s'", jid, name);
     131
     132                if ((c2 = xt_find_node_by_attr(c->children, "x", "xmlns", XMLNS_HIPCHAT_MUC)) &&
     133                    (c2 = xt_find_node(c2->children, "topic"))) {
     134                        topic = c2->text;
     135                }
     136
     137                imcb_chat_placeholder_new(ic, jid, name, topic);
     138                c = c->next;
     139        }
     140        return XT_HANDLED;
     141
     142}
  • protocols/jabber/iq.c

    rd304445 rc720890  
    2727static xt_status jabber_parse_roster(struct im_connection *ic, struct xt_node *node, struct xt_node *orig);
    2828static xt_status jabber_iq_display_vcard(struct im_connection *ic, struct xt_node *node, struct xt_node *orig);
     29static xt_status jabber_gmail_handle_new(struct im_connection *ic, struct xt_node *node);
    2930
    3031xt_status jabber_pkt_iq(struct xt_node *node, gpointer data)
     
    141142                    (strcmp(s, XMLNS_SI) == 0)) {
    142143                        return jabber_si_handle_request(ic, node, c);
     144                } else if ((c = xt_find_node(node->children, "new-mail")) &&
     145                           (s = xt_find_attr(c, "xmlns")) &&
     146                           (strcmp(s, XMLNS_GMAILNOTIFY) == 0)) {
     147                        return jabber_gmail_handle_new(ic, node);
    143148                } else if (!(c = xt_find_node(node->children, "query")) ||
    144149                           !(s = xt_find_attr(c, "xmlns"))) {
     
    342347                        return XT_ABORT;
    343348                }
     349                if (jd->flags & JFLAG_GMAILNOTIFY && node == NULL) {
     350                        jabber_iq_query_server(ic, jd->server, XMLNS_DISCO_INFO);
     351                }
    344352        } else if ((jd->flags & (JFLAG_WANT_BIND | JFLAG_WANT_SESSION)) == 0) {
    345353                if (!jabber_get_roster(ic)) {
     
    369377
    370378        return st;
     379}
     380
     381xt_status jabber_iq_query_gmail(struct im_connection *ic);
     382
     383static xt_status jabber_gmail_handle_new(struct im_connection *ic, struct xt_node *node)
     384{
     385        struct xt_node *response;
     386        struct jabber_data *jd = ic->proto_data;
     387
     388        response = jabber_make_packet("iq", "result", g_strdup_printf("%s@%s", jd->username, jd->server), NULL);
     389
     390        jabber_cache_add(ic, response, NULL);
     391        if (!jabber_write_packet(ic, response)) {
     392                return XT_ABORT;
     393        }
     394
     395        jabber_iq_query_gmail(ic);
     396
     397        return XT_HANDLED;
    371398}
    372399
     
    710737}
    711738
     739xt_status jabber_iq_parse_gmail(struct im_connection *ic, struct xt_node *node, struct xt_node *orig);
     740
     741xt_status jabber_iq_query_gmail(struct im_connection *ic)
     742{
     743        struct xt_node *node, *query;
     744        struct jabber_data *jd = ic->proto_data;
     745
     746        node = xt_new_node("query", NULL, NULL);
     747        xt_add_attr(node, "xmlns", XMLNS_GMAILNOTIFY);
     748        if (jd->gmail_time) {
     749                char *formatted = g_strdup_printf("%" G_GUINT64_FORMAT, (jd->gmail_time + 1));
     750                xt_add_attr(node, "newer-than-time", formatted);
     751                g_free(formatted);
     752        }
     753        if (jd->gmail_tid) {
     754                xt_add_attr(node, "newer-than-tid", jd->gmail_tid);
     755        }
     756
     757        if (!(query = jabber_make_packet("iq", "get", jd->me, node))) {
     758                imcb_log(ic, "WARNING: Couldn't generate server query");
     759                xt_free_node(node);
     760        }
     761
     762        jabber_cache_add(ic, query, jabber_iq_parse_gmail);
     763
     764        return jabber_write_packet(ic, query) ? XT_HANDLED : XT_ABORT;
     765}
     766
    712767xt_status jabber_iq_parse_server_features(struct im_connection *ic, struct xt_node *node, struct xt_node *orig);
    713768
     
    729784
    730785        return jabber_write_packet(ic, query) ? XT_HANDLED : XT_ABORT;
     786}
     787
     788xt_status jabber_iq_parse_gmail(struct im_connection *ic, struct xt_node *node, struct xt_node *orig)
     789{
     790        struct xt_node *c;
     791        struct jabber_data *jd = ic->proto_data;
     792        char *xmlns, *from;
     793        guint64 l_time = 0;
     794        char *tid = NULL;
     795        int max = 0;
     796
     797        if (!(c = xt_find_node(node->children, "mailbox")) ||
     798            !(from = xt_find_attr(node, "from")) ||
     799            !(xmlns = xt_find_attr(c, "xmlns")) ||
     800            (g_strcmp0(xmlns, XMLNS_GMAILNOTIFY) != 0)) {
     801                imcb_log(ic, "WARNING: Received incomplete mailbox packet for gmail notify");
     802                return XT_HANDLED;
     803        }
     804
     805        max = set_getint(&ic->acc->set, "mail_notifications_limit");
     806        c = c->children;
     807
     808        while ((max-- > 0) && (c = xt_find_node(c, "mail-thread-info"))) {
     809                struct xt_node *s;
     810                char *subject = "<no subject>";
     811                char *sender = "<no sender>";
     812                guint64 t_time;
     813
     814                t_time = g_ascii_strtoull(xt_find_attr(c, "date"), NULL, 10);
     815                if (t_time && t_time > l_time) {
     816                        l_time = t_time;
     817                        tid = xt_find_attr(c, "tid");
     818                }
     819
     820                if ((s = xt_find_node(c->children, "senders")) &&
     821                    (s = xt_find_node_by_attr(s->children, "sender", "unread", "1"))) {
     822                        sender = xt_find_attr(s, "name");
     823                }
     824
     825                if ((s = xt_find_node(c->children, "subject")) && s->text) {
     826                        subject = s->text;
     827                }
     828
     829                imcb_notify_email(ic, "New mail from %s: %s", sender, subject);
     830
     831                c = c->next;
     832        }
     833
     834        if (l_time && (!jd->gmail_time || l_time > jd->gmail_time)) {
     835                jd->gmail_time = l_time;
     836                if (tid) {
     837                        g_free(jd->gmail_tid);
     838                        jd->gmail_tid = g_strdup(tid);
     839                }
     840        }
     841
     842        return XT_HANDLED;
    731843}
    732844
     
    781893                        c = c->next;
    782894                }
     895
     896                if (jd->flags & JFLAG_GMAILNOTIFY) {
     897                        /* search for gmail notification feature */
     898                        c = xt_find_node(node->children, "query");
     899                        c = c->children;
     900                        while ((c = xt_find_node(c, "feature"))) {
     901                                if (strcmp(xt_find_attr(c, "var"), XMLNS_GMAILNOTIFY) == 0) {
     902                                        jabber_iq_query_gmail(ic);
     903                                }
     904                                c = c->next;
     905                        }
     906                }
     907
    783908        } else if (strcmp(xmlns, XMLNS_BYTESTREAMS) == 0) {
    784909                char *host, *jid, *port_s;
  • protocols/jabber/jabber.c

    rd304445 rc720890  
    100100
    101101        s = set_add(&acc->set, "xmlconsole", "false", set_eval_bool, acc);
     102
     103        s = set_add(&acc->set, "mail_notifications", "false", set_eval_bool, acc);
    102104        s->flags |= ACC_SET_OFFLINE_ONLY;
     105
     106        /* changing this is rarely needed so keeping it secret */
     107        s = set_add(&acc->set, "mail_notifications_limit", "5", set_eval_int, acc);
     108        s->flags |= SET_HIDDEN_DEFAULT;
     109
     110        s = set_add(&acc->set, "mail_notifications_handle", NULL, NULL, acc);
     111        s->flags |= ACC_SET_OFFLINE_ONLY | SET_NULL_OK;
    103112
    104113        acc->flags |= ACC_FLAG_AWAY_MESSAGE | ACC_FLAG_STATUS_MESSAGE |
     
    260269        }
    261270
     271        if (set_getbool(&acc->set, "mail_notifications")) {
     272                /* It's gmail specific, but it checks for server support before enabling it */
     273                jd->flags |= JFLAG_GMAILNOTIFY;
     274                if (set_getstr(&acc->set, "mail_notifications_handle")) {
     275                        imcb_add_buddy(ic, set_getstr(&acc->set, "mail_notifications_handle"), NULL);
     276                }
     277        }
     278
    262279        jabber_generate_id_hash(jd);
    263280}
     
    334351        g_free(jd->away_message);
    335352        g_free(jd->internal_jid);
     353        g_free(jd->gmail_tid);
    336354        g_free(jd->username);
    337355        g_free(jd->me);
  • protocols/jabber/jabber.h

    rd304445 rc720890  
    4646        JFLAG_XMLCONSOLE = 64,          /* If the user added an xmlconsole buddy. */
    4747        JFLAG_STARTTLS_DONE = 128,      /* If a plaintext session was converted to TLS. */
     48        JFLAG_GMAILNOTIFY = 256,        /* If gmail notification is enabled */
    4849
    4950        JFLAG_GTALK =  0x100000,        /* Is Google Talk, as confirmed by iq discovery */
     
    102103        const struct jabber_away_state *away_state;
    103104        char *away_message;
     105        guint64 gmail_time;
     106        char *gmail_tid;
    104107
    105108        md5_state_t cached_id_prefix;
     
    224227#define XMLNS_DELAY        "urn:xmpp:delay"                                      /* XEP-0203 */
    225228#define XMLNS_XDATA        "jabber:x:data"                                       /* XEP-0004 */
     229#define XMLNS_GMAILNOTIFY  "google:mail:notify"                                  /* Not a XEP */
    226230#define XMLNS_CHATSTATES   "http://jabber.org/protocol/chatstates"               /* XEP-0085 */
    227231#define XMLNS_DISCO_INFO   "http://jabber.org/protocol/disco#info"               /* XEP-0030 */
     
    239243#define XMLNS_HIPCHAT         "http://hipchat.com"
    240244#define XMLNS_HIPCHAT_PROFILE "http://hipchat.com/protocol/profile"
     245#define XMLNS_HIPCHAT_MUC     "http://hipchat.com/protocol/muc#room"
    241246
    242247/* jabber.c */
     
    249254int jabber_get_roster(struct im_connection *ic);
    250255int jabber_get_vcard(struct im_connection *ic, char *bare_jid);
     256int jabber_iq_disco_muc(struct im_connection *ic, char *muc_server);
    251257int jabber_add_to_roster(struct im_connection *ic, const char *handle, const char *name, const char *group);
    252258int jabber_remove_from_roster(struct im_connection *ic, char *handle);
     
    312318void jabber_error_free(struct jabber_error *err);
    313319gboolean jabber_set_me(struct im_connection *ic, const char *me);
     320char *jabber_get_bare_jid(char *jid);
    314321
    315322extern const struct jabber_away_state jabber_away_state_list[];
     
    351358xt_status jabber_parse_hipchat_profile(struct im_connection *ic, struct xt_node *node, struct xt_node *orig);
    352359xt_status hipchat_handle_success(struct im_connection *ic, struct xt_node *node);
     360xt_status jabber_parse_muc_list(struct im_connection *ic, struct xt_node *node, struct xt_node *orig);
    353361
    354362#endif
  • protocols/jabber/jabber_util.c

    rd304445 rc720890  
    820820        return TRUE;
    821821}
     822
     823/* Returns new reference! g_free() afterwards. */
     824char *jabber_get_bare_jid(char *jid)
     825{
     826        char *s = NULL;
     827
     828        if (jid == NULL) {
     829                return NULL;
     830        }
     831
     832        if ((s = strchr(jid, '/'))) {
     833                return g_strndup(jid, s - jid);
     834        } else {
     835                return g_strdup(jid);
     836        }
     837}
  • protocols/jabber/presence.c

    rd304445 rc720890  
    181181}
    182182
     183static char *choose_priority(struct im_connection *ic)
     184{
     185        struct jabber_data *jd = ic->proto_data;
     186        char *prio = set_getstr(&ic->acc->set, "priority");
     187
     188        if (jd->away_state->code != NULL) {
     189                int new_prio = (atoi(prio) - 5);
     190                if (new_prio < 0) {
     191                        new_prio = 0;
     192                }
     193                return g_strdup_printf("%d", new_prio);
     194        }
     195
     196        return g_strdup(prio);
     197}
     198
    183199/* Whenever presence information is updated, call this function to inform the
    184200   server. */
     
    189205        GSList *l;
    190206        int st;
     207        char *prio = choose_priority(ic);
    191208
    192209        node = jabber_make_packet("presence", NULL, NULL, NULL);
    193         xt_add_child(node, xt_new_node("priority", set_getstr(&ic->acc->set, "priority"), NULL));
     210        xt_add_child(node, xt_new_node("priority", prio, NULL));
    194211        if (jd->away_state) {
    195212                xt_add_child(node, xt_new_node("show", jd->away_state->code, NULL));
     
    222239
    223240        xt_free_node(node);
     241        g_free(prio);
    224242        return st;
    225243}
  • protocols/msn/msn.c

    rd304445 rc720890  
    4646        s->flags |= ACC_SET_OFFLINE_ONLY;
    4747
    48         set_add(&acc->set, "mail_notifications", "false", set_eval_bool, acc);
     48        s = set_add(&acc->set, "mail_notifications", "false", set_eval_bool, acc);
     49        s->flags |= ACC_SET_OFFLINE_ONLY;
     50
     51        s = set_add(&acc->set, "mail_notifications_handle", NULL, NULL, acc);
     52        s->flags |= ACC_SET_OFFLINE_ONLY | SET_NULL_OK;
    4953
    5054        acc->flags |= ACC_FLAG_AWAY_MESSAGE | ACC_FLAG_STATUS_MESSAGE |
     
    8286        msn_ns_connect(ic, server,
    8387                       set_getint(&ic->acc->set, "port"));
     88
     89        if (set_getbool(&acc->set, "mail_notifications") && set_getstr(&acc->set, "mail_notifications_handle")) {
     90                imcb_add_buddy(ic, set_getstr(&acc->set, "mail_notifications_handle"), NULL);
     91        }
    8492}
    8593
  • protocols/msn/ns.c

    rd304445 rc720890  
    394394
    395395                                        if (inbox && folders) {
    396                                                 imcb_log(ic,
    397                                                          "INBOX contains %s new messages, plus %s messages in other folders.", inbox,
    398                                                          folders);
     396                                                imcb_notify_email(ic,
     397                                                        "INBOX contains %s new messages, plus %s messages in other folders.", inbox,
     398                                                        folders);
    399399                                        }
    400400
     
    408408
    409409                                        if (from && fromname) {
    410                                                 imcb_log(ic, "Received an e-mail message from %s <%s>.", fromname,
    411                                                          from);
     410                                                imcb_notify_email(ic, "Received an e-mail message from %s <%s>.", fromname, from);
    412411                                        }
    413412
  • protocols/purple/purple.c

    rd304445 rc720890  
    238238                s = set_add(&acc->set, "mail_notifications", "false", set_eval_bool, acc);
    239239                s->flags |= ACC_SET_OFFLINE_ONLY;
     240
     241                s = set_add(&acc->set, "mail_notifications_handle", NULL, NULL, acc);
     242                s->flags |= ACC_SET_OFFLINE_ONLY | SET_NULL_OK;
    240243        }
    241244
     
    332335
    333336        purple_account_set_enabled(pd->account, "BitlBee", TRUE);
     337
     338        if (set_getbool(&acc->set, "mail_notifications") && set_getstr(&acc->set, "mail_notifications_handle")) {
     339                imcb_add_buddy(ic, set_getstr(&acc->set, "mail_notifications_handle"), NULL);
     340        }
    334341}
    335342
     
    12551262        struct im_connection *ic = purple_ic_by_gc(gc);
    12561263
    1257         imcb_log(ic, "Received e-mail from %s for %s: %s <%s>", from, to, subject, url);
     1264        imcb_notify_email(ic, "Received e-mail from %s for %s: %s <%s>", from, to, subject, url);
    12581265
    12591266        return NULL;
  • protocols/yahoo/yahoo.c

    rd304445 rc720890  
    123123static void byahoo_init(account_t *acc)
    124124{
    125         set_add(&acc->set, "mail_notifications", "false", set_eval_bool, acc);
     125        set_t *s;
     126
     127        s = set_add(&acc->set, "mail_notifications", "false", set_eval_bool, acc);
     128        s->flags |= ACC_SET_OFFLINE_ONLY;
     129
     130        s = set_add(&acc->set, "mail_notifications_handle", NULL, NULL, acc);
     131        s->flags |= ACC_SET_OFFLINE_ONLY | SET_NULL_OK;
    126132
    127133        acc->flags |= ACC_FLAG_AWAY_MESSAGE | ACC_FLAG_STATUS_MESSAGE;
     
    145151        yd->y2_id = yahoo_init(acc->user, acc->pass);
    146152        yahoo_login(yd->y2_id, yd->current_status);
     153
     154        if (set_getbool(&acc->set, "mail_notifications") && set_getstr(&acc->set, "mail_notifications_handle")) {
     155                imcb_add_buddy(ic, set_getstr(&acc->set, "mail_notifications_handle"), NULL);
     156        }
    147157}
    148158
     
    950960        struct im_connection *ic = byahoo_get_ic_by_id(id);
    951961
    952         if (!set_getbool(&ic->acc->set, "mail_notifications")) {
    953                 ; /* The user doesn't care. */
    954         } else if (from && subj) {
    955                 imcb_log(ic, "Received e-mail message from %s with subject `%s'", from, subj);
     962        if (from && subj) {
     963                imcb_notify_email(ic, "Received e-mail message from %s with subject `%s'", from, subj);
    956964        } else if (cnt > 0) {
    957                 imcb_log(ic, "Received %d new e-mails", cnt);
     965                imcb_notify_email(ic, "Received %d new e-mails", cnt);
    958966        }
    959967}
Note: See TracChangeset for help on using the changeset viewer.