Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 138740 | Differences between
and this patch

Collapse All | Expand All

(-)centericq-4.21.0.orig/libmsn-0.1/msn/connection.cpp (-23 / +36 lines)
Lines 25-43 Link Here
25
#include <msn/util.h>
25
#include <msn/util.h>
26
#include <msn/passport.h>
26
#include <msn/passport.h>
27
#include <msn/externals.h>
27
#include <msn/externals.h>
28
#include <msn/notificationserver.h>
28
29
29
#ifndef WIN32
30
#ifndef WIN32
30
#include <sys/socket.h>
31
#include <unistd.h>
31
#include <unistd.h>
32
#include <sys/types.h>
33
#include <sys/time.h>
34
#include <sys/socket.h>
32
#else
35
#else
33
#include <winsock.h>
36
#include <winsock.h>
34
#include <io.h>
37
#include <io.h>
35
#endif
38
#endif
36
39
37
#include <stdlib.h>
40
#include <stdlib.h>
41
#include <stdio.h>
42
#include <cerrno>
38
#include <time.h>
43
#include <time.h>
39
#include <cassert>
44
#include <cassert>
40
#include <cerrno>
41
45
42
namespace MSN
46
namespace MSN
43
{
47
{
Lines 45-51 Link Here
45
    static std::vector<std::string> errors;
49
    static std::vector<std::string> errors;
46
50
47
    Connection::Connection() 
51
    Connection::Connection() 
48
        : sock(0), connected(false), trid(1), user_data(NULL)
52
        : sock(0), connected(false), trID(1), user_data(NULL)
49
    {
53
    {
50
        srand((unsigned int) time(NULL));
54
        srand((unsigned int) time(NULL));
51
55
Lines 112-126 Link Here
112
    
116
    
113
    void Connection::disconnect()
117
    void Connection::disconnect()
114
    {
118
    {
115
        ext::unregisterSocket(this->sock);
119
        this->myNotificationServer()->externalCallbacks.unregisterSocket(this->sock);
116
        ::close(this->sock);
120
        ::close(this->sock);
121
        this->sock = -1;
122
        this->writeBuffer.erase();
123
        this->readBuffer.erase();
124
        this->trID = 1;
117
    }
125
    }
118
    
126
    
119
    std::vector<std::string> Connection::getLine()
127
    std::vector<std::string> Connection::getLine()
120
    {
128
    {
121
        assert(this->isWholeLineAvailable());
129
        assert(this->isWholeLineAvailable());
122
        std::string s = this->readBuffer.substr(0, this->readBuffer.find("\r\n"));
130
        std::string s = this->readBuffer.substr(0, this->readBuffer.find("\r\n"));
123
        ext::log(0, (s + "\n").c_str());
131
        this->myNotificationServer()->externalCallbacks.log(0, (s + "\n").c_str());
124
        return splitString(s, " ");
132
        return splitString(s, " ");
125
    }
133
    }
126
    
134
    
Lines 131-137 Link Here
131
    
139
    
132
    void Connection::errorOnSocket(int errno_)
140
    void Connection::errorOnSocket(int errno_)
133
    {
141
    {
134
        ext::showError(this, strerror(errno_));
142
        this->myNotificationServer()->externalCallbacks.showError(this, strerror(errno_));
135
        this->disconnect();
143
        this->disconnect();
136
    }
144
    }
137
    
145
    
Lines 140-147 Link Here
140
        this->connected = true;
148
        this->connected = true;
141
        
149
        
142
        // We know that we are connected, so this will try writing to the network.
150
        // We know that we are connected, so this will try writing to the network.
143
        this->write(this->writeBuffer, 1);
151
        size_t writtenLength = this->write(this->writeBuffer, 1);
144
        this->writeBuffer = "";
152
        this->writeBuffer = this->writeBuffer.substr(writtenLength);
145
    }
153
    }
146
        
154
        
147
    size_t Connection::write(std::string s, bool log) throw (std::runtime_error)
155
    size_t Connection::write(std::string s, bool log) throw (std::runtime_error)
Lines 151-162 Link Here
151
        else
159
        else
152
        {
160
        {
153
            if (log)
161
            if (log)
154
                ext::log(1, s.c_str());
162
                this->myNotificationServer()->externalCallbacks.log(1, s.c_str());
155
            
163
            
156
            size_t written = 0;
164
            size_t written = 0;
157
            while (written < s.size())
165
            while (written < s.size())
158
            {
166
            {
159
                size_t newWritten = ::write(this->sock, s.substr(written).c_str(), (int) (s.size() - written));
167
                size_t newWritten = ::send(this->sock, s.substr(written).c_str(), (int) (s.size() - written), 0);
160
                if (newWritten <= 0)
168
                if (newWritten <= 0)
161
                {
169
                {
162
                    if (errno == EAGAIN)
170
                    if (errno == EAGAIN)
Lines 167-173 Link Here
167
                written += newWritten;
175
                written += newWritten;
168
            }
176
            }
169
            if (written != s.size())
177
            if (written != s.size())
170
                throw std::runtime_error(strerror(errno));
178
            {
179
                this->errorOnSocket(errno);
180
                return written;
181
            }
171
        }
182
        }
172
        return s.size();
183
        return s.size();
173
    }
184
    }
Lines 176-202 Link Here
176
    {
187
    {
177
        std::string s = ss.str();
188
        std::string s = ss.str();
178
        size_t result = write(s, log);
189
        size_t result = write(s, log);
179
        ss.clear();
180
        return result;        
190
        return result;        
181
    }
191
    }
182
        
192
        
183
    void Connection::dataArrivedOnSocket()
193
    void Connection::dataArrivedOnSocket()
184
    {
194
    {
185
        char tempReadBuffer[8192];
195
        char tempReadBuffer[8192];
186
        int amountRead = ::read(this->sock, &tempReadBuffer, 8192);
196
        int amountRead = ::recv(this->sock, &tempReadBuffer, 8192, 0);
187
        if (amountRead < 0)
197
        if (amountRead < 0)
188
        {
198
        {
199
            if (errno == EAGAIN)
200
                return;
201
            
189
            // We shouldn't get EAGAIN here because dataArrivedOnSocket
202
            // We shouldn't get EAGAIN here because dataArrivedOnSocket
190
            // is only called when select/poll etc has told us that
203
            // is only called when select/poll etc has told us that
191
            // the socket is readable.
204
            // the socket is readable.
192
            assert(errno != EAGAIN);
205
            // assert(errno != EAGAIN);
193
            
206
            
194
            ext::showError(this, strerror(errno));                
207
            this->myNotificationServer()->externalCallbacks.showError(this, strerror(errno));                
195
            this->disconnect();            
208
            this->disconnect();            
196
        }
209
        }
197
        else if (amountRead == 0)
210
        else if (amountRead == 0)
198
        {
211
        {
199
            ext::showError(this, "Connection closed by remote endpoint.");
212
            this->myNotificationServer()->externalCallbacks.showError(this, "Connection closed by remote endpoint.");
200
            this->disconnect();
213
            this->disconnect();
201
        }
214
        }
202
        else
215
        else
Lines 208-214 Link Here
208
            }
221
            }
209
            catch (std::exception & e)
222
            catch (std::exception & e)
210
            {
223
            {
211
                ext::showError(this, e.what());
224
                this->myNotificationServer()->externalCallbacks.showError(this, e.what());
212
            }
225
            }
213
        }
226
        }
214
    }
227
    }
Lines 244-250 Link Here
244
    {
257
    {
245
        Message msg = Message(body, mime);
258
        Message msg = Message(body, mime);
246
        
259
        
247
        ext::gotInstantMessage(static_cast<SwitchboardServerConnection *>(this),
260
        this->myNotificationServer()->externalCallbacks.gotInstantMessage(static_cast<SwitchboardServerConnection *>(this),
248
                               args[1], decodeURL(args[2]), &msg);
261
                               args[1], decodeURL(args[2]), &msg);
249
    }
262
    }
250
    
263
    
Lines 265-271 Link Here
265
        if (! unreadFolder.empty())
278
        if (! unreadFolder.empty())
266
            unreadFolderCount = decimalFromString(unreadFolder);
279
            unreadFolderCount = decimalFromString(unreadFolder);
267
        
280
        
268
        ext::gotInitialEmailNotification(this, unreadInboxCount, unreadFolderCount);
281
        this->myNotificationServer()->externalCallbacks.gotInitialEmailNotification(this, unreadInboxCount, unreadFolderCount);
269
    }
282
    }
270
283
271
    
284
    
Lines 277-283 Link Here
277
        std::string from = headers["From-Addr"];
290
        std::string from = headers["From-Addr"];
278
        std::string subject = headers["Subject"];
291
        std::string subject = headers["Subject"];
279
        
292
        
280
        ext::gotNewEmailNotification(this, from, subject);
293
        this->myNotificationServer()->externalCallbacks.gotNewEmailNotification(this, from, subject);
281
    }
294
    }
282
295
283
    
296
    
Lines 288-300 Link Here
288
301
289
    void Connection::message_typing_user(std::vector<std::string> & args, std::string mime, std::string body)
302
    void Connection::message_typing_user(std::vector<std::string> & args, std::string mime, std::string body)
290
    {
303
    {
291
        ext::buddyTyping(this, args[1], decodeURL(args[2]));        
304
        this->myNotificationServer()->externalCallbacks.buddyTyping(this, args[1], decodeURL(args[2]));        
292
    }   
305
    }   
293
    
306
    
294
    void Connection::showError(int errorCode)
307
    void Connection::showError(int errorCode)
295
    {
308
    {
296
        std::ostringstream buf_;
309
        std::ostringstream buf_;
297
        buf_ << "An error has occurred while communicating with the MSN Messenger server: " << errors[errorCode] << " (code " << errorCode << ")";
310
        buf_ << "Error code: " << errorCode << " (" << errors[errorCode] << ")";
298
        ext::showError(this, buf_.str());        
311
        this->myNotificationServer()->externalCallbacks.showError(this, buf_.str());        
299
    }
312
    }
300
}
313
}
(-)centericq-4.21.0.orig/libmsn-0.1/msn/connection.h (-1 / +4 lines)
Lines 35-40 Link Here
35
    class callback;
35
    class callback;
36
    class Message;
36
    class Message;
37
    class Passport;
37
    class Passport;
38
    class NotificationServerConnection;
38
    
39
    
39
    /** An abstract base class that represents a connection to another computer.
40
    /** An abstract base class that represents a connection to another computer.
40
     *
41
     *
Lines 68-74 Link Here
68
protected:
69
protected:
69
        /** The transaction ID of the next command to be sent.
70
        /** The transaction ID of the next command to be sent.
70
         */
71
         */
71
        int trid;
72
        int trID;
72
        
73
        
73
        std::string readBuffer;
74
        std::string readBuffer;
74
public: 
75
public: 
Lines 143-148 Link Here
143
        /** Is this Connection connected to a remote endpoint?
144
        /** Is this Connection connected to a remote endpoint?
144
         */
145
         */
145
        bool isConnected() { return this->connected; };
146
        bool isConnected() { return this->connected; };
147
        virtual NotificationServerConnection *myNotificationServer() = 0;        
148
146
protected:
149
protected:
147
         /** Process a @c <code>MSG</code> command.
150
         /** Process a @c <code>MSG</code> command.
148
          *
151
          *
(-)centericq-4.21.0.orig/libmsn-0.1/msn/errorcodes.h (-3 / +3 lines)
Lines 27-41 Link Here
27
#include <list>
27
#include <list>
28
#include <msn/switchboardserver.h>
28
#include <msn/switchboardserver.h>
29
29
30
/** \mainpage libmsn 3.1.1 Reference
30
/** \mainpage libmsn 3.2 Reference
31
 *
31
 *
32
 * <code>libmsn</code> is a C++ library for Microsoft's MSN Messenger service. It
32
 * <code>libmsn</code> is a C++ library for Microsoft's MSN Messenger service. It
33
 * provides a high-level interface that allows an application to access instant
33
 * provides a high-level interface that allows an application to access instant
34
 * messaging features with ease.  For more information, please visit the
34
 * messaging features with ease.  For more information, please visit the
35
 * <a href='http://libmsn.bluewire.org.nz'><code>libmsn</code></a> homepage.
35
 * <a href='http://libmsn.bdash.net.nz'><code>libmsn</code></a> homepage.
36
 *
36
 *
37
 * It is recommended that you read the
37
 * It is recommended that you read the
38
 * <a href='http://libmsn.bluewire.org.nz/overview.php'>library overview</a>
38
 * <a href='http://libmsn.bdash.net.nz/overview.php'>library overview</a>
39
 * before reading the reference documentation.  The library overview will
39
 * before reading the reference documentation.  The library overview will
40
 * familiarise you with the architecture and core data-types of <code>libmsn</code>,
40
 * familiarise you with the architecture and core data-types of <code>libmsn</code>,
41
 * and will make the reference documentation much more understandable.
41
 * and will make the reference documentation much more understandable.
(-)centericq-4.21.0.orig/libmsn-0.1/msn/externals.h (-38 / +39 lines)
Lines 29-99 Link Here
29
{
29
{
30
    class ListSyncInfo;
30
    class ListSyncInfo;
31
    
31
    
32
    namespace ext
32
    class Callbacks
33
    {
33
    {
34
        void registerSocket(int s, int read, int write);
34
    public:
35
        void unregisterSocket(int s);
35
        virtual void registerSocket(int s, int read, int write) = 0;
36
        virtual void unregisterSocket(int s) = 0;
36
        
37
        
37
        void showError(MSN::Connection * conn, std::string msg);
38
        virtual void showError(MSN::Connection * conn, std::string msg) = 0;
38
        
39
        
39
        void buddyChangedStatus(MSN::Connection * conn, MSN::Passport buddy, std::string friendlyname, MSN::BuddyStatus state);
40
        virtual void buddyChangedStatus(MSN::Connection * conn, MSN::Passport buddy, std::string friendlyname, MSN::BuddyStatus state) = 0;
40
        void buddyOffline(MSN::Connection * conn, MSN::Passport buddy);
41
        virtual void buddyOffline(MSN::Connection * conn, MSN::Passport buddy) = 0;
41
        
42
        
42
        void log(int writing, const char* buf);
43
        virtual void log(int writing, const char* buf) = 0;
43
        
44
        
44
        void gotFriendlyName(MSN::Connection * conn, std::string friendlyname);       
45
        virtual void gotFriendlyName(MSN::Connection * conn, std::string friendlyname) = 0;
45
        void gotBuddyListInfo(MSN::NotificationServerConnection * conn, MSN::ListSyncInfo * data);
46
        virtual void gotBuddyListInfo(MSN::NotificationServerConnection * conn, MSN::ListSyncInfo * data) = 0;
46
        void gotLatestListSerial(MSN::Connection * conn, int serial);
47
        virtual void gotLatestListSerial(MSN::Connection * conn, int serial) = 0;
47
        void gotGTC(MSN::Connection * conn, char c);        
48
        virtual void gotGTC(MSN::Connection * conn, char c) = 0;
48
        void gotBLP(MSN::Connection * conn, char c);
49
        virtual void gotBLP(MSN::Connection * conn, char c) = 0;
49
        
50
        
50
        void gotNewReverseListEntry(MSN::Connection * conn, MSN::Passport buddy, std::string friendlyname);
51
        virtual void gotNewReverseListEntry(MSN::Connection * conn, MSN::Passport buddy, std::string friendlyname) = 0;
51
        
52
        
52
        void addedListEntry(MSN::Connection * conn, std::string list, MSN::Passport buddy, int groupID);
53
        virtual void addedListEntry(MSN::Connection * conn, std::string list, MSN::Passport buddy, int groupID) = 0;
53
        
54
        
54
        void removedListEntry(MSN::Connection * conn, std::string list, MSN::Passport buddy, int groupID);
55
        virtual void removedListEntry(MSN::Connection * conn, std::string list, MSN::Passport buddy, int groupID) = 0;
55
        
56
        
56
        void addedGroup(MSN::Connection * conn, std::string groupName, int groupID);
57
        virtual void addedGroup(MSN::Connection * conn, std::string groupName, int groupID) = 0;
57
        void removedGroup(MSN::Connection * conn, int groupID);
58
        virtual void removedGroup(MSN::Connection * conn, int groupID) = 0;
58
        void renamedGroup(MSN::Connection * conn, int groupID, std::string newGroupName);
59
        virtual void renamedGroup(MSN::Connection * conn, int groupID, std::string newGroupName) = 0;
59
        
60
        
60
        void gotSwitchboard(MSN::SwitchboardServerConnection * conn, const void * tag);
61
        virtual void gotSwitchboard(MSN::SwitchboardServerConnection * conn, const void * tag) = 0;
61
        
62
        
62
        void buddyJoinedConversation(MSN::SwitchboardServerConnection * conn, MSN::Passport buddy, std::string friendlyname, int is_initial);
63
        virtual void buddyJoinedConversation(MSN::SwitchboardServerConnection * conn, MSN::Passport buddy, std::string friendlyname, int is_initial) = 0;
63
        
64
        
64
        void buddyLeftConversation(MSN::SwitchboardServerConnection * conn, MSN::Passport buddy);
65
        virtual void buddyLeftConversation(MSN::SwitchboardServerConnection * conn, MSN::Passport buddy) = 0;
65
        
66
        
66
        void gotInstantMessage(MSN::SwitchboardServerConnection * conn, MSN::Passport buddy, std::string friendlyname, MSN::Message * msg);
67
        virtual void gotInstantMessage(MSN::SwitchboardServerConnection * conn, MSN::Passport buddy, std::string friendlyname, MSN::Message * msg) = 0;
67
        
68
        
68
        void failedSendingMessage(MSN::Connection * conn);
69
        virtual void failedSendingMessage(MSN::Connection * conn) = 0;
69
        
70
        
70
        void buddyTyping(MSN::Connection * conn, MSN::Passport buddy, std::string friendlyname);
71
        virtual void buddyTyping(MSN::Connection * conn, MSN::Passport buddy, std::string friendlyname) = 0;
71
        
72
        
72
        void gotInitialEmailNotification(MSN::Connection * conn, int unread_inbox, int unread_folders);
73
        virtual void gotInitialEmailNotification(MSN::Connection * conn, int unread_inbox, int unread_folders) = 0;
73
        
74
        
74
        void gotNewEmailNotification(MSN::Connection * conn, std::string from, std::string subject);
75
        virtual void gotNewEmailNotification(MSN::Connection * conn, std::string from, std::string subject) = 0;
75
        
76
        
76
        void gotFileTransferInvitation(MSN::Connection * conn, MSN::Passport buddy, std::string friendlyname, MSN::FileTransferInvitation * inv);
77
        virtual void gotFileTransferInvitation(MSN::Connection * conn, MSN::Passport buddy, std::string friendlyname, MSN::FileTransferInvitation * inv) = 0;
77
        
78
        
78
        void fileTransferProgress(MSN::FileTransferInvitation * inv, std::string status, unsigned long recv, unsigned long total);
79
        virtual void fileTransferProgress(MSN::FileTransferInvitation * inv, std::string status, unsigned long recv, unsigned long total) = 0;
79
        
80
        
80
        void fileTransferFailed(MSN::FileTransferInvitation * inv, int error, std::string message);
81
        virtual void fileTransferFailed(MSN::FileTransferInvitation * inv, int error, std::string message) = 0;
81
        
82
        
82
        void fileTransferSucceeded(MSN::FileTransferInvitation * inv);
83
        virtual void fileTransferSucceeded(MSN::FileTransferInvitation * inv) = 0;
83
        
84
        
84
        void gotNewConnection(MSN::Connection * conn);
85
        virtual void gotNewConnection(MSN::Connection * conn) = 0;
85
        
86
        
86
        void closingConnection(MSN::Connection * conn);
87
        virtual void closingConnection(MSN::Connection * conn) = 0;
87
        
88
        
88
        void changedStatus(MSN::Connection * conn, MSN::BuddyStatus state);
89
        virtual void changedStatus(MSN::Connection * conn, MSN::BuddyStatus state) = 0;
89
        
90
        
90
        int connectToServer(std::string server, int port, bool *connected);
91
        virtual int connectToServer(std::string server, int port, bool *connected) = 0;
91
        
92
        
92
        int listenOnPort(int port);
93
        virtual int listenOnPort(int port) = 0;
93
        
94
        
94
        std::string getOurIP(void);
95
        virtual std::string getOurIP() = 0;
95
        
96
        
96
        std::string getSecureHTTPProxy(void);
97
        virtual std::string getSecureHTTPProxy() = 0;
97
    }
98
    };
98
}
99
}
99
#endif
100
#endif
(-)centericq-4.21.0.orig/libmsn-0.1/msn/filetransfer.cpp (-59 / +67 lines)
Lines 24-40 Link Here
24
#include <msn/message.h>
24
#include <msn/message.h>
25
#include <msn/errorcodes.h>
25
#include <msn/errorcodes.h>
26
#include <msn/externals.h>
26
#include <msn/externals.h>
27
#include <msn/notificationserver.h>
27
28
28
#ifndef WIN32
29
#ifndef WIN32
29
#include <unistd.h>
30
#include <unistd.h>
31
#include <time.h>
32
#include <sys/types.h>
33
#include <sys/time.h>
30
#include <sys/socket.h>
34
#include <sys/socket.h>
31
#else
35
#else
32
#include <winsock.h>
36
#include <winsock.h>
33
#include <io.h>
37
#include <io.h>
34
#endif
38
#endif
35
39
36
#include <cassert>
37
#include <cerrno>
40
#include <cerrno>
41
#include <cassert>
38
42
39
namespace MSN 
43
namespace MSN 
40
{
44
{
Lines 54-60 Link Here
54
    
58
    
55
    void FileTransferInvitation::invitationWasCanceled(const std::string & body)
59
    void FileTransferInvitation::invitationWasCanceled(const std::string & body)
56
    {
60
    {
57
        ext::fileTransferFailed(this, 0, "Cancelled by remote user");
61
        this->switchboardConnection->myNotificationServer()->externalCallbacks.fileTransferFailed(this, 0, "Cancelled by remote user");
58
        if (this->invitationWasSent())
62
        if (this->invitationWasSent())
59
        {
63
        {
60
            this->switchboardConnection->invitationsSent.remove(this);
64
            this->switchboardConnection->invitationsSent.remove(this);
Lines 75-102 Link Here
75
                                                                                 std::string(tmp), FileTransferConnection::MSNFTP_SEND, this);
79
                                                                                 std::string(tmp), FileTransferConnection::MSNFTP_SEND, this);
76
        FileTransferConnection * conn = new FileTransferConnection(auth);
80
        FileTransferConnection * conn = new FileTransferConnection(auth);
77
        
81
        
78
        ext::fileTransferProgress(this, "Sending IP address", 0, 0);
82
        this->switchboardConnection->myNotificationServer()->externalCallbacks.fileTransferProgress(this, "Sending IP address", 0, 0);
79
        
83
        
80
        while((conn->sock = ext::listenOnPort(port)) < 0)
84
        while((conn->sock = this->switchboardConnection->myNotificationServer()->externalCallbacks.listenOnPort(port)) < 0)
81
        {
85
        {
82
            port++;
86
            port++;
83
            if (port > 6911)
87
            if (port > 6911)
84
            {
88
            {
85
                ext::fileTransferFailed(this, errno, strerror(errno));
89
                this->switchboardConnection->myNotificationServer()->externalCallbacks.fileTransferFailed(this, errno, strerror(errno));
86
                this->switchboardConnection->invitationsSent.remove(this);
90
                this->switchboardConnection->invitationsSent.remove(this);
87
                conn->disconnect();
91
                conn->disconnect();
88
                return;
92
                return;
89
            }
93
            }
90
        }
94
        }
91
        
95
        
92
        ext::registerSocket(conn->sock, 1, 0);
96
        this->switchboardConnection->myNotificationServer()->externalCallbacks.registerSocket(conn->sock, 1, 0);
93
        
97
        
94
        this->switchboardConnection->addFileTransferConnection(conn);
98
        this->switchboardConnection->addFileTransferConnection(conn);
95
        
99
        
96
        std::ostringstream buf_;
100
        std::ostringstream buf_;
97
        buf_ << "Invitation-Command: ACCEPT\r\n";
101
        buf_ << "Invitation-Command: ACCEPT\r\n";
98
        buf_ << "Invitation-Cookie: " << this->cookie << "\r\n";
102
        buf_ << "Invitation-Cookie: " << this->cookie << "\r\n";
99
        buf_ << "IP-Address: " << ext::getOurIP() << "\r\n";
103
        buf_ << "IP-Address: " << this->switchboardConnection->myNotificationServer()->externalCallbacks.getOurIP() << "\r\n";
100
        buf_ << "Port: " << port << "\r\n";
104
        buf_ << "Port: " << port << "\r\n";
101
        buf_ << "AuthCookie: " << conn->auth.cookie << "\r\n";
105
        buf_ << "AuthCookie: " << conn->auth.cookie << "\r\n";
102
        buf_ << "Launch-Application: FALSE\r\n";
106
        buf_ << "Launch-Application: FALSE\r\n";
Lines 119-125 Link Here
119
        
123
        
120
        if (cookie.empty() || remote.empty() || port_c.empty())
124
        if (cookie.empty() || remote.empty() || port_c.empty())
121
        {
125
        {
122
            ext::fileTransferFailed(this, 0, "Missing parameters");
126
            this->switchboardConnection->myNotificationServer()->externalCallbacks.fileTransferFailed(this, 0, "Missing parameters");
123
            this->switchboardConnection->invitationsReceived.remove(this);
127
            this->switchboardConnection->invitationsReceived.remove(this);
124
            return;
128
            return;
125
        }
129
        }
Lines 132-154 Link Here
132
        
136
        
133
        std::ostringstream buf_;
137
        std::ostringstream buf_;
134
        buf_ << "Connecting to " << remote << ":" << port << "\n";
138
        buf_ << "Connecting to " << remote << ":" << port << "\n";
135
        ext::fileTransferProgress(this, buf_.str(), 0, 0);
139
        this->switchboardConnection->myNotificationServer()->externalCallbacks.fileTransferProgress(this, buf_.str(), 0, 0);
136
        
140
        
137
        conn->sock = ext::connectToServer(remote, port, &conn->connected);
141
        conn->sock = this->switchboardConnection->myNotificationServer()->externalCallbacks.connectToServer(remote, port, &conn->connected);
138
        
142
        
139
        if (conn->sock < 0)
143
        if (conn->sock < 0)
140
        {
144
        {
141
            ext::fileTransferFailed(this, errno, strerror(errno));
145
            this->switchboardConnection->myNotificationServer()->externalCallbacks.fileTransferFailed(this, errno, strerror(errno));
142
            this->switchboardConnection->invitationsReceived.remove(this);
146
            this->switchboardConnection->invitationsReceived.remove(this);
143
            return;
147
            return;
144
        }
148
        }
145
149
146
        if (! conn->isConnected())
150
        if (! conn->isConnected())
147
            ext::registerSocket(conn->sock, 0, 1);
151
            this->switchboardConnection->myNotificationServer()->externalCallbacks.registerSocket(conn->sock, 0, 1);
148
        else
152
        else
149
            ext::registerSocket(conn->sock, 1, 0);
153
            this->switchboardConnection->myNotificationServer()->externalCallbacks.registerSocket(conn->sock, 1, 0);
150
        
154
        
151
        ext::fileTransferProgress(this, "Connected", 0, 0);
155
        this->switchboardConnection->myNotificationServer()->externalCallbacks.fileTransferProgress(this, "Connected", 0, 0);
152
        this->switchboardConnection->addFileTransferConnection(conn);
156
        this->switchboardConnection->addFileTransferConnection(conn);
153
        
157
        
154
        conn->write("VER MSNFTP\r\n");
158
        conn->write("VER MSNFTP\r\n");
Lines 156-165 Link Here
156
    
160
    
157
    void FileTransferConnection::disconnect()
161
    void FileTransferConnection::disconnect()
158
    {
162
    {
163
        Connection::disconnect();
164
        
165
        if (this->auth.fd)
166
        {
167
            fclose(this->auth.fd);
168
            this->auth.fd = NULL;
169
        }
170
        
159
        this->auth.inv->switchboardConnection->removeFileTransferConnection(this);
171
        this->auth.inv->switchboardConnection->removeFileTransferConnection(this);
160
        delete this->auth.inv;
172
        delete this->auth.inv;
161
        this->auth.inv = NULL;
173
        this->auth.inv = NULL;
162
        Connection::disconnect();
163
    }
174
    }
164
    
175
    
165
    FileTransferConnection::~FileTransferConnection()
176
    FileTransferConnection::~FileTransferConnection()
Lines 170-177 Link Here
170
    void FileTransferConnection::socketConnectionCompleted()
181
    void FileTransferConnection::socketConnectionCompleted()
171
    {
182
    {
172
        Connection::socketConnectionCompleted();
183
        Connection::socketConnectionCompleted();
173
        ext::unregisterSocket(this->sock);
184
        this->myNotificationServer()->externalCallbacks.unregisterSocket(this->sock);
174
        ext::registerSocket(this->sock, 1, 0);
185
        this->myNotificationServer()->externalCallbacks.registerSocket(this->sock, 1, 0);
175
    }    
186
    }    
176
    
187
    
177
    void FileTransferConnection::socketIsWritable()
188
    void FileTransferConnection::socketIsWritable()
Lines 223-240 Link Here
223
        if ((s = accept(this->sock, NULL, NULL)) < 0)
234
        if ((s = accept(this->sock, NULL, NULL)) < 0)
224
        {
235
        {
225
            perror("Could not accept()\n");
236
            perror("Could not accept()\n");
226
            ext::fileTransferFailed(this->auth.inv, errno, strerror(errno));
237
            this->myNotificationServer()->externalCallbacks.fileTransferFailed(this->auth.inv, errno, strerror(errno));
227
            this->auth.inv->switchboardConnection->invitationsSent.remove(this->auth.inv);
238
            this->auth.inv->switchboardConnection->invitationsSent.remove(this->auth.inv);
228
            return;
239
            return;
229
        }
240
        }
230
        
241
        
231
        ext::unregisterSocket(this->sock);
242
        this->myNotificationServer()->externalCallbacks.unregisterSocket(this->sock);
232
        close(this->sock);
243
        close(this->sock);
233
        
244
        
234
        this->sock = s;
245
        this->sock = s;
235
        ext::registerSocket(this->sock, 1, 0);
246
        this->myNotificationServer()->externalCallbacks.registerSocket(this->sock, 1, 0);
236
        
247
        
237
        ext::fileTransferProgress(this->auth.inv, "Connected", 0, 0);
248
        this->myNotificationServer()->externalCallbacks.fileTransferProgress(this->auth.inv, "Connected", 0, 0);
238
        
249
        
239
        this->auth.connected = 1;
250
        this->auth.connected = 1;
240
        this->connected = true;        
251
        this->connected = true;        
Lines 250-263 Link Here
250
                
261
                
251
        if (args[0] == "VER")
262
        if (args[0] == "VER")
252
        {
263
        {
253
            this->write("VER MSNFTP\r\n");
264
            if (this->write("VER MSNFTP\r\n") != strlen("VER MSNFTP\r\n"))
254
            ext::fileTransferProgress(this->auth.inv, "Negotiating", 0, 0);
265
                return;
266
            this->myNotificationServer()->externalCallbacks.fileTransferProgress(this->auth.inv, "Negotiating", 0, 0);
255
        }
267
        }
256
        else if (args[0] == "USR")
268
        else if (args[0] == "USR")
257
        {
269
        {
258
            if (args[2] != this->auth.cookie)  // if they DIFFER
270
            if (args[2] != this->auth.cookie)  // if they DIFFER
259
            {
271
            {
260
                ext::fileTransferFailed(this->auth.inv, errno, strerror(errno));
272
                this->myNotificationServer()->externalCallbacks.fileTransferFailed(this->auth.inv, errno, strerror(errno));
261
                this->auth.inv->switchboardConnection->invitationsSent.remove(this->auth.inv);
273
                this->auth.inv->switchboardConnection->invitationsSent.remove(this->auth.inv);
262
                return;
274
                return;
263
            }
275
            }
Lines 272-287 Link Here
272
            if (this->auth.fd == NULL)
284
            if (this->auth.fd == NULL)
273
            {
285
            {
274
                perror("fopen() failed");
286
                perror("fopen() failed");
275
                ext::fileTransferFailed(this->auth.inv, errno, "Could not open file for reading");
287
                this->myNotificationServer()->externalCallbacks.fileTransferFailed(this->auth.inv, errno, "Could not open file for reading");
276
                this->auth.inv->switchboardConnection->invitationsSent.remove(this->auth.inv);
288
                this->auth.inv->switchboardConnection->invitationsSent.remove(this->auth.inv);
277
                return;
289
                return;
278
            }
290
            }
279
            
291
            
280
            // OK, now we lose control, but the next round of the polling loop will
292
            // OK, now we lose control, but the next round of the polling loop will
281
            // say that the socket is writable, and then the fun starts...
293
            // say that the socket is writable, and then the fun starts...
282
            ext::fileTransferProgress(this->auth.inv, "Sending data", 0, 0);
294
            this->myNotificationServer()->externalCallbacks.fileTransferProgress(this->auth.inv, "Sending data", 0, 0);
283
            ext::unregisterSocket(this->sock);
295
            this->myNotificationServer()->externalCallbacks.unregisterSocket(this->sock);
284
            ext::registerSocket(this->sock, 0, 1);                        
296
            this->myNotificationServer()->externalCallbacks.registerSocket(this->sock, 0, 1);                        
285
        }
297
        }
286
    }
298
    }
287
    
299
    
Lines 309-363 Link Here
309
            blockHeader[1] = (blockLength >> 0) & 0xff;
321
            blockHeader[1] = (blockLength >> 0) & 0xff;
310
            blockHeader[2] = (blockLength >> 8) & 0xff;
322
            blockHeader[2] = (blockLength >> 8) & 0xff;
311
            
323
            
312
            if (this->write(std::string((char *) &blockHeader[bytesWritten], 3 - bytesWritten), false) < 0)
324
            if (this->write(std::string((char *) &blockHeader[bytesWritten], 3 - bytesWritten), false) != 3)
313
            {
325
            {
314
                ext::fileTransferFailed(this->auth.inv, errno, strerror(errno));
326
                this->myNotificationServer()->externalCallbacks.fileTransferFailed(this->auth.inv, errno, strerror(errno));
315
                goto cleanup;
327
                goto cleanup;
316
            }
328
            }
317
            
329
            
318
            if (fread(readBuffer, sizeof(unsigned char), blockLength, this->auth.fd) < 0)
330
            if (fread(readBuffer, sizeof(unsigned char), blockLength, this->auth.fd) < 0)
319
            {
331
            {
320
                ext::fileTransferFailed(this->auth.inv, errno, strerror(errno));
332
                this->myNotificationServer()->externalCallbacks.fileTransferFailed(this->auth.inv, errno, strerror(errno));
321
                goto cleanup;
333
                goto cleanup;
322
            }
334
            }
323
            
335
            
324
            if (this->write(std::string((char *) readBuffer, blockLength), false) < 0)
336
            if ((blockLength = this->write(std::string((char *) readBuffer, blockLength), false)) < 0)
325
            {
337
            {
326
                ext::fileTransferFailed(this->auth.inv, errno, strerror(errno));
338
                this->myNotificationServer()->externalCallbacks.fileTransferFailed(this->auth.inv, errno, strerror(errno));
327
                goto cleanup;
339
                goto cleanup;
328
            }
340
            }
329
            this->auth.bytes_done += blockLength;
341
            this->auth.bytes_done += blockLength;
330
        }
342
        }
331
        free(readBuffer);
343
        free(readBuffer);
332
        ext::fileTransferProgress(this->auth.inv, "Sending file", this->auth.bytes_done, this->auth.inv->fileSize);
344
        this->myNotificationServer()->externalCallbacks.fileTransferProgress(this->auth.inv, "Sending file", this->auth.bytes_done, this->auth.inv->fileSize);
333
        return;
345
        return;
334
cleanup:
346
cleanup:
335
            ;
347
            ;
336
        this->auth.inv->switchboardConnection->invitationsSent.remove(this->auth.inv);
348
        this->auth.inv->switchboardConnection->invitationsSent.remove(this->auth.inv);
337
        if (readBuffer)
349
        if (readBuffer)
338
            free(readBuffer);
350
            free(readBuffer);
351
        if (this->auth.fd)
352
        {
353
            fclose(this->auth.fd);
354
            this->auth.fd = NULL;
355
        }
339
    }
356
    }
340
    
357
    
341
    void FileTransferConnection::handleSend_Bye()
358
    void FileTransferConnection::handleSend_Bye()
342
    {
359
    {
343
        if (! this->isWholeLineAvailable())
360
        this->myNotificationServer()->externalCallbacks.fileTransferSucceeded(this->auth.inv);
344
            return;
345
        
346
        std::vector<std::string> args;
347
        ext::fileTransferSucceeded(this->auth.inv);
348
        
361
        
349
        args = this->getLine();
362
        this->auth.inv->switchboardConnection->invitationsSent.remove(this->auth.inv);
350
        this->readBuffer = this->readBuffer.substr(this->readBuffer.find("\r\n") + 2);
363
        this->disconnect();
351
352
        if (args.size() > 0)
353
        {
354
            printf("%s", args[0].c_str());
355
            if (args.size() > 1)
356
                printf(" %s", args[1].c_str());
357
            printf("\n");
358
        }
359
        
360
        this->auth.inv->switchboardConnection->invitationsSent.remove(this->auth.inv);        
361
    }
364
    }
362
    
365
    
363
    
366
    
Lines 382-388 Link Here
382
            std::ostringstream buf_;
385
            std::ostringstream buf_;
383
            buf_ << "USR " << this->auth.username << " " << this->auth.cookie << "\r\n";
386
            buf_ << "USR " << this->auth.username << " " << this->auth.cookie << "\r\n";
384
            this->write(buf_);
387
            this->write(buf_);
385
            ext::fileTransferProgress(this->auth.inv, "Negotiating", 0, 0);
388
            this->myNotificationServer()->externalCallbacks.fileTransferProgress(this->auth.inv, "Negotiating", 0, 0);
386
            return;
389
            return;
387
        } 
390
        } 
388
        else if (args[0] == "FIL")
391
        else if (args[0] == "FIL")
Lines 396-402 Link Here
396
        return;
399
        return;
397
error:
400
error:
398
            ;
401
            ;
399
        ext::fileTransferFailed(this->auth.inv, errno, strerror(errno));
402
        this->myNotificationServer()->externalCallbacks.fileTransferFailed(this->auth.inv, errno, strerror(errno));
400
        this->switchboardConnection()->invitationsReceived.remove(this->auth.inv);
403
        this->switchboardConnection()->invitationsReceived.remove(this->auth.inv);
401
    }
404
    }
402
    
405
    
Lines 422-438 Link Here
422
                // Transfer completed block
425
                // Transfer completed block
423
                if (blockHeader[1] != 0 || blockHeader[2] != 0)
426
                if (blockHeader[1] != 0 || blockHeader[2] != 0)
424
                {
427
                {
425
                    ext::fileTransferFailed(this->auth.inv, 0, "Invalid block header.\n");
428
                    this->myNotificationServer()->externalCallbacks.fileTransferFailed(this->auth.inv, 0, "Invalid block header.\n");
426
                    goto cleanup;
429
                    goto cleanup;
427
                }
430
                }
428
                this->write("BYE 16777989\r\n");
431
                this->write("BYE 16777989\r\n");
429
                ext::fileTransferSucceeded(this->auth.inv);
432
                this->myNotificationServer()->externalCallbacks.fileTransferSucceeded(this->auth.inv);
430
                
433
                
431
                goto cleanup;
434
                goto cleanup;
432
            }
435
            }
433
            else if (blockHeader[0] != 0U)
436
            else if (blockHeader[0] != 0U)
434
            {
437
            {
435
                ext::fileTransferFailed(this->auth.inv, 0, "Invalid block header.");
438
                this->myNotificationServer()->externalCallbacks.fileTransferFailed(this->auth.inv, 0, "Invalid block header.");
436
                goto cleanup;
439
                goto cleanup;
437
            }
440
            }
438
            
441
            
Lines 440-446 Link Here
440
            blockLength = ((unsigned char) blockHeader[1]) | ((unsigned char) blockHeader[2]) << 8;
443
            blockLength = ((unsigned char) blockHeader[1]) | ((unsigned char) blockHeader[2]) << 8;
441
            if (blockLength > MAX_FTP_BLOCK_SIZE)
444
            if (blockLength > MAX_FTP_BLOCK_SIZE)
442
            {
445
            {
443
                ext::fileTransferFailed(this->auth.inv, 0, "Block size greater than largest expected block size.");
446
                this->myNotificationServer()->externalCallbacks.fileTransferFailed(this->auth.inv, 0, "Block size greater than largest expected block size.");
444
                goto cleanup;
447
                goto cleanup;
445
            }
448
            }
446
            
449
            
Lines 459-473 Link Here
459
                // that indicates success isnt sent...
462
                // that indicates success isnt sent...
460
                
463
                
461
                this->write("BYE 16777989\r\n");
464
                this->write("BYE 16777989\r\n");
462
                ext::fileTransferSucceeded(this->auth.inv);
465
                this->myNotificationServer()->externalCallbacks.fileTransferSucceeded(this->auth.inv);
463
                goto cleanup;
466
                goto cleanup;
464
            }
467
            }
465
            ext::fileTransferProgress(this->auth.inv, "Receiving file", this->auth.bytes_done, this->auth.inv->fileSize);
468
            this->myNotificationServer()->externalCallbacks.fileTransferProgress(this->auth.inv, "Receiving file", this->auth.bytes_done, this->auth.inv->fileSize);
466
        }
469
        }
467
        return;
470
        return;
468
cleanup:
471
cleanup:
469
            ;
472
            ;
470
        this->auth.inv->switchboardConnection->invitationsReceived.remove(this->auth.inv);
473
        this->auth.inv->switchboardConnection->invitationsReceived.remove(this->auth.inv);
474
        if (this->auth.fd)
475
        {
476
            fclose(this->auth.fd);
477
            this->auth.fd = NULL;
478
        }
471
    }
479
    }
472
    
480
    
473
    void FileTransferInvitation::rejectTransfer()
481
    void FileTransferInvitation::rejectTransfer()
(-)centericq-4.21.0.orig/libmsn-0.1/msn/filetransfer.h (-1 / +1 lines)
Lines 164-172 Link Here
164
        virtual void socketIsWritable();
164
        virtual void socketIsWritable();
165
        virtual void socketConnectionCompleted();
165
        virtual void socketConnectionCompleted();
166
        virtual void dataArrivedOnSocket();
166
        virtual void dataArrivedOnSocket();
167
        virtual NotificationServerConnection *myNotificationServer() { return switchboardConnection()->myNotificationServer(); };        
167
protected:
168
protected:
168
        virtual void handleIncomingData();
169
        virtual void handleIncomingData();
169
170
private:
170
private:
171
        void handleSend();
171
        void handleSend();
172
        void handleReceive();
172
        void handleReceive();
(-)centericq-4.21.0.orig/libmsn-0.1/msn/md5.h (+94 lines)
Line 0 Link Here
1
/*
2
  Copyright (C) 1999 Aladdin Enterprises.  All rights reserved.
3
4
  This software is provided 'as-is', without any express or implied
5
  warranty.  In no event will the authors be held liable for any damages
6
  arising from the use of this software.
7
8
  Permission is granted to anyone to use this software for any purpose,
9
  including commercial applications, and to alter it and redistribute it
10
  freely, subject to the following restrictions:
11
12
  1. The origin of this software must not be misrepresented; you must not
13
     claim that you wrote the original software. If you use this software
14
     in a product, an acknowledgment in the product documentation would be
15
     appreciated but is not required.
16
  2. Altered source versions must be plainly marked as such, and must not be
17
     misrepresented as being the original software.
18
  3. This notice may not be removed or altered from any source distribution.
19
20
  L. Peter Deutsch
21
  ghost@aladdin.com
22
23
 */
24
/*$Id: md5.h,v 1.3 2002/10/11 06:49:22 jtownsend Exp $ */
25
/*
26
  Independent implementation of MD5 (RFC 1321).
27
28
  This code implements the MD5 Algorithm defined in RFC 1321.
29
  It is derived directly from the text of the RFC and not from the
30
  reference implementation.
31
32
  The original and principal author of md5.h is L. Peter Deutsch
33
  <ghost@aladdin.com>.  Other authors are noted in the change history
34
  that follows (in reverse chronological order):
35
36
  1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
37
  1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
38
	added conditionalization for C++ compilation from Martin
39
	Purschke <purschke@bnl.gov>.
40
  1999-05-03 lpd Original version.
41
 */
42
43
#ifndef md5_INCLUDED
44
#  define md5_INCLUDED
45
46
/*
47
 * This code has some adaptations for the Ghostscript environment, but it
48
 * will compile and run correctly in any environment with 8-bit chars and
49
 * 32-bit ints.  Specifically, it assumes that if the following are
50
 * defined, they have the same meaning as in Ghostscript: P1, P2, P3,
51
 * ARCH_IS_BIG_ENDIAN.
52
 */
53
54
typedef unsigned char md5_byte_t; /* 8-bit byte */
55
typedef unsigned int md5_word_t; /* 32-bit word */
56
57
/* Define the state of the MD5 Algorithm. */
58
typedef struct md5_state_s {
59
    md5_word_t count[2];	/* message length in bits, lsw first */
60
    md5_word_t abcd[4];		/* digest buffer */
61
    md5_byte_t buf[64];		/* accumulate block */
62
} md5_state_t;
63
64
#ifdef __cplusplus
65
extern "C" 
66
{
67
#endif
68
69
/* Initialize the algorithm. */
70
#ifdef P1
71
void md5_init(P1(md5_state_t *pms));
72
#else
73
void md5_init(md5_state_t *pms);
74
#endif
75
76
/* Append a string to the message. */
77
#ifdef P3
78
void md5_append(P3(md5_state_t *pms, const md5_byte_t *data, int nbytes));
79
#else
80
void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes);
81
#endif
82
83
/* Finish the message and return the digest. */
84
#ifdef P2
85
void md5_finish(P2(md5_state_t *pms, md5_byte_t digest[16]));
86
#else
87
void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
88
#endif
89
90
#ifdef __cplusplus
91
}  /* end extern "C" */
92
#endif
93
94
#endif /* md5_INCLUDED */
(-)centericq-4.21.0.orig/libmsn-0.1/msn/msntest.cpp (+647 lines)
Line 0 Link Here
1
/*
2
 * msntest.cpp
3
 * libmsn
4
 *
5
 * Created by Meredydd Luff.
6
 * Copyright (c) 2004 Meredydd Luff. All rights reserved.
7
 *
8
 * This program is free software; you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License as published by
10
 * the Free Software Foundation; either version 2 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21
 */
22
23
#include <errno.h>
24
#include <sys/types.h>
25
#include <sys/socket.h>
26
#include <unistd.h>
27
#include <sys/stat.h>
28
#include <sys/poll.h>
29
#include <arpa/inet.h>
30
#include <fcntl.h>
31
#include <netinet/in.h>
32
#include <netdb.h>
33
#include <stdlib.h>
34
#include <string.h>
35
36
#include <msn/msn.h>
37
#include <string>
38
#include <iostream>
39
40
class Callbacks : public MSN::Callbacks
41
{
42
    
43
    virtual void registerSocket(int s, int read, int write);
44
    virtual void unregisterSocket(int s);
45
    
46
    virtual void showError(MSN::Connection * conn, std::string msg);
47
    
48
    virtual void buddyChangedStatus(MSN::Connection * conn, MSN::Passport buddy, std::string friendlyname, MSN::BuddyStatus state);
49
    virtual void buddyOffline(MSN::Connection * conn, MSN::Passport buddy);
50
    
51
    virtual void log(int writing, const char* buf);
52
    
53
    virtual void gotFriendlyName(MSN::Connection * conn, std::string friendlyname);
54
    virtual void gotBuddyListInfo(MSN::NotificationServerConnection * conn, MSN::ListSyncInfo * data);
55
    virtual void gotLatestListSerial(MSN::Connection * conn, int serial);
56
    virtual void gotGTC(MSN::Connection * conn, char c);
57
    virtual void gotBLP(MSN::Connection * conn, char c);
58
    
59
    virtual void gotNewReverseListEntry(MSN::Connection * conn, MSN::Passport buddy, std::string friendlyname);
60
    
61
    virtual void addedListEntry(MSN::Connection * conn, std::string list, MSN::Passport buddy, int groupID);
62
    
63
    virtual void removedListEntry(MSN::Connection * conn, std::string list, MSN::Passport buddy, int groupID);
64
    
65
    virtual void addedGroup(MSN::Connection * conn, std::string groupName, int groupID);
66
    virtual void removedGroup(MSN::Connection * conn, int groupID);
67
    virtual void renamedGroup(MSN::Connection * conn, int groupID, std::string newGroupName);
68
    
69
    virtual void gotSwitchboard(MSN::SwitchboardServerConnection * conn, const void * tag);
70
    
71
    virtual void buddyJoinedConversation(MSN::SwitchboardServerConnection * conn, MSN::Passport buddy, std::string friendlyname, int is_initial);
72
    
73
    virtual void buddyLeftConversation(MSN::SwitchboardServerConnection * conn, MSN::Passport buddy);
74
    
75
    virtual void gotInstantMessage(MSN::SwitchboardServerConnection * conn, MSN::Passport buddy, std::string friendlyname, MSN::Message * msg);
76
    
77
    virtual void failedSendingMessage(MSN::Connection * conn);
78
    
79
    virtual void buddyTyping(MSN::Connection * conn, MSN::Passport buddy, std::string friendlyname);
80
    
81
    virtual void gotInitialEmailNotification(MSN::Connection * conn, int unread_inbox, int unread_folders);
82
    
83
    virtual void gotNewEmailNotification(MSN::Connection * conn, std::string from, std::string subject);
84
    
85
    virtual void gotFileTransferInvitation(MSN::Connection * conn, MSN::Passport buddy, std::string friendlyname, MSN::FileTransferInvitation * inv);
86
    
87
    virtual void fileTransferProgress(MSN::FileTransferInvitation * inv, std::string status, unsigned long recv, unsigned long total);
88
    
89
    virtual void fileTransferFailed(MSN::FileTransferInvitation * inv, int error, std::string message);
90
    
91
    virtual void fileTransferSucceeded(MSN::FileTransferInvitation * inv);
92
    
93
    virtual void gotNewConnection(MSN::Connection * conn);
94
    
95
    virtual void closingConnection(MSN::Connection * conn);
96
    
97
    virtual void changedStatus(MSN::Connection * conn, MSN::BuddyStatus state);
98
    
99
    virtual int connectToServer(std::string server, int port, bool *connected);
100
    
101
    virtual int listenOnPort(int port);
102
    
103
    virtual std::string getOurIP();
104
    
105
    virtual std::string getSecureHTTPProxy();
106
};
107
108
struct pollfd mySockets[21];
109
110
void handle_command(MSN::NotificationServerConnection &);
111
int countsocks(void);
112
113
int main()
114
{
115
    for (int i = 1; i < 20; i++)
116
    {
117
        mySockets[i].fd = -1;
118
        mySockets[i].events = POLLIN; 
119
        mySockets[i].revents = 0;
120
    }
121
    
122
    mySockets[0].fd = 0;
123
    mySockets[0].events = POLLIN;
124
    mySockets[0].revents = 0;
125
    
126
    Callbacks cb;
127
    MSN::Passport uname;
128
    char *pass = NULL;
129
    while (1)
130
    {
131
        fprintf(stderr, "Enter your login name: ");
132
        fflush(stdout);
133
        try
134
        {
135
            std::cin >> uname;
136
            break;
137
        }
138
        catch (MSN::InvalidPassport & e)
139
        {
140
            std::cout << e.what() << std::endl;
141
        }
142
    }
143
    
144
    pass = getpass("Enter your password: ");
145
    
146
    fprintf(stderr, "Connecting to the MSN Messenger service...\n");
147
    
148
    MSN::NotificationServerConnection mainConnection(uname, pass, cb);
149
    mainConnection.connect("messenger.hotmail.com", 1863);
150
        
151
    fprintf(stderr, "> ");
152
    fflush(stderr);
153
    while (1)
154
    {
155
        poll(mySockets, 20, -1);
156
        for (int i = 1; i < 20; i++)
157
        {
158
            if (mySockets[i].fd == -1)
159
                break; 
160
            
161
            if (mySockets[i].revents & POLLHUP) 
162
	    {
163
                mySockets[i].revents = 0; 
164
		continue; 
165
	    }
166
            
167
            if (mySockets[i].revents & (POLLERR | POLLNVAL))
168
            {
169
                printf("Dud socket (%d)! Code %x (ERR=%x, INVAL=%x)\n", mySockets[i].fd, mySockets[i].revents, POLLERR, POLLNVAL);
170
                
171
                MSN::Connection *c;
172
                
173
                // Retrieve the connection associated with the
174
                // socket's file handle on which the event has
175
                // occurred.
176
                c = mainConnection.connectionWithSocket(mySockets[i].fd);
177
                
178
                // if this is a libmsn socket
179
                if (c != NULL)
180
                {
181
                    // Delete the connection.  This will cause the resources
182
                    // that are being used to be freed.
183
                    delete c;
184
                }
185
                
186
                mySockets[i].fd = -1;
187
                mySockets[i].revents = 0;
188
                continue;
189
            }
190
            
191
            if (mySockets[i].revents & (POLLIN | POLLOUT | POLLPRI))
192
            {
193
                MSN::Connection *c;
194
                
195
                // Retrieve the connection associated with the
196
                // socket's file handle on which the event has
197
                // occurred.
198
                c = mainConnection.connectionWithSocket(mySockets[i].fd);
199
                
200
                // if this is a libmsn socket
201
                if (c != NULL)
202
                {
203
                    // If we aren't yet connected, a socket event means that
204
                    // our connection attempt has completed.
205
                    if (c->isConnected() == false)
206
                        c->socketConnectionCompleted();
207
                    
208
                    // If this event is due to new data becoming available 
209
                    if (mySockets[i].revents & POLLIN)
210
                        c->dataArrivedOnSocket();
211
                    
212
                    // If this event is due to the socket becoming writable
213
                    if (mySockets[i].revents & POLLOUT)
214
                        c->socketIsWritable();
215
                }          
216
            }
217
            mySockets[i].revents = 0;
218
        }
219
220
        if (mySockets[0].revents & POLLIN)
221
        {
222
            handle_command(mainConnection);
223
            mySockets[0].revents = 0;
224
        }
225
    }
226
}
227
228
void handle_command(MSN::NotificationServerConnection & mainConnection)
229
{
230
    char command[40];
231
    
232
    if (scanf(" %s", command) == EOF)
233
    {
234
        printf("\n");
235
        exit(0);
236
    }
237
    
238
    if (!strcmp(command, "quit"))
239
    {
240
        exit(0);
241
    } else if (!strcmp(command, "msg")) {
242
        char rcpt[80];
243
        char msg[1024];
244
        
245
        scanf(" %s", rcpt);
246
        
247
        fgets(msg, 1024, stdin);
248
        
249
        msg[strlen(msg)-1] = '\0';
250
        
251
        const std::string rcpt_ = rcpt;
252
        const std::string msg_ = msg;
253
        const std::pair<std::string, std::string> *ctx = new std::pair<std::string, std::string>(rcpt_, msg_);
254
        mainConnection.requestSwitchboardConnection(ctx);
255
    } else if (!strcmp(command, "status")) {
256
        char state[10];
257
        
258
        scanf(" %s", state);
259
        
260
        mainConnection.setState(MSN::buddyStatusFromString(state));
261
    } else if (!strcmp(command, "friendlyname")) {
262
        char fn[256];
263
        
264
        fgets(fn, 256, stdin);
265
        fn[strlen(fn)-1] = '\0';
266
        
267
        mainConnection.setFriendlyName(fn);
268
    } else if (!strcmp(command, "add")) {
269
        char list[10];
270
        char user[128];
271
        
272
        scanf(" %s %s", list, user);
273
        
274
        mainConnection.addToList(list, user);
275
    } else if (!strcmp(command, "del")) {
276
        char list[10];
277
        char user[128];
278
        
279
        scanf(" %s %s", list, user);
280
        
281
        mainConnection.removeFromList(list, user);
282
    } else if (!strcmp(command, "reconnect")) {
283
        if (mainConnection.connectionState() != MSN::NotificationServerConnection::NS_DISCONNECTED)
284
            mainConnection.disconnect();
285
286
        mainConnection.connect("messenger.hotmail.com", 1863);
287
    } else if (!strcmp(command, "disconnect")) {
288
        mainConnection.disconnect();
289
    } else {
290
        fprintf(stderr, "\nBad command \"%s\"", command);
291
    }
292
    
293
    fprintf(stderr, "\n> ");
294
    fflush(stderr);
295
}
296
297
int countsocks(void)
298
{
299
    int retval = 0;
300
    
301
    for (int a = 0; a < 20; a++)
302
    {
303
        if (mySockets[a].fd == -1) 
304
            break; 
305
        
306
        retval++;
307
    }
308
    return retval;
309
}
310
311
void Callbacks::registerSocket(int s, int reading, int writing)
312
{
313
    for (int a = 1; a < 20; a++)
314
    {
315
        if (mySockets[a].fd == -1)
316
        {
317
            mySockets[a].events = 0;
318
            if (reading)
319
                mySockets[a].events |= POLLIN;  
320
            
321
            if (writing)
322
                mySockets[a].events |= POLLOUT;  
323
            
324
            mySockets[a].fd = s;
325
            return;
326
        }
327
    }
328
}
329
330
void Callbacks::unregisterSocket(int s)
331
{
332
    for (int a = 1; a < 20; a++)
333
    {
334
        if (mySockets[a].fd == s)
335
        {
336
            for (int b = a; b < 19; b++)
337
                mySockets[b].fd = mySockets[b + 1].fd;
338
            
339
            mySockets[19].fd = -1;
340
        }
341
    }
342
}
343
344
void Callbacks::gotFriendlyName(MSN::Connection * conn, std::string friendlyname)
345
{
346
    printf("Your friendlyname is now: %s\n", friendlyname.c_str());
347
}
348
349
void Callbacks::gotBuddyListInfo(MSN::NotificationServerConnection * conn, MSN::ListSyncInfo * info)
350
{
351
    int a;
352
    std::list<MSN::Buddy> & list = info->forwardList;
353
    std::list<MSN::Buddy>::iterator i;
354
        
355
    for (a = 0; a < 4; a++)
356
    {
357
        switch (a)
358
        {
359
            case 0:
360
            {
361
                list = info->forwardList; 
362
                printf("Forward list:\n"); 
363
                break; 
364
            }
365
                
366
            case 1:
367
            { 
368
                list = info->reverseList; 
369
                printf("Reverse list:\n"); 
370
                break; 
371
            }
372
                
373
            case 2:
374
            {
375
                list = info->allowList; 
376
                printf("Allow list:\n");
377
                break;
378
            }
379
                
380
            case 3:
381
            { 
382
                list = info->blockList; 
383
                printf("Block list:\n"); 
384
                break; 
385
            }
386
        }
387
        
388
        for (i = list.begin(); i != list.end(); i++)
389
        {
390
            printf("-  %s (%s)\n", (*i).friendlyName.c_str(), (*i).userName.c_str());
391
            std::list<MSN::Buddy::PhoneNumber>::iterator pns = (*i).phoneNumbers.begin();
392
            std::list<MSN::Group *>::iterator g = (*i).groups.begin();
393
            for (; g != (*i).groups.end(); g++)
394
            {
395
                printf("    G: %s\n", (*g)->name.c_str());
396
            }
397
            
398
            for (; pns != (*i).phoneNumbers.end(); pns++)
399
            {
400
                printf("    %s: %s (%d)\n", (*pns).title.c_str(), (*pns).number.c_str(), (*pns).enabled);
401
            }
402
        }
403
    }
404
    
405
    printf("Available Groups:\n");
406
    std::map<int, MSN::Group>::iterator g = info->groups.begin();
407
    for (; g != info->groups.end(); g++)
408
    {
409
        printf("    %d: %s\n", (*g).second.groupID, (*g).second.name.c_str());
410
    }
411
}
412
413
void Callbacks::gotLatestListSerial(MSN::Connection * conn, int serial)
414
{
415
    printf("The latest serial number is: %d\n", serial);
416
}
417
418
void Callbacks::gotGTC(MSN::Connection * conn, char c)
419
{
420
    printf("Your GTC value is now %c\n", c);
421
}
422
423
void Callbacks::gotBLP(MSN::Connection * conn, char c)
424
{
425
    printf("Your BLP value is now %cL\n", c);
426
}
427
428
void Callbacks::gotNewReverseListEntry(MSN::Connection * conn, MSN::Passport username, std::string friendlyname)
429
{
430
    printf("%s (%s) has added you to their contact list.\nYou might want to add them to your Allow or Block list\n", username.c_str(), friendlyname.c_str());
431
}
432
433
void Callbacks::addedListEntry(MSN::Connection * conn, std::string list, MSN::Passport username, int groupID)
434
{
435
    printf("%s is now on your %s, group %d\n", username.c_str(), list.c_str(), groupID);
436
}
437
438
void Callbacks::removedListEntry(MSN::Connection * conn, std::string list, MSN::Passport username, int groupID)
439
{
440
    printf("%s has been removed from your %s, group %d\n", username.c_str(), list.c_str(), groupID);
441
}
442
443
void Callbacks::addedGroup(MSN::Connection *conn, std::string groupName, int groupID)
444
{
445
    printf("A group named %s (%d) was added\n", groupName.c_str(), groupID);
446
}
447
448
void Callbacks::removedGroup(MSN::Connection *conn, int groupID)
449
{
450
    printf("A group with ID %d was removed\n", groupID);
451
}
452
453
void Callbacks::renamedGroup(MSN::Connection *conn, int groupID, std::string newGroupName)
454
{
455
    printf("A group with ID %d was renamed to %s\n", groupID, newGroupName.c_str());
456
}
457
458
void Callbacks::showError(MSN::Connection * conn, std::string msg)
459
{
460
    printf("MSN: Error: %s\n", msg.c_str());
461
}
462
463
void Callbacks::buddyChangedStatus(MSN::Connection * conn, MSN::Passport buddy, std::string friendlyname, MSN::BuddyStatus status)
464
{
465
    printf("%s (%s) is now %s\n", friendlyname.c_str(), buddy.c_str(), MSN::buddyStatusToString(status).c_str());
466
}
467
468
void Callbacks::buddyOffline(MSN::Connection *conn, MSN::Passport buddy)
469
{
470
    printf("%s is now offline\n", buddy.c_str());
471
}
472
473
void Callbacks::gotSwitchboard(MSN::SwitchboardServerConnection * conn, const void * tag)
474
{
475
    printf("Got switchboard connection\n");
476
    if (tag)
477
    {
478
        const std::pair<std::string, std::string> *ctx = static_cast<const std::pair<std::string, std::string> *>(tag);
479
        conn->inviteUser(ctx->first);
480
    }
481
}
482
483
void Callbacks::buddyJoinedConversation(MSN::SwitchboardServerConnection * conn, MSN::Passport username, std::string friendlyname, int is_initial)
484
{
485
    printf("%s (%s) is now in the session\n", friendlyname.c_str(), username.c_str());
486
    if (conn->auth.tag)
487
    {
488
        const std::pair<std::string, std::string> *ctx = static_cast<const std::pair<std::string, std::string> *>(conn->auth.tag);
489
        conn->sendMessage(ctx->second);
490
        delete ctx;
491
        conn->auth.tag = NULL;
492
    }
493
}
494
495
void Callbacks::buddyLeftConversation(MSN::SwitchboardServerConnection * conn, MSN::Passport username)
496
{
497
    printf("%s has now left the session\n", username.c_str());
498
}
499
500
void Callbacks::gotInstantMessage(MSN::SwitchboardServerConnection * conn, MSN::Passport username, std::string friendlyname, MSN::Message * msg)
501
{
502
    printf("--- Message from %s (%s) in font %s:\n%s\n", friendlyname.c_str(), username.c_str(), msg->getFontName().c_str(), msg->getBody().c_str());
503
}
504
505
void Callbacks::failedSendingMessage(MSN::Connection * conn)
506
{
507
    printf("**************************************************\n");
508
    printf("ERROR:  Your last message failed to send correctly\n");
509
    printf("**************************************************\n");
510
}
511
512
void Callbacks::buddyTyping(MSN::Connection * conn, MSN::Passport username, std::string friendlyname)
513
{
514
    printf("\t%s (%s) is typing...\n", friendlyname.c_str(), username.c_str());
515
}
516
517
void Callbacks::gotInitialEmailNotification(MSN::Connection * conn, int unread_inbox, int unread_folders)
518
{
519
    if (unread_inbox > 0) 
520
        printf("You have %d new messages in your Inbox\n", unread_inbox); 
521
    
522
    if (unread_folders > 0) 
523
        printf("You have %d new messages in other folders.\n", unread_folders); 
524
}
525
526
void Callbacks::gotNewEmailNotification(MSN::Connection * conn, std::string from, std::string subject)
527
{
528
    printf("New e-mail has arrived from %s.\nSubject: %s\n", from.c_str(), subject.c_str());
529
}
530
531
void Callbacks::gotFileTransferInvitation(MSN::Connection *conn, MSN::Passport username, std::string friendlyname, MSN::FileTransferInvitation * inv)
532
{
533
    printf("Got file transfer invitation from %s (%s)\n", friendlyname.c_str(), username.c_str());
534
    inv->acceptTransfer("tmp.out");
535
}
536
537
void Callbacks::fileTransferProgress(MSN::FileTransferInvitation * inv, std::string status, unsigned long sent, unsigned long total)
538
{
539
    printf("File transfer: %s\t(%lu/%lu bytes sent)\n", status.c_str(), sent, total);
540
}
541
542
void Callbacks::fileTransferFailed(MSN::FileTransferInvitation * inv, int error, std::string message)
543
{
544
    printf("File transfer failed: %s\n", message.c_str());
545
}
546
547
void Callbacks::fileTransferSucceeded(MSN::FileTransferInvitation * inv)
548
{
549
    printf("File transfer successfully completed\n");
550
}
551
552
void Callbacks::gotNewConnection(MSN::Connection * conn)
553
{
554
    if (dynamic_cast<MSN::NotificationServerConnection *>(conn))
555
        dynamic_cast<MSN::NotificationServerConnection *>(conn)->synchronizeLists();
556
}
557
558
void Callbacks::closingConnection(MSN::Connection * conn)
559
{
560
    printf("Closed connection with socket %d\n", conn->sock);
561
}
562
563
void Callbacks::changedStatus(MSN::Connection * conn, MSN::BuddyStatus state)
564
{
565
    printf("Your state is now: %s\n", MSN::buddyStatusToString(state).c_str());
566
}
567
568
int Callbacks::connectToServer(std::string hostname, int port, bool *connected)
569
{
570
    struct sockaddr_in sa;
571
    struct hostent     *hp;
572
    int s;
573
    
574
    if ((hp = gethostbyname(hostname.c_str())) == NULL) {
575
        errno = ECONNREFUSED;                       
576
        return -1;
577
    }
578
    
579
    memset(&sa,0,sizeof(sa));
580
    memcpy((char *)&sa.sin_addr,hp->h_addr,hp->h_length);     /* set address */
581
    sa.sin_family = hp->h_addrtype;
582
    sa.sin_port = htons((u_short)port);
583
    
584
    if ((s = socket(hp->h_addrtype,SOCK_STREAM,0)) < 0)     /* get socket */
585
        return -1;
586
587
    int oldfdArgs = fcntl(s, F_GETFL, 0);
588
    fcntl(s, F_SETFL, oldfdArgs | O_NONBLOCK);
589
    
590
    if (connect(s,(struct sockaddr *)&sa,sizeof sa) < 0)
591
    {
592
        if (errno != EINPROGRESS) 
593
        { 
594
            close(s);
595
            return -1;
596
        }
597
        *connected = false;
598
    }
599
    else
600
        *connected = true;
601
    
602
    return s;
603
}
604
605
int Callbacks::listenOnPort(int port)
606
{
607
    int s;
608
    struct sockaddr_in addr;
609
    
610
    if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
611
    {
612
        return -1;
613
    }
614
    
615
    memset(&addr, 0, sizeof(addr));
616
    addr.sin_family = AF_INET;
617
    addr.sin_port = htons(port);
618
    
619
    if (bind(s, (sockaddr *)(&addr), sizeof(addr)) < 0 || listen(s, 1) < 0)
620
    {
621
        close(s);
622
        return -1;
623
    }
624
    
625
    return s;
626
}
627
628
std::string Callbacks::getOurIP(void)
629
{
630
    struct hostent * hn;
631
    char buf2[1024];
632
    
633
    gethostname(buf2,1024);
634
    hn = gethostbyname(buf2);
635
    
636
    return inet_ntoa( *((struct in_addr*)hn->h_addr));
637
}
638
639
void Callbacks::log(int i, const char *s)
640
{
641
    
642
}
643
644
std::string Callbacks::getSecureHTTPProxy()
645
{
646
    return "";
647
}
(-)centericq-4.21.0.orig/libmsn-0.1/msn/notificationserver.cpp (-671 / +703 lines)
Lines 23-40 Link Here
23
#include <msn/notificationserver.h>
23
#include <msn/notificationserver.h>
24
#include <msn/errorcodes.h>
24
#include <msn/errorcodes.h>
25
#include <msn/externals.h>
25
#include <msn/externals.h>
26
#include <md5.h>
26
#include <msn/md5.h>
27
#include <msn/util.h>
27
#include <msn/util.h>
28
#include <curl/curl.h>
28
#include <curl/curl.h>
29
#include <algorithm>
29
#include <algorithm>
30
#include <cassert>
31
#include <cctype>
30
#include <cctype>
31
#include <cassert>
32
32
33
#ifndef WIN32
33
#ifndef WIN32
34
#include <unistd.h>
34
#include <unistd.h>
35
#else
35
#else
36
#include <io.h>
36
#include <io.h>
37
#define EINPROGRESS WSAEINPROGRESS
37
#endif
38
39
#include <stdio.h>
40
41
#ifndef curl_free
42
#define curl_free free
38
#endif
43
#endif
39
44
40
namespace MSN
45
namespace MSN
Lines 43-951 Link Here
43
    
48
    
44
    static size_t msn_handle_curl_write(void *ptr, size_t size, size_t nmemb, void  *stream);
49
    static size_t msn_handle_curl_write(void *ptr, size_t size, size_t nmemb, void  *stream);
45
    static size_t msn_handle_curl_header(void *ptr, size_t size, size_t nmemb, void *stream) ;    
50
    static size_t msn_handle_curl_header(void *ptr, size_t size, size_t nmemb, void *stream) ;    
46
	    
51
            
47
    NotificationServerConnection::NotificationServerConnection(NotificationServerConnection::AuthData & auth_)
52
    NotificationServerConnection::NotificationServerConnection(NotificationServerConnection::AuthData & auth_, Callbacks & cb_)
48
	: Connection(), auth(auth_), connectionStatus(NS_DISCONNECTED)
53
        : Connection(), auth(auth_), externalCallbacks(cb_), _connectionState(NS_DISCONNECTED)
49
    {
54
    {
50
	registerCommandHandlers();
55
        registerCommandHandlers();
51
    }
56
    }
52
    
57
    
53
    NotificationServerConnection::NotificationServerConnection(Passport username_, std::string password_) 
58
    NotificationServerConnection::NotificationServerConnection(Passport username_, std::string password_, Callbacks & cb_) 
54
	: Connection(), auth(username_, password_), connectionStatus(NS_DISCONNECTED)
59
        : Connection(), auth(username_, password_), externalCallbacks(cb_), _connectionState(NS_DISCONNECTED)
55
    {
60
    {
56
	registerCommandHandlers();
61
        registerCommandHandlers();
57
    }
62
    }
58
    
63
    
59
    NotificationServerConnection::NotificationServerConnection() : Connection(), auth(Passport(), ""), connectionStatus(NS_DISCONNECTED)
64
    NotificationServerConnection::NotificationServerConnection(Callbacks & cb_) : Connection(), auth(Passport(), ""), externalCallbacks(cb_), _connectionState(NS_DISCONNECTED)
60
    {
65
    {
61
	registerCommandHandlers();
66
        registerCommandHandlers();
62
    }
67
    }
63
    
68
    
64
    NotificationServerConnection::~NotificationServerConnection()
69
    NotificationServerConnection::~NotificationServerConnection()
65
    {
70
    {
66
	if (connectionStatus != NS_DISCONNECTED)
71
        if (this->connectionState() != NS_DISCONNECTED)
67
	    this->disconnect();
72
            this->disconnect();
68
    }
73
    }
69
    
74
    
70
    Connection *NotificationServerConnection::connectionWithSocket(int fd)
75
    Connection *NotificationServerConnection::connectionWithSocket(int fd)
71
    {
76
    {
72
	assert(connectionStatus != NS_DISCONNECTED);
77
        this->assertConnectionStateIsNot(NS_DISCONNECTED);
73
	std::list<SwitchboardServerConnection *> & list = _switchboardConnections;
78
        std::list<SwitchboardServerConnection *> & list = _switchboardConnections;
74
	std::list<SwitchboardServerConnection *>::iterator i = list.begin();
79
        std::list<SwitchboardServerConnection *>::iterator i = list.begin();
75
	
80
        
76
	if (this->sock == fd)
81
        if (this->sock == fd)
77
	    return this;
82
            return this;
78
	
83
        
79
	for (; i != list.end(); i++)
84
        for (; i != list.end(); i++)
80
	{
85
        {
81
	    Connection *c = (*i)->connectionWithSocket(fd);
86
            Connection *c = (*i)->connectionWithSocket(fd);
82
	    if (c)
87
            if (c)
83
		return c;
88
                return c;
84
	}
89
        }
85
	return NULL;
90
        return NULL;
86
    }
91
    }
87
    
92
    
88
    SwitchboardServerConnection *NotificationServerConnection::switchboardWithOnlyUser(Passport username)
93
    SwitchboardServerConnection *NotificationServerConnection::switchboardWithOnlyUser(Passport username)
89
    {
94
    {
90
	assert(connectionStatus >= NS_CONNECTED);
95
        if (this->connectionState() >= NS_CONNECTED)
91
	std::list<SwitchboardServerConnection *> & list = _switchboardConnections;
96
        {
92
	std::list<SwitchboardServerConnection *>::iterator i = list.begin();
97
            std::list<SwitchboardServerConnection *> & list = _switchboardConnections;
93
98
            std::list<SwitchboardServerConnection *>::iterator i = list.begin();
94
	for (; i != list.end(); i++)
99
            
95
	{
100
            for (; i != list.end(); i++)
96
	    if ((*i)->users.size() == 1 &&
101
            {
97
		*((*i)->users.begin()) == username)
102
                if ((*i)->users.size() == 1 &&
98
		return *i;
103
                    *((*i)->users.begin()) == username)
99
	}
104
                    return *i;
100
	return NULL;
105
            }
106
        }
107
        return NULL;
101
    }
108
    }
102
    
109
    
103
    const std::list<SwitchboardServerConnection *> & NotificationServerConnection::switchboardConnections()
110
    const std::list<SwitchboardServerConnection *> & NotificationServerConnection::switchboardConnections()
104
    {
111
    {
105
	assert(connectionStatus >= NS_CONNECTED);        
112
        this->assertConnectionStateIsAtLeast(NS_CONNECTED);
106
	return _switchboardConnections;
113
        return _switchboardConnections;
107
    }
114
    }
108
    
115
    
109
    void NotificationServerConnection::addSwitchboardConnection(SwitchboardServerConnection *c)
116
    void NotificationServerConnection::addSwitchboardConnection(SwitchboardServerConnection *c)
110
    {
117
    {
111
	assert(connectionStatus >= NS_CONNECTED);        
118
        this->assertConnectionStateIsAtLeast(NS_CONNECTED);        
112
	_switchboardConnections.push_back(c);
119
        _switchboardConnections.push_back(c);
113
    }
120
    }
114
121
115
    void NotificationServerConnection::removeSwitchboardConnection(SwitchboardServerConnection *c)
122
    void NotificationServerConnection::removeSwitchboardConnection(SwitchboardServerConnection *c)
116
    {
123
    {
117
	assert(connectionStatus >= NS_CONNECTED);        
124
        this->assertConnectionStateIsAtLeast(NS_CONNECTED);        
118
	_switchboardConnections.remove(c);
125
        _switchboardConnections.remove(c);
119
    }
126
    }
120
    
127
    
121
    void NotificationServerConnection::addCallback(NotificationServerCallback callback,
128
    void NotificationServerConnection::addCallback(NotificationServerCallback callback,
122
						   int trid, void *data)
129
                                                   int trid, void *data)
123
    {
130
    {
124
	assert(connectionStatus >= NS_CONNECTING);        
131
        this->assertConnectionStateIsAtLeast(NS_CONNECTING);        
125
	this->callbacks[trid] = std::make_pair(callback, data);
132
        this->callbacks[trid] = std::make_pair(callback, data);
126
    }
133
    }
127
    
134
    
128
    void NotificationServerConnection::removeCallback(int trid)
135
    void NotificationServerConnection::removeCallback(int trid)
129
    {
136
    {
130
	assert(connectionStatus >= NS_CONNECTING);        
137
        this->assertConnectionStateIsAtLeast(NS_CONNECTING);        
131
	this->callbacks.erase(trid);
138
        this->callbacks.erase(trid);
132
    }
139
    }
133
    
140
    
134
    void NotificationServerConnection::registerCommandHandlers()
141
    void NotificationServerConnection::registerCommandHandlers()
135
    {
142
    {
136
	if (commandHandlers.size() == 0)
143
        if (commandHandlers.size() == 0)
137
	{
144
        {
138
	    commandHandlers["OUT"] = &NotificationServerConnection::handle_OUT;
145
            commandHandlers["OUT"] = &NotificationServerConnection::handle_OUT;
139
	    commandHandlers["ADD"] = &NotificationServerConnection::handle_ADD;
146
            commandHandlers["ADD"] = &NotificationServerConnection::handle_ADD;
140
	    commandHandlers["REM"] = &NotificationServerConnection::handle_REM;
147
            commandHandlers["REM"] = &NotificationServerConnection::handle_REM;
141
	    commandHandlers["BLP"] = &NotificationServerConnection::handle_BLP;
148
            commandHandlers["BLP"] = &NotificationServerConnection::handle_BLP;
142
	    commandHandlers["GTC"] = &NotificationServerConnection::handle_GTC;
149
            commandHandlers["GTC"] = &NotificationServerConnection::handle_GTC;
143
	    commandHandlers["REA"] = &NotificationServerConnection::handle_REA;
150
            commandHandlers["REA"] = &NotificationServerConnection::handle_REA;
144
	    commandHandlers["CHG"] = &NotificationServerConnection::handle_CHG;
151
            commandHandlers["CHG"] = &NotificationServerConnection::handle_CHG;
145
	    commandHandlers["CHL"] = &NotificationServerConnection::handle_CHL;
152
            commandHandlers["CHL"] = &NotificationServerConnection::handle_CHL;
146
	    commandHandlers["ILN"] = &NotificationServerConnection::handle_ILN;
153
            commandHandlers["ILN"] = &NotificationServerConnection::handle_ILN;
147
	    commandHandlers["NLN"] = &NotificationServerConnection::handle_NLN;
154
            commandHandlers["NLN"] = &NotificationServerConnection::handle_NLN;
148
	    commandHandlers["FLN"] = &NotificationServerConnection::handle_FLN;
155
            commandHandlers["FLN"] = &NotificationServerConnection::handle_FLN;
149
	    commandHandlers["MSG"] = &NotificationServerConnection::handle_MSG;
156
            commandHandlers["MSG"] = &NotificationServerConnection::handle_MSG;
150
	    commandHandlers["ADG"] = &NotificationServerConnection::handle_ADG;
157
            commandHandlers["ADG"] = &NotificationServerConnection::handle_ADG;
151
	    commandHandlers["RMG"] = &NotificationServerConnection::handle_RMG;
158
            commandHandlers["RMG"] = &NotificationServerConnection::handle_RMG;
152
	    commandHandlers["REG"] = &NotificationServerConnection::handle_REG;
159
            commandHandlers["REG"] = &NotificationServerConnection::handle_REG;
153
	}
160
        }
154
    }
161
    }
155
    
162
    
156
    void NotificationServerConnection::dispatchCommand(std::vector<std::string> & args)
163
    void NotificationServerConnection::dispatchCommand(std::vector<std::string> & args)
157
    {
164
    {
158
	assert(connectionStatus >= NS_CONNECTED);        
165
        this->assertConnectionStateIsAtLeast(NS_CONNECTED);        
159
	std::map<std::string, void (NotificationServerConnection::*)(std::vector<std::string> &)>::iterator i = commandHandlers.find(args[0]);
166
        std::map<std::string, void (NotificationServerConnection::*)(std::vector<std::string> &)>::iterator i = commandHandlers.find(args[0]);
160
	if (i != commandHandlers.end())
167
        if (i != commandHandlers.end())
161
	    (this->*commandHandlers[args[0]])(args);
168
            (this->*commandHandlers[args[0]])(args);
162
    }
169
    }
163
    
170
    
164
    void NotificationServerConnection::handle_OUT(std::vector<std::string> & args)
171
    void NotificationServerConnection::handle_OUT(std::vector<std::string> & args)
165
    {
172
    {
166
	assert(connectionStatus >= NS_CONNECTED);        
173
        this->assertConnectionStateIsAtLeast(NS_CONNECTED);        
167
	if (args.size() > 1)
174
        if (args.size() > 1)
168
	{
175
        {
169
	    if (args[1] == "OTH")
176
            if (args[1] == "OTH")
170
	    {
177
            {
171
		ext::showError(this, "You have logged onto MSN twice at once. Your MSN session will now terminate.");
178
                this->myNotificationServer()->externalCallbacks.showError(this, "You have logged onto MSN twice at once. Your MSN session will now terminate.");
172
	    }
179
            }
173
	    else if (args[1] == "SSD")
180
            else if (args[1] == "SSD")
174
	    {
181
            {
175
		ext::showError(this, "This MSN server is going down for maintenance. Your MSN session will now terminate.");
182
                this->myNotificationServer()->externalCallbacks.showError(this, "This MSN server is going down for maintenance. Your MSN session will now terminate.");
176
	    } else {
183
            } else {
177
		ext::showError(this, (std::string("The MSN server has terminated the connection with an unknown reason code. Please report this code: ") + 
184
                this->myNotificationServer()->externalCallbacks.showError(this, (std::string("The MSN server has terminated the connection with an unknown reason code. Please report this code: ") + 
178
				      args[1]).c_str());
185
                                      args[1]).c_str());
179
	    }
186
            }
180
	}
187
        }
181
	this->disconnect();
188
        this->disconnect();
182
    }
189
    }
183
    
190
    
184
    void NotificationServerConnection::handle_ADD(std::vector<std::string> & args)
191
    void NotificationServerConnection::handle_ADD(std::vector<std::string> & args)
185
    {
192
    {
186
	assert(connectionStatus >= NS_CONNECTED);        
193
        this->assertConnectionStateIsAtLeast(NS_CONNECTED);        
187
	if (args[2] == "RL")
194
        if (args[2] == "RL")
188
	{
195
        {
189
	    ext::gotNewReverseListEntry(this, args[4], decodeURL(args[5]));
196
            this->myNotificationServer()->externalCallbacks.gotNewReverseListEntry(this, args[4], decodeURL(args[5]));
190
	}
197
        }
191
	else
198
        else
192
	{
199
        {
193
	    int groupID = -1;
200
            int groupID = -1;
194
	    if (args.size() > 5)
201
            if (args.size() > 5)
195
		groupID = decimalFromString(args[5]);
202
                groupID = decimalFromString(args[5]);
196
	    
203
            
197
	    ext::addedListEntry(this, args[2], args[4], groupID);
204
            this->myNotificationServer()->externalCallbacks.addedListEntry(this, args[2], args[4], groupID);
198
	}
205
        }
199
	ext::gotLatestListSerial(this, decimalFromString(args[3]));
206
        this->myNotificationServer()->externalCallbacks.gotLatestListSerial(this, decimalFromString(args[3]));
200
    }
207
    }
201
208
202
    void NotificationServerConnection::handle_REM(std::vector<std::string> & args)
209
    void NotificationServerConnection::handle_REM(std::vector<std::string> & args)
203
    {
210
    {
204
	assert(connectionStatus >= NS_CONNECTED);
211
        this->assertConnectionStateIsAtLeast(NS_CONNECTED);
205
	int groupID = -1;
212
        int groupID = -1;
206
	if (args.size() > 4)
213
        if (args.size() > 4)
207
	    groupID = decimalFromString(args[4]);
214
            groupID = decimalFromString(args[4]);
208
	
215
        
209
	ext::removedListEntry(this, args[2], args[4], groupID);
216
        this->myNotificationServer()->externalCallbacks.removedListEntry(this, args[2], args[4], groupID);
210
	ext::gotLatestListSerial(this, decimalFromString(args[3]));
217
        this->myNotificationServer()->externalCallbacks.gotLatestListSerial(this, decimalFromString(args[3]));
211
    }
218
    }
212
    
219
    
213
    void NotificationServerConnection::handle_BLP(std::vector<std::string> & args)
220
    void NotificationServerConnection::handle_BLP(std::vector<std::string> & args)
214
    {
221
    {
215
	assert(connectionStatus >= NS_CONNECTED);
222
        this->assertConnectionStateIsAtLeast(NS_CONNECTED);
216
	ext::gotBLP(this, args[3][0]);
223
        this->myNotificationServer()->externalCallbacks.gotBLP(this, args[3][0]);
217
	ext::gotLatestListSerial(this, decimalFromString(args[3]));
224
        this->myNotificationServer()->externalCallbacks.gotLatestListSerial(this, decimalFromString(args[3]));
218
    }
225
    }
219
226
220
    void NotificationServerConnection::handle_GTC(std::vector<std::string> & args)
227
    void NotificationServerConnection::handle_GTC(std::vector<std::string> & args)
221
    {
228
    {
222
	assert(connectionStatus >= NS_CONNECTED);
229
        this->assertConnectionStateIsAtLeast(NS_CONNECTED);
223
	ext::gotGTC(this, args[3][0]);
230
        this->myNotificationServer()->externalCallbacks.gotGTC(this, args[3][0]);
224
	ext::gotLatestListSerial(this, decimalFromString(args[3]));
231
        this->myNotificationServer()->externalCallbacks.gotLatestListSerial(this, decimalFromString(args[3]));
225
    }
232
    }
226
    
233
    
227
    void NotificationServerConnection::handle_REA(std::vector<std::string> & args)
234
    void NotificationServerConnection::handle_REA(std::vector<std::string> & args)
228
    {
235
    {
229
	assert(connectionStatus >= NS_CONNECTED);
236
        this->assertConnectionStateIsAtLeast(NS_CONNECTED);
230
	ext::gotFriendlyName(this, decodeURL(args[4]));
237
        this->myNotificationServer()->externalCallbacks.gotFriendlyName(this, decodeURL(args[4]));
231
	ext::gotLatestListSerial(this, decimalFromString(args[2]));        
238
        this->myNotificationServer()->externalCallbacks.gotLatestListSerial(this, decimalFromString(args[2]));        
232
    }
239
    }
233
    
240
    
234
    void NotificationServerConnection::handle_CHG(std::vector<std::string> & args)
241
    void NotificationServerConnection::handle_CHG(std::vector<std::string> & args)
235
    {
242
    {
236
	assert(connectionStatus >= NS_CONNECTED);
243
        this->assertConnectionStateIsAtLeast(NS_CONNECTED);
237
	ext::changedStatus(this, buddyStatusFromString(args[2]));
244
        this->myNotificationServer()->externalCallbacks.changedStatus(this, buddyStatusFromString(args[2]));
238
    }
245
    }
239
    
246
    
240
    void NotificationServerConnection::handle_CHL(std::vector<std::string> & args)
247
    void NotificationServerConnection::handle_CHL(std::vector<std::string> & args)
241
    {
248
    {
242
	assert(connectionStatus >= NS_CONNECTED);
249
        this->assertConnectionStateIsAtLeast(NS_CONNECTED);
243
	md5_state_t state;
250
        md5_state_t state;
244
	md5_byte_t digest[16];
251
        md5_byte_t digest[16];
245
	int a;
252
        int a;
246
	
253
        
247
	md5_init(&state);
254
        md5_init(&state);
248
	md5_append(&state, (md5_byte_t *)(args[2].c_str()), (int) args[2].size());
255
        md5_append(&state, (md5_byte_t *)(args[2].c_str()), (int) args[2].size());
249
	md5_append(&state, (md5_byte_t *)"VT6PX?UQTM4WM%YR", 16);
256
        md5_append(&state, (md5_byte_t *)"VT6PX?UQTM4WM%YR", 16);
250
	md5_finish(&state, digest);
257
        md5_finish(&state, digest);
251
	
258
        
252
	std::ostringstream buf_;
259
        std::ostringstream buf_;
253
	buf_ << "QRY " << trid++ << " PROD0038W!61ZTF9 32\r\n";
260
        buf_ << "QRY " << this->trID++ << " PROD0038W!61ZTF9 32\r\n";
254
	write(buf_);
261
        if (write(buf_) != buf_.str().size())
255
	
262
            return;
256
	
263
        
257
	char hexdigest[3];
264
        
258
	for (a = 0; a < 16; a++)
265
        char hexdigest[3];
259
	{
266
        for (a = 0; a < 16; a++)
260
	    sprintf(hexdigest, "%02x", digest[a]);
267
        {
261
	    write(std::string(hexdigest, 2), false);
268
            sprintf(hexdigest, "%02x", digest[a]);
262
	}
269
            write(std::string(hexdigest, 2), false);
270
        }
263
    }
271
    }
264
    
272
    
265
    void NotificationServerConnection::handle_ILN(std::vector<std::string> & args)
273
    void NotificationServerConnection::handle_ILN(std::vector<std::string> & args)
266
    {
274
    {
267
	assert(connectionStatus == NS_CONNECTED);
275
        this->assertConnectionStateIs(NS_CONNECTED);
268
	ext::buddyChangedStatus(this, args[3], decodeURL(args[4]), buddyStatusFromString(args[2]));
276
        this->myNotificationServer()->externalCallbacks.buddyChangedStatus(this, args[3], decodeURL(args[4]), buddyStatusFromString(args[2]));
269
    }
277
    }
270
    
278
    
271
    void NotificationServerConnection::handle_NLN(std::vector<std::string> & args)
279
    void NotificationServerConnection::handle_NLN(std::vector<std::string> & args)
272
    {
280
    {
273
	assert(connectionStatus >= NS_CONNECTED);
281
        this->assertConnectionStateIsAtLeast(NS_CONNECTED);
274
	ext::buddyChangedStatus(this, args[2], decodeURL(args[3]), buddyStatusFromString(args[1]));
282
        this->myNotificationServer()->externalCallbacks.buddyChangedStatus(this, args[2], decodeURL(args[3]), buddyStatusFromString(args[1]));
275
    }
283
    }
276
    
284
    
277
    void NotificationServerConnection::handle_FLN(std::vector<std::string> & args)
285
    void NotificationServerConnection::handle_FLN(std::vector<std::string> & args)
278
    {
286
    {
279
	assert(connectionStatus >= NS_CONNECTED);
287
        this->assertConnectionStateIsAtLeast(NS_CONNECTED);
280
	ext::buddyOffline(this, args[1]);
288
        this->myNotificationServer()->externalCallbacks.buddyOffline(this, args[1]);
281
    }    
289
    }    
282
    
290
    
283
    void NotificationServerConnection::handle_MSG(std::vector<std::string> & args)
291
    void NotificationServerConnection::handle_MSG(std::vector<std::string> & args)
284
    {
292
    {
285
	assert(connectionStatus >= NS_CONNECTED);
293
        this->assertConnectionStateIsAtLeast(NS_CONNECTED);
286
	Connection::handle_MSG(args);
294
        Connection::handle_MSG(args);
287
    }
295
    }
288
    
296
    
289
    void NotificationServerConnection::handle_RNG(std::vector<std::string> & args)
297
    void NotificationServerConnection::handle_RNG(std::vector<std::string> & args)
290
    {
298
    {
291
	assert(connectionStatus >= NS_CONNECTED);
299
        this->assertConnectionStateIsAtLeast(NS_CONNECTED);
292
	SwitchboardServerConnection::AuthData auth = SwitchboardServerConnection::AuthData(this->auth.username,
300
        SwitchboardServerConnection::AuthData auth = SwitchboardServerConnection::AuthData(this->auth.username,
293
											   args[1],
301
                                                                                           args[1],
294
											   args[4]);
302
                                                                                           args[4]);
295
	SwitchboardServerConnection *newSBconn = new SwitchboardServerConnection(auth, *this);
303
        SwitchboardServerConnection *newSBconn = new SwitchboardServerConnection(auth, *this);
296
	this->addSwitchboardConnection(newSBconn);  
304
        this->addSwitchboardConnection(newSBconn);  
297
	std::pair<std::string, int> server_address = splitServerAddress(args[2]);  
305
        std::pair<std::string, int> server_address = splitServerAddress(args[2]);  
298
	newSBconn->connect(server_address.first, server_address.second);        
306
        newSBconn->connect(server_address.first, server_address.second);        
299
    }
307
    }
300
    
308
    
301
    void NotificationServerConnection::handle_ADG(std::vector<std::string> & args)
309
    void NotificationServerConnection::handle_ADG(std::vector<std::string> & args)
302
    {
310
    {
303
	assert(connectionStatus >= NS_CONNECTED);        
311
        this->assertConnectionStateIsAtLeast(NS_CONNECTED);        
304
	ext::addedGroup(this, args[3], decimalFromString(args[4]));
312
        this->myNotificationServer()->externalCallbacks.addedGroup(this, decodeURL(args[3]), decimalFromString(args[4]));
305
	ext::gotLatestListSerial(this, decimalFromString(args[2]));
313
        this->myNotificationServer()->externalCallbacks.gotLatestListSerial(this, decimalFromString(args[2]));
306
    }
314
    }
307
315
308
    void NotificationServerConnection::handle_RMG(std::vector<std::string> & args)
316
    void NotificationServerConnection::handle_RMG(std::vector<std::string> & args)
309
    {
317
    {
310
	assert(connectionStatus >= NS_CONNECTED);
318
        this->assertConnectionStateIsAtLeast(NS_CONNECTED);
311
	ext::removedGroup(this, decimalFromString(args[3]));
319
        this->myNotificationServer()->externalCallbacks.removedGroup(this, decimalFromString(args[3]));
312
	ext::gotLatestListSerial(this, decimalFromString(args[2]));
320
        this->myNotificationServer()->externalCallbacks.gotLatestListSerial(this, decimalFromString(args[2]));
313
    }
321
    }
314
322
315
    void NotificationServerConnection::handle_REG(std::vector<std::string> & args)
323
    void NotificationServerConnection::handle_REG(std::vector<std::string> & args)
316
    {
324
    {
317
	assert(connectionStatus >= NS_CONNECTED);
325
        this->assertConnectionStateIsAtLeast(NS_CONNECTED);
318
	ext::renamedGroup(this, decimalFromString(args[3]), args[4]);
326
        this->myNotificationServer()->externalCallbacks.renamedGroup(this, decimalFromString(args[3]), decodeURL(args[4]));
319
	ext::gotLatestListSerial(this, decimalFromString(args[2]));
327
        this->myNotificationServer()->externalCallbacks.gotLatestListSerial(this, decimalFromString(args[2]));
320
    }
328
    }
321
329
322
330
323
    void NotificationServerConnection::setState(BuddyStatus state)
331
    void NotificationServerConnection::setState(BuddyStatus state)
324
    {
332
    {
325
	assert(connectionStatus >= NS_CONNECTED);
333
        this->assertConnectionStateIsAtLeast(NS_CONNECTED);
326
	std::ostringstream buf_;
334
        std::ostringstream buf_;
327
	buf_ << "CHG " << trid++ << " " << buddyStatusToString(state) << " 0\r\n";
335
        buf_ << "CHG " << this->trID++ << " " << buddyStatusToString(state) << " 0\r\n";
328
	write(buf_);        
336
        write(buf_);        
329
    }
337
    }
330
    
338
    
331
    void NotificationServerConnection::setBLP(char setting)
339
    void NotificationServerConnection::setBLP(char setting)
332
    {
340
    {
333
	assert(connectionStatus >= NS_CONNECTED);
341
        this->assertConnectionStateIsAtLeast(NS_CONNECTED);
334
	std::ostringstream buf_;
342
        std::ostringstream buf_;
335
	buf_ << "BLP " << trid++ << " " << setting << "L\r\n";
343
        buf_ << "BLP " << this->trID++ << " " << setting << "L\r\n";
336
	write(buf_);        
344
        write(buf_);        
337
    }
345
    }
338
346
339
    void NotificationServerConnection::setGTC(char setting)
347
    void NotificationServerConnection::setGTC(char setting)
340
    {
348
    {
341
	assert(connectionStatus >= NS_CONNECTED);
349
        this->assertConnectionStateIsAtLeast(NS_CONNECTED);
342
	std::ostringstream buf_;
350
        std::ostringstream buf_;
343
	buf_ << "GTC " << trid++ << " " << setting << "\r\n";
351
        buf_ << "GTC " << this->trID++ << " " << setting << "\r\n";
344
	write(buf_);        
352
        write(buf_);        
345
    }
353
    }
346
    
354
    
347
    void NotificationServerConnection::setFriendlyName(std::string friendlyName) throw (std::runtime_error)
355
    void NotificationServerConnection::setFriendlyName(std::string friendlyName) throw (std::runtime_error)
348
    {
356
    {
349
	assert(connectionStatus >= NS_CONNECTED);
357
        this->assertConnectionStateIsAtLeast(NS_CONNECTED);
350
	if (friendlyName.size() > 387)
358
        if (friendlyName.size() > 387)
351
	    throw std::runtime_error("Friendly name too long!");
359
            throw std::runtime_error("Friendly name too long!");
352
	
360
        
353
	std::ostringstream buf_;  
361
        std::ostringstream buf_;  
354
	buf_ << "REA " << trid++ << " " << this->auth.username << " " << encodeURL(friendlyName) << "\r\n";
362
        buf_ << "REA " << this->trID++ << " " << this->auth.username << " " << encodeURL(friendlyName) << "\r\n";
355
	write(buf_);        
363
        write(buf_);        
356
    }
364
    }
357
365
358
    void NotificationServerConnection::addToList(std::string list, Passport buddyName)
366
    void NotificationServerConnection::addToList(std::string list, Passport buddyName)
359
    {
367
    {
360
	assert(connectionStatus >= NS_CONNECTED);
368
        this->assertConnectionStateIsAtLeast(NS_CONNECTED);
361
	std::ostringstream buf_;
369
        std::ostringstream buf_;
362
	buf_ << "ADD " << trid++ << " " << list << " " << buddyName << " " << buddyName << "\r\n";
370
        buf_ << "ADD " << this->trID++ << " " << list << " " << buddyName << " " << buddyName << "\r\n";
363
	write(buf_);        
371
        write(buf_);        
364
    }
372
    }
365
    
373
    
366
    void NotificationServerConnection::removeFromList(std::string list, Passport buddyName)
374
    void NotificationServerConnection::removeFromList(std::string list, Passport buddyName)
367
    {
375
    {
368
	assert(connectionStatus >= NS_CONNECTED);
376
        this->assertConnectionStateIsAtLeast(NS_CONNECTED);
369
	std::ostringstream buf_;
377
        std::ostringstream buf_;
370
	buf_ << "REM " << trid++ << " " << list << " " << buddyName << "\r\n";
378
        buf_ << "REM " << this->trID++ << " " << list << " " << buddyName << "\r\n";
371
	write(buf_);        
379
        write(buf_);        
372
    }
380
    }
373
    
381
    
374
    void NotificationServerConnection::addToGroup(Passport buddyName, int groupID)
382
    void NotificationServerConnection::addToGroup(Passport buddyName, int groupID)
375
    {
383
    {
376
	assert(connectionStatus >= NS_CONNECTED);
384
        this->assertConnectionStateIsAtLeast(NS_CONNECTED);
377
	std::ostringstream buf_;
385
        std::ostringstream buf_;
378
	buf_ << "ADD " << trid++ << " " << "FL" << " " << buddyName << " " << buddyName <<  " "  << groupID << "\r\n";
386
        buf_ << "ADD " << this->trID++ << " " << "FL" << " " << buddyName << " " << buddyName <<  " " << groupID << "\r\n";
379
	write(buf_);
387
        write(buf_);
380
    }
388
    }
381
    
389
    
382
    void NotificationServerConnection::removeFromGroup(Passport buddyName, int groupID)
390
    void NotificationServerConnection::removeFromGroup(Passport buddyName, int groupID)
383
    {
391
    {
384
	assert(connectionStatus >= NS_CONNECTED);
392
        this->assertConnectionStateIsAtLeast(NS_CONNECTED);
385
	std::ostringstream buf_;
393
        std::ostringstream buf_;
386
	buf_ << "REM " << trid++ << " " << "FL" << " " << buddyName << " " << groupID << "\r\n";
394
        buf_ << "REM " << this->trID++ << " " << "FL" << " " << buddyName << " " << groupID << "\r\n";
387
	write(buf_);
395
        write(buf_);
388
    }
396
    }
389
    
397
    
390
    void NotificationServerConnection::addGroup(std::string groupName)
398
    void NotificationServerConnection::addGroup(std::string groupName)
391
    {
399
    {
392
	assert(connectionStatus >= NS_CONNECTED);
400
        this->assertConnectionStateIsAtLeast(NS_CONNECTED);
393
	std::ostringstream buf_;
401
        std::ostringstream buf_;
394
	buf_ << "ADG " << trid++ << " " << encodeURL(groupName) << " " << 0 << "\r\n";
402
        buf_ << "ADG " << this->trID++ << " " << encodeURL(groupName) << " " << 0 << "\r\n";
395
	write(buf_);        
403
        write(buf_);        
396
    }
404
    }
397
    
405
    
398
    void NotificationServerConnection::removeGroup(int groupID)
406
    void NotificationServerConnection::removeGroup(int groupID)
399
    {
407
    {
400
	assert(connectionStatus >= NS_CONNECTED);
408
        this->assertConnectionStateIsAtLeast(NS_CONNECTED);
401
	std::ostringstream buf_;
409
        std::ostringstream buf_;
402
	buf_ << "RMG " << trid++ << " " << groupID << "\r\n";
410
        buf_ << "RMG " << this->trID++ << " " << groupID << "\r\n";
403
	write(buf_);
411
        write(buf_);
404
    }
412
    }
405
    
413
    
406
    void NotificationServerConnection::renameGroup(int groupID, std::string newGroupName)
414
    void NotificationServerConnection::renameGroup(int groupID, std::string newGroupName)
407
    {
415
    {
408
	assert(connectionStatus >= NS_CONNECTED);
416
        this->assertConnectionStateIsAtLeast(NS_CONNECTED);
409
	std::ostringstream buf_;
417
        std::ostringstream buf_;
410
	buf_ << "REG " << trid++ << " " << groupID << " " << encodeURL(newGroupName) << " " << 0 << "\r\n";
418
        buf_ << "REG " << this->trID++ << " " << groupID << " " << encodeURL(newGroupName) << " " << 0 << "\r\n";
411
	write(buf_);
419
        write(buf_);
412
    }
420
    }
413
    
421
    
414
    
422
    
415
    void NotificationServerConnection::synchronizeLists(int version)
423
    void NotificationServerConnection::synchronizeLists(int version)
416
    {
424
    {
417
	assert(connectionStatus >= NS_CONNECTED && connectionStatus != NS_SYNCHRONISING);
425
        this->assertConnectionStateIsAtLeast(NS_CONNECTED);
418
	ListSyncInfo *info = new ListSyncInfo(version);
426
        this->assertConnectionStateIsNot(NS_SYNCHRONISING);
419
	
427
        ListSyncInfo *info = new ListSyncInfo(version);
420
	std::ostringstream buf_;
428
        
421
	buf_ << "SYN " << trid << " " << version << "\r\n";
429
        std::ostringstream buf_;
422
	write(buf_);
430
        buf_ << "SYN " << this->trID << " " << version << "\r\n";
423
	
431
        if (write(buf_) != buf_.str().size())
424
	this->addCallback(&NotificationServerConnection::callback_SyncData, trid, (void *)info);
432
            return;
425
	this->synctrid = trid++;
433
        
426
	connectionStatus = NS_SYNCHRONISING;
434
        this->addCallback(&NotificationServerConnection::callback_SyncData, this->trID, (void *)info);
435
        this->synctrid = this->trID++;
436
        this->setConnectionState(NS_SYNCHRONISING);
427
    }
437
    }
428
    
438
    
429
    void NotificationServerConnection::sendPing()
439
    void NotificationServerConnection::sendPing()
430
    {
440
    {
431
	assert(connectionStatus >= NS_CONNECTED);
441
        this->assertConnectionStateIsAtLeast(NS_CONNECTED);
432
	write("PNG\r\n");        
442
        write("PNG\r\n");        
433
    }
443
    }
434
    
444
    
435
    void NotificationServerConnection::requestSwitchboardConnection(const void *tag)
445
    void NotificationServerConnection::requestSwitchboardConnection(const void *tag)
436
    {
446
    {
437
	assert(connectionStatus >= NS_CONNECTED);        
447
        this->assertConnectionStateIsAtLeast(NS_CONNECTED);
438
	SwitchboardServerConnection::AuthData *auth = new SwitchboardServerConnection::AuthData(this->auth.username, tag);
448
        SwitchboardServerConnection::AuthData *auth = new SwitchboardServerConnection::AuthData(this->auth.username, tag);
439
	std::ostringstream buf_;
449
        std::ostringstream buf_;
440
	buf_ << "XFR " << trid << " SB\r\n";
450
        buf_ << "XFR " << this->trID << " SB\r\n";
441
	write(buf_);
451
        if (write(buf_) != buf_.str().size())
442
	this->addCallback(&NotificationServerConnection::callback_TransferToSwitchboard, trid++, (void *)auth);        
452
            return;
453
        
454
        this->addCallback(&NotificationServerConnection::callback_TransferToSwitchboard, this->trID++, (void *)auth);        
443
    }
455
    }
444
    
456
    
445
    template <class _Tp>
457
    template <class _Tp>
446
    class _sameUserName
458
    class _sameUserName
447
    {
459
    {
448
	Buddy buddy;
460
        Buddy buddy;
449
public:
461
public:
450
	_sameUserName(const _Tp &__u) : buddy(__u) {};
462
        _sameUserName(const _Tp &__u) : buddy(__u) {};
451
	bool operator()(const _Tp &__x) { return __x.userName == buddy.userName; }
463
        bool operator()(const _Tp &__x) { return __x.userName == buddy.userName; }
452
    };
464
    };
453
    
465
    
454
    void NotificationServerConnection::checkReverseList(ListSyncInfo *info)
466
    void NotificationServerConnection::checkReverseList(ListSyncInfo *info)
455
    {
467
    {
456
	std::list<Buddy> & flist = info->reverseList;
468
        std::list<Buddy> & flist = info->reverseList;
457
	std::list<Buddy> & alist = info->allowList;
469
        std::list<Buddy> & alist = info->allowList;
458
	std::list<Buddy> & blist = info->blockList;
470
        std::list<Buddy> & blist = info->blockList;
459
	std::list<Buddy>::iterator flist_i;
471
        std::list<Buddy>::iterator flist_i;
460
	std::list<Buddy>::iterator alist_i;
472
        std::list<Buddy>::iterator alist_i;
461
	std::list<Buddy>::iterator blist_i;
473
        std::list<Buddy>::iterator blist_i;
462
	
474
        
463
	for (flist_i = flist.begin(); flist_i != flist.end(); flist_i++)
475
        for (flist_i = flist.begin(); flist_i != flist.end(); flist_i++)
464
	{
476
        {
465
	    if (std::count_if(alist.begin(), alist.end(), _sameUserName<Buddy>(*flist_i)) == 0 &&
477
            if (std::count_if(alist.begin(), alist.end(), _sameUserName<Buddy>(*flist_i)) == 0 &&
466
		std::count_if(blist.begin(), blist.end(), _sameUserName<Buddy>(*flist_i)) == 0)
478
                std::count_if(blist.begin(), blist.end(), _sameUserName<Buddy>(*flist_i)) == 0)
467
	    {
479
            {
468
		ext::gotNewReverseListEntry(this, (*flist_i).userName, (*flist_i).friendlyName);
480
                this->myNotificationServer()->externalCallbacks.gotNewReverseListEntry(this, (*flist_i).userName, (*flist_i).friendlyName);
469
	    }
481
            }
470
	}
482
        }
471
    }
483
    }
472
    
484
    
473
    void NotificationServerConnection::socketConnectionCompleted()
485
    void NotificationServerConnection::socketConnectionCompleted()
474
    {
486
    {
475
	assert(connectionStatus == NS_CONNECTING);
487
        this->assertConnectionStateIs(NS_CONNECTING);
476
	Connection::socketConnectionCompleted();
488
        this->setConnectionState(NS_CONNECTED);
477
	ext::unregisterSocket(this->sock);
489
        
478
	ext::registerSocket(this->sock, 1, 0);
490
        Connection::socketConnectionCompleted();
479
	connectionStatus = NS_CONNECTED;
491
        
492
        // If an error occurs in Connection::socketConnectionCompleted, we
493
        // will be disconnected before we get here.
494
        if (this->connectionState() != NS_DISCONNECTED)
495
        {
496
            this->myNotificationServer()->externalCallbacks.unregisterSocket(this->sock);
497
            this->myNotificationServer()->externalCallbacks.registerSocket(this->sock, 1, 0);
498
        }
480
    }
499
    }
481
    
500
    
482
    void NotificationServerConnection::connect(const std::string & hostname, unsigned int port)
501
    void NotificationServerConnection::connect(const std::string & hostname, unsigned int port)
483
    {
502
    {
484
	assert(connectionStatus == NS_DISCONNECTED);
503
        this->assertConnectionStateIs(NS_DISCONNECTED);
485
	connectinfo *info = new connectinfo(this->auth.username, this->auth.password);
504
        connectinfo *info = new connectinfo(this->auth.username, this->auth.password);
486
	
505
        
487
	if ((this->sock = ext::connectToServer(hostname, port, &this->connected)) == -1)
506
        if ((this->sock = this->myNotificationServer()->externalCallbacks.connectToServer(hostname, port, &this->connected)) == -1)
488
	{
507
        {
489
	    ext::showError(this, "Could not connect to MSN server");
508
            this->myNotificationServer()->externalCallbacks.showError(this, "Could not connect to MSN server");
490
	    ext::closingConnection(this);
509
            this->myNotificationServer()->externalCallbacks.closingConnection(this);
491
	    return;
510
            return;
492
	}
511
        }
493
512
        this->setConnectionState(NS_CONNECTING);
494
	connectionStatus = NS_CONNECTING;
513
        this->myNotificationServer()->externalCallbacks.registerSocket(this->sock, 0, 1);
495
	ext::registerSocket(this->sock, 0, 1);
514
        if (this->connected)
496
515
            this->socketConnectionCompleted();
497
	std::ostringstream buf_;
516
        
498
	buf_ << "VER " << trid << " MSNP8\r\n";
517
        std::ostringstream buf_;
499
	this->write(buf_);
518
        buf_ << "VER " << this->trID << " MSNP8\r\n";
500
	this->addCallback(&NotificationServerConnection::callback_NegotiateCVR, trid++, (void *)info);
519
        if (this->write(buf_) != buf_.str().size())
520
            return;
521
        
522
        this->addCallback(&NotificationServerConnection::callback_NegotiateCVR, this->trID++, (void *)info);
501
    }
523
    }
502
    
524
    
503
    void NotificationServerConnection::connect(const std::string & hostname, unsigned int port, const Passport & username, const std::string & password)
525
    void NotificationServerConnection::connect(const std::string & hostname, unsigned int port, const Passport & username, const std::string & password)
504
    {
526
    {
505
	this->auth.username = username;
527
        this->auth.username = username;
506
	this->auth.password = password;
528
        this->auth.password = password;
507
	this->connect(hostname, port);
529
        this->connect(hostname, port);
508
    }
530
    }
509
    
531
    
510
    void NotificationServerConnection::disconnect()
532
    void NotificationServerConnection::disconnect()
511
    {
533
    {
512
	assert(connectionStatus != NS_DISCONNECTED);
534
        this->assertConnectionStateIsNot(NS_DISCONNECTED);
513
	ext::closingConnection(this);
535
        
514
	
536
        std::list<SwitchboardServerConnection *> list = _switchboardConnections;
515
	std::list<SwitchboardServerConnection *> list = _switchboardConnections;
537
        std::list<SwitchboardServerConnection *>::iterator i = list.begin();
516
	std::list<SwitchboardServerConnection *>::iterator i = list.begin();
538
        for (; i != list.end(); i++)
517
	for (; i != list.end(); i++)
539
        {
518
	{
540
            delete *i;
519
	    delete *i;
541
        }
520
	}
542
        
521
	Connection::disconnect();
543
        this->callbacks.clear();
522
	connectionStatus = NS_DISCONNECTED;
544
        
545
        this->setConnectionState(NS_DISCONNECTED);        
546
        this->myNotificationServer()->externalCallbacks.closingConnection(this);        
547
        Connection::disconnect();
523
    }
548
    }
524
    
549
    
525
    void NotificationServerConnection::disconnectForTransfer()
550
    void NotificationServerConnection::disconnectForTransfer()
526
    {
551
    {
527
	assert(connectionStatus != NS_DISCONNECTED);
552
        this->assertConnectionStateIsNot(NS_DISCONNECTED);
528
	ext::unregisterSocket(this->sock);
553
        this->myNotificationServer()->externalCallbacks.unregisterSocket(this->sock);
529
	::close(this->sock);
554
        ::close(this->sock);
530
	connectionStatus = NS_DISCONNECTED;
555
        this->setConnectionState(NS_DISCONNECTED);
531
    }
556
    }
532
    
557
    
533
    void NotificationServerConnection::handleIncomingData()
558
    void NotificationServerConnection::handleIncomingData()
534
    {
559
    {
535
	assert(connectionStatus >= NS_CONNECTED);
560
        this->assertConnectionStateIsAtLeast(NS_CONNECTED);
536
	while (this->isWholeLineAvailable())
561
        while (this->isWholeLineAvailable())
537
	{
562
        {
538
	    std::vector<std::string> args = this->getLine();
563
            std::vector<std::string> args = this->getLine();
539
	    if (args[0] == "MSG" || args[0] == "NOT")
564
            if (args[0] == "MSG" || args[0] == "NOT" || args[0] == "IPG")
540
	    {
565
            {
541
		int dataLength = decimalFromString(args[3]);
566
                int dataLength;
542
		if (this->readBuffer.find("\r\n") + 2 + dataLength > this->readBuffer.size())
567
                if (args[0] == "MSG")
543
		    return;
568
                    dataLength = decimalFromString(args[3]);
544
	    }
569
                else
545
	    this->readBuffer = this->readBuffer.substr(this->readBuffer.find("\r\n") + 2);
570
                    dataLength = decimalFromString(args[1]);
546
	    int trid = 0;
571
547
	    
572
                if (this->readBuffer.find("\r\n") + 2 + dataLength > this->readBuffer.size())
548
	    if (args.size() >= 6 && args[0] == "XFR" && args[2] == "NS")
573
                    return;
549
	    {
574
            }
550
		// XFR TrID NS NotificationServerIP:Port 0 ThisServerIP:Port
575
            this->readBuffer = this->readBuffer.substr(this->readBuffer.find("\r\n") + 2);
551
		//  0    1  2             3              4        5    
576
            int trid = 0;
552
		this->callbacks.clear(); // delete the callback data
577
            
553
		
578
            if (args.size() >= 6 && args[0] == "XFR" && args[2] == "NS")
554
		this->disconnectForTransfer();
579
            {
555
		
580
                // XFR TrID NS NotificationServerIP:Port 0 ThisServerIP:Port
556
		std::pair<std::string, int> server_address = splitServerAddress(args[3]);
581
                //  0    1  2             3              4        5    
557
		this->connect(server_address.first, server_address.second);
582
                this->callbacks.clear(); // delete the callback data
558
		return;
583
                
559
	    }
584
                this->disconnectForTransfer();
560
	    
585
                
561
	    if (args.size() >= 7 && args[0] == "RNG")
586
                std::pair<std::string, int> server_address = splitServerAddress(args[3]);
562
	    {
587
                this->connect(server_address.first, server_address.second);
563
		// RNG SessionID SwitchboardServerIP:Port CKI AuthString InvitingUser InvitingDisplayName
588
                return;
564
		// 0      1                 2              3       4           5             6
589
            }
565
		this->handle_RNG(args);
590
            
566
		return;
591
            if (args.size() >= 7 && args[0] == "RNG")
567
	    }
592
            {
568
	    
593
                // RNG SessionID SwitchboardServerIP:Port CKI AuthString InvitingUser InvitingDisplayName
569
	    if (args.size() >= 1 && args[0] == "QNG")
594
                // 0      1                 2              3       4           5             6
570
	    {
595
                this->handle_RNG(args);
571
		// QNG
596
                return;
572
		//  0
597
            }
573
		
598
            
574
		// ping response, ignore
599
            if (args.size() >= 1 && args[0] == "QNG")
575
		return;
600
            {
576
	    }
601
                // QNG
577
	    
602
                //  0
578
	    if ((args.size() >= 4 && (args[0] == "LST" || args[0] == "LSG")) ||
603
                
579
		(args.size() >= 2 && (args[0] == "GTC" || args[0] == "BLP")) ||
604
                // ping response, ignore
580
		(args.size() >= 3 && args[0] == "BPR")
605
                return;
581
		)
606
            }
582
	    {
607
            
583
		// LST UserName FriendlyName UserLists [GroupNumbers]
608
            if ((args.size() >= 4 && (args[0] == "LST" || args[0] == "LSG")) ||
584
		//  0      1          2          3           4
609
                (args.size() >= 2 && (args[0] == "GTC" || args[0] == "BLP")) ||
585
		//
610
                (args.size() >= 3 && args[0] == "BPR")
586
		// or
611
                )
587
		// (GTC|BLP) [TrID] [ListVersion] Setting
612
            {
588
		//     0        1        2          4
613
                // LST UserName FriendlyName UserLists [GroupNumbers]
589
		
614
                //  0      1          2          3           4
590
		if (this->synctrid)
615
                //
591
		{
616
                // or
592
		    trid = this->synctrid;
617
                // (GTC|BLP) [TrID] [ListVersion] Setting
593
		}
618
                //     0        1        2          4
594
		else
619
                
595
		{
620
                if (this->synctrid)
596
		    trid = decimalFromString(args[1]);
621
                {
597
		}
622
                    trid = this->synctrid;
598
	    } 
623
                }
599
	    else if (args.size() > 1)
624
                else
600
	    {
625
                {
601
		try
626
                    trid = decimalFromString(args[1]);
602
		{
627
                }
603
		    trid = decimalFromString(args[1]);
628
            } 
604
		}
629
            else if (args.size() > 1)
605
		catch (...)
630
            {
606
		{
631
                try
607
		}
632
                {
608
	    }
633
                    trid = decimalFromString(args[1]);
609
	    
634
                }
610
	    if (!this->callbacks.empty() && trid > 0)
635
                catch (...)
611
	    {
636
                {
612
		if (this->callbacks.find(trid) != this->callbacks.end())
637
                }
613
		{
638
            }
614
		    (this->*(this->callbacks[trid].first))(args, trid, this->callbacks[trid].second);
639
            
615
		    continue;
640
            if (!this->callbacks.empty() && trid >= 0)
616
		}
641
            {
617
	    }
642
                if (this->callbacks.find(trid) != this->callbacks.end())
618
	    
643
                {
619
	    if (isdigit(args[0][0]))
644
                    (this->*(this->callbacks[trid].first))(args, trid, this->callbacks[trid].second);
620
		this->showError(decimalFromString(args[0]));
645
                    continue;
621
	    else
646
                }
622
		this->dispatchCommand(args);
647
            }
623
	}
648
            
649
            if (isdigit(args[0][0]))
650
                this->showError(decimalFromString(args[0]));
651
            else
652
                this->dispatchCommand(args);
653
        }
624
    }
654
    }
625
    
655
    
626
    void NotificationServerConnection::callback_SyncData(std::vector<std::string> & args, int trid, void *data) throw (std::runtime_error)
656
    void NotificationServerConnection::callback_SyncData(std::vector<std::string> & args, int trid, void *data) throw (std::runtime_error)
627
    {
657
    {
628
	assert(connectionStatus == NS_SYNCHRONISING);
658
        this->assertConnectionStateIs(NS_SYNCHRONISING);
629
	ListSyncInfo *info = static_cast<ListSyncInfo *>(data);
659
        ListSyncInfo *info = static_cast<ListSyncInfo *>(data);
630
	
660
        
631
	if (args[0] == "SYN")
661
        if (args[0] == "SYN")
632
	{
662
        {
633
	    if (info->listVersion == decimalFromString(args[2]))
663
            if (info->listVersion == decimalFromString(args[2]))
634
	    {
664
            {
635
		delete info;
665
                delete info;
636
		info = NULL;
666
                info = NULL;
637
		this->removeCallback(trid);
667
                this->removeCallback(trid);
638
		ext::gotBuddyListInfo(this, NULL);
668
                this->myNotificationServer()->externalCallbacks.gotBuddyListInfo(this, NULL);
639
		return;
669
                this->setConnectionState(NS_CONNECTED);                
640
	    }
670
                return;
641
	    else 
671
            }
642
	    {
672
            else 
643
		info->listVersion = decimalFromString(args[2]);
673
            {
644
		info->usersRemaining = decimalFromString(args[3]);
674
                info->listVersion = decimalFromString(args[2]);
645
		info->groupsRemaining = decimalFromString(args[4]);
675
                info->usersRemaining = decimalFromString(args[3]);
646
		ext::gotLatestListSerial(this, info->listVersion);
676
                info->groupsRemaining = decimalFromString(args[4]);
647
	    }
677
                this->myNotificationServer()->externalCallbacks.gotLatestListSerial(this, info->listVersion);
648
	}
678
            }
649
	else if (args[0] == "LST")
679
        }
650
	{
680
        else if (args[0] == "LST")
651
	    int list = decimalFromString(args[3]);
681
        {
652
	    if ((list & ListSyncInfo::LST_FL) == ListSyncInfo::LST_FL)
682
            int list = decimalFromString(args[3]);
653
	    {
683
            if ((list & ListSyncInfo::LST_FL) == ListSyncInfo::LST_FL)
654
		info->forwardList.push_back(Buddy(args[1], decodeURL(args[2])));
684
            {
655
		std::vector<std::string> groups = splitString(args[4], ",");
685
                info->forwardList.push_back(Buddy(args[1], decodeURL(args[2])));
656
		std::vector<std::string>::iterator i = groups.begin();
686
                std::vector<std::string> groups = splitString(args[4], ",");
657
		for (; i != groups.end(); i++)
687
                std::vector<std::string>::iterator i = groups.begin();
658
		{
688
                for (; i != groups.end(); i++)
659
		    int group = atoi(i->c_str());
689
                {
660
		    info->groups[group].buddies.push_back(&(info->forwardList.back()));
690
                    int group = atoi(i->c_str());
661
		    info->forwardList.back().groups.push_back(&info->groups[group]);
691
                    info->groups[group].buddies.push_back(&(info->forwardList.back()));
662
		}
692
                    info->forwardList.back().groups.push_back(&info->groups[group]);
663
	    }
693
                }
664
	    if ((list & ListSyncInfo::LST_RL) == ListSyncInfo::LST_RL)
694
            }
665
	    {
695
            if ((list & ListSyncInfo::LST_RL) == ListSyncInfo::LST_RL)
666
		info->reverseList.push_back(Buddy(args[1], decodeURL(args[2])));
696
            {
667
	    }
697
                info->reverseList.push_back(Buddy(args[1], decodeURL(args[2])));
668
	    if ((list & ListSyncInfo::LST_AL) == ListSyncInfo::LST_AL)
698
            }
669
	    {
699
            if ((list & ListSyncInfo::LST_AL) == ListSyncInfo::LST_AL)
670
		info->allowList.push_back(Buddy(args[1], decodeURL(args[2])));
700
            {
671
	    }
701
                info->allowList.push_back(Buddy(args[1], decodeURL(args[2])));
672
	    if ((list & ListSyncInfo::LST_BL) == ListSyncInfo::LST_BL)
702
            }
673
	    {
703
            if ((list & ListSyncInfo::LST_BL) == ListSyncInfo::LST_BL)
674
		info->blockList.push_back(Buddy(args[1], decodeURL(args[2])));
704
            {
675
	    }
705
                info->blockList.push_back(Buddy(args[1], decodeURL(args[2])));
676
	    info->usersRemaining--;
706
            }
677
	    if (info->usersRemaining == 0)
707
            info->usersRemaining--;
678
	    {
708
            if (info->usersRemaining == 0)
679
		info->progress |= ListSyncInfo::LST_FL | ListSyncInfo::LST_RL | ListSyncInfo::LST_AL | ListSyncInfo::LST_BL;
709
            {
680
	    }
710
                info->progress |= ListSyncInfo::LST_FL | ListSyncInfo::LST_RL | ListSyncInfo::LST_AL | ListSyncInfo::LST_BL;
681
	}
711
            }
682
	else if (args[0] == "GTC")
712
        }
683
	{
713
        else if (args[0] == "GTC")
684
	    info->reverseListPrompting = args[1][0];
714
        {
685
	    info->progress |= ListSyncInfo::COMPLETE_GTC;
715
            info->reverseListPrompting = args[1][0];
686
	    ext::gotGTC(this, info->reverseListPrompting);
716
            info->progress |= ListSyncInfo::COMPLETE_GTC;
687
	}
717
            this->myNotificationServer()->externalCallbacks.gotGTC(this, info->reverseListPrompting);
688
	else if (args[0] == "BLP")
718
        }
689
	{
719
        else if (args[0] == "BLP")
690
	    info->privacySetting = args[1][0];
720
        {
691
	    info->progress |= ListSyncInfo::COMPLETE_BLP;
721
            info->privacySetting = args[1][0];
692
	    ext::gotBLP(this, info->privacySetting);
722
            info->progress |= ListSyncInfo::COMPLETE_BLP;
693
	}
723
            this->myNotificationServer()->externalCallbacks.gotBLP(this, info->privacySetting);
694
	else if (args[0] == "LSG")
724
        }
695
	{
725
        else if (args[0] == "LSG")
696
	    int groupID = decimalFromString(args[1]);
726
        {
697
	    Group g(groupID, decodeURL(args[2]));
727
            int groupID = decimalFromString(args[1]);
698
	    info->groups[groupID] = g;
728
            Group g(groupID, decodeURL(args[2]));
699
	}
729
            info->groups[groupID] = g;
700
	else if (args[0] == "BPR")
730
        }
701
	{
731
        else if (args[0] == "BPR")
702
	    bool enabled;
732
        {
703
	    if (decodeURL(args[2])[0] == 'Y')
733
            bool enabled;
704
		enabled = true;
734
            if (decodeURL(args[2])[0] == 'Y')
705
	    else
735
                enabled = true;
706
		enabled = false;
736
            else
707
	    info->forwardList.back().phoneNumbers.push_back(Buddy::PhoneNumber(args[1], 
737
                enabled = false;
708
									       decodeURL(args[2]), 
738
            info->forwardList.back().phoneNumbers.push_back(Buddy::PhoneNumber(args[1], 
709
									       enabled));
739
                                                                               decodeURL(args[2]), 
710
	}
740
                                                                               enabled));
711
	else
741
        }
712
	    throw std::runtime_error("Unexpected sync data");
742
        else
713
		
743
            throw std::runtime_error("Unexpected sync data");
714
	if (info->progress == (ListSyncInfo::LST_FL | ListSyncInfo::LST_RL |
744
                
715
			       ListSyncInfo::LST_AL | ListSyncInfo::LST_BL | 
745
        if (info->progress == (ListSyncInfo::LST_FL | ListSyncInfo::LST_RL |
716
			       ListSyncInfo::COMPLETE_BLP | ListSyncInfo::COMPLETE_GTC))
746
                               ListSyncInfo::LST_AL | ListSyncInfo::LST_BL | 
717
	{
747
                               ListSyncInfo::COMPLETE_BLP | ListSyncInfo::COMPLETE_GTC))
718
	    this->removeCallback(trid);
748
        {
719
	    this->checkReverseList(info);
749
            this->removeCallback(trid);
720
	    ext::gotBuddyListInfo(this, info);
750
            this->checkReverseList(info);
721
	    this->synctrid = 0;
751
            this->myNotificationServer()->externalCallbacks.gotBuddyListInfo(this, info);
722
	    delete info;
752
            this->synctrid = 0;
723
	    connectionStatus = NS_CONNECTED;
753
            delete info;
724
	}
754
            this->setConnectionState(NS_CONNECTED);
725
	else if (info->progress > 63 || info->progress < 0)
755
        }
726
	    throw std::runtime_error("Corrupt sync progress!");
756
        else if (info->progress > 63 || info->progress < 0)
757
            throw std::runtime_error("Corrupt sync progress!");
727
    }
758
    }
728
    
759
    
729
    
760
    
730
    void NotificationServerConnection::callback_NegotiateCVR(std::vector<std::string> & args, int trid, void *data)
761
    void NotificationServerConnection::callback_NegotiateCVR(std::vector<std::string> & args, int trid, void *data)
731
    {
762
    {
732
	assert(connectionStatus >= NS_CONNECTED);
763
        this->assertConnectionStateIsAtLeast(NS_CONNECTED);
733
	connectinfo * info = (connectinfo *) data;
764
        connectinfo * info = (connectinfo *) data;
734
	this->removeCallback(trid);
765
        this->removeCallback(trid);
735
	
766
        
736
	if (args.size() >= 3)
767
        if (args.size() >= 3 && args[0] != "VER" || args[2] != "MSNP8") // if either *differs*...
737
	if (args[0] != "VER" || args[2] != "MSNP8") // if either *differs*...
768
        {
738
	{
769
            this->myNotificationServer()->externalCallbacks.showError(NULL, "Protocol negotiation failed");
739
	    ext::showError(NULL, "Protocol negotiation failed");
770
            delete info;
740
	    delete info;
771
            this->disconnect();
741
	    this->disconnect();
772
            return;
742
	    return;
773
        }
743
	}
774
        
744
	
775
        std::ostringstream buf_;
745
	std::ostringstream buf_;
776
        buf_ << "CVR " << this->trID << " 0x0409 winnt 5.2 i386 MSNMSGR 6.0.0250 MSMSGS " << info->username << "\r\n";
746
	buf_ << "CVR " << trid << " 0x0409 winnt 5.2 i386 MSNMSGR 6.0.0250 MSMSGS " << info->username << "\r\n";
777
        if (this->write(buf_) != buf_.str().size())
747
	this->write(buf_);
778
            return;
748
	this->addCallback(&NotificationServerConnection::callback_RequestUSR, trid++, (void *) data);
779
        this->addCallback(&NotificationServerConnection::callback_RequestUSR, this->trID++, (void *) data);
749
    }
780
    }
750
    
781
    
751
    void NotificationServerConnection::callback_TransferToSwitchboard(std::vector<std::string> & args, int trid, void *data)
782
    void NotificationServerConnection::callback_TransferToSwitchboard(std::vector<std::string> & args, int trid, void *data)
752
    {
783
    {
753
	assert(connectionStatus >= NS_CONNECTED);
784
        this->assertConnectionStateIsAtLeast(NS_CONNECTED);
754
	SwitchboardServerConnection::AuthData *auth = static_cast<SwitchboardServerConnection::AuthData *>(data);
785
        SwitchboardServerConnection::AuthData *auth = static_cast<SwitchboardServerConnection::AuthData *>(data);
755
	this->removeCallback(trid);
786
        this->removeCallback(trid);
756
	
787
        
757
	if (args[0] != "XFR")
788
        if (args[0] != "XFR")
758
	{
789
        {
759
	    this->showError(decimalFromString(args[0]));
790
            this->showError(decimalFromString(args[0]));
760
	    this->disconnect();
791
            this->disconnect();
761
	    delete auth;
792
            delete auth;
762
	    return;
793
            return;
763
	}
794
        }
764
	
795
        
765
	auth->cookie = args[5];
796
        auth->cookie = args[5];
766
	auth->sessionID = "";
797
        auth->sessionID = "";
767
	
798
        
768
	SwitchboardServerConnection *newconn = new SwitchboardServerConnection(*auth, *this);
799
        SwitchboardServerConnection *newconn = new SwitchboardServerConnection(*auth, *this);
769
	
800
        
770
	this->addSwitchboardConnection(newconn);
801
        this->addSwitchboardConnection(newconn);
771
	std::pair<std::string, int> server_address = splitServerAddress(args[3]);
802
        std::pair<std::string, int> server_address = splitServerAddress(args[3]);
772
	newconn->connect(server_address.first, server_address.second);
803
        newconn->connect(server_address.first, server_address.second);
773
	
804
        
774
	delete auth;
805
        delete auth;
775
    }
806
    }
776
    
807
    
777
    void NotificationServerConnection::callback_RequestUSR(std::vector<std::string> & args, int trid, void *data)
808
    void NotificationServerConnection::callback_RequestUSR(std::vector<std::string> & args, int trid, void *data)
778
    {
809
    {
779
	assert(connectionStatus >= NS_CONNECTED);
810
        this->assertConnectionStateIsAtLeast(NS_CONNECTED);
780
	connectinfo *info = (connectinfo *)data;
811
        connectinfo *info = (connectinfo *)data;
781
	this->removeCallback(trid);
812
        this->removeCallback(trid);
782
	
813
        
783
	if (args.size() > 1 && args[0] != "CVR") // if*differs*...
814
        if (args.size() > 1 && args[0] != "CVR") // if*differs*...
784
	{
815
        {
785
	    ext::showError(NULL, "Protocol negotiation failed");
816
            this->myNotificationServer()->externalCallbacks.showError(NULL, "Protocol negotiation failed");
786
	    delete info;
817
            delete info;
787
	    this->disconnect();
818
            this->disconnect();
788
	    return;
819
            return;
789
	}
820
        }
790
	
821
        
791
	std::ostringstream buf_;
822
        std::ostringstream buf_;
792
	buf_ << "USR " << trid << " TWN I " << info->username << "\r\n";
823
        buf_ << "USR " << this->trID << " TWN I " << info->username << "\r\n";
793
	this->write(buf_);
824
        if (this->write(buf_) != buf_.str().size())
794
	
825
            return;
795
	this->addCallback(&NotificationServerConnection::callback_PassportAuthentication, trid++, (void *) data);
826
        
827
        this->addCallback(&NotificationServerConnection::callback_PassportAuthentication, this->trID++, (void *) data);
796
    }    
828
    }    
797
    
829
    
798
    void NotificationServerConnection::callback_PassportAuthentication(std::vector<std::string> & args, int trid, void * data)
830
    void NotificationServerConnection::callback_PassportAuthentication(std::vector<std::string> & args, int trid, void * data)
799
    {
831
    {
800
	assert(connectionStatus >= NS_CONNECTED);
832
        this->assertConnectionStateIsAtLeast(NS_CONNECTED);
801
	connectinfo * info;
833
        connectinfo * info;
802
	
834
        
803
	CURL *curl;
835
        CURL *curl;
804
	CURLcode ret;
836
        CURLcode ret;
805
	curl_slist *slist = NULL;
837
        curl_slist *slist = NULL;
806
	std::string auth;
838
        std::string auth;
807
	char *uname, *pword;
839
        char *uname, *pword;
808
	std::string proxy;
840
        std::string proxy;
809
	
841
        
810
	info=(connectinfo *)data;
842
        info=(connectinfo *)data;
811
	this->removeCallback(trid);
843
        this->removeCallback(trid);
812
	
844
        
813
	if (isdigit(args[0][0]))
845
        if (isdigit(args[0][0]))
814
	{
846
        {
815
	    this->showError(decimalFromString(args[0]));
847
            this->showError(decimalFromString(args[0]));
816
	    delete info;
848
            delete info;
817
	    this->disconnect();
849
            this->disconnect();
818
	    return;
850
            return;
819
	}
851
        }
820
	
852
        
821
	if (args.size() >= 4 && args[4].empty()) {
853
        if (args.size() >= 4 && args[4].empty()) {
822
	    this->disconnect();
854
            this->disconnect();
823
	    delete info;
855
            delete info;
824
	    return;
856
            return;
825
	}
857
        }
826
	
858
        
827
	/* Now to fire off some HTTPS login */
859
        /* Now to fire off some HTTPS login */
828
	/* args[4] contains the most interesting part we need to send on */
860
        /* args[4] contains the most interesting part we need to send on */
829
	curl = curl_easy_init();
861
        curl = curl_easy_init();
830
	if (curl == NULL) {
862
        if (curl == NULL) {
831
	    this->disconnect();
863
            this->disconnect();
832
	    delete info;
864
            delete info;
833
	    return;
865
            return;
834
	}
866
        }
835
	
867
        
836
	proxy = ext::getSecureHTTPProxy();
868
        proxy = this->myNotificationServer()->externalCallbacks.getSecureHTTPProxy();
837
	if (! proxy.empty()) 
869
        if (! proxy.empty()) 
838
	    ret = curl_easy_setopt(curl, CURLOPT_PROXY, proxy.c_str());
870
            ret = curl_easy_setopt(curl, CURLOPT_PROXY, proxy.c_str());
839
	else    
871
        else	
840
	    ret = CURLE_OK;
872
            ret = CURLE_OK;
841
	
873
        
842
	if (ret == CURLE_OK)
874
        if (ret == CURLE_OK)
843
	    ret = curl_easy_setopt(curl, CURLOPT_URL, "https://login.passport.com/login2.srf");
875
            ret = curl_easy_setopt(curl, CURLOPT_URL, "https://login.passport.com/login2.srf");
844
	
876
        
845
	uname = curl_escape(const_cast<char *>(info->username.c_str()), 0);
877
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
846
	pword = curl_escape(const_cast<char *>(info->password.c_str()), 0);
878
        uname = curl_escape(const_cast<char *>(info->username.c_str()), 0);
847
	auth = std::string("Authorization: Passport1.4 OrgVerb=GET,OrgURL=http%3A%2F%2Fmessenger%2Emsn%2Ecom,sign-in=") + uname + ",pwd=" + pword + ","+ args[4];
879
        pword = curl_escape(const_cast<char *>(info->password.c_str()), 0);
848
	free(uname);
880
        auth = std::string("Authorization: Passport1.4 OrgVerb=GET,OrgURL=http%3A%2F%2Fmessenger%2Emsn%2Ecom,sign-in=") + uname + ",pwd=" + pword + ","+ args[4];
849
	free(pword);
881
        curl_free(uname);
850
	slist = curl_slist_append(slist, auth.c_str());
882
        curl_free(pword);
851
	
883
        slist = curl_slist_append(slist, auth.c_str());
852
	if (ret == CURLE_OK)
884
        
853
	    ret = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
885
        if (ret == CURLE_OK)
854
	if (ret == CURLE_OK)
886
            ret = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
855
	    ret = curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
887
        if (ret == CURLE_OK)
856
	if (ret == CURLE_OK)
888
            ret = curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
857
	    ret = curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
889
        if (ret == CURLE_OK)
858
	/*if (ret == CURLE_OK)
890
            ret = curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
859
	    ret = curl_easy_setopt(curl, CURLOPT_UNRESTRICTED_AUTH, 1);*/
891
        /*if (ret == CURLE_OK)
860
	/*  if (ret == CURLE_OK)
892
            ret = curl_easy_setopt(curl, CURLOPT_UNRESTRICTED_AUTH, 1);*/
861
	    ret = curl_easy_setopt(curl, CURLOPT_USERAGENT, "msnlib/1.0 (Proteus)");*/
893
        /*  if (ret == CURLE_OK)
862
	if (ret == CURLE_OK)
894
            ret = curl_easy_setopt(curl, CURLOPT_USERAGENT, "msnlib/1.0 (Proteus)");*/
863
	    ret = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &msn_handle_curl_write);
895
        if (ret == CURLE_OK)
864
	/*if (ret == CURLE_OK)
896
            ret = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &msn_handle_curl_write);
865
	    ret = curl_easy_setopt(curl, CURLOPT_WRITEDATA, info);*/
897
        /*if (ret == CURLE_OK)
866
	if (ret == CURLE_OK)
898
            ret = curl_easy_setopt(curl, CURLOPT_WRITEDATA, info);*/
867
	    ret = curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, &msn_handle_curl_header);
899
        if (ret == CURLE_OK)
868
	if (ret == CURLE_OK)
900
            ret = curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, &msn_handle_curl_header);
869
	    ret = curl_easy_setopt(curl, CURLOPT_WRITEHEADER, info);
901
        if (ret == CURLE_OK)
870
	
902
            ret = curl_easy_setopt(curl, CURLOPT_WRITEHEADER, info);
871
	if (ret == CURLE_OK)
903
        
872
	    ret = curl_easy_perform(curl);
904
        if (ret == CURLE_OK)
873
	
905
            ret = curl_easy_perform(curl);
874
	curl_easy_cleanup(curl);
906
        
875
	curl_slist_free_all(slist);
907
        curl_easy_cleanup(curl);
876
	
908
        curl_slist_free_all(slist);
877
	/* ok, if auth succeeded info->cookie is now the cookie to pass back */
909
        
878
	if (info->cookie.empty())
910
        /* ok, if auth succeeded info->cookie is now the cookie to pass back */
879
	{
911
        if (info->cookie.empty())
880
	    // No authentication cookie /usually/ means that authentication failed.
912
        {
881
	    this->showError(911);
913
            // No authentication cookie /usually/ means that authentication failed.
882
	    
914
            this->showError(911);
883
	    this->disconnect();
915
            
884
	    delete info;
916
            this->disconnect();
885
	    return;
917
            delete info;
886
	}
918
            return;
887
	
919
        }
888
	std::ostringstream buf_;
920
        
889
	buf_ << "USR " << trid << " TWN S " << info->cookie << "\r\n";
921
        std::ostringstream buf_;
890
	this->write(buf_);
922
        buf_ << "USR " << this->trID << " TWN S " << info->cookie << "\r\n";
891
	this->addCallback(&NotificationServerConnection::callback_AuthenticationComplete, trid++, (void *) data);
923
        if (this->write(buf_) != buf_.str().size())
924
            return;
925
        this->addCallback(&NotificationServerConnection::callback_AuthenticationComplete, this->trID++, (void *) data);
892
    }
926
    }
893
    
927
    
894
    void NotificationServerConnection::callback_AuthenticationComplete(std::vector<std::string> & args, int trid, void * data)
928
    void NotificationServerConnection::callback_AuthenticationComplete(std::vector<std::string> & args, int trid, void * data)
895
    {
929
    {
896
	assert(connectionStatus >= NS_CONNECTED);
930
        this->assertConnectionStateIsAtLeast(NS_CONNECTED);
897
	connectinfo * info = (connectinfo *) data;
931
        connectinfo * info = (connectinfo *) data;
898
	this->removeCallback(trid);
932
        this->removeCallback(trid);
899
	
933
        
900
	if (isdigit(args[0][0]))
934
        if (isdigit(args[0][0]))
901
	{
935
        {
902
	    this->showError(decimalFromString(args[0]));
936
            this->showError(decimalFromString(args[0]));
903
	    delete info;
937
            delete info;
904
	    this->disconnect();
938
            this->disconnect();
905
	    return;
939
            return;
906
	}
940
        }
907
	
941
        
908
	ext::gotFriendlyName(this, decodeURL(args[4]));
942
        this->myNotificationServer()->externalCallbacks.gotFriendlyName(this, decodeURL(args[4]));
909
	
943
        
910
	delete info;
944
        delete info;
911
	
945
        
912
	trid++;
946
        this->myNotificationServer()->externalCallbacks.gotNewConnection(this);
913
	
914
	ext::gotNewConnection(this);
915
    }    
947
    }    
916
    
948
    
917
    
949
    
918
    static size_t msn_handle_curl_write(void *ptr, size_t size, size_t nmemb, void  *stream) {
950
    static size_t msn_handle_curl_write(void *ptr, size_t size, size_t nmemb, void  *stream) {
919
	return size * nmemb;
951
        return size * nmemb;
920
    }
952
    }
921
    
953
    
922
    static size_t msn_handle_curl_header(void *ptr, size_t size, size_t nmemb, void *stream) 
954
    static size_t msn_handle_curl_header(void *ptr, size_t size, size_t nmemb, void *stream) 
923
    {
955
    {
924
	connectinfo * info;
956
        connectinfo * info;
925
	std::string cookiedata;
957
        std::string cookiedata;
926
	
958
        
927
	info = (connectinfo *)stream;
959
        info = (connectinfo *)stream;
928
	
960
        
929
	if ((size * nmemb) < strlen("Authentication-Info:"))
961
        if ((size * nmemb) < strlen("Authentication-Info:"))
930
	    return (size * nmemb);
962
            return (size * nmemb);
931
	
963
        
932
	std::string headers_ = std::string((char *)ptr, size * nmemb);
964
        std::string headers_ = std::string((char *)ptr, size * nmemb);
933
	Message::Headers headers = Message::Headers(headers_);
965
        Message::Headers headers = Message::Headers(headers_);
934
	cookiedata = headers["Authentication-Info:"];
966
        cookiedata = headers["Authentication-Info:"];
935
967
936
	if (! cookiedata.empty()) 
968
        if (! cookiedata.empty()) 
937
	{
969
        {
938
	    size_t pos = cookiedata.find(",from-PP='");
970
            size_t pos = cookiedata.find(",from-PP='");
939
	    if (pos == std::string::npos) {
971
            if (pos == std::string::npos) {
940
		info->cookie = "";
972
                info->cookie = "";
941
	    } else {
973
            } else {
942
		info->cookie = cookiedata.substr(pos + strlen(",from-PP='"));
974
                info->cookie = cookiedata.substr(pos + strlen(",from-PP='"));
943
		pos = info->cookie.find("'");
975
                pos = info->cookie.find("'");
944
		if (pos != std::string::npos)
976
                if (pos != std::string::npos)
945
		    info->cookie = info->cookie.substr(0, pos);
977
                    info->cookie = info->cookie.substr(0, pos);
946
	    }
978
            }
947
	}
979
        }
948
	
980
        
949
	return (size * nmemb);
981
        return (size * nmemb);
950
    }    
982
    }    
951
}
983
}
(-)centericq-4.21.0.orig/libmsn-0.1/msn/notificationserver.h (-6 / +13 lines)
Lines 29-34 Link Here
29
#include <msn/buddy.h>
29
#include <msn/buddy.h>
30
#include <msn/passport.h>
30
#include <msn/passport.h>
31
#include <stdexcept>
31
#include <stdexcept>
32
#include <msn/externals.h>
32
33
33
namespace MSN
34
namespace MSN
34
{    
35
{    
Lines 154-168 Link Here
154
public:
155
public:
155
        /** Create a NotificationServerConnection with the specified authentication data
156
        /** Create a NotificationServerConnection with the specified authentication data
156
         */
157
         */
157
        NotificationServerConnection(AuthData & auth_);
158
        NotificationServerConnection(AuthData & auth_, Callbacks & cb);
158
        
159
        
159
        /** Create a NotificationServerConnection with the specified @a username and 
160
        /** Create a NotificationServerConnection with the specified @a username and 
160
         *  @a password.
161
         *  @a password.
161
         */
162
         */
162
        NotificationServerConnection(Passport username, std::string password);
163
        NotificationServerConnection(Passport username, std::string password, Callbacks & cb);
163
        
164
        
164
        /** Create a NotificationServerConnection with no specified username or password. */
165
        /** Create a NotificationServerConnection with no specified username or password. */
165
        NotificationServerConnection();
166
        NotificationServerConnection(Callbacks & cb);
166
        
167
        
167
        virtual ~NotificationServerConnection();
168
        virtual ~NotificationServerConnection();
168
        virtual void dispatchCommand(std::vector<std::string> & args);
169
        virtual void dispatchCommand(std::vector<std::string> & args);
Lines 283-293 Link Here
283
            NS_ONLINE
284
            NS_ONLINE
284
        };
285
        };
285
286
286
        NotificationServerState connectionState() const { return this->connectionStatus; };
287
        NotificationServerState connectionState() const { return this->_connectionState; };
288
        Callbacks & externalCallbacks;
289
        virtual NotificationServerConnection *myNotificationServer() { return this; };        
287
protected:
290
protected:
288
        virtual void handleIncomingData();
291
        virtual void handleIncomingData();
289
        NotificationServerState connectionStatus;
292
        NotificationServerState _connectionState;
290
293
        
294
        void setConnectionState(NotificationServerState s) { this->_connectionState = s; };
295
        void assertConnectionStateIs(NotificationServerState s) { assert(this->_connectionState == s); };
296
        void assertConnectionStateIsNot(NotificationServerState s) { assert(this->_connectionState != s); };
297
        void assertConnectionStateIsAtLeast(NotificationServerState s) { assert(this->_connectionState >= s); };        
291
private:
298
private:
292
        std::list<SwitchboardServerConnection *> _switchboardConnections;
299
        std::list<SwitchboardServerConnection *> _switchboardConnections;
293
        std::map<int, std::pair<NotificationServerCallback, void *> > callbacks;
300
        std::map<int, std::pair<NotificationServerCallback, void *> > callbacks;
(-)centericq-4.21.0.orig/libmsn-0.1/msn/switchboardserver.cpp (-63 / +68 lines)
Lines 26-31 Link Here
26
#include <msn/externals.h>
26
#include <msn/externals.h>
27
#include <msn/filetransfer.h>
27
#include <msn/filetransfer.h>
28
28
29
#include <stdio.h>
29
#include <sys/stat.h>
30
#include <sys/stat.h>
30
#include <algorithm>
31
#include <algorithm>
31
#include <cassert>
32
#include <cassert>
Lines 35-54 Link Here
35
    std::map<std::string, void (SwitchboardServerConnection::*)(std::vector<std::string> &)> SwitchboardServerConnection::commandHandlers;
36
    std::map<std::string, void (SwitchboardServerConnection::*)(std::vector<std::string> &)> SwitchboardServerConnection::commandHandlers;
36
    
37
    
37
    SwitchboardServerConnection::SwitchboardServerConnection(AuthData & auth_, NotificationServerConnection & n)
38
    SwitchboardServerConnection::SwitchboardServerConnection(AuthData & auth_, NotificationServerConnection & n)
38
        : Connection(), auth(auth_), connectionStatus(SB_DISCONNECTED), notificationServer(n)
39
        : Connection(), auth(auth_), _connectionState(SB_DISCONNECTED), notificationServer(n)
39
    {
40
    {
40
        registerCommandHandlers();
41
        registerCommandHandlers();
41
    }
42
    }
42
    
43
    
43
    SwitchboardServerConnection::~SwitchboardServerConnection()
44
    SwitchboardServerConnection::~SwitchboardServerConnection()
44
    {
45
    {
45
        if (connectionStatus != SB_DISCONNECTED)
46
        if (this->connectionState() != SB_DISCONNECTED)
46
            this->disconnect();
47
            this->disconnect();
47
    }
48
    }
48
        
49
        
49
    Connection *SwitchboardServerConnection::connectionWithSocket(int fd)
50
    Connection *SwitchboardServerConnection::connectionWithSocket(int fd)
50
    {
51
    {
51
        assert(connectionStatus >= SB_CONNECTING);
52
        this->assertConnectionStateIsAtLeast(SB_CONNECTING);
52
        std::list<FileTransferConnection *> & list = _fileTransferConnections;
53
        std::list<FileTransferConnection *> & list = _fileTransferConnections;
53
        std::list<FileTransferConnection *>::iterator i = list.begin();
54
        std::list<FileTransferConnection *>::iterator i = list.begin();
54
        
55
        
Lines 65-86 Link Here
65
    
66
    
66
    void SwitchboardServerConnection::addFileTransferConnection(FileTransferConnection *c)
67
    void SwitchboardServerConnection::addFileTransferConnection(FileTransferConnection *c)
67
    {
68
    {
68
        assert(connectionStatus >= SB_CONNECTED);        
69
        this->assertConnectionStateIsAtLeast(SB_CONNECTED);        
69
        _fileTransferConnections.push_back(c);
70
        _fileTransferConnections.push_back(c);
70
    }
71
    }
71
72
72
    void SwitchboardServerConnection::removeFileTransferConnection(FileTransferConnection *c)
73
    void SwitchboardServerConnection::removeFileTransferConnection(FileTransferConnection *c)
73
    {
74
    {
74
        assert(connectionStatus >= SB_CONNECTED);        
75
        this->assertConnectionStateIsAtLeast(SB_CONNECTED);        
75
        _fileTransferConnections.remove(c);
76
        _fileTransferConnections.remove(c);
76
    }
77
    }
77
78
78
    /**
79
     *  @todo  FIX THIS.  Delete shouldn't be here.
80
     */    
81
    void SwitchboardServerConnection::removeFileTransferConnection(FileTransferInvitation *inv)
79
    void SwitchboardServerConnection::removeFileTransferConnection(FileTransferInvitation *inv)
82
    {
80
    {
83
        assert(connectionStatus >= SB_CONNECTED);        
81
        this->assertConnectionStateIsAtLeast(SB_CONNECTED);        
84
        std::list<FileTransferConnection *> & list = _fileTransferConnections;
82
        std::list<FileTransferConnection *> & list = _fileTransferConnections;
85
        std::list<FileTransferConnection *>::iterator i = list.begin();        
83
        std::list<FileTransferConnection *>::iterator i = list.begin();        
86
        for (i = list.begin(); i != list.end(); i++)
84
        for (i = list.begin(); i != list.end(); i++)
Lines 120-132 Link Here
120
    void SwitchboardServerConnection::addCallback(SwitchboardServerCallback callback,
118
    void SwitchboardServerConnection::addCallback(SwitchboardServerCallback callback,
121
                                                   int trid, void *data)
119
                                                   int trid, void *data)
122
    {
120
    {
123
        assert(connectionStatus >= SB_CONNECTING);        
121
        this->assertConnectionStateIsAtLeast(SB_CONNECTING);        
124
        this->callbacks[trid] = std::make_pair(callback, data);
122
        this->callbacks[trid] = std::make_pair(callback, data);
125
    }
123
    }
126
124
127
    void SwitchboardServerConnection::removeCallback(int trid)
125
    void SwitchboardServerConnection::removeCallback(int trid)
128
    {
126
    {
129
        assert(connectionStatus >= SB_CONNECTING);        
127
        this->assertConnectionStateIsAtLeast(SB_CONNECTING);        
130
        this->callbacks.erase(trid);
128
        this->callbacks.erase(trid);
131
    }
129
    }
132
    
130
    
Lines 143-149 Link Here
143
    
141
    
144
    void SwitchboardServerConnection::dispatchCommand(std::vector<std::string> & args)
142
    void SwitchboardServerConnection::dispatchCommand(std::vector<std::string> & args)
145
    {
143
    {
146
        assert(connectionStatus >= SB_CONNECTED);        
144
        this->assertConnectionStateIsAtLeast(SB_CONNECTED);        
147
        std::map<std::string, void (SwitchboardServerConnection::*)(std::vector<std::string> &)>::iterator i = commandHandlers.find(args[0]);
145
        std::map<std::string, void (SwitchboardServerConnection::*)(std::vector<std::string> &)>::iterator i = commandHandlers.find(args[0]);
148
        if (i != commandHandlers.end())
146
        if (i != commandHandlers.end())
149
            (this->*commandHandlers[args[0]])(args);
147
            (this->*commandHandlers[args[0]])(args);
Lines 151-161 Link Here
151
    
149
    
152
    void SwitchboardServerConnection::sendMessage(const Message *msg)
150
    void SwitchboardServerConnection::sendMessage(const Message *msg)
153
    {
151
    {
154
        assert(connectionStatus >= SB_READY);        
152
        this->assertConnectionStateIsAtLeast(SB_READY);        
155
        std::string s = msg->asString();
153
        std::string s = msg->asString();
156
        
154
        
157
        std::ostringstream buf_;
155
        std::ostringstream buf_;
158
        buf_ << "MSG " << trid++ << " N " << (int) s.size() << "\r\n" << s;
156
        buf_ << "MSG " << this->trID++ << " A " << (int) s.size() << "\r\n" << s;
159
        this->write(buf_);
157
        this->write(buf_);
160
    }
158
    }
161
159
Lines 167-173 Link Here
167
    
165
    
168
    void SwitchboardServerConnection::handleInvite(Passport from, const std::string & friendly, const std::string & mime, const std::string & body)
166
    void SwitchboardServerConnection::handleInvite(Passport from, const std::string & friendly, const std::string & mime, const std::string & body)
169
    {
167
    {
170
        assert(connectionStatus >= SB_READY);        
168
        this->assertConnectionStateIsAtLeast(SB_READY);        
171
        Message::Headers headers = Message::Headers(body);
169
        Message::Headers headers = Message::Headers(body);
172
        std::string command = headers["Invitation-Command"];
170
        std::string command = headers["Invitation-Command"];
173
        std::string cookie = headers["Invitation-Cookie"];
171
        std::string cookie = headers["Invitation-Cookie"];
Lines 181-187 Link Here
181
        } 
179
        } 
182
        else if (inv == NULL)
180
        else if (inv == NULL)
183
        {
181
        {
184
//            printf("Very odd - just got a %s out of mid-air...\n", command.c_str()); 
182
            printf("Very odd - just got a %s out of mid-air...\n", command.c_str()); 
185
        }
183
        }
186
        else if (command == "ACCEPT")
184
        else if (command == "ACCEPT")
187
        {
185
        {
Lines 191-203 Link Here
191
        {
189
        {
192
            inv->invitationWasCanceled(body);
190
            inv->invitationWasCanceled(body);
193
        } else {
191
        } else {
194
//            printf("Argh, don't support %s yet!\n", command.c_str());
192
            printf("Argh, don't support %s yet!\n", command.c_str());
195
        }
193
        }
196
    }
194
    }
197
    
195
    
198
    void SwitchboardServerConnection::handleNewInvite(Passport & from, const std::string & friendly, const std::string & mime, const std::string & body)
196
    void SwitchboardServerConnection::handleNewInvite(Passport & from, const std::string & friendly, const std::string & mime, const std::string & body)
199
    {
197
    {
200
        assert(connectionStatus >= SB_READY);        
198
        this->assertConnectionStateIsAtLeast(SB_READY);        
201
        Message::Headers headers = Message::Headers(body);
199
        Message::Headers headers = Message::Headers(body);
202
        std::string appname;
200
        std::string appname;
203
        std::string filename;
201
        std::string filename;
Lines 211-222 Link Here
211
        {
209
        {
212
            invg = new FileTransferInvitation(Invitation::MSNFTP, headers["Invitation-Cookie"], from, 
210
            invg = new FileTransferInvitation(Invitation::MSNFTP, headers["Invitation-Cookie"], from, 
213
                                              this, filename, atol(filesize.c_str()));
211
                                              this, filename, atol(filesize.c_str()));
214
            ext::gotFileTransferInvitation(this, from, friendly, static_cast<FileTransferInvitation *>(invg));
212
            this->myNotificationServer()->externalCallbacks.gotFileTransferInvitation(this, from, friendly, static_cast<FileTransferInvitation *>(invg));
215
        }
213
        }
216
        
214
        
217
        if (invg == NULL)
215
        if (invg == NULL)
218
        {
216
        {
219
            ext::showError(this, "Unknown invitation type!");
217
            this->myNotificationServer()->externalCallbacks.showError(this, "Unknown invitation type!");
220
            return;
218
            return;
221
        }
219
        }
222
        
220
        
Lines 225-235 Link Here
225
    
223
    
226
    void SwitchboardServerConnection::handle_BYE(std::vector<std::string> & args)
224
    void SwitchboardServerConnection::handle_BYE(std::vector<std::string> & args)
227
    {
225
    {
228
        assert(connectionStatus >= SB_CONNECTED);        
226
        this->assertConnectionStateIsAtLeast(SB_CONNECTED);        
229
        std::list<Passport> & list = this->users;
227
        std::list<Passport> & list = this->users;
230
        std::list<Passport>::iterator i;
228
        std::list<Passport>::iterator i;
231
        
229
        
232
        ext::buddyLeftConversation(this, args[1]);
230
        this->myNotificationServer()->externalCallbacks.buddyLeftConversation(this, args[1]);
233
        
231
        
234
        for (i = list.begin(); i != list.end(); i++)
232
        for (i = list.begin(); i != list.end(); i++)
235
        {
233
        {
Lines 249-280 Link Here
249
    
247
    
250
    void SwitchboardServerConnection::handle_JOI(std::vector<std::string> & args)
248
    void SwitchboardServerConnection::handle_JOI(std::vector<std::string> & args)
251
    {
249
    {
252
        assert(connectionStatus >= SB_CONNECTED);        
250
        this->assertConnectionStateIsAtLeast(SB_CONNECTED);        
253
        if (args[1] == this->auth.username)
251
        if (args[1] == this->auth.username)
254
            return;
252
            return;
255
        
253
        
256
        if (this->auth.sessionID.empty() && connectionStatus == SB_WAITING_FOR_USERS)
254
        if (this->auth.sessionID.empty() && this->connectionState() == SB_WAITING_FOR_USERS)
257
            connectionStatus = SB_READY;
255
            this->setConnectionState(SB_READY);
258
        
256
        
259
        this->users.push_back(args[1]);
257
        this->users.push_back(args[1]);
260
        ext::buddyJoinedConversation(this, args[1], decodeURL(args[2]), 0);
258
        this->myNotificationServer()->externalCallbacks.buddyJoinedConversation(this, args[1], decodeURL(args[2]), 0);
261
    }
259
    }
262
    
260
    
263
    void SwitchboardServerConnection::handle_NAK(std::vector<std::string> & args)
261
    void SwitchboardServerConnection::handle_NAK(std::vector<std::string> & args)
264
    {
262
    {
265
        assert(connectionStatus >= SB_CONNECTED);        
263
        this->assertConnectionStateIsAtLeast(SB_CONNECTED);        
266
        ext::failedSendingMessage(this);
264
        this->myNotificationServer()->externalCallbacks.failedSendingMessage(this);
267
    }
265
    }
268
    
266
    
269
    void SwitchboardServerConnection::handle_MSG(std::vector<std::string> & args)
267
    void SwitchboardServerConnection::handle_MSG(std::vector<std::string> & args)
270
    {
268
    {
271
        assert(connectionStatus >= SB_CONNECTED);        
269
        this->assertConnectionStateIsAtLeast(SB_CONNECTED);        
272
        Connection::handle_MSG(args);
270
        Connection::handle_MSG(args);
273
    }
271
    }
274
    
272
    
275
    void SwitchboardServerConnection::sendTypingNotification()
273
    void SwitchboardServerConnection::sendTypingNotification()
276
    {
274
    {
277
        assert(connectionStatus >= SB_READY);        
275
        this->assertConnectionStateIsAtLeast(SB_READY);        
278
        std::ostringstream buf_, msg_;
276
        std::ostringstream buf_, msg_;
279
        msg_ << "MIME-Version: 1.0\r\n";
277
        msg_ << "MIME-Version: 1.0\r\n";
280
        msg_ << "Content-Type: text/x-msmsgscontrol\r\n";
278
        msg_ << "Content-Type: text/x-msmsgscontrol\r\n";
Lines 283-336 Link Here
283
        msg_ << "\r\n";
281
        msg_ << "\r\n";
284
        size_t msg_length = msg_.str().size();
282
        size_t msg_length = msg_.str().size();
285
        
283
        
286
        buf_ << "MSG " << trid++ << " U " << (int) msg_length << "\r\n" << msg_.str();
284
        buf_ << "MSG " << this->trID++ << " U " << (int) msg_length << "\r\n" << msg_.str();
287
        
285
        
288
        write(buf_);        
286
        write(buf_);        
289
    }
287
    }
290
    
288
    
291
    void SwitchboardServerConnection::inviteUser(Passport userName)
289
    void SwitchboardServerConnection::inviteUser(Passport userName)
292
    {
290
    {
293
        assert(connectionStatus >= SB_WAITING_FOR_USERS);        
291
        this->assertConnectionStateIsAtLeast(SB_WAITING_FOR_USERS);        
294
        std::ostringstream buf_;
292
        std::ostringstream buf_;
295
        buf_ << "CAL " << trid++ << " " << userName << "\r\n";
293
        buf_ << "CAL " << this->trID++ << " " << userName << "\r\n";
296
        write(buf_);        
294
        write(buf_);        
297
    }
295
    }
298
    
296
    
299
    void SwitchboardServerConnection::connect(const std::string & hostname, unsigned int port)
297
    void SwitchboardServerConnection::connect(const std::string & hostname, unsigned int port)
300
    {
298
    {
301
        assert(connectionStatus == SB_DISCONNECTED);
299
        this->assertConnectionStateIs(SB_DISCONNECTED);
302
300
303
        if ((this->sock = ext::connectToServer(hostname, port, &this->connected)) == -1)
301
        if ((this->sock = this->myNotificationServer()->externalCallbacks.connectToServer(hostname, port, &this->connected)) == -1)
304
        {
302
        {
305
            ext::showError(this, "Could not connect to switchboard server");
303
            this->myNotificationServer()->externalCallbacks.showError(this, "Could not connect to switchboard server");
306
            return;
304
            return;
307
        }
305
        }
308
        
306
        
309
        ext::registerSocket(this->sock, 1, 1);
307
        this->myNotificationServer()->externalCallbacks.registerSocket(this->sock, 1, 1);
310
        connectionStatus = SB_CONNECTING;
308
        this->setConnectionState(SB_CONNECTING);
309
        
310
        if (this->connected)
311
            this->socketConnectionCompleted();
312
        
311
        std::ostringstream buf_;
313
        std::ostringstream buf_;
312
        if (this->auth.sessionID.empty())
314
        if (this->auth.sessionID.empty())
313
        {
315
        {
314
            buf_ << "USR " << trid << " " << this->auth.username << " " << this->auth.cookie << "\r\n";
316
            buf_ << "USR " << this->trID << " " << this->auth.username << " " << this->auth.cookie << "\r\n";
315
            this->write(buf_);
317
            if (this->write(buf_) != buf_.str().size())
316
            this->addCallback(&SwitchboardServerConnection::callback_InviteUsers, trid, NULL);
318
                return;
319
            this->addCallback(&SwitchboardServerConnection::callback_InviteUsers, this->trID, NULL);
317
        } 
320
        } 
318
        else
321
        else
319
        {
322
        {
320
            buf_ << "ANS " << trid << " " << this->auth.username << " " << this->auth.cookie << " " << this->auth.sessionID << "\r\n";
323
            buf_ << "ANS " << this->trID << " " << this->auth.username << " " << this->auth.cookie << " " << this->auth.sessionID << "\r\n";
321
            this->write(buf_);
324
            if (this->write(buf_) != buf_.str().size())
322
            ext::gotNewConnection(this);
325
                return;
323
            this->addCallback(&SwitchboardServerConnection::callback_AnsweredCall, trid, NULL);
326
            this->myNotificationServer()->externalCallbacks.gotNewConnection(this);
327
            this->addCallback(&SwitchboardServerConnection::callback_AnsweredCall, this->trID, NULL);
324
        }
328
        }
325
        
329
        
326
        trid++;    
330
        this->trID++;    
327
    }
331
    }
328
    
332
    
329
    void SwitchboardServerConnection::disconnect()
333
    void SwitchboardServerConnection::disconnect()
330
    {
334
    {
331
        assert(connectionStatus != SB_DISCONNECTED);
335
        this->assertConnectionStateIsNot(SB_DISCONNECTED);
332
        notificationServer.removeSwitchboardConnection(this);
336
        notificationServer.removeSwitchboardConnection(this);
333
        ext::closingConnection(this);
337
        this->myNotificationServer()->externalCallbacks.closingConnection(this);
334
        
338
        
335
        std::list<FileTransferConnection *> list = _fileTransferConnections;
339
        std::list<FileTransferConnection *> list = _fileTransferConnections;
336
        std::list<FileTransferConnection *>::iterator i = list.begin();
340
        std::list<FileTransferConnection *>::iterator i = list.begin();
Lines 338-359 Link Here
338
        {
342
        {
339
            removeFileTransferConnection(*i);
343
            removeFileTransferConnection(*i);
340
        }
344
        }
345
        this->callbacks.clear();
341
        Connection::disconnect();
346
        Connection::disconnect();
342
        connectionStatus = SB_DISCONNECTED;
347
        this->setConnectionState(SB_DISCONNECTED);
343
    }    
348
    }    
344
    
349
    
345
    void SwitchboardServerConnection::socketConnectionCompleted()
350
    void SwitchboardServerConnection::socketConnectionCompleted()
346
    {
351
    {
347
        assert(connectionStatus == SB_CONNECTING);
352
        this->assertConnectionStateIs(SB_CONNECTING);
348
        Connection::socketConnectionCompleted();
353
        Connection::socketConnectionCompleted();
349
        ext::unregisterSocket(this->sock);
354
        this->myNotificationServer()->externalCallbacks.unregisterSocket(this->sock);
350
        ext::registerSocket(this->sock, 1, 0);
355
        this->myNotificationServer()->externalCallbacks.registerSocket(this->sock, 1, 0);
351
        connectionStatus = SB_WAITING_FOR_USERS;
356
        this->setConnectionState(SB_WAITING_FOR_USERS);
352
    }
357
    }
353
    
358
    
354
    void SwitchboardServerConnection::handleIncomingData()
359
    void SwitchboardServerConnection::handleIncomingData()
355
    {
360
    {
356
        assert(connectionStatus >= SB_CONNECTED);        
361
        this->assertConnectionStateIsAtLeast(SB_CONNECTED);        
357
        while (this->isWholeLineAvailable())
362
        while (this->isWholeLineAvailable())
358
        {                
363
        {                
359
            std::vector<std::string> args = this->getLine();
364
            std::vector<std::string> args = this->getLine();
Lines 397-403 Link Here
397
    
402
    
398
    void SwitchboardServerConnection::callback_InviteUsers(std::vector<std::string> & args, int trid, void *)
403
    void SwitchboardServerConnection::callback_InviteUsers(std::vector<std::string> & args, int trid, void *)
399
    {    
404
    {    
400
        assert(connectionStatus >= SB_CONNECTED);
405
        this->assertConnectionStateIsAtLeast(SB_CONNECTED);
401
        this->removeCallback(trid);
406
        this->removeCallback(trid);
402
        
407
        
403
        if (args[2] != "OK")
408
        if (args[2] != "OK")
Lines 407-419 Link Here
407
            return;
412
            return;
408
        }
413
        }
409
        
414
        
410
        ext::gotSwitchboard(this, this->auth.tag);
415
        this->myNotificationServer()->externalCallbacks.gotSwitchboard(this, this->auth.tag);
411
        ext::gotNewConnection(this);
416
        this->myNotificationServer()->externalCallbacks.gotNewConnection(this);
412
    }
417
    }
413
    
418
    
414
    void SwitchboardServerConnection::callback_AnsweredCall(std::vector<std::string> & args, int trid, void * data)
419
    void SwitchboardServerConnection::callback_AnsweredCall(std::vector<std::string> & args, int trid, void * data)
415
    {
420
    {
416
        assert(connectionStatus == SB_WAITING_FOR_USERS);        
421
        this->assertConnectionStateIs(SB_WAITING_FOR_USERS);        
417
        if (args.size() >= 3 && args[0] == "ANS" && args[2] == "OK")
422
        if (args.size() >= 3 && args[0] == "ANS" && args[2] == "OK")
418
            return;
423
            return;
419
        
424
        
Lines 431-453 Link Here
431
                return;
436
                return;
432
            
437
            
433
            this->users.push_back(args[4]);
438
            this->users.push_back(args[4]);
434
            ext::buddyJoinedConversation(this, args[4], decodeURL(args[5]), 1);
439
            this->myNotificationServer()->externalCallbacks.buddyJoinedConversation(this, args[4], decodeURL(args[5]), 1);
435
            if (args[2] == args[3])
440
            if (args[2] == args[3])
436
            {
441
            {
437
                this->removeCallback(trid);
442
                this->removeCallback(trid);
438
                connectionStatus = SB_READY;
443
                this->setConnectionState(SB_READY);
439
            }
444
            }
440
        }
445
        }
441
    }
446
    }
442
    
447
    
443
    FileTransferInvitation *SwitchboardServerConnection::sendFile(const std::string path)
448
    FileTransferInvitation *SwitchboardServerConnection::sendFile(const std::string path)
444
    {
449
    {
445
        assert(connectionStatus == SB_READY);        
450
        this->assertConnectionStateIs(SB_READY);        
446
        struct stat st_info;
451
        struct stat st_info;
447
        
452
        
448
        if (stat(path.c_str(), &st_info) < 0)
453
        if (stat(path.c_str(), &st_info) < 0)
449
        { 
454
        { 
450
            ext::showError(this, "Could not open file"); 
455
            this->myNotificationServer()->externalCallbacks.showError(this, "Could not open file"); 
451
            return NULL; 
456
            return NULL; 
452
        }
457
        }
453
        
458
        
Lines 486-492 Link Here
486
        
491
        
487
        delete msg;
492
        delete msg;
488
        
493
        
489
        ext::fileTransferProgress(inv, "Negotiating connection", 0, 0);
494
        this->myNotificationServer()->externalCallbacks.fileTransferProgress(inv, "Negotiating connection", 0, 0);
490
        
495
        
491
        return inv;
496
        return inv;
492
    }
497
    }
(-)centericq-4.21.0.orig/libmsn-0.1/msn/switchboardserver.h (-2 / +11 lines)
Lines 28-33 Link Here
28
#include <msn/connection.h>
28
#include <msn/connection.h>
29
#include <msn/passport.h>
29
#include <msn/passport.h>
30
#include <string>
30
#include <string>
31
#include <cassert>
31
32
32
namespace MSN
33
namespace MSN
33
{
34
{
Lines 40-45 Link Here
40
     */
41
     */
41
    class SwitchboardServerConnection : public Connection
42
    class SwitchboardServerConnection : public Connection
42
    {
43
    {
44
        friend class FileTransferConnection;        
45
        friend class FileTransferInvitation;
43
private:
46
private:
44
        typedef void (SwitchboardServerConnection::*SwitchboardServerCallback)(std::vector<std::string> & args, int trid, void *);
47
        typedef void (SwitchboardServerConnection::*SwitchboardServerCallback)(std::vector<std::string> & args, int trid, void *);
45
public:
48
public:
Lines 141-150 Link Here
141
            SB_READY
144
            SB_READY
142
        };
145
        };
143
        
146
        
144
        SwitchboardServerState connectionState() const { return this->connectionStatus; };
147
        SwitchboardServerState connectionState() const { return this->_connectionState; };
148
        virtual NotificationServerConnection *myNotificationServer() { return &notificationServer; };        
145
protected:
149
protected:
146
        virtual void handleIncomingData();
150
        virtual void handleIncomingData();
147
        SwitchboardServerState connectionStatus;
151
        SwitchboardServerState _connectionState;
152
153
        void setConnectionState(SwitchboardServerState s) { this->_connectionState = s; };
154
        void assertConnectionStateIs(SwitchboardServerState s) { assert(this->_connectionState == s); };
155
        void assertConnectionStateIsNot(SwitchboardServerState s) { assert(this->_connectionState != s); };
156
        void assertConnectionStateIsAtLeast(SwitchboardServerState s) { assert(this->_connectionState >= s); };
148
private:
157
private:
149
        NotificationServerConnection & notificationServer;
158
        NotificationServerConnection & notificationServer;
150
        std::list<FileTransferConnection *> _fileTransferConnections;
159
        std::list<FileTransferConnection *> _fileTransferConnections;
(-)centericq-4.21.0.orig/libmsn-0.1/msn/util.cpp (-1 / +1 lines)
Lines 21-27 Link Here
21
 */
21
 */
22
22
23
#include <msn/util.h>
23
#include <msn/util.h>
24
#include <cerrno>
24
#include <errno.h>
25
#include <cctype>
25
#include <cctype>
26
26
27
namespace MSN 
27
namespace MSN 
(-)centericq-4.21.0.orig/src/hooks/msnhook.cc (-71 / +71 lines)
Lines 86-92 Link Here
86
86
87
// ----------------------------------------------------------------------------
87
// ----------------------------------------------------------------------------
88
88
89
msnhook::msnhook(): abstracthook(msn), conn() {
89
msnhook::msnhook(): abstracthook(msn), conn(cb) {
90
    ourstatus = offline;
90
    ourstatus = offline;
91
    fonline = false;
91
    fonline = false;
92
    destroying = false;
92
    destroying = false;
Lines 605-623 Link Here
605
	face.log(s);
605
	face.log(s);
606
}
606
}
607
607
608
void MSN::ext::log(int writing, const char* buf) {
608
void msncallbacks::log(int writing, const char* buf) {
609
    string pref = writing ? "OUT" : "IN";
609
    string pref = writing ? "OUT" : "IN";
610
    ::log((string) "[" + pref + "] " + buf);
610
    ::log((string) "[" + pref + "] " + buf);
611
}
611
}
612
612
613
void MSN::ext::registerSocket(int s, int reading, int writing) {
613
void msncallbacks::registerSocket(int s, int reading, int writing) {
614
    ::log("MSN::ext::registerSocket");
614
    ::log("msncallbacks::registerSocket");
615
    if(reading) mhook.rfds.push_back(s);
615
    if(reading) mhook.rfds.push_back(s);
616
    if(writing) mhook.wfds.push_back(s);
616
    if(writing) mhook.wfds.push_back(s);
617
}
617
}
618
618
619
void MSN::ext::unregisterSocket(int s) {
619
void msncallbacks::unregisterSocket(int s) {
620
    ::log("MSN::ext::unregisterSocket");
620
    ::log("msncallbacks::unregisterSocket");
621
    vector<int>::iterator i;
621
    vector<int>::iterator i;
622
622
623
    i = find(mhook.rfds.begin(), mhook.rfds.end(), s);
623
    i = find(mhook.rfds.begin(), mhook.rfds.end(), s);
Lines 627-640 Link Here
627
    if(i != mhook.wfds.end()) mhook.wfds.erase(i);
627
    if(i != mhook.wfds.end()) mhook.wfds.erase(i);
628
}
628
}
629
629
630
void MSN::ext::gotFriendlyName(MSN::Connection * conn, string friendlyname) {
630
void msncallbacks::gotFriendlyName(MSN::Connection * conn, string friendlyname) {
631
    ::log("MSN::ext::gotFriendlyName");
631
    ::log("msncallbacks::gotFriendlyName");
632
    if(!friendlyname.empty())
632
    if(!friendlyname.empty())
633
	mhook.friendlynicks[conf.getourid(msn).nickname] = friendlyname;
633
	mhook.friendlynicks[conf.getourid(msn).nickname] = friendlyname;
634
}
634
}
635
635
636
void MSN::ext::gotBuddyListInfo(MSN::NotificationServerConnection * conn, MSN::ListSyncInfo * data) {
636
void msncallbacks::gotBuddyListInfo(MSN::NotificationServerConnection * conn, MSN::ListSyncInfo * data) {
637
    ::log("MSN::ext::gotBuddyListInfo");
637
    ::log("msncallbacks::gotBuddyListInfo");
638
    imcontact ic;
638
    imcontact ic;
639
    bool found;
639
    bool found;
640
640
Lines 689-708 Link Here
689
    face.update();
689
    face.update();
690
}
690
}
691
691
692
void MSN::ext::gotLatestListSerial(MSN::Connection * conn, int serial) {
692
void msncallbacks::gotLatestListSerial(MSN::Connection * conn, int serial) {
693
    ::log("MSN::ext::gotLatestListSerial");
693
    ::log("msncallbacks::gotLatestListSerial");
694
}
694
}
695
695
696
void MSN::ext::gotGTC(MSN::Connection * conn, char c) {
696
void msncallbacks::gotGTC(MSN::Connection * conn, char c) {
697
    ::log("MSN::ext::gotGTC");
697
    ::log("msncallbacks::gotGTC");
698
}
698
}
699
699
700
void MSN::ext::gotBLP(MSN::Connection * conn, char c) {
700
void msncallbacks::gotBLP(MSN::Connection * conn, char c) {
701
    ::log("MSN::ext::gotBLP");
701
    ::log("msncallbacks::gotBLP");
702
}
702
}
703
703
704
void MSN::ext::gotNewReverseListEntry(MSN::Connection * conn, MSN::Passport buddy, std::string friendlyname) {
704
void msncallbacks::gotNewReverseListEntry(MSN::Connection * conn, MSN::Passport buddy, std::string friendlyname) {
705
    ::log("MSN::ext::gotNewReverseListEntry");
705
    ::log("msncallbacks::gotNewReverseListEntry");
706
706
707
    try {
707
    try {
708
	mhook.conn.addToList("AL", buddy);
708
	mhook.conn.addToList("AL", buddy);
Lines 714-726 Link Here
714
    em.store(imnotification(ic, _("The user has added you to his/her contact list")));
714
    em.store(imnotification(ic, _("The user has added you to his/her contact list")));
715
}
715
}
716
716
717
void MSN::ext::addedListEntry(MSN::Connection * conn, string lst, MSN::Passport buddy, int groupID) {
717
void msncallbacks::addedListEntry(MSN::Connection * conn, string lst, MSN::Passport buddy, int groupID) {
718
    ::log("MSN::ext::addedListEntry");
718
    ::log("msncallbacks::addedListEntry");
719
    mhook.slst[lst].push_back(msnbuddy(buddy, "", groupID));
719
    mhook.slst[lst].push_back(msnbuddy(buddy, "", groupID));
720
}
720
}
721
721
722
void MSN::ext::removedListEntry(MSN::Connection * conn, string lst, MSN::Passport buddy, int groupID) {
722
void msncallbacks::removedListEntry(MSN::Connection * conn, string lst, MSN::Passport buddy, int groupID) {
723
    ::log("MSN::ext::removedListEntry");
723
    ::log("msncallbacks::removedListEntry");
724
    vector<msnbuddy>::iterator i = mhook.slst[lst].begin();
724
    vector<msnbuddy>::iterator i = mhook.slst[lst].begin();
725
    while(i != mhook.slst[lst].end()) {
725
    while(i != mhook.slst[lst].end()) {
726
	if(i->nick == buddy) {
726
	if(i->nick == buddy) {
Lines 732-753 Link Here
732
    }
732
    }
733
}
733
}
734
734
735
void MSN::ext::showError(MSN::Connection * conn, string msg) {
735
void msncallbacks::showError(MSN::Connection * conn, string msg) {
736
    ::log(msg);
736
    ::log(msg);
737
}
737
}
738
738
739
void MSN::ext::buddyChangedStatus(MSN::Connection * conn, MSN::Passport buddy, string friendlyname, MSN::BuddyStatus state) {
739
void msncallbacks::buddyChangedStatus(MSN::Connection * conn, MSN::Passport buddy, string friendlyname, MSN::BuddyStatus state) {
740
    ::log("MSN::ext::buddyChangedStatus");
740
    ::log("msncallbacks::buddyChangedStatus");
741
    mhook.statusupdate(buddy, friendlyname, buddy2stat(state));
741
    mhook.statusupdate(buddy, friendlyname, buddy2stat(state));
742
}
742
}
743
743
744
void MSN::ext::buddyOffline(MSN::Connection * conn, MSN::Passport buddy) {
744
void msncallbacks::buddyOffline(MSN::Connection * conn, MSN::Passport buddy) {
745
    ::log("MSN::ext::buddyOffline");
745
    ::log("msncallbacks::buddyOffline");
746
    mhook.statusupdate(buddy, "", offline);
746
    mhook.statusupdate(buddy, "", offline);
747
}
747
}
748
748
749
void MSN::ext::gotSwitchboard(MSN::SwitchboardServerConnection * conn, const void * tag) {
749
void msncallbacks::gotSwitchboard(MSN::SwitchboardServerConnection * conn, const void * tag) {
750
    ::log("MSN::ext::gotSwitchboard");
750
    ::log("msncallbacks::gotSwitchboard");
751
751
752
    if(tag) {
752
    if(tag) {
753
	const msnhook::qevent *ctx = static_cast<const msnhook::qevent *>(tag);
753
	const msnhook::qevent *ctx = static_cast<const msnhook::qevent *>(tag);
Lines 755-762 Link Here
755
    }
755
    }
756
}
756
}
757
757
758
void MSN::ext::buddyJoinedConversation(MSN::SwitchboardServerConnection * conn, MSN::Passport buddy, std::string friendlyname, int is_initial) {
758
void msncallbacks::buddyJoinedConversation(MSN::SwitchboardServerConnection * conn, MSN::Passport buddy, std::string friendlyname, int is_initial) {
759
    ::log("MSN::ext::buddyJoinedConversation");
759
    ::log("msncallbacks::buddyJoinedConversation");
760
    if(conn->auth.tag) {
760
    if(conn->auth.tag) {
761
	const msnhook::qevent *ctx = static_cast<const msnhook::qevent *>(conn->auth.tag);
761
	const msnhook::qevent *ctx = static_cast<const msnhook::qevent *>(conn->auth.tag);
762
	mhook.lconn[ctx->nick] = conn;
762
	mhook.lconn[ctx->nick] = conn;
Lines 765-776 Link Here
765
    }
765
    }
766
}
766
}
767
767
768
void MSN::ext::buddyLeftConversation(MSN::SwitchboardServerConnection * conn, MSN::Passport buddy) {
768
void msncallbacks::buddyLeftConversation(MSN::SwitchboardServerConnection * conn, MSN::Passport buddy) {
769
    ::log("MSN::ext::buddyLeftConversation");
769
    ::log("msncallbacks::buddyLeftConversation");
770
}
770
}
771
771
772
void MSN::ext::gotInstantMessage(MSN::SwitchboardServerConnection * conn, MSN::Passport buddy, std::string friendlyname, MSN::Message * msg) {
772
void msncallbacks::gotInstantMessage(MSN::SwitchboardServerConnection * conn, MSN::Passport buddy, std::string friendlyname, MSN::Message * msg) {
773
    ::log("MSN::ext::gotInstantMessage");
773
    ::log("msncallbacks::gotInstantMessage");
774
    imcontact ic(nicktodisp(buddy), msn);
774
    imcontact ic(nicktodisp(buddy), msn);
775
775
776
    mhook.checkinlist(ic);
776
    mhook.checkinlist(ic);
Lines 779-808 Link Here
779
    em.store(immessage(ic, imevent::incoming, text));
779
    em.store(immessage(ic, imevent::incoming, text));
780
}
780
}
781
781
782
void MSN::ext::failedSendingMessage(MSN::Connection * conn) {
782
void msncallbacks::failedSendingMessage(MSN::Connection * conn) {
783
    ::log("MSN::ext::failedSendingMessage");
783
    ::log("msncallbacks::failedSendingMessage");
784
}
784
}
785
785
786
void MSN::ext::buddyTyping(MSN::Connection * conn, MSN::Passport buddy, std::string friendlyname) {
786
void msncallbacks::buddyTyping(MSN::Connection * conn, MSN::Passport buddy, std::string friendlyname) {
787
    ::log("MSN::ext::buddyTyping");
787
    ::log("msncallbacks::buddyTyping");
788
    icqcontact *c = clist.get(imcontact(nicktodisp(buddy), msn));
788
    icqcontact *c = clist.get(imcontact(nicktodisp(buddy), msn));
789
    if(c) c->setlasttyping(timer_current);
789
    if(c) c->setlasttyping(timer_current);
790
}
790
}
791
791
792
void MSN::ext::gotInitialEmailNotification(MSN::Connection * conn, int unread_inbox, int unread_folders) {
792
void msncallbacks::gotInitialEmailNotification(MSN::Connection * conn, int unread_inbox, int unread_folders) {
793
    ::log("MSN::ext::gotInitialEmailNotification");
793
    ::log("msncallbacks::gotInitialEmailNotification");
794
    face.log(_("+ [msn] unread e-mail: %d in inbox, %d in folders"),
794
    face.log(_("+ [msn] unread e-mail: %d in inbox, %d in folders"),
795
	unread_inbox, unread_folders);
795
	unread_inbox, unread_folders);
796
}
796
}
797
797
798
void MSN::ext::gotNewEmailNotification(MSN::Connection * conn, string from, string subject) {
798
void msncallbacks::gotNewEmailNotification(MSN::Connection * conn, string from, string subject) {
799
    ::log("MSN::ext::gotNewEmailNotification");
799
    ::log("msncallbacks::gotNewEmailNotification");
800
    face.log(_("+ [msn] e-mail from %s, %s"), from.c_str(), subject.c_str());
800
    face.log(_("+ [msn] e-mail from %s, %s"), from.c_str(), subject.c_str());
801
    clist.get(contactroot)->playsound(imevent::email);
801
    clist.get(contactroot)->playsound(imevent::email);
802
}
802
}
803
803
804
void MSN::ext::gotFileTransferInvitation(MSN::Connection * conn, MSN::Passport buddy, std::string friendlyname, MSN::FileTransferInvitation * inv) {
804
void msncallbacks::gotFileTransferInvitation(MSN::Connection * conn, MSN::Passport buddy, std::string friendlyname, MSN::FileTransferInvitation * inv) {
805
    ::log("MSN::ext::gotFileTransferInvitation");
805
    ::log("msncallbacks::gotFileTransferInvitation");
806
    if(!mhook.fcapabs.count(hookcapab::files))
806
    if(!mhook.fcapabs.count(hookcapab::files))
807
	return;
807
	return;
808
808
Lines 821-828 Link Here
821
    face.transferupdate(inv->fileName, fr, icqface::tsInit, inv->fileSize, 0);
821
    face.transferupdate(inv->fileName, fr, icqface::tsInit, inv->fileSize, 0);
822
}
822
}
823
823
824
void MSN::ext::fileTransferProgress(MSN::FileTransferInvitation * inv, string status, unsigned long recv, unsigned long total) {
824
void msncallbacks::fileTransferProgress(MSN::FileTransferInvitation * inv, string status, unsigned long recv, unsigned long total) {
825
    ::log("MSN::ext::fileTransferProgress");
825
    ::log("msncallbacks::fileTransferProgress");
826
    imfile fr;
826
    imfile fr;
827
827
828
    if(mhook.getfevent(inv, fr)) {
828
    if(mhook.getfevent(inv, fr)) {
Lines 831-838 Link Here
831
    }
831
    }
832
}
832
}
833
833
834
void MSN::ext::fileTransferFailed(MSN::FileTransferInvitation * inv, int error, string message) {
834
void msncallbacks::fileTransferFailed(MSN::FileTransferInvitation * inv, int error, string message) {
835
    ::log("MSN::ext::fileTransferFailed");
835
    ::log("msncallbacks::fileTransferFailed");
836
    imfile fr;
836
    imfile fr;
837
837
838
    if(mhook.getfevent(inv, fr)) {
838
    if(mhook.getfevent(inv, fr)) {
Lines 841-848 Link Here
841
    }
841
    }
842
}
842
}
843
843
844
void MSN::ext::fileTransferSucceeded(MSN::FileTransferInvitation * inv) {
844
void msncallbacks::fileTransferSucceeded(MSN::FileTransferInvitation * inv) {
845
    ::log("MSN::ext::fileTransferSucceeded");
845
    ::log("msncallbacks::fileTransferSucceeded");
846
    imfile fr;
846
    imfile fr;
847
847
848
    if(mhook.getfevent(inv, fr)) {
848
    if(mhook.getfevent(inv, fr)) {
Lines 851-864 Link Here
851
    }
851
    }
852
}
852
}
853
853
854
void MSN::ext::gotNewConnection(MSN::Connection * conn) {
854
void msncallbacks::gotNewConnection(MSN::Connection * conn) {
855
    ::log("MSN::ext::gotNewConnection");
855
    ::log("msncallbacks::gotNewConnection");
856
    if(dynamic_cast<MSN::NotificationServerConnection *>(conn))
856
    if(dynamic_cast<MSN::NotificationServerConnection *>(conn))
857
	dynamic_cast<MSN::NotificationServerConnection *>(conn)->synchronizeLists();
857
	dynamic_cast<MSN::NotificationServerConnection *>(conn)->synchronizeLists();
858
}
858
}
859
859
860
void MSN::ext::closingConnection(MSN::Connection * conn) {
860
void msncallbacks::closingConnection(MSN::Connection * conn) {
861
    ::log("MSN::ext::closingConnection");
861
    ::log("msncallbacks::closingConnection");
862
862
863
    MSN::SwitchboardServerConnection *swc;
863
    MSN::SwitchboardServerConnection *swc;
864
864
Lines 894-905 Link Here
894
    unregisterSocket(conn->sock);
894
    unregisterSocket(conn->sock);
895
}
895
}
896
896
897
void MSN::ext::changedStatus(MSN::Connection * conn, MSN::BuddyStatus state) {
897
void msncallbacks::changedStatus(MSN::Connection * conn, MSN::BuddyStatus state) {
898
    ::log("MSN::ext::changedStatus");
898
    ::log("msncallbacks::changedStatus");
899
}
899
}
900
900
901
int MSN::ext::connectToServer(string server, int port, bool *connected) {
901
int msncallbacks::connectToServer(string server, int port, bool *connected) {
902
    ::log("MSN::ext::connectToServer");
902
    ::log("msncallbacks::connectToServer");
903
    struct sockaddr_in sa;
903
    struct sockaddr_in sa;
904
    struct hostent *hp;
904
    struct hostent *hp;
905
    int a, s;
905
    int a, s;
Lines 936-943 Link Here
936
    return s;
936
    return s;
937
}
937
}
938
938
939
int MSN::ext::listenOnPort(int port) {
939
int msncallbacks::listenOnPort(int port) {
940
    ::log("MSN::ext::listenOnPort");
940
    ::log("msncallbacks::listenOnPort");
941
    int s;
941
    int s;
942
    struct sockaddr_in addr;
942
    struct sockaddr_in addr;
943
943
Lines 956-963 Link Here
956
    return s;
956
    return s;
957
}
957
}
958
958
959
string MSN::ext::getOurIP() {
959
string msncallbacks::getOurIP() {
960
    ::log("MSN::ext::getOurIP");
960
    ::log("msncallbacks::getOurIP");
961
    struct hostent *hn;
961
    struct hostent *hn;
962
    char buf2[1024];
962
    char buf2[1024];
963
963
Lines 967-979 Link Here
967
    return inet_ntoa(*((struct in_addr*) hn->h_addr));
967
    return inet_ntoa(*((struct in_addr*) hn->h_addr));
968
}
968
}
969
969
970
string MSN::ext::getSecureHTTPProxy() {
970
string msncallbacks::getSecureHTTPProxy() {
971
    ::log("MSN::ext::getSecureHTTPProxy");
971
    ::log("msncallbacks::getSecureHTTPProxy");
972
    return "";
972
    return "";
973
}
973
}
974
974
975
void MSN::ext::addedGroup(MSN::Connection * conn, string groupName, int groupID) {
975
void msncallbacks::addedGroup(MSN::Connection * conn, string groupName, int groupID) {
976
    ::log("MSN::ext::addedGroup");
976
    ::log("msncallbacks::addedGroup");
977
    int i;
977
    int i;
978
    icqcontact *c;
978
    icqcontact *c;
979
979
Lines 994-1006 Link Here
994
    }
994
    }
995
}
995
}
996
996
997
void MSN::ext::renamedGroup(MSN::Connection * conn, int groupID, string newGroupName) {
997
void msncallbacks::renamedGroup(MSN::Connection * conn, int groupID, string newGroupName) {
998
    ::log("MSN::ext::renamedGroup");
998
    ::log("msncallbacks::renamedGroup");
999
    mhook.mgroups[groupID] = newGroupName;
999
    mhook.mgroups[groupID] = newGroupName;
1000
}
1000
}
1001
1001
1002
void MSN::ext::removedGroup(MSN::Connection * conn, int groupID) {
1002
void msncallbacks::removedGroup(MSN::Connection * conn, int groupID) {
1003
    ::log("MSN::ext::removedGroup");
1003
    ::log("msncallbacks::removedGroup");
1004
    mhook.mgroups.erase(groupID);
1004
    mhook.mgroups.erase(groupID);
1005
}
1005
}
1006
1006
(-)centericq-4.21.0.orig/src/hooks/msnhook.h (-36 / +77 lines)
Lines 20-68 Link Here
20
	{ return nick != anick; }
20
	{ return nick != anick; }
21
};
21
};
22
22
23
class msncallbacks : public MSN::Callbacks {
24
    public:
25
        void registerSocket(int s, int read, int write);
26
        void unregisterSocket(int s);
27
        void showError(MSN::Connection * conn, std::string msg);
28
        void buddyChangedStatus(MSN::Connection * conn, MSN::Passport buddy, std::string friendlyname, MSN::BuddyStatus state);
29
        void buddyOffline(MSN::Connection * conn, MSN::Passport buddy);
30
        void log(int writing, const char* buf);
31
        void gotFriendlyName(MSN::Connection * conn, std::string friendlyname);
32
        void gotBuddyListInfo(MSN::NotificationServerConnection * conn, MSN::ListSyncInfo * data);
33
        void gotLatestListSerial(MSN::Connection * conn, int serial);
34
        void gotGTC(MSN::Connection * conn, char c);
35
        void gotBLP(MSN::Connection * conn, char c);
36
        void gotNewReverseListEntry(MSN::Connection * conn, MSN::Passport buddy, std::string friendlyname);
37
        void addedListEntry(MSN::Connection * conn, std::string list, MSN::Passport buddy, int groupID);
38
        void removedListEntry(MSN::Connection * conn, std::string list, MSN::Passport buddy, int groupID);
39
        void addedGroup(MSN::Connection * conn, std::string groupName, int groupID);
40
        void removedGroup(MSN::Connection * conn, int groupID);
41
        void renamedGroup(MSN::Connection * conn, int groupID, std::string newGroupName);
42
        void gotSwitchboard(MSN::SwitchboardServerConnection * conn, const void * tag);
43
        void buddyJoinedConversation(MSN::SwitchboardServerConnection * conn, MSN::Passport buddy, std::string friendlyname, int is_initial);
44
        void buddyLeftConversation(MSN::SwitchboardServerConnection * conn, MSN::Passport buddy);
45
        void gotInstantMessage(MSN::SwitchboardServerConnection * conn, MSN::Passport buddy, std::string friendlyname, MSN::Message * msg);
46
        void failedSendingMessage(MSN::Connection * conn);
47
        void buddyTyping(MSN::Connection * conn, MSN::Passport buddy, std::string friendlyname);
48
        void gotInitialEmailNotification(MSN::Connection * conn, int unread_inbox, int unread_folders);
49
        void gotNewEmailNotification(MSN::Connection * conn, std::string from, std::string subject);
50
        void gotFileTransferInvitation(MSN::Connection * conn, MSN::Passport buddy, std::string friendlyname, MSN::FileTransferInvitation * inv);
51
        void fileTransferProgress(MSN::FileTransferInvitation * inv, std::string status, unsigned long recv, unsigned long total);
52
        void fileTransferFailed(MSN::FileTransferInvitation * inv, int error, std::string message);
53
        void fileTransferSucceeded(MSN::FileTransferInvitation * inv);
54
        void gotNewConnection(MSN::Connection * conn);
55
        void closingConnection(MSN::Connection * conn);
56
        void changedStatus(MSN::Connection * conn, MSN::BuddyStatus state);
57
        int connectToServer(std::string server, int port, bool *connected);
58
        int listenOnPort(int port);
59
        std::string getOurIP();
60
        std::string getSecureHTTPProxy();
61
};
62
23
class msnhook : public abstracthook {
63
class msnhook : public abstracthook {
24
64
25
    friend void MSN::ext::registerSocket(int s, int reading, int writing);
65
    friend void msncallbacks::registerSocket(int s, int reading, int writing);
26
    friend void MSN::ext::unregisterSocket(int s);
66
    friend void msncallbacks::unregisterSocket(int s);
27
    friend void MSN::ext::showError(MSN::Connection * conn, string msg);
67
    friend void msncallbacks::showError(MSN::Connection * conn, string msg);
28
    friend void MSN::ext::buddyChangedStatus(MSN::Connection * conn, MSN::Passport buddy, string friendlyname, MSN::BuddyStatus state);
68
    friend void msncallbacks::buddyChangedStatus(MSN::Connection * conn, MSN::Passport buddy, string friendlyname, MSN::BuddyStatus state);
29
    friend void MSN::ext::buddyOffline(MSN::Connection * conn, MSN::Passport buddy);
69
    friend void msncallbacks::buddyOffline(MSN::Connection * conn, MSN::Passport buddy);
30
    friend void MSN::ext::log(int writing, const char* buf);
70
    friend void msncallbacks::log(int writing, const char* buf);
31
    friend void MSN::ext::gotFriendlyName(MSN::Connection * conn, string friendlyname);
71
    friend void msncallbacks::gotFriendlyName(MSN::Connection * conn, string friendlyname);
32
    friend void MSN::ext::gotBuddyListInfo(MSN::NotificationServerConnection * conn, MSN::ListSyncInfo * data);
72
    friend void msncallbacks::gotBuddyListInfo(MSN::NotificationServerConnection * conn, MSN::ListSyncInfo * data);
33
    friend void MSN::ext::gotLatestListSerial(MSN::Connection * conn, int serial);
73
    friend void msncallbacks::gotLatestListSerial(MSN::Connection * conn, int serial);
34
    friend void MSN::ext::gotGTC(MSN::Connection * conn, char c);
74
    friend void msncallbacks::gotGTC(MSN::Connection * conn, char c);
35
    friend void MSN::ext::gotBLP(MSN::Connection * conn, char c);
75
    friend void msncallbacks::gotBLP(MSN::Connection * conn, char c);
36
    friend void MSN::ext::gotNewReverseListEntry(MSN::Connection * conn, MSN::Passport buddy, std::string friendlyname);
76
    friend void msncallbacks::gotNewReverseListEntry(MSN::Connection * conn, MSN::Passport buddy, std::string friendlyname);
37
    friend void MSN::ext::addedListEntry(MSN::Connection * conn, std::string list, MSN::Passport buddy, int groupID);
77
    friend void msncallbacks::addedListEntry(MSN::Connection * conn, std::string list, MSN::Passport buddy, int groupID);
38
    friend void MSN::ext::removedListEntry(MSN::Connection * conn, std::string list, MSN::Passport buddy, int groupID);
78
    friend void msncallbacks::removedListEntry(MSN::Connection * conn, std::string list, MSN::Passport buddy, int groupID);
39
    friend void MSN::ext::addedGroup(MSN::Connection * conn, string groupName, int groupID);
79
    friend void msncallbacks::addedGroup(MSN::Connection * conn, string groupName, int groupID);
40
    friend void MSN::ext::removedGroup(MSN::Connection * conn, int groupID);
80
    friend void msncallbacks::removedGroup(MSN::Connection * conn, int groupID);
41
    friend void MSN::ext::renamedGroup(MSN::Connection * conn, int groupID, string newGroupName);
81
    friend void msncallbacks::renamedGroup(MSN::Connection * conn, int groupID, string newGroupName);
42
    friend void MSN::ext::gotSwitchboard(MSN::SwitchboardServerConnection * conn, const void * tag);
82
    friend void msncallbacks::gotSwitchboard(MSN::SwitchboardServerConnection * conn, const void * tag);
43
    friend void MSN::ext::buddyJoinedConversation(MSN::SwitchboardServerConnection * conn, MSN::Passport buddy, std::string friendlyname, int is_initial);
83
    friend void msncallbacks::buddyJoinedConversation(MSN::SwitchboardServerConnection * conn, MSN::Passport buddy, std::string friendlyname, int is_initial);
44
    friend void MSN::ext::buddyLeftConversation(MSN::SwitchboardServerConnection * conn, MSN::Passport buddy);
84
    friend void msncallbacks::buddyLeftConversation(MSN::SwitchboardServerConnection * conn, MSN::Passport buddy);
45
    friend void MSN::ext::gotInstantMessage(MSN::SwitchboardServerConnection * conn, MSN::Passport buddy, std::string friendlyname, MSN::Message * msg);
85
    friend void msncallbacks::gotInstantMessage(MSN::SwitchboardServerConnection * conn, MSN::Passport buddy, std::string friendlyname, MSN::Message * msg);
46
    friend void MSN::ext::failedSendingMessage(MSN::Connection * conn);
86
    friend void msncallbacks::failedSendingMessage(MSN::Connection * conn);
47
    friend void MSN::ext::buddyTyping(MSN::Connection * conn, MSN::Passport buddy, std::string friendlyname);
87
    friend void msncallbacks::buddyTyping(MSN::Connection * conn, MSN::Passport buddy, std::string friendlyname);
48
    friend void MSN::ext::gotInitialEmailNotification(MSN::Connection * conn, int unread_inbox, int unread_folders);
88
    friend void msncallbacks::gotInitialEmailNotification(MSN::Connection * conn, int unread_inbox, int unread_folders);
49
    friend void MSN::ext::gotNewEmailNotification(MSN::Connection * conn, string from, string subject);
89
    friend void msncallbacks::gotNewEmailNotification(MSN::Connection * conn, string from, string subject);
50
    friend void MSN::ext::gotFileTransferInvitation(MSN::Connection * conn, MSN::Passport buddy, std::string friendlyname, MSN::FileTransferInvitation * inv);
90
    friend void msncallbacks::gotFileTransferInvitation(MSN::Connection * conn, MSN::Passport buddy, std::string friendlyname, MSN::FileTransferInvitation * inv);
51
    friend void MSN::ext::fileTransferProgress(MSN::FileTransferInvitation * inv, string status, unsigned long recv, unsigned long total);
91
    friend void msncallbacks::fileTransferProgress(MSN::FileTransferInvitation * inv, string status, unsigned long recv, unsigned long total);
52
    friend void MSN::ext::fileTransferFailed(MSN::FileTransferInvitation * inv, int error, string message);
92
    friend void msncallbacks::fileTransferFailed(MSN::FileTransferInvitation * inv, int error, string message);
53
    friend void MSN::ext::fileTransferSucceeded(MSN::FileTransferInvitation * inv);
93
    friend void msncallbacks::fileTransferSucceeded(MSN::FileTransferInvitation * inv);
54
    friend void MSN::ext::gotNewConnection(MSN::Connection * conn);
94
    friend void msncallbacks::gotNewConnection(MSN::Connection * conn);
55
    friend void MSN::ext::closingConnection(MSN::Connection * conn);
95
    friend void msncallbacks::closingConnection(MSN::Connection * conn);
56
    friend void MSN::ext::changedStatus(MSN::Connection * conn, MSN::BuddyStatus state);
96
    friend void msncallbacks::changedStatus(MSN::Connection * conn, MSN::BuddyStatus state);
57
    friend int MSN::ext::connectToServer(string server, int port, bool *connected);
97
    friend int msncallbacks::connectToServer(string server, int port, bool *connected);
58
    friend int MSN::ext::listenOnPort(int port);
98
    friend int msncallbacks::listenOnPort(int port);
59
    friend string MSN::ext::getOurIP();
99
    friend string msncallbacks::getOurIP();
60
    friend string MSN::ext::getSecureHTTPProxy();
100
    friend string msncallbacks::getSecureHTTPProxy();
61
101
62
    protected:
102
    protected:
63
	imstatus ourstatus;
103
	imstatus ourstatus;
64
	bool fonline, flogged, readinfo, destroying;
104
	bool fonline, flogged, readinfo, destroying;
65
	MSN::NotificationServerConnection conn;
105
	MSN::NotificationServerConnection conn;
106
	msncallbacks cb;
66
	time_t timer_ping;
107
	time_t timer_ping;
67
108
68
	struct qevent {
109
	struct qevent {

Return to bug 138740