comparison mcabber/src/jabglue.c @ 1014:99c5278bf6b8

Keep the status and status messages when we're disconnected Improve the automatic reconnection after a network failure. - AutoConnection is only set to false when the user disconnects explicitly (i.e. in do_disconnect()). - AutoConnection is set to TRUE after the 1st successful connection. - In jb_setstatus(), update the status message and the "wanted status" even in offline mode. It helps with auto-away.
author Mikael Berthe <mikael@lilotux.net>
date Sun, 12 Nov 2006 22:25:14 +0100
parents f1a9ca2348e5
children 579299b1c9b2
comparison
equal deleted inserted replaced
1013:f1a9ca2348e5 1014:99c5278bf6b8
37 #define JABBERSSLPORT 5223 37 #define JABBERSSLPORT 5223
38 38
39 #define RECONNECTION_TIMEOUT 60L 39 #define RECONNECTION_TIMEOUT 60L
40 40
41 jconn jc; 41 jconn jc;
42 guint AutoConnection;
42 enum enum_jstate jstate; 43 enum enum_jstate jstate;
43 44
44 char imstatus2char[imstatus_size+1] = { 45 char imstatus2char[imstatus_size+1] = {
45 '_', 'o', 'i', 'f', 'd', 'n', 'a', '\0' 46 '_', 'o', 'i', 'f', 'd', 'n', 'a', '\0'
46 }; 47 };
47 48
48 static bool AutoConnection;
49 static time_t LastPingTime; 49 static time_t LastPingTime;
50 static unsigned int KeepaliveDelay; 50 static unsigned int KeepaliveDelay;
51 static enum imstatus mystatus = offline; 51 static enum imstatus mystatus = offline;
52 static enum imstatus mywantedstatus = available;
52 static gchar *mystatusmsg; 53 static gchar *mystatusmsg;
53 static unsigned char online; 54 static unsigned char online;
54 55
55 static void statehandler(jconn, int); 56 static void statehandler(jconn, int);
56 static void packethandler(jconn, jpacket); 57 static void packethandler(jconn, jpacket);
123 jstate = STATE_CONNECTING; 124 jstate = STATE_CONNECTING;
124 statehandler(0, -1); 125 statehandler(0, -1);
125 jab_start(jc); 126 jab_start(jc);
126 } 127 }
127 128
128 if (jc)
129 AutoConnection = true;
130
131 return jc; 129 return jc;
132 } 130 }
133 131
134 void jb_disconnect(void) 132 void jb_disconnect(void)
135 { 133 {
138 if (online) { 136 if (online) {
139 // Announce it to everyone else 137 // Announce it to everyone else
140 jb_setstatus(offline, NULL, ""); 138 jb_setstatus(offline, NULL, "");
141 // End the XML flow 139 // End the XML flow
142 jb_send_raw("</stream:stream>"); 140 jb_send_raw("</stream:stream>");
141 /*
142 // Free status message
143 g_free(mystatusmsg);
144 mystatusmsg = NULL;
145 */
143 } 146 }
144 147
145 // Announce it to the user 148 // Announce it to the user
146 statehandler(jc, JCONN_STATE_OFF); 149 statehandler(jc, JCONN_STATE_OFF);
147 150
148 jab_delete(jc); 151 jab_delete(jc);
149 jc = NULL; 152 jc = NULL;
150 AutoConnection = false;
151 } 153 }
152 154
153 inline void jb_reset_keepalive() 155 inline void jb_reset_keepalive()
154 { 156 {
155 time(&LastPingTime); 157 time(&LastPingTime);
179 static void check_connection(void) 181 static void check_connection(void)
180 { 182 {
181 static time_t disconnection_timestamp = 0L; 183 static time_t disconnection_timestamp = 0L;
182 time_t now; 184 time_t now;
183 185
186 // Maybe we're voluntarily offline...
187 if (!AutoConnection)
188 return;
189
184 // Are we totally disconnected? 190 // Are we totally disconnected?
185 if (jc && jc->state != JCONN_STATE_OFF) { 191 if (jc && jc->state != JCONN_STATE_OFF) {
186 disconnection_timestamp = 0L; 192 disconnection_timestamp = 0L;
187 return; 193 return;
188 } 194 }
189
190 // Maybe we're voluntarily offline...
191 if (!AutoConnection)
192 return;
193 195
194 time(&now); 196 time(&now);
195 if (!disconnection_timestamp) { 197 if (!disconnection_timestamp) {
196 disconnection_timestamp = now; 198 disconnection_timestamp = now;
197 return; 199 return;
401 } 403 }
402 404
403 void jb_setstatus(enum imstatus st, const char *recipient, const char *msg) 405 void jb_setstatus(enum imstatus st, const char *recipient, const char *msg)
404 { 406 {
405 xmlnode x; 407 xmlnode x;
406
407 if (!online) return;
408 408
409 if (msg) { 409 if (msg) {
410 // The status message has been specified. We'll use it, unless it is 410 // The status message has been specified. We'll use it, unless it is
411 // "-" which is a special case (option meaning "no status message"). 411 // "-" which is a special case (option meaning "no status message").
412 if (!strcmp(msg, "-")) 412 if (!strcmp(msg, "-"))
423 else 423 else
424 msg = ""; 424 msg = "";
425 } 425 }
426 } 426 }
427 427
428 x = presnew(st, recipient, (st != invisible ? msg : NULL)); 428 // Only send the packet if we're online.
429 jab_send(jc, x); 429 // (But we want to update internal status even when disconnected,
430 xmlnode_free(x); 430 // in order to avoid some problems during network failures)
431 if (online) {
432 x = presnew(st, recipient, (st != invisible ? msg : NULL));
433 jab_send(jc, x);
434 xmlnode_free(x);
435 }
431 436
432 // If we didn't change our _global_ status, we are done 437 // If we didn't change our _global_ status, we are done
433 if (recipient) return; 438 if (recipient) return;
434 439
435 // Send presence to chatrooms 440 if (online) {
436 if (st != invisible) { 441 // Send presence to chatrooms
437 struct T_presence room_presence; 442 if (st != invisible) {
438 room_presence.st = st; 443 struct T_presence room_presence;
439 room_presence.msg = msg; 444 room_presence.st = st;
440 foreach_buddy(ROSTER_TYPE_ROOM, &roompresence, &room_presence); 445 room_presence.msg = msg;
441 } 446 foreach_buddy(ROSTER_TYPE_ROOM, &roompresence, &room_presence);
442 447 }
443 // We'll need to update the roster if we switch to/from offline because 448 }
444 // we don't know the presences of buddies when offline... 449
445 if (mystatus == offline || st == offline) 450 if (online) {
446 update_roster = TRUE; 451 // We'll need to update the roster if we switch to/from offline because
447 452 // we don't know the presences of buddies when offline...
448 hk_mystatuschange(0, mystatus, st, (st != invisible ? msg : "")); 453 if (mystatus == offline || st == offline)
449 mystatus = st; 454 update_roster = TRUE;
455
456 hk_mystatuschange(0, mystatus, st, (st != invisible ? msg : ""));
457 mystatus = st;
458 }
459 if (st)
460 mywantedstatus = st;
450 if (msg != mystatusmsg) { 461 if (msg != mystatusmsg) {
451 g_free(mystatusmsg); 462 g_free(mystatusmsg);
452 if (*msg) 463 if (*msg)
453 mystatusmsg = g_strdup(msg); 464 mystatusmsg = g_strdup(msg);
454 else 465 else
455 mystatusmsg = NULL; 466 mystatusmsg = NULL;
456 } 467 }
457 468
458 // Update status line 469 // Update status line
459 scr_UpdateMainStatus(TRUE); 470 scr_UpdateMainStatus(TRUE);
471 }
472
473 // jb_setprevstatus()
474 // Set previous status. This wrapper function is used after a disconnection.
475 inline void jb_setprevstatus(void)
476 {
477 jb_setstatus(mywantedstatus, NULL, mystatusmsg);
460 } 478 }
461 479
462 // new_msgid() 480 // new_msgid()
463 // Generate a new id string. The caller should free it. 481 // Generate a new id string. The caller should free it.
464 static char *new_msgid(void) 482 static char *new_msgid(void)
1370 switch(state) { 1388 switch(state) {
1371 case JCONN_STATE_OFF: 1389 case JCONN_STATE_OFF:
1372 if (previous_state != JCONN_STATE_OFF) 1390 if (previous_state != JCONN_STATE_OFF)
1373 scr_LogPrint(LPRINT_LOGNORM, "[Jabber] Not connected to the server"); 1391 scr_LogPrint(LPRINT_LOGNORM, "[Jabber] Not connected to the server");
1374 1392
1393 // Sometimes the state isn't correctly updated
1394 if (jc)
1395 jc->state = JCONN_STATE_OFF;
1375 online = FALSE; 1396 online = FALSE;
1376 mystatus = offline; 1397 mystatus = offline;
1377 // Free status message
1378 g_free(mystatusmsg);
1379 mystatusmsg = NULL;
1380 // Free bookmarks 1398 // Free bookmarks
1381 xmlnode_free(bookmarks); 1399 xmlnode_free(bookmarks);
1382 bookmarks = NULL; 1400 bookmarks = NULL;
1383 // Free roster 1401 // Free roster
1384 roster_free(); 1402 roster_free();
1397 1415
1398 case JCONN_STATE_ON: 1416 case JCONN_STATE_ON:
1399 scr_LogPrint(LPRINT_LOGNORM, "[Jabber] Communication with the server " 1417 scr_LogPrint(LPRINT_LOGNORM, "[Jabber] Communication with the server "
1400 "established"); 1418 "established");
1401 online = TRUE; 1419 online = TRUE;
1420 // We set AutoConnection to true after the 1st successful connection
1421 AutoConnection = true;
1402 break; 1422 break;
1403 1423
1404 case JCONN_STATE_CONNECTING: 1424 case JCONN_STATE_CONNECTING:
1405 if (previous_state != state) 1425 if (previous_state != state)
1406 scr_LogPrint(LPRINT_LOGNORM, "[Jabber] Connecting to the server"); 1426 scr_LogPrint(LPRINT_LOGNORM, "[Jabber] Connecting to the server");