Changes in / [d832164:b75671d]


Ignore:
Files:
2 added
42 edited

Legend:

Unmodified
Added
Removed
  • .travis.yml

    rd832164 rb75671d  
    44 - ./configure
    55 - make check
    6  - dpkg-buildpackage -uc -us
     6 - BITLBEE_SKYPE=plugin dpkg-buildpackage -uc -us
    77
    88before_install:
    99 - sudo apt-get update -qq
    10  - sudo apt-get install --no-install-recommends -qq asciidoc xsltproc xmlto lynx check libevent-dev libpurple-dev check
     10 - sudo apt-get install --no-install-recommends -qq libevent-dev libpurple-dev check
    1111 - wget http://dump.dequis.org/indexed/bitlbee-travis-libs/libotr5{,-dev}_4.1.0-2~bpo70+1_amd64.deb
    1212 - sudo dpkg -i *.deb
  • Makefile

    rd832164 rb75671d  
    2020
    2121all: $(OUTFILE) $(OTR_PI) $(SKYPE_PI) doc systemd
    22 ifdef SKYPE_PI
    23         $(MAKE) -C protocols/skype doc
    24 endif
    2522
    2623doc:
  • bitlbee.h

    rd832164 rb75671d  
    3636
    3737#define PACKAGE "BitlBee"
    38 #define BITLBEE_VERSION "3.4"
     38#define BITLBEE_VERSION "3.4.1"
    3939#define VERSION BITLBEE_VERSION
    4040#define BITLBEE_VER(a, b, c) (((a) << 16) + ((b) << 8) + (c))
    41 #define BITLBEE_VERSION_CODE BITLBEE_VER(3, 4, 0)
     41#define BITLBEE_VERSION_CODE BITLBEE_VER(3, 4, 1)
    4242
    4343#define MAX_STRING 511
     
    9393#undef g_source_remove
    9494#define g_source_remove         __PLEASE_USE_B_EVENT_REMOVE__
    95 #undef g_source_remove_by_user_data
    96 #define g_source_remove_by_user_data    __PLEASE_USE_B_SOURCE_REMOVE_BY_USER_DATA__
    9795#undef g_main_run
    9896#define g_main_run              __PLEASE_USE_B_MAIN_RUN__
  • configure

    rd832164 rb75671d  
    6767get_version() {
    6868        REAL_BITLBEE_VERSION=$(grep '^#define BITLBEE_VERSION ' $srcdir/bitlbee.h | sed 's/.*\"\(.*\)\".*/\1/')
     69
     70        if [ -n "$BITLBEE_VERSION" ]; then
     71                # environment variable already set to something to spoof it
     72                # don't replace it with the git stuff
     73                return
     74        fi
     75
    6976        BITLBEE_VERSION=$REAL_BITLBEE_VERSION
    7077
     
    7380                branch=$(cd $srcdir; git rev-parse --abbrev-ref HEAD)
    7481
    75                 search="(.+)-([0-9]+)-(g[0-9a-f]+)"
     82                search='\(.*\)-\([0-9]*\)-\(g[0-9a-f]*\)'
    7683                replace="\1+$timestamp+$branch+\2-\3-git"
    7784
    78                 BITLBEE_VERSION=$(cd $srcdir; git describe --long --tags | sed -r "s/$search/$replace/")
    79 
    80                 unset timestamp branch search replace
     85                describe=$(cd $srcdir; git describe --long --tags 2>/dev/null)
     86                if [ $? -ne 0 ]; then
     87                        describe=${REAL_BITLBEE_VERSION}-0-g$(cd $srcdir; git rev-parse --short HEAD)
     88                fi
     89
     90                BITLBEE_VERSION=$(echo $describe | sed "s#$search#$replace#")
     91
     92                unset timestamp branch search replace describe
    8193        fi
    8294}
     
    675687fi
    676688
     689if [ -z "$PYTHON" ]; then
     690        PYTHON=python
     691fi
     692
    677693if [ "$doc" = "1" ]; then
    678         if [ ! -e doc/user-guide/help.txt ] && \
    679              ! type xmlto > /dev/null 2> /dev/null || \
    680              ! type xsltproc > /dev/null 2> /dev/null
    681         then
     694        # check this here just in case someone tries to install it in python2.4...
     695        if ! $PYTHON -m xml.etree.ElementTree > /dev/null 2>&1; then
    682696                echo
    683                 echo 'WARNING: Building from an unreleased source tree without prebuilt helpfile.'
    684                 echo 'Install xmlto and xsltproc if you want online help to work.'
    685         else
    686                 echo "DOC=1" >> Makefile.settings
    687         fi
    688 
    689         if [ "$skype" = "1" -o "$skype" = "plugin" ]; then
    690                 # skype also needs asciidoc
    691                 if ! type a2x > /dev/null 2> /dev/null; then
    692                         echo
    693                         echo 'WARNING: The skyped man page requires asciidoc. It will not be generated.'
    694                 else
    695                         echo "ASCIIDOC=1" >> Makefile.settings
    696                 fi
    697         fi
     697                echo 'ERROR: Python (>=2.5 or 3.x) is required to generate docs'
     698                echo "(Use the PYTHON environment variable if it's in a weird location)"
     699                exit 1
     700        fi
     701        echo "DOC=1" >> Makefile.settings
     702        echo "PYTHON=$PYTHON" >> Makefile.settings
    698703fi
    699704
  • debian/bitlbee-common.docs

    rd832164 rb75671d  
    1 doc/user-guide/user-guide.txt
    2 doc/user-guide/user-guide.html
    31doc/AUTHORS
    42doc/CREDITS
  • debian/control

    rd832164 rb75671d  
    55Uploaders: Jelmer Vernooij <jelmer@debian.org>
    66Standards-Version: 3.9.5
    7 Build-Depends: libglib2.0-dev (>= 2.4), libevent-dev, libgnutls28-dev | libgnutls-dev | gnutls-dev, po-debconf, libpurple-dev, libotr5-dev, debhelper (>= 6.0.7~), asciidoc
     7Build-Depends: libglib2.0-dev (>= 2.4), libevent-dev, libgnutls28-dev | libgnutls-dev | gnutls-dev, po-debconf, libpurple-dev, libotr5-dev, debhelper (>= 6.0.7~)
    88Homepage: http://www.bitlbee.org/
    99Vcs-Bzr: http://code.bitlbee.org/bitlbee/
  • doc/CHANGES

    rd832164 rb75671d  
    33
    44https://github.com/bitlbee/bitlbee/commits/master
     5
     6Version 3.4.1:
     7- msn:
     8  * Upgraded protocol to MSNP21, works again (dx)
     9  * Contact list management, groupchats and skype username logins won't work.
     10    Next release!
     11- jabber:
     12  * Add "hipchat" protocol, for smoother login. Takes the same username as
     13    the official client. Note that unlike the 'hip-cat' branch, this doesn't
     14    preload channels. https://wiki.bitlbee.org/HowtoHipchat for details (dx)
     15  * Fixed a bug when receiving topics set by people who left the channel (dx)
     16  * Create fake users instead of showing "unknown participant" errors (dx)
     17  * Gmail mail notifications support (Artem Savkov)
     18  * Lowering xmpp presence priority on away (Artem Savkov)
     19- twitter:
     20  * Show quoted tweets/RTs with comment inline (wilmer)
     21  * Added "url" command, can be used to quote tweets (wilmer)
     22  * Make replies to self work (wilmer)
     23- Building documentation is now done with a python script (both 2.x/3.x work)
     24  Asciidoc/xsltproc/xmlto are no longer build dependencies (dx)
     25
     26Finished 16 Jun 2015
    527
    628Version 3.4:
  • doc/Makefile

    rd832164 rb75671d  
    55
    66all:
    7         # Only build the docs if this is a git tree
    8         test ! '(' -d ../.git -o -d ../.bzr ')' || $(MAKE) -C user-guide
     7        $(MAKE) -C user-guide
    98
    109install:
  • doc/user-guide/Makefile

    rd832164 rb75671d  
    44endif
    55
    6 EXTRAPARANEWLINE = 1
    7 # EXTRAPARANEWLINE = 0
     6ifndef PYTHON
     7PYTHON = python
     8endif
    89
    9 all: user-guide.txt user-guide.html help.txt # user-guide.pdf user-guide.ps user-guide.rtf
     10all: help.txt
     11
     12user-guide: user-guide.txt user-guide.html # user-guide.pdf user-guide.ps user-guide.rtf
    1013
    1114%.tex: %.db.xml
     
    3235        xsltproc --xinclude --output $@ docbook.xsl $<
    3336
    34 help.txt: help.xml help.xsl commands.xml misc.xml quickstart.xml
    35         xsltproc --stringparam extraparanewline "$(EXTRAPARANEWLINE)" --xinclude help.xsl $< | perl -0077 -pe 's/\n\n%/\n%/s; s/_b_/\002/g;' > $@
     37help.txt: $(_SRCDIR_)help.xml $(_SRCDIR_)commands.xml $(_SRCDIR_)misc.xml $(_SRCDIR_)quickstart.xml
     38        $(PYTHON) $(_SRCDIR_)genhelp.py $< $@
    3639
    3740clean:
     
    4851        -rmdir $(DESTDIR)$(DATADIR)
    4952
    50 .PHONY: clean install uninstall
     53.PHONY: clean install uninstall user-guide
  • doc/user-guide/commands.xml

    rd832164 rb75671d  
    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>
  • doc/user-guide/misc.xml

    rd832164 rb75671d  
    433433</sect1>
    434434
     435<sect1 id="whatsnew030401">
     436<title>New stuff in BitlBee 3.4.1</title>
     437
     438<simplelist>
     439        <member><emphasis>msn:</emphasis> Upgraded protocol version to MSNP21, works again</member>
     440        <member><emphasis>jabber:</emphasis> Add "hipchat" protocol, for smoother login. Takes the same username as the official client. Note that unlike the 'hip-cat' branch, this doesn't preload channels. See the <emphasis>HowtoHipchat</emphasis> wiki page for details</member>
     441        <member><emphasis>jabber:</emphasis> Gmail notifications support</member>
     442        <member><emphasis>twitter:</emphasis> Show quoted tweets inline. Added "url" command, can be used to quote tweets.</member>
     443</simplelist>
     444
     445</sect1>
     446
    435447</chapter>
  • irc_im.c

    rd832164 rb75671d  
    5050
    5151        memset(nick, 0, MAX_NICK_LENGTH + 1);
    52         strcpy(nick, nick_get(bu));
     52        strncpy(nick, nick_get(bu), MAX_NICK_LENGTH);
    5353
    5454        bu->ui_data = iu = irc_user_new(irc, nick);
     
    723723                        g_free(channel);
    724724                        channel = s;
     725                } else {
     726                        g_free(s);
    725727                }
    726728        }
  • irc_send.c

    rd832164 rb75671d  
    175175
    176176        if (iu == irc->user) {
    177                 irc_write(irc, ":%s MODE %s +%s", irc->root->host, ic->name, ic->mode);
    178                 irc_send_names(ic);
    179177                if (ic->topic && *ic->topic) {
    180178                        irc_send_topic(ic, FALSE);
    181179                }
     180                irc_send_names(ic);
    182181        }
    183182}
  • lib/events_glib.c

    rd832164 rb75671d  
    8282        }
    8383
    84         event_debug("gaim_io_invoke( %d, %d, 0x%x )\n", g_io_channel_unix_get_fd(source), condition, data);
     84        event_debug("gaim_io_invoke( %d, %d, %p )\n", g_io_channel_unix_get_fd(source), condition, data);
    8585
    8686        st = closure->function(closure->data, g_io_channel_unix_get_fd(source), gaim_cond);
     
    101101static void gaim_io_destroy(gpointer data)
    102102{
    103         event_debug("gaim_io_destroy( 0x%x )\n", data);
     103        event_debug("gaim_io_destroy( 0%p )\n", data);
    104104        g_free(data);
    105105}
     
    127127                                 gaim_io_invoke, closure, gaim_io_destroy);
    128128
    129         event_debug("b_input_add( %d, %d, 0x%x, 0x%x ) = %d (%p)\n", source, condition, function, data, st, closure);
     129        event_debug("b_input_add( %d, %d, %p, %p ) = %d (%p)\n", source, condition, function, data, st, closure);
    130130
    131131        g_io_channel_unref(channel);
     
    140140        gint st = g_timeout_add(timeout, (GSourceFunc) func, data);
    141141
    142         event_debug("b_timeout_add( %d, %d, %d ) = %d\n", timeout, func, data, st);
     142        event_debug("b_timeout_add( %d, %p, %p ) = %d\n", timeout, func, data, st);
    143143
    144144        return st;
  • lib/misc.c

    rd832164 rb75671d  
    751751        return end - string;
    752752}
     753
     754/* Parses a guint64 from string, returns TRUE on success */
     755gboolean parse_int64(char *string, int base, guint64 *number)
     756{
     757        guint64 parsed;
     758        char *endptr;
     759
     760        errno = 0;
     761        parsed = g_ascii_strtoull(string, &endptr, base);
     762        if (errno || endptr == string || *endptr != '\0') {
     763                return FALSE;
     764        }
     765        *number = parsed;
     766        return TRUE;
     767}
     768
  • lib/misc.h

    rd832164 rb75671d  
    149149G_MODULE_EXPORT char *get_rfc822_header(const char *text, const char *header, int len);
    150150G_MODULE_EXPORT int truncate_utf8(char *string, int maxlen);
     151G_MODULE_EXPORT gboolean parse_int64(char *string, int base, guint64 *number);
    151152
    152153#endif
  • lib/oauth2.c

    rd832164 rb75671d  
    138138        struct oauth2_access_token_data *cb_data = req->data;
    139139        char *atoken = NULL, *rtoken = NULL, *error = NULL;
    140         char *content_type;
     140        char *content_type = NULL;
    141141
    142         if (getenv("BITLBEE_DEBUG") && req->reply_body) {
     142        if (req->status_code <= 0 && !req->reply_body) {
     143                cb_data->func(cb_data->data, NULL, NULL, req->status_string);
     144                g_free(cb_data);
     145                return;
     146        }
     147
     148        if (getenv("BITLBEE_DEBUG")) {
    143149                printf("%s\n", req->reply_body);
    144150        }
  • nick.c

    rd832164 rb75671d  
    186186                   LC_CTYPE being set to something other than C/POSIX. */
    187187                if (!(irc && irc->status & IRC_UTF8_NICKS)) {
    188                         part = asc = g_convert_with_fallback(part, -1, "ASCII//TRANSLIT",
    189                                                              "UTF-8", "", NULL, NULL, NULL);
     188                        asc = g_convert_with_fallback(part, -1, "ASCII//TRANSLIT", "UTF-8", "", NULL, NULL, NULL);
     189
     190                        if (!asc) {
     191                                /* If above failed, try again without //TRANSLIT.
     192                                   //TRANSLIT is a GNU iconv special and is not POSIX.
     193                                   Other platforms may not support it. */
     194                                asc = g_convert_with_fallback(part, -1, "ASCII", "UTF-8", "", NULL, NULL, NULL);
     195                        }
     196
     197                        part = asc;
    190198                }
    191199
     
    368376
    369377        if (tab['A'] == 0) {
     378                /* initialize table so nonchars are mapped to themselves */
     379                for (i = 0; i < sizeof(tab); i++) {
     380                        tab[i] = i;
     381                }
     382                /* replace uppercase chars with lowercase chars */
    370383                for (i = 0; nick_lc_chars[i]; i++) {
    371384                        tab[(int) nick_uc_chars[i]] = nick_lc_chars[i];
    372                         tab[(int) nick_lc_chars[i]] = nick_lc_chars[i];
    373385                }
    374386        }
  • otr.c

    rd832164 rb75671d  
    193193void show_general_otr_info(irc_t *irc);
    194194
    195 /* show info about a given OTR context */
    196 void show_otr_context_info(irc_t *irc, ConnContext *ctx);
     195/* show info about a given OTR context and subcontexts/instances. bestctx
     196   may be either NULL or preferred destination context (this is hilighted
     197   in the output as being the target for a message) */
     198void show_otr_context_info(irc_t *irc, ConnContext *ctx, ConnContext *bestctx);
    197199
    198200/* show the list of fingerprints associated with a given context */
     
    11021104                char *arg = g_strdup(args[1]);
    11031105                char *myhandle, *handle = NULL, *protocol;
    1104                 ConnContext *ctx;
     1106                ConnContext *bestctx = NULL, *ctx;
    11051107
    11061108                /* interpret arg as 'user/protocol/account' if possible */
     
    11351137                                return;
    11361138                        }
     1139                        /* This does no harm if it returns NULL */
     1140                        bestctx = otrl_context_find(irc->otr->us, u->bu->handle, u->bu->ic->acc->user,
     1141                                                    u->bu->ic->acc->prpl->name, OTRL_INSTAG_BEST, 0, NULL, NULL, NULL);
    11371142                }
    11381143
    11391144                /* show how we resolved the (nick) argument, if we did */
    11401145                if (handle != arg) {
    1141                         irc_rootmsg(irc, "%s is %s/%s; we are %s/%s to them", args[1],
    1142                                     ctx->username, ctx->protocol, ctx->accountname, ctx->protocol);
    1143                 }
    1144                 show_otr_context_info(irc, ctx);
     1146                        irc_rootmsg(irc, "%s:", args[1]);
     1147                        irc_rootmsg(irc, "  they are: %s/%s", ctx->username, ctx->protocol);
     1148                        irc_rootmsg(irc, "  we are: %s/%s", ctx->accountname, ctx->protocol);
     1149                }
     1150                show_otr_context_info(irc, ctx, bestctx);
    11451151                g_free(arg);
    11461152        }
     
    15491555        int count = 0;
    15501556
    1551         for (fp = &ctx->fingerprint_root; fp; fp = fp->next) {
     1557        /* Is this a subcontext? If so, only list the active fingerprint */
     1558        if (ctx->m_context != ctx) {
     1559                fp = ctx->active_fingerprint;
     1560        } else {
     1561                fp = &ctx->fingerprint_root;
     1562        }
     1563
     1564        while (fp) {
    15521565                if (!fp->fingerprint) {
     1566                        fp = fp->next;
    15531567                        continue;
    15541568                }
     
    15611575                }
    15621576                if (fp == ctx->active_fingerprint) {
    1563                         irc_rootmsg(irc, "    \x02%s (%s)\x02", human, trust);
     1577                        irc_rootmsg(irc, "      \x02%s (%s)\x02", human, trust);
    15641578                } else {
    1565                         irc_rootmsg(irc, "    %s (%s)", human, trust);
    1566                 }
     1579                        irc_rootmsg(irc, "      %s (%s)", human, trust);
     1580                }
     1581
     1582                /* Break if this is a subcontext - we only print active fp */
     1583                if (ctx->m_context != ctx) {
     1584                        break;
     1585                }
     1586                fp = fp->next;
    15671587        }
    15681588        if (count == 0) {
    1569                 irc_rootmsg(irc, "    (none)");
     1589                irc_rootmsg(irc, "      (none)");
    15701590        }
    15711591}
     
    17551775        /* list all contexts */
    17561776        /* XXX remove this, or split off as its own command */
    1757         /* XXX show instags? */
    17581777        irc_rootmsg(irc, "%s", "");
    17591778        irc_rootmsg(irc, "\x1f" "connection contexts:\x1f (bold=currently encrypted)");
    1760         for (ctx = irc->otr->us->context_root; ctx; ctx = ctx->next) { \
     1779
     1780        ctx = irc->otr->us->context_root;
     1781        while (ctx) {
     1782                ConnContext *subctx;
    17611783                irc_user_t *u;
    17621784                char *userstring;
     1785                char encrypted = 0;
    17631786
    17641787                u = peeruser(irc, ctx->username, ctx->protocol);
     
    17711794                }
    17721795
    1773                 if (ctx->msgstate == OTRL_MSGSTATE_ENCRYPTED) {
     1796                subctx = ctx;
     1797                while (subctx && subctx->m_context == ctx) {
     1798                        if (subctx->msgstate == OTRL_MSGSTATE_ENCRYPTED) {
     1799                                encrypted = 1;
     1800                        }
     1801                        subctx = subctx->next;
     1802                }
     1803
     1804                if(encrypted) {
    17741805                        irc_rootmsg(irc, "  \x02%s\x02", userstring);
    17751806                } else {
     
    17771808                }
    17781809
     1810                /* Skip subcontexts/instances from output */
     1811                ctx = subctx;
     1812
    17791813                g_free(userstring);
    17801814        }
     1815
    17811816        if (ctx == irc->otr->us->context_root) {
    17821817                irc_rootmsg(irc, "  (none)");
     
    17841819}
    17851820
    1786 void show_otr_context_info(irc_t *irc, ConnContext *ctx)
    1787 {
    1788         // XXX show all instags/subcontexts
    1789 
    1790         switch (ctx->otr_offer) {
    1791         case OFFER_NOT:
    1792                 irc_rootmsg(irc, "  otr offer status: none sent");
    1793                 break;
    1794         case OFFER_SENT:
    1795                 irc_rootmsg(irc, "  otr offer status: awaiting reply");
    1796                 break;
    1797         case OFFER_ACCEPTED:
    1798                 irc_rootmsg(irc, "  otr offer status: accepted our offer");
    1799                 break;
    1800         case OFFER_REJECTED:
    1801                 irc_rootmsg(irc, "  otr offer status: ignored our offer");
    1802                 break;
    1803         default:
    1804                 irc_rootmsg(irc, "  otr offer status: %d", ctx->otr_offer);
    1805         }
    1806 
    1807         switch (ctx->msgstate) {
    1808         case OTRL_MSGSTATE_PLAINTEXT:
    1809                 irc_rootmsg(irc, "  connection state: cleartext");
    1810                 break;
    1811         case OTRL_MSGSTATE_ENCRYPTED:
    1812                 irc_rootmsg(irc, "  connection state: encrypted (v%d)", ctx->protocol_version);
    1813                 break;
    1814         case OTRL_MSGSTATE_FINISHED:
    1815                 irc_rootmsg(irc, "  connection state: shut down");
    1816                 break;
    1817         default:
    1818                 irc_rootmsg(irc, "  connection state: %d", ctx->msgstate);
    1819         }
    1820 
    1821         irc_rootmsg(irc, "  fingerprints: (bold=active)");
    1822         show_fingerprints(irc, ctx);
     1821void show_otr_context_info(irc_t *irc, ConnContext *ctx, ConnContext *bestctx)
     1822{
     1823        ConnContext *subctx;
     1824        int instcount = 0;
     1825
     1826        subctx = ctx;
     1827        while (subctx && subctx->m_context == ctx) {
     1828                if (subctx->m_context == subctx) {
     1829                        if (subctx == bestctx) {
     1830                                irc_rootmsg(irc, "  \x02master context (target):\x02");
     1831                        } else {
     1832                                irc_rootmsg(irc, "  master context:");
     1833                        }
     1834                        irc_rootmsg(irc, "    known fingerprints (bold = active for v1 or v2):");
     1835                } else {
     1836                        if (subctx == bestctx) {
     1837                                irc_rootmsg(irc, "  \x02instance %d (target):\x02", instcount);
     1838                        } else {
     1839                                irc_rootmsg(irc, "  instance %d:", instcount);
     1840                        }
     1841                        irc_rootmsg(irc, "    active fingerprint:");
     1842                        instcount++;
     1843                }
     1844
     1845                show_fingerprints(irc, subctx);
     1846
     1847                switch (subctx->msgstate) {
     1848                case OTRL_MSGSTATE_PLAINTEXT:
     1849                        irc_rootmsg(irc, "    connection state: cleartext");
     1850                        break;
     1851                case OTRL_MSGSTATE_ENCRYPTED:
     1852                        irc_rootmsg(irc, "    connection state: encrypted (v%d)", subctx->protocol_version);
     1853                        break;
     1854                case OTRL_MSGSTATE_FINISHED:
     1855                        irc_rootmsg(irc, "    connection state: shut down");
     1856                        break;
     1857                default:
     1858                        irc_rootmsg(irc, "    connection state: %d", subctx->msgstate);
     1859                }
     1860
     1861                subctx = subctx->next;
     1862        }
    18231863}
    18241864
  • protocols/bee.h

    rd832164 rb75671d  
    156156G_MODULE_EXPORT void imcb_buddy_msg(struct im_connection *ic, const char *handle, const char *msg, guint32 flags,
    157157                                    time_t sent_at);
     158G_MODULE_EXPORT void imcb_notify_email(struct im_connection *ic, char *format, ...) G_GNUC_PRINTF(2, 3);
    158159
    159160/* bee_chat.c */
  • protocols/bee_user.c

    rd832164 rb75671d  
    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

    rd832164 rb75671d  
    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/iq.c

    rd832164 rb75671d  
    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

    rd832164 rb75671d  
    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);
     
    428446        }
    429447
    430         jabber_get_vcard(ic, bud ? bud->full_jid : who);
     448        jabber_get_vcard(ic, who);
    431449}
    432450
  • protocols/jabber/jabber.h

    rd832164 rb75671d  
    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 */
     
    312316void jabber_error_free(struct jabber_error *err);
    313317gboolean jabber_set_me(struct im_connection *ic, const char *me);
     318char *jabber_get_bare_jid(char *jid);
    314319
    315320extern const struct jabber_away_state jabber_away_state_list[];
  • protocols/jabber/jabber_util.c

    rd832164 rb75671d  
    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

    rd832164 rb75671d  
    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/gw.c

    rd832164 rb75671d  
    8787        gw->polling = FALSE;
    8888
     89        if (req->status_code != 200 || !req->reply_body) {
     90                gw->callback(gw->md, -1, B_EV_IO_READ);
     91                return;
     92        }
     93
    8994        if (getenv("BITLBEE_DEBUG")) {
    9095                fprintf(stderr, "\n\x1b[90mHTTP:%s\n", req->reply_body);
    9196                fprintf(stderr, "\n\x1b[97m\n");
    92         }
    93 
    94         if (req->status_code != 200) {
    95                 gw->callback(gw->md, -1, B_EV_IO_READ);
    96                 return;
    9797        }
    9898
     
    113113        if (req->body_size) {
    114114                g_byte_array_append(gw->in, (const guint8 *) req->reply_body, req->body_size);
    115                 gw->callback(gw->md, -1, B_EV_IO_READ);
     115
     116                if (!gw->callback(gw->md, -1, B_EV_IO_READ)) {
     117                        return;
     118                }
    116119        }
    117120
  • protocols/msn/msn.c

    rd832164 rb75671d  
    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
     
    144152{
    145153        struct bee_user *bu = bee_user_by_handle(ic->bee, ic, who);
    146 
    147 #ifdef DEBUG
    148         if (strcmp(who, "raw") == 0) {
    149                 msn_ns_write(ic, -1, "%s\r\n", message);
    150                 return 0;
    151         }
    152 #endif
    153 
    154         msn_ns_sendmessage(ic, bu, message);
    155         return(0);
     154        msn_ns_send_message(ic, bu, message);
     155        return 0;
    156156}
    157157
     
    277277                return 0;
    278278        } else if (typing & OPT_TYPING) {
    279                 return(msn_buddy_msg(ic, who, TYPING_NOTIFICATION_MESSAGE, 0));
     279                return msn_ns_send_typing(ic, bu);
    280280        } else {
    281281                return 1;
     
    338338
    339339        g_tree_remove(md->domaintree, bu->handle);
    340 }
    341 
    342 GList *msn_buddy_action_list(bee_user_t *bu)
    343 {
    344         static GList *ret = NULL;
    345 
    346         if (ret == NULL) {
    347                 static const struct buddy_action ba[2] = {
    348                         { "NUDGE", "Draw attention" },
    349                 };
    350 
    351                 ret = g_list_prepend(ret, (void *) ba + 0);
    352         }
    353 
    354         return ret;
    355 }
    356 
    357 void *msn_buddy_action(struct bee_user *bu, const char *action, char * const args[], void *data)
    358 {
    359         if (g_strcasecmp(action, "NUDGE") == 0) {
    360                 msn_buddy_msg(bu->ic, bu->handle, NUDGE_MESSAGE, 0);
    361         }
    362 
    363         return NULL;
    364340}
    365341
     
    392368        ret->buddy_data_add = msn_buddy_data_add;
    393369        ret->buddy_data_free = msn_buddy_data_free;
    394         ret->buddy_action_list = msn_buddy_action_list;
    395         ret->buddy_action = msn_buddy_action;
    396370
    397371        register_protocol(ret);
  • protocols/msn/msn.h

    rd832164 rb75671d  
    2626#ifndef _MSN_H
    2727#define _MSN_H
    28 
    29 /* Some hackish magicstrings to make special-purpose messages/switchboards.
    30  */
    31 #define TYPING_NOTIFICATION_MESSAGE "\r\r\rBEWARE, ME R TYPINK MESSAGE!!!!\r\r\r"
    32 #define NUDGE_MESSAGE "\r\r\rSHAKE THAT THING\r\r\r"
    33 #define GROUPCHAT_SWITCHBOARD_MESSAGE "\r\r\rME WANT TALK TO MANY PEOPLE\r\r\r"
    34 
    35 #ifdef DEBUG_MSN
    36 #define debug(text ...) imcb_log(ic, text);
    37 #else
    38 #define debug(text ...)
    39 #endif
    4028
    4129/* This should be MSN Messenger 7.0.0813
     
    7765#define MSN_MESSAGE_HEADERS MSN_BASE_HEADERS \
    7866        "Messaging: 2.0\r\n" \
    79         "Message-Type: Text\r\n" \
     67        "Message-Type: %s\r\n" \
    8068        "Content-Length: %zd\r\n" \
    8169        "Content-Type: text/plain; charset=UTF-8\r\n" \
     
    10391        "</user>"
    10492
    105 #define MSN_TYPING_HEADERS "MIME-Version: 1.0\r\n" \
    106         "Content-Type: text/x-msmsgscontrol\r\n" \
    107         "TypingUser: %s\r\n" \
    108         "\r\n\r\n"
    109 
    110 #define MSN_NUDGE_HEADERS "MIME-Version: 1.0\r\n" \
    111         "Content-Type: text/x-msnmsgr-datacast\r\n" \
    112         "\r\n" \
    113         "ID: 1\r\n" \
    114         "\r\n"
    115 
    11693#define PROFILE_URL "http://members.msn.com/"
    11794
     
    242219void msn_auth_got_contact_list(struct im_connection *ic);
    243220int msn_ns_finish_login(struct im_connection *ic);
    244 int msn_ns_sendmessage(struct im_connection *ic, struct bee_user *bu, const char *text);
     221int msn_ns_send_typing(struct im_connection *ic, struct bee_user *bu);
     222int msn_ns_send_message(struct im_connection *ic, struct bee_user *bu, const char *text);
    245223int msn_ns_command(struct msn_data *md, char **cmd, int num_parts);
    246224int msn_ns_message(struct msn_data *md, char *msg, int msglen, char **cmd, int num_parts);
  • protocols/msn/ns.c

    rd832164 rb75671d  
    181181                imcb_error(ic, "Error while reading from server");
    182182                imc_logout(ic, TRUE);
     183                g_free(bytes);
    183184                return FALSE;
    184185        }
     
    188189        g_free(bytes);
    189190
    190         /* Ignore ret == 0, it's already disconnected then. */
    191         msn_handler(md);
    192 
    193         return TRUE;
    194        
     191        return msn_handler(md);
    195192}
    196193
     
    397394
    398395                                        if (inbox && folders) {
    399                                                 imcb_log(ic,
    400                                                          "INBOX contains %s new messages, plus %s messages in other folders.", inbox,
    401                                                          folders);
     396                                                imcb_notify_email(ic,
     397                                                        "INBOX contains %s new messages, plus %s messages in other folders.", inbox,
     398                                                        folders);
    402399                                        }
    403400
     
    411408
    412409                                        if (from && fromname) {
    413                                                 imcb_log(ic, "Received an e-mail message from %s <%s>.", fromname,
    414                                                          from);
     410                                                imcb_notify_email(ic, "Received an e-mail message from %s <%s>.", fromname, from);
    415411                                        }
    416412
     
    420416                        } else if (g_strncasecmp(ct, "text/x-msmsgsactivemailnotification", 35) == 0) {
    421417                                /* Notification that a message has been read... Ignore it */
    422                         } else {
    423                                 debug("Can't handle %s packet from notification server", ct);
    424418                        }
    425419
     
    626620        char l[4];
    627621
    628         if ((bd->flags & 7) == 0 || (bd->flags & MSN_BUDDY_ADL_SYNCED)) {
     622        if ((bd->flags & (MSN_BUDDY_FL | MSN_BUDDY_AL)) == 0 || (bd->flags & MSN_BUDDY_ADL_SYNCED)) {
    629623                return FALSE;
    630624        }
     
    644638        }
    645639
    646         g_snprintf(l, sizeof(l), "%d", bd->flags & 7);
     640        g_snprintf(l, sizeof(l), "%d", bd->flags & (MSN_BUDDY_FL | MSN_BUDDY_AL));
    647641        c = xt_new_node("c", NULL, NULL);
    648642        xt_add_attr(c, "n", handle);
     
    697691                struct msn_buddy_data *bd = bu->data;
    698692
    699                 if (bu->ic != ic || (bd->flags & 7) == 0) {
     693                if (bu->ic != ic || (bd->flags & (MSN_BUDDY_FL | MSN_BUDDY_AL)) == 0) {
    700694                        continue;
    701695                }
     
    727721}
    728722
    729 // TODO: typing notifications, nudges lol, etc
    730 int msn_ns_sendmessage(struct im_connection *ic, bee_user_t *bu, const char *text)
     723static int msn_ns_send_sdg(struct im_connection *ic, bee_user_t *bu, const char *message_type, const char *text)
    731724{
    732725        struct msn_data *md = ic->proto_data;
     
    734727        char *buf;
    735728
    736         if (strncmp(text, "\r\r\r", 3) == 0) {
    737                 /* Err. Shouldn't happen but I guess it can. Don't send others
    738                    any of the "SHAKE THAT THING" messages. :-D */
    739                 return 1;
    740         }
    741 
    742         buf = g_strdup_printf(MSN_MESSAGE_HEADERS, bu->handle, ic->acc->user, md->uuid, strlen(text), text);
     729        buf = g_strdup_printf(MSN_MESSAGE_HEADERS, bu->handle, ic->acc->user, md->uuid, message_type, strlen(text), text);
    743730        retval = msn_ns_write(ic, -1, "SDG %d %zd\r\n%s", ++md->trId, strlen(buf), buf);
    744731        g_free(buf);
    745732        return retval;
    746733}
     734
     735int msn_ns_send_typing(struct im_connection *ic, bee_user_t *bu)
     736{
     737        return msn_ns_send_sdg(ic, bu, "Control/Typing", "");
     738}
     739
     740int msn_ns_send_message(struct im_connection *ic, bee_user_t *bu, const char *text)
     741{
     742        return msn_ns_send_sdg(ic, bu, "Text", text);
     743}
     744
  • protocols/oscar/oscar.c

    rd832164 rb75671d  
    456456                        b_event_remove(n->inpa);
    457457                }
     458                n->inpa = 0;
    458459                g_free(n->name);
    459460                g_free(n->show);
     
    481482        if (ic->inpa > 0) {
    482483                b_event_remove(ic->inpa);
     484                ic->inpa = 0;
    483485        }
    484486        if (odata->cnpa > 0) {
    485487                b_event_remove(odata->cnpa);
     488                odata->cnpa = 0;
    486489        }
    487490        if (odata->paspa > 0) {
    488491                b_event_remove(odata->paspa);
     492                odata->paspa = 0;
    489493        }
    490494        aim_session_kill(odata->sess);
     
    637641        aim_sendcookie(sess, bosconn, info->cookie);
    638642        b_event_remove(ic->inpa);
     643        ic->inpa = 0;
    639644
    640645        return 1;
     
    25862591        if (cc->inpa > 0) {
    25872592                b_event_remove(cc->inpa);
     2593                cc->inpa = 0;
    25882594        }
    25892595        aim_conn_kill(od->sess, &cc->conn);
  • protocols/oscar/ssi.c

    rd832164 rb75671d  
    6666                                newitem->gid += 0x0001;
    6767                                for (cur = *list, i = 0; ((cur) && (!i)); cur = cur->next) {
    68                                         if ((cur->gid == newitem->gid) && (cur->gid == newitem->gid)) {
     68                                        if ((cur->bid == newitem->bid) && (cur->gid == newitem->gid)) {
    6969                                                i = 1;
    7070                                        }
  • protocols/purple/purple.c

    rd832164 rb75671d  
    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
     
    337340
    338341        purple_account_set_enabled(pd->account, "BitlBee", TRUE);
     342
     343        if (set_getbool(&acc->set, "mail_notifications") && set_getstr(&acc->set, "mail_notifications_handle")) {
     344                imcb_add_buddy(ic, set_getstr(&acc->set, "mail_notifications_handle"), NULL);
     345        }
    339346}
    340347
     
    12601267        struct im_connection *ic = purple_ic_by_gc(gc);
    12611268
    1262         imcb_log(ic, "Received e-mail from %s for %s: %s <%s>", from, to, subject, url);
     1269        imcb_notify_email(ic, "Received e-mail from %s for %s: %s <%s>", from, to, subject, url);
    12631270
    12641271        return NULL;
  • protocols/skype/Makefile

    rd832164 rb75671d  
    77INSTALL = install
    88
    9 
    10 ifdef ASCIIDOC
    11 MANPAGES = skyped.1
    12 else
    13 MANPAGES =
    14 endif
    15 
    16 all: $(MANPAGES)
    17 
     9all:
    1810clean:
    19         rm -f $(MANPAGES)
    2011
    2112# take this from the kernel
     
    2617        ./test.py
    2718
    28 doc: $(MANPAGES)
    29 
    30 install-doc: doc
    31 ifdef ASCIIDOC
     19install-doc:
    3220        $(INSTALL) -d $(DESTDIR)$(MANDIR)/man1
    33         $(INSTALL) -m644 $(MANPAGES) $(DESTDIR)$(MANDIR)/man1
    34 endif
     21        $(INSTALL) -m644 $(_SRCDIR_)skyped.1 $(DESTDIR)$(MANDIR)/man1
    3522
    3623uninstall-doc:
     
    3825
    3926%.1: $(_SRCDIR_)%.txt $(_SRCDIR_)asciidoc.conf
    40         a2x --asciidoc-opts="-f $(_SRCDIR_)asciidoc.conf" -a bee_date=$(DATE) -f manpage -D . $<
     27        a2x --asciidoc-opts="-f $(_SRCDIR_)asciidoc.conf" -a bee_date=$(DATE) -f manpage $<
  • protocols/twitter/twitter.c

    rd832164 rb75671d  
    469469        g_regex_match(regex, msg, 0, &match_info);
    470470        while (g_match_info_matches(match_info)) {
    471                 gchar *url = g_match_info_fetch(match_info, 2);
     471                gchar *s, *url;
     472
     473                url = g_match_info_fetch(match_info, 2);
    472474                url_len_diff += target_len - g_utf8_strlen(url, -1);
     475
    473476                /* Add another character for https://t.co/... URLs */
    474                 if (g_match_info_fetch(match_info, 3) != NULL) {
     477                if ((s = g_match_info_fetch(match_info, 3))) {
    475478                        url_len_diff += 1;
     479                        g_free(s);
    476480                }
    477481                g_free(url);
     
    483487}
    484488
    485 static gboolean twitter_length_check(struct im_connection *ic, gchar * msg)
    486 {
    487         int max = set_getint(&ic->acc->set, "message_length"), len;
    488         int target_len = set_getint(&ic->acc->set, "target_url_length");
     489int twitter_message_len(gchar *msg, int target_len)
     490{
    489491        int url_len_diff = 0;
    490492
     
    493495        }
    494496
    495         if (max == 0 || (len = g_utf8_strlen(msg, -1) + url_len_diff) <= max) {
     497        return g_utf8_strlen(msg, -1) + url_len_diff;
     498}
     499
     500static gboolean twitter_length_check(struct im_connection *ic, gchar * msg)
     501{
     502        int max = set_getint(&ic->acc->set, "message_length");
     503        int target_len = set_getint(&ic->acc->set, "target_url_length");
     504        int len = twitter_message_len(msg, target_len);
     505
     506        if (max == 0 || len <= max) {
    496507                return TRUE;
    497508        }
     
    852863}
    853864
    854 /* Parses a decimal or hex tweet ID, returns TRUE on success */
    855 static gboolean twitter_parse_id(char *string, int base, guint64 *id)
    856 {
    857         guint64 parsed;
    858         char *endptr;
    859 
    860         errno = 0;
    861         parsed = g_ascii_strtoull(string, &endptr, base);
    862         if (errno || endptr == string || *endptr != '\0') {
    863                 return FALSE;
    864         }
    865         *id = parsed;
    866         return TRUE;
    867 }
    868 
    869865bee_user_t twitter_log_local_user;
    870866
     
    896892                        arg++;
    897893                }
    898                 if (twitter_parse_id(arg, 16, &id) && id < TWITTER_LOG_LENGTH) {
     894                if (parse_int64(arg, 16, &id) && id < TWITTER_LOG_LENGTH) {
    899895                        bu = td->log[id].bu;
    900896                        id = td->log[id].id;
    901                 } else if (twitter_parse_id(arg, 10, &id)) {
     897                } else if (parse_int64(arg, 10, &id)) {
    902898                        /* Allow normal tweet IDs as well; not a very useful
    903899                           feature but it's always been there. Just ignore
     
    10161012                        twitter_log(ic, "Tweet `%s' does not exist", cmd[1]);
    10171013                } else {
    1018                         /* More common link is twitter.com/$UID/status/$ID (and that's
    1019                          * what this will 302 to) but can't generate that since for RTs,
    1020                          * bu here points at the retweeter while id contains the id of
    1021                          * the original message. */
    1022                         twitter_log(ic, "https://twitter.com/statuses/%lld", id);
     1014                        twitter_status_show_url(ic, id);
    10231015                }
    10241016                goto eof;
  • protocols/twitter/twitter_lib.c

    rd832164 rb75671d  
    15781578        g_free(args[1]);
    15791579}
     1580
     1581static void twitter_http_status_show_url(struct http_request *req)
     1582{
     1583        struct im_connection *ic = req->data;
     1584        json_value *parsed, *id;
     1585        const char *name;
     1586
     1587        // Check if the connection is still active.
     1588        if (!g_slist_find(twitter_connections, ic)) {
     1589                return;
     1590        }
     1591
     1592        if (!(parsed = twitter_parse_response(ic, req))) {
     1593                return;
     1594        }
     1595
     1596        /* for the parson branch:
     1597        name = json_object_dotget_string(json_object(parsed), "user.screen_name");
     1598        id = json_object_get_integer(json_object(parsed), "id");
     1599        */
     1600
     1601        name = json_o_str(json_o_get(parsed, "user"), "screen_name");
     1602        id = json_o_get(parsed, "id");
     1603
     1604        if (name && id && id->type == json_integer) {
     1605                twitter_log(ic, "https://twitter.com/%s/status/%" G_GUINT64_FORMAT, name, id->u.integer);
     1606        } else {
     1607                twitter_log(ic, "Error: could not fetch tweet url.");
     1608        }
     1609
     1610        json_value_free(parsed);
     1611}
     1612
     1613void twitter_status_show_url(struct im_connection *ic, guint64 id)
     1614{
     1615        char *url = g_strdup_printf("%s%" G_GUINT64_FORMAT "%s", TWITTER_STATUS_SHOW_URL, id, ".json");
     1616        twitter_http(ic, url, twitter_http_status_show_url, ic, 0, NULL, 0);
     1617        g_free(url);
     1618}
  • protocols/twitter/twitter_lib.h

    rd832164 rb75671d  
    9696void twitter_report_spam(struct im_connection *ic, char *screen_name);
    9797void twitter_favourite_tweet(struct im_connection *ic, guint64 id);
     98void twitter_status_show_url(struct im_connection *ic, guint64 id);
    9899
    99100#endif //_TWITTER_LIB_H
  • protocols/yahoo/yahoo.c

    rd832164 rb75671d  
    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}
  • protocols/yahoo/yahoo2.h

    rd832164 rb75671d  
    3333#undef malloc
    3434#define malloc(x)             g_malloc(x)
    35 #undef calloc
    36 #define calloc(x, y)          g_calloc(x, y)
    3735#undef realloc
    3836#define realloc(x, y)         g_realloc(x, y)
  • sock.h

    rd832164 rb75671d  
    99#define sock_make_nonblocking(fd) fcntl(fd, F_SETFL, O_NONBLOCK)
    1010#define sock_make_blocking(fd) fcntl(fd, F_SETFL, 0)
    11 #define sockerr_again() (errno == EINPROGRESS || errno == EINTR)
     11#define sockerr_again() (errno == EINPROGRESS || errno == EINTR || errno == EAGAIN)
    1212void closesocket(int fd);
  • unix.c

    rd832164 rb75671d  
    212212                       argv[0], argv[0], argv[0], argv[0], argv[0]);
    213213        } else if (strcmp(argv[2], "enc") == 0) {
    214                 pass_len = arc_encode(argv[4], strlen(argv[4]), (unsigned char **) &pass_cr, argv[3], 12);
    215                 printf("%s\n", base64_encode(pass_cr, pass_len));
     214                char *encoded;
     215
     216                pass_len = arc_encode(argv[4], strlen(argv[4]), &pass_cr, argv[3], 12);
     217
     218                encoded = base64_encode(pass_cr, pass_len);
     219                printf("%s\n", encoded);
     220                g_free(encoded);
     221                g_free(pass_cr);
    216222        } else if (strcmp(argv[2], "dec") == 0) {
    217                 pass_len = base64_decode(argv[4], (unsigned char **) &pass_cr);
     223                pass_len = base64_decode(argv[4], &pass_cr);
    218224                arc_decode(pass_cr, pass_len, (char **) &pass_cl, argv[3]);
    219225                printf("%s\n", pass_cl);
     226
     227                g_free(pass_cr);
     228                g_free(pass_cl);
    220229        } else if (strcmp(argv[2], "hash") == 0) {
    221230                md5_byte_t pass_md5[21];
    222231                md5_state_t md5_state;
     232                char *encoded;
    223233
    224234                random_bytes(pass_md5 + 16, 5);
     
    228238                md5_finish(&md5_state, pass_md5);
    229239
    230                 printf("%s\n", base64_encode(pass_md5, 21));
     240                encoded = base64_encode(pass_md5, 21);
     241                printf("%s\n", encoded);
     242                g_free(encoded);
    231243        } else if (strcmp(argv[2], "unhash") == 0) {
    232244                printf("Hash %s submitted to a massive Beowulf cluster of\n"
Note: See TracChangeset for help on using the changeset viewer.