- Timestamp:
- 2010-04-24T17:02:07Z (15 years ago)
- Branches:
- master
- Children:
- c521362
- Parents:
- b5b40ff (diff), f1b7711 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- protocols
- Files:
-
- 7 added
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
protocols/jabber/jabber_util.c
rb5b40ff rae3dc99 671 671 time_t jabber_get_timestamp( struct xt_node *xt ) 672 672 { 673 struct tm tp, utc;674 673 struct xt_node *c; 675 time_t res, tres;676 674 char *s = NULL; 675 struct tm tp; 677 676 678 677 for( c = xt->children; ( c = xt_find_node( c, "x" ) ); c = c->next ) … … 692 691 tp.tm_year -= 1900; 693 692 tp.tm_mon --; 694 tp.tm_isdst = -1; /* GRRRRRRRRRRR */ 695 696 res = mktime( &tp ); 697 /* Problem is, mktime() just gave us the GMT timestamp for the 698 given local time... While the given time WAS NOT local. So 699 we should fix this now. 700 701 Now I could choose between messing with environment variables 702 (kludgy) or using timegm() (not portable)... Or doing the 703 following, which I actually prefer... */ 704 gmtime_r( &res, &utc ); 705 utc.tm_isdst = -1; /* Once more: GRRRRRRRRRRRRRRRRRR!!! */ 706 if( utc.tm_hour == tp.tm_hour && utc.tm_min == tp.tm_min ) 707 /* Sweet! We're in UTC right now... */ 708 return res; 709 710 tres = mktime( &utc ); 711 res += res - tres; 712 713 /* Yes, this is a hack. And it will go wrong around DST changes. 714 BUT this is more likely to be threadsafe than messing with 715 environment variables, and possibly more portable... */ 716 717 return res; 693 694 return mktime_utc( &tp ); 718 695 } 719 696 -
protocols/jabber/message.c
rb5b40ff rae3dc99 80 80 if( type && strcmp( type, "headline" ) == 0 ) 81 81 { 82 c = xt_find_node( node->children, "subject" );83 g_string_append_printf( fullmsg, "Headline: %s\n", c && c->text_len > 0 ? c->text : "");82 if( ( c = xt_find_node( node->children, "subject" ) ) && c->text_len > 0 ) 83 g_string_append_printf( fullmsg, "Headline: %s\n", c->text ); 84 84 85 85 /* <x xmlns="jabber:x:oob"><url>http://....</url></x> can contain a URL, it seems. */ -
protocols/msn/msn.c
rb5b40ff rae3dc99 31 31 GSList *msn_switchboards; 32 32 33 static char * msn_set_display_name( set_t *set, char *value );33 static char *set_eval_display_name( set_t *set, char *value ); 34 34 35 35 static void msn_init( account_t *acc ) 36 36 { 37 set_t *s; 38 39 s = set_add( &acc->set, "display_name", NULL, msn_set_display_name, acc ); 40 s->flags |= ACC_SET_NOSAVE | ACC_SET_ONLINE_ONLY; 41 42 s = set_add( &acc->set, "mail_notifications", "false", set_eval_bool, acc ); 37 set_add( &acc->set, "display_name", NULL, set_eval_display_name, acc ); 38 set_add( &acc->set, "local_display_name", "false", set_eval_bool, acc ); 39 set_add( &acc->set, "mail_notifications", "false", set_eval_bool, acc ); 40 set_add( &acc->set, "switchboard_keepalives", "false", set_eval_bool, acc ); 43 41 } 44 42 … … 171 169 static void msn_set_my_name( struct im_connection *ic, char *info ) 172 170 { 173 msn_set_display_name( set_find( &ic->acc->set, "display_name" ), info );171 msn_set_display_name( ic, info ); 174 172 } 175 173 … … 287 285 } 288 286 289 static char * msn_set_display_name( set_t *set, char *value )287 static char *set_eval_display_name( set_t *set, char *value ) 290 288 { 291 289 account_t *acc = set->data; 292 290 struct im_connection *ic = acc->ic; 293 struct msn_data *md; 294 char buf[1024], *fn; 295 296 /* Double-check. */ 291 292 /* Allow any name if we're offline. */ 297 293 if( ic == NULL ) 298 return NULL; 299 300 md = ic->proto_data; 294 return value; 301 295 302 296 if( strlen( value ) > 129 ) … … 305 299 return NULL; 306 300 } 307 308 fn = msn_http_encode( value );309 310 g_snprintf( buf, sizeof( buf ), "REA %d %s %s\r\n", ++md->trId, ic->acc->user, fn );311 msn_write( ic, buf, strlen( buf ) );312 g_free( fn );313 301 314 302 /* Returning NULL would be better, because the server still has to 315 303 confirm the name change. However, it looks a bit confusing to the 316 304 user. */ 317 return value;305 return msn_set_display_name( ic, value ) ? value : NULL; 318 306 } 319 307 -
protocols/msn/msn.h
rb5b40ff rae3dc99 31 31 #define TYPING_NOTIFICATION_MESSAGE "\r\r\rBEWARE, ME R TYPINK MESSAGE!!!!\r\r\r" 32 32 #define GROUPCHAT_SWITCHBOARD_MESSAGE "\r\r\rME WANT TALK TO MANY PEOPLE\r\r\r" 33 #define SB_KEEPALIVE_MESSAGE "\r\r\rDONT HANG UP ON ME!\r\r\r" 33 34 34 35 #ifdef DEBUG_MSN … … 53 54 "TypingUser: %s\r\n" \ 54 55 "\r\n\r\n" 56 57 #define SB_KEEPALIVE_HEADERS "MIME-Version: 1.0\r\n" \ 58 "Content-Type: text/x-ping\r\n" \ 59 "\r\n\r\n" 55 60 56 61 #define PROFILE_URL "http://members.msn.com/" … … 84 89 gint inp; 85 90 struct msn_handler_data *handler; 91 gint keepalive; 86 92 87 93 int trId; … … 162 168 char *msn_http_encode( const char *input ); 163 169 void msn_msgq_purge( struct im_connection *ic, GSList **list ); 170 gboolean msn_set_display_name( struct im_connection *ic, const char *rawname ); 164 171 165 172 /* tables.c */ … … 180 187 gboolean msn_sb_connected( gpointer data, gint source, b_input_condition cond ); 181 188 int msn_sb_write_msg( struct im_connection *ic, struct msn_message *m ); 189 void msn_sb_start_keepalives( struct msn_switchboard *sb, gboolean initial ); 190 void msn_sb_stop_keepalives( struct msn_switchboard *sb ); 182 191 183 192 /* invitation.c */ -
protocols/msn/msn_util.c
rb5b40ff rae3dc99 38 38 imcb_error( ic, "Short write() to main server" ); 39 39 imc_logout( ic, TRUE ); 40 return ( 0 );41 } 42 43 return ( 1 );40 return 0; 41 } 42 43 return 1; 44 44 } 45 45 … … 377 377 g_string_free( ret, TRUE ); 378 378 } 379 380 gboolean msn_set_display_name( struct im_connection *ic, const char *rawname ) 381 { 382 char *fn = msn_http_encode( rawname ); 383 struct msn_data *md = ic->proto_data; 384 char buf[1024]; 385 386 g_snprintf( buf, sizeof( buf ), "REA %d %s %s\r\n", ++md->trId, ic->acc->user, fn ); 387 g_free( fn ); 388 389 return msn_write( ic, buf, strlen( buf ) ) != 0; 390 } -
protocols/msn/ns.c
rb5b40ff rae3dc99 35 35 36 36 static void msn_auth_got_passport_token( struct msn_auth_data *mad ); 37 static gboolean msn_ns_got_display_name( struct im_connection *ic, char *name ); 37 38 38 39 gboolean msn_ns_connected( gpointer data, gint source, b_input_condition cond ) … … 231 232 else if( num_parts >= 7 && strcmp( cmd[2], "OK" ) == 0 ) 232 233 { 233 set_t *s;234 235 234 if( num_parts == 7 ) 236 { 237 http_decode( cmd[4] ); 238 239 strncpy( ic->displayname, cmd[4], sizeof( ic->displayname ) ); 240 ic->displayname[sizeof(ic->displayname)-1] = 0; 241 242 if( ( s = set_find( &ic->acc->set, "display_name" ) ) ) 243 { 244 g_free( s->value ); 245 s->value = g_strdup( cmd[4] ); 246 } 247 } 235 msn_ns_got_display_name( ic, cmd[4] ); 248 236 else 249 {250 237 imcb_log( ic, "Warning: Friendly name in server response was corrupted" ); 251 }252 238 253 239 imcb_log( ic, "Authenticated, getting buddy list" ); … … 436 422 else if( strcmp( cmd[0], "FLN" ) == 0 ) 437 423 { 438 if( cmd[1] ) 439 imcb_buddy_status( ic, cmd[1], 0, NULL, NULL ); 424 if( cmd[1] == NULL ) 425 return 1; 426 427 imcb_buddy_status( ic, cmd[1], 0, NULL, NULL ); 428 429 msn_sb_start_keepalives( msn_sb_by_handle( ic, cmd[1] ), TRUE ); 440 430 } 441 431 else if( strcmp( cmd[0], "NLN" ) == 0 ) … … 463 453 ( st != msn_away_state_list ? OPT_AWAY : 0 ), 464 454 st->name, NULL ); 455 456 msn_sb_stop_keepalives( msn_sb_by_handle( ic, cmd[2] ) ); 465 457 } 466 458 else if( strcmp( cmd[0], "RNG" ) == 0 ) … … 567 559 return( 0 ); 568 560 } 561 #if 0 562 /* Discard this one completely for now since I don't care about the ack 563 and since MSN servers can apparently screw up the formatting. */ 569 564 else if( strcmp( cmd[0], "REA" ) == 0 ) 570 565 { … … 597 592 } 598 593 } 594 #endif 599 595 else if( strcmp( cmd[0], "IPG" ) == 0 ) 600 596 { … … 746 742 } 747 743 } 744 745 static gboolean msn_ns_got_display_name( struct im_connection *ic, char *name ) 746 { 747 set_t *s; 748 749 if( ( s = set_find( &ic->acc->set, "display_name" ) ) == NULL ) 750 return FALSE; /* Shouldn't happen.. */ 751 752 http_decode( name ); 753 754 if( s->value && strcmp( s->value, name ) == 0 ) 755 { 756 return TRUE; 757 /* The names match, nothing to worry about. */ 758 } 759 else if( s->value != NULL && 760 ( strcmp( name, ic->acc->user ) == 0 || 761 set_getbool( &ic->acc->set, "local_display_name" ) ) ) 762 { 763 /* The server thinks our display name is our e-mail address 764 which is probably wrong, or the user *wants* us to do this: 765 Always use the locally set display_name. */ 766 return msn_set_display_name( ic, s->value ); 767 } 768 else 769 { 770 if( s->value && *s->value ) 771 imcb_log( ic, "BitlBee thinks your display name is `%s' but " 772 "the MSN server says it's `%s'. Using the MSN " 773 "server's name. Set local_display_name to true " 774 "to use the local name.", s->value, name ); 775 776 if( g_utf8_validate( name, -1, NULL ) ) 777 { 778 g_free( s->value ); 779 s->value = g_strdup( name ); 780 } 781 else 782 { 783 imcb_log( ic, "Warning: Friendly name in server response was corrupted" ); 784 } 785 786 return TRUE; 787 } 788 } -
protocols/msn/sb.c
rb5b40ff rae3dc99 180 180 i = strlen( buf ); 181 181 } 182 else if( strcmp( text, SB_KEEPALIVE_MESSAGE ) == 0 ) 183 { 184 buf = g_strdup( SB_KEEPALIVE_HEADERS ); 185 i = strlen( buf ); 186 } 182 187 else 183 188 { … … 256 261 257 262 msn_msgq_purge( ic, &sb->msgq ); 263 msn_sb_stop_keepalives( sb ); 258 264 259 265 if( sb->key ) g_free( sb->key ); … … 477 483 478 484 sb->ready = 1; 485 486 msn_sb_start_keepalives( sb, FALSE ); 479 487 } 480 488 else if( strcmp( cmd[0], "CAL" ) == 0 ) … … 526 534 } 527 535 536 msn_sb_start_keepalives( sb, FALSE ); 537 528 538 return( st ); 529 539 } … … 587 597 if( sb->who ) 588 598 { 599 msn_sb_stop_keepalives( sb ); 600 589 601 /* This is a single-person chat, and the other person is leaving. */ 590 602 g_free( sb->who ); … … 749 761 return( 1 ); 750 762 } 763 764 static gboolean msn_sb_keepalive( gpointer data, gint source, b_input_condition cond ) 765 { 766 struct msn_switchboard *sb = data; 767 return sb->ready && msn_sb_sendmessage( sb, SB_KEEPALIVE_MESSAGE ); 768 } 769 770 void msn_sb_start_keepalives( struct msn_switchboard *sb, gboolean initial ) 771 { 772 struct buddy *b; 773 774 if( sb && sb->who && sb->keepalive == 0 && 775 ( b = imcb_find_buddy( sb->ic, sb->who ) ) && !b->present && 776 set_getbool( &sb->ic->acc->set, "switchboard_keepalives" ) ) 777 { 778 if( initial ) 779 msn_sb_keepalive( sb, 0, 0 ); 780 781 sb->keepalive = b_timeout_add( 20000, msn_sb_keepalive, sb ); 782 } 783 } 784 785 void msn_sb_stop_keepalives( struct msn_switchboard *sb ) 786 { 787 if( sb && sb->keepalive > 0 ) 788 { 789 b_event_remove( sb->keepalive ); 790 sb->keepalive = 0; 791 } 792 } -
protocols/nogaim.c
rb5b40ff rae3dc99 39 39 40 40 static int remove_chat_buddy_silent( struct groupchat *b, const char *handle ); 41 static char *format_timestamp( irc_t *irc, time_t msg_ts ); 41 42 42 43 GSList *connections; … … 135 136 extern void byahoo_initmodule(); 136 137 extern void jabber_initmodule(); 138 extern void twitter_initmodule(); 137 139 extern void purple_initmodule(); 138 140 … … 151 153 #ifdef WITH_JABBER 152 154 jabber_initmodule(); 155 #endif 156 157 #ifdef WITH_TWITTER 158 twitter_initmodule(); 153 159 #endif 154 160 … … 726 732 { 727 733 irc_t *irc = ic->irc; 728 char *wrapped ;734 char *wrapped, *ts = NULL; 729 735 user_t *u; 730 736 … … 768 774 ( ( ic->flags & OPT_DOES_HTML ) && set_getbool( &ic->irc->set, "strip_html" ) ) ) 769 775 strip_html( msg ); 770 776 777 if( set_getbool( &ic->irc->set, "display_timestamps" ) && 778 ( ts = format_timestamp( irc, sent_at ) ) ) 779 { 780 char *new = g_strconcat( ts, msg, NULL ); 781 g_free( ts ); 782 ts = msg = new; 783 } 784 771 785 wrapped = word_wrap( msg, 425 ); 772 786 irc_msgfrom( irc, u->nick, wrapped ); 773 787 g_free( wrapped ); 788 g_free( ts ); 774 789 } 775 790 … … 813 828 814 829 return c; 830 } 831 832 void imcb_chat_name_hint( struct groupchat *c, const char *name ) 833 { 834 if( !c->joined ) 835 { 836 struct im_connection *ic = c->ic; 837 char stripped[MAX_NICK_LENGTH+1], *full_name; 838 839 strncpy( stripped, name, MAX_NICK_LENGTH ); 840 stripped[MAX_NICK_LENGTH] = '\0'; 841 nick_strip( stripped ); 842 if( set_getbool( &ic->irc->set, "lcnicks" ) ) 843 nick_lc( stripped ); 844 845 full_name = g_strdup_printf( "&%s", stripped ); 846 847 if( stripped[0] && 848 nick_cmp( stripped, ic->irc->channel + 1 ) != 0 && 849 irc_chat_by_channel( ic->irc, full_name ) == NULL ) 850 { 851 g_free( c->channel ); 852 c->channel = full_name; 853 } 854 else 855 { 856 g_free( full_name ); 857 } 858 } 815 859 } 816 860 … … 875 919 if( c && u ) 876 920 { 877 irc_privmsg( ic->irc, u, "PRIVMSG", c->channel, "", wrapped ); 921 char *ts = NULL; 922 if( set_getbool( &ic->irc->set, "display_timestamps" ) ) 923 ts = format_timestamp( ic->irc, sent_at ); 924 irc_privmsg( ic->irc, u, "PRIVMSG", c->channel, ts ? : "", wrapped ); 925 g_free( ts ); 878 926 } 879 927 else … … 1069 1117 } 1070 1118 1071 1072 1119 char *set_eval_timezone( set_t *set, char *value ) 1120 { 1121 char *s; 1122 1123 if( strcmp( value, "local" ) == 0 || 1124 strcmp( value, "gmt" ) == 0 || strcmp( value, "utc" ) == 0 ) 1125 return value; 1126 1127 /* Otherwise: +/- at the beginning optional, then one or more numbers, 1128 possibly followed by a colon and more numbers. Don't bother bound- 1129 checking them since users are free to shoot themselves in the foot. */ 1130 s = value; 1131 if( *s == '+' || *s == '-' ) 1132 s ++; 1133 1134 /* \d+ */ 1135 if( !isdigit( *s ) ) 1136 return SET_INVALID; 1137 while( *s && isdigit( *s ) ) s ++; 1138 1139 /* EOS? */ 1140 if( *s == '\0' ) 1141 return value; 1142 1143 /* Otherwise, colon */ 1144 if( *s != ':' ) 1145 return SET_INVALID; 1146 s ++; 1147 1148 /* \d+ */ 1149 if( !isdigit( *s ) ) 1150 return SET_INVALID; 1151 while( *s && isdigit( *s ) ) s ++; 1152 1153 /* EOS */ 1154 return *s == '\0' ? value : SET_INVALID; 1155 } 1156 1157 static char *format_timestamp( irc_t *irc, time_t msg_ts ) 1158 { 1159 time_t now_ts = time( NULL ); 1160 struct tm now, msg; 1161 char *set; 1162 1163 /* If the timestamp is <= 0 or less than a minute ago, discard it as 1164 it doesn't seem to add to much useful info and/or might be noise. */ 1165 if( msg_ts <= 0 || msg_ts > now_ts - 60 ) 1166 return NULL; 1167 1168 set = set_getstr( &irc->set, "timezone" ); 1169 if( strcmp( set, "local" ) == 0 ) 1170 { 1171 localtime_r( &now_ts, &now ); 1172 localtime_r( &msg_ts, &msg ); 1173 } 1174 else 1175 { 1176 int hr, min = 0, sign = 60; 1177 1178 if( set[0] == '-' ) 1179 { 1180 sign *= -1; 1181 set ++; 1182 } 1183 else if( set[0] == '+' ) 1184 { 1185 set ++; 1186 } 1187 1188 if( sscanf( set, "%d:%d", &hr, &min ) >= 1 ) 1189 { 1190 msg_ts += sign * ( hr * 60 + min ); 1191 now_ts += sign * ( hr * 60 + min ); 1192 } 1193 1194 gmtime_r( &now_ts, &now ); 1195 gmtime_r( &msg_ts, &msg ); 1196 } 1197 1198 if( msg.tm_year == now.tm_year && msg.tm_yday == now.tm_yday ) 1199 return g_strdup_printf( "\x02[\x02\x02\x02%02d:%02d:%02d\x02]\x02 ", 1200 msg.tm_hour, msg.tm_min, msg.tm_sec ); 1201 else 1202 return g_strdup_printf( "\x02[\x02\x02\x02%04d-%02d-%02d " 1203 "%02d:%02d:%02d\x02]\x02 ", 1204 msg.tm_year + 1900, msg.tm_mon, msg.tm_mday, 1205 msg.tm_hour, msg.tm_min, msg.tm_sec ); 1206 } 1073 1207 1074 1208 /* The plan is to not allow straight calls to prpl functions anymore, but do … … 1113 1247 { 1114 1248 char *away, *msg = NULL; 1249 1250 if( ic->acc->prpl->away_states == NULL || 1251 ic->acc->prpl->set_away == NULL ) 1252 return 0; 1115 1253 1116 1254 away = set_getstr( &ic->acc->set, "away" ) ? -
protocols/nogaim.h
rb5b40ff rae3dc99 308 308 * user, too. */ 309 309 G_MODULE_EXPORT struct groupchat *imcb_chat_new( struct im_connection *ic, const char *handle ); 310 G_MODULE_EXPORT void imcb_chat_name_hint( struct groupchat *c, const char *name ); 310 311 G_MODULE_EXPORT void imcb_chat_add_buddy( struct groupchat *b, const char *handle ); 311 312 /* To remove a handle from a group chat. Reason can be NULL. */ … … 330 331 331 332 /* Misc. stuff */ 333 char *set_eval_timezone( set_t *set, char *value ); 332 334 char *set_eval_away_devoice( set_t *set, char *value ); 333 335 gboolean auto_reconnect( gpointer data, gint fd, b_input_condition cond );
Note: See TracChangeset
for help on using the changeset viewer.