Changeset 5ebff60 for protocols/bee_user.c
- Timestamp:
- 2015-02-20T22:50:54Z (9 years ago)
- Branches:
- master
- Children:
- 0b9daac, 3d45471, 7733b8c
- Parents:
- af359b4
- git-author:
- Indent <please@…> (19-02-15 05:47:20)
- git-committer:
- dequis <dx@…> (20-02-15 22:50:54)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
protocols/bee_user.c
raf359b4 r5ebff60 1 1 /********************************************************************\ 2 2 * BitlBee -- An IRC to other IM-networks gateway * 3 3 * * … … 27 27 #include "bitlbee.h" 28 28 29 bee_user_t *bee_user_new( bee_t *bee, struct im_connection *ic, const char *handle, bee_user_flags_t flags)30 { 31 bee_user_t *bu; 32 33 if ( bee_user_by_handle( bee, ic, handle ) != NULL )29 bee_user_t *bee_user_new(bee_t *bee, struct im_connection *ic, const char *handle, bee_user_flags_t flags) 30 { 31 bee_user_t *bu; 32 33 if (bee_user_by_handle(bee, ic, handle) != NULL) { 34 34 return NULL; 35 36 bu = g_new0( bee_user_t, 1 ); 35 } 36 37 bu = g_new0(bee_user_t, 1); 37 38 bu->bee = bee; 38 39 bu->ic = ic; 39 40 bu->flags = flags; 40 bu->handle = g_strdup( handle ); 41 bee->users = g_slist_prepend( bee->users, bu ); 42 43 if( bee->ui->user_new ) 44 bee->ui->user_new( bee, bu ); 45 if( ic->acc->prpl->buddy_data_add ) 46 ic->acc->prpl->buddy_data_add( bu ); 47 41 bu->handle = g_strdup(handle); 42 bee->users = g_slist_prepend(bee->users, bu); 43 44 if (bee->ui->user_new) { 45 bee->ui->user_new(bee, bu); 46 } 47 if (ic->acc->prpl->buddy_data_add) { 48 ic->acc->prpl->buddy_data_add(bu); 49 } 50 48 51 /* Offline by default. This will set the right flags. */ 49 imcb_buddy_status( ic, handle, 0, NULL, NULL);50 52 imcb_buddy_status(ic, handle, 0, NULL, NULL); 53 51 54 return bu; 52 55 } 53 56 54 int bee_user_free( bee_t *bee, bee_user_t *bu)55 { 56 if ( !bu )57 int bee_user_free(bee_t *bee, bee_user_t *bu) 58 { 59 if (!bu) { 57 60 return 0; 58 59 if( bee->ui->user_free ) 60 bee->ui->user_free( bee, bu ); 61 if( bu->ic->acc->prpl->buddy_data_free ) 62 bu->ic->acc->prpl->buddy_data_free( bu ); 63 64 g_free( bu->handle ); 65 g_free( bu->fullname ); 66 g_free( bu->nick ); 67 g_free( bu->status ); 68 g_free( bu->status_msg ); 69 g_free( bu ); 70 71 bee->users = g_slist_remove( bee->users, bu ); 72 61 } 62 63 if (bee->ui->user_free) { 64 bee->ui->user_free(bee, bu); 65 } 66 if (bu->ic->acc->prpl->buddy_data_free) { 67 bu->ic->acc->prpl->buddy_data_free(bu); 68 } 69 70 g_free(bu->handle); 71 g_free(bu->fullname); 72 g_free(bu->nick); 73 g_free(bu->status); 74 g_free(bu->status_msg); 75 g_free(bu); 76 77 bee->users = g_slist_remove(bee->users, bu); 78 73 79 return 1; 74 80 } 75 81 76 bee_user_t *bee_user_by_handle( bee_t *bee, struct im_connection *ic, const char *handle)82 bee_user_t *bee_user_by_handle(bee_t *bee, struct im_connection *ic, const char *handle) 77 83 { 78 84 GSList *l; 79 80 for( l = bee->users; l; l = l->next ) 81 { 85 86 for (l = bee->users; l; l = l->next) { 82 87 bee_user_t *bu = l->data; 83 84 if ( bu->ic == ic && ic->acc->prpl->handle_cmp( bu->handle, handle ) == 0 )88 89 if (bu->ic == ic && ic->acc->prpl->handle_cmp(bu->handle, handle) == 0) { 85 90 return bu; 86 } 87 91 } 92 } 93 88 94 return NULL; 89 95 } 90 96 91 int bee_user_msg( bee_t *bee, bee_user_t *bu, const char *msg, int flags)97 int bee_user_msg(bee_t *bee, bee_user_t *bu, const char *msg, int flags) 92 98 { 93 99 char *buf = NULL; 94 100 int st; 95 96 if( ( bu->ic->flags & OPT_DOES_HTML ) && ( g_strncasecmp( msg, "<html>", 6 ) != 0 ) ) 97 { 98 buf = escape_html( msg ); 101 102 if ((bu->ic->flags & OPT_DOES_HTML) && (g_strncasecmp(msg, "<html>", 6) != 0)) { 103 buf = escape_html(msg); 99 104 msg = buf; 100 } 101 else102 buf = g_strdup( msg );103 104 st = bu->ic->acc->prpl->buddy_msg( bu->ic, bu->handle, buf, flags);105 g_free( buf);106 105 } else { 106 buf = g_strdup(msg); 107 } 108 109 st = bu->ic->acc->prpl->buddy_msg(bu->ic, bu->handle, buf, flags); 110 g_free(buf); 111 107 112 return st; 108 113 } … … 110 115 111 116 /* Groups */ 112 static bee_group_t *bee_group_new( bee_t *bee, const char *name)113 { 114 bee_group_t *bg = g_new0( bee_group_t, 1);115 116 bg->name = g_strdup( name);117 bg->key = g_utf8_casefold( name, -1);118 bee->groups = g_slist_prepend( bee->groups, bg);119 117 static bee_group_t *bee_group_new(bee_t *bee, const char *name) 118 { 119 bee_group_t *bg = g_new0(bee_group_t, 1); 120 121 bg->name = g_strdup(name); 122 bg->key = g_utf8_casefold(name, -1); 123 bee->groups = g_slist_prepend(bee->groups, bg); 124 120 125 return bg; 121 126 } 122 127 123 bee_group_t *bee_group_by_name( bee_t *bee, const char *name, gboolean creat)128 bee_group_t *bee_group_by_name(bee_t *bee, const char *name, gboolean creat) 124 129 { 125 130 GSList *l; 126 131 char *key; 127 128 if ( name == NULL )132 133 if (name == NULL) { 129 134 return NULL; 130 131 key = g_utf8_casefold( name, -1 ); 132 for( l = bee->groups; l; l = l->next )133 {135 } 136 137 key = g_utf8_casefold(name, -1); 138 for (l = bee->groups; l; l = l->next) { 134 139 bee_group_t *bg = l->data; 135 if ( strcmp( bg->key, key ) == 0 )140 if (strcmp(bg->key, key) == 0) { 136 141 break; 137 } 138 g_free( key ); 139 140 if( !l ) 141 return creat ? bee_group_new( bee, name ) : NULL; 142 else 142 } 143 } 144 g_free(key); 145 146 if (!l) { 147 return creat ? bee_group_new(bee, name) : NULL; 148 } else { 143 149 return l->data; 144 }145 146 void bee_group_free( bee_t *bee ) 147 { 148 while( bee->groups ) 149 {150 } 151 } 152 153 void bee_group_free(bee_t *bee) 154 { 155 while (bee->groups) { 150 156 bee_group_t *bg = bee->groups->data; 151 g_free( bg->name);152 g_free( bg->key);153 g_free( bg);154 bee->groups = g_slist_remove( bee->groups, bee->groups->data);157 g_free(bg->name); 158 g_free(bg->key); 159 g_free(bg); 160 bee->groups = g_slist_remove(bee->groups, bee->groups->data); 155 161 } 156 162 } … … 158 164 159 165 /* IM->UI callbacks */ 160 void imcb_buddy_status( struct im_connection *ic, const char *handle, int flags, const char *state, const char *message)166 void imcb_buddy_status(struct im_connection *ic, const char *handle, int flags, const char *state, const char *message) 161 167 { 162 168 bee_t *bee = ic->bee; 163 169 bee_user_t *bu, *old; 164 165 if( !( bu = bee_user_by_handle( bee, ic, handle ) ) ) 166 { 167 if( g_strcasecmp( set_getstr( &ic->bee->set, "handle_unknown" ), "add" ) == 0 ) 168 { 169 bu = bee_user_new( bee, ic, handle, BEE_USER_LOCAL ); 170 } 171 else 172 { 173 if( g_strcasecmp( set_getstr( &ic->bee->set, "handle_unknown" ), "ignore" ) != 0 ) 174 { 175 imcb_log( ic, "imcb_buddy_status() for unknown handle %s:\n" 176 "flags = %d, state = %s, message = %s", handle, flags, 177 state ? state : "NULL", message ? message : "NULL" ); 170 171 if (!(bu = bee_user_by_handle(bee, ic, handle))) { 172 if (g_strcasecmp(set_getstr(&ic->bee->set, "handle_unknown"), "add") == 0) { 173 bu = bee_user_new(bee, ic, handle, BEE_USER_LOCAL); 174 } else { 175 if (g_strcasecmp(set_getstr(&ic->bee->set, "handle_unknown"), "ignore") != 0) { 176 imcb_log(ic, "imcb_buddy_status() for unknown handle %s:\n" 177 "flags = %d, state = %s, message = %s", handle, flags, 178 state ? state : "NULL", message ? message : "NULL"); 178 179 } 179 180 180 181 return; 181 182 } 182 183 } 183 184 184 185 /* May be nice to give the UI something to compare against. */ 185 old = g_memdup( bu, sizeof( bee_user_t ));186 186 old = g_memdup(bu, sizeof(bee_user_t)); 187 187 188 /* TODO(wilmer): OPT_AWAY, or just state == NULL ? */ 188 189 bu->flags = flags; 189 bu->status_msg = g_strdup( message);190 if ( state && *state )191 bu->status = g_strdup( state);192 else if( flags & OPT_AWAY )193 bu->status = g_strdup( "Away");194 else190 bu->status_msg = g_strdup(message); 191 if (state && *state) { 192 bu->status = g_strdup(state); 193 } else if (flags & OPT_AWAY) { 194 bu->status = g_strdup("Away"); 195 } else { 195 196 bu->status = NULL; 196 197 if( bu->status == NULL && ( flags & OPT_MOBILE ) && 198 set_getbool( &bee->set, "mobile_is_away" ) )199 {197 } 198 199 if (bu->status == NULL && (flags & OPT_MOBILE) && 200 set_getbool(&bee->set, "mobile_is_away")) { 200 201 bu->flags |= BEE_USER_AWAY; 201 bu->status = g_strdup( "Mobile" ); 202 } 203 204 if( bee->ui->user_status ) 205 bee->ui->user_status( bee, bu, old ); 206 207 g_free( old->status_msg ); 208 g_free( old->status ); 209 g_free( old ); 202 bu->status = g_strdup("Mobile"); 203 } 204 205 if (bee->ui->user_status) { 206 bee->ui->user_status(bee, bu, old); 207 } 208 209 g_free(old->status_msg); 210 g_free(old->status); 211 g_free(old); 210 212 } 211 213 212 214 /* Same, but only change the away/status message, not any away/online state info. */ 213 void imcb_buddy_status_msg( struct im_connection *ic, const char *handle, const char *message)215 void imcb_buddy_status_msg(struct im_connection *ic, const char *handle, const char *message) 214 216 { 215 217 bee_t *bee = ic->bee; 216 218 bee_user_t *bu, *old; 217 218 if( !( bu = bee_user_by_handle( bee, ic, handle ) ) ) 219 { 219 220 if (!(bu = bee_user_by_handle(bee, ic, handle))) { 220 221 return; 221 222 } 222 223 old = g_memdup( bu, sizeof( bee_user_t ) ); 224 225 bu->status_msg = message && *message ? g_strdup( message ) : NULL; 226 227 if( bee->ui->user_status ) 228 bee->ui->user_status( bee, bu, old ); 229 230 g_free( old->status_msg ); 231 g_free( old ); 232 } 233 234 void imcb_buddy_times( struct im_connection *ic, const char *handle, time_t login, time_t idle ) 235 { 236 bee_t *bee = ic->bee; 237 bee_user_t *bu; 238 239 if( !( bu = bee_user_by_handle( bee, ic, handle ) ) ) 223 224 old = g_memdup(bu, sizeof(bee_user_t)); 225 226 bu->status_msg = message && *message ? g_strdup(message) : NULL; 227 228 if (bee->ui->user_status) { 229 bee->ui->user_status(bee, bu, old); 230 } 231 232 g_free(old->status_msg); 233 g_free(old); 234 } 235 236 void imcb_buddy_times(struct im_connection *ic, const char *handle, time_t login, time_t idle) 237 { 238 bee_t *bee = ic->bee; 239 bee_user_t *bu; 240 241 if (!(bu = bee_user_by_handle(bee, ic, handle))) { 240 242 return; 241 243 } 244 242 245 bu->login_time = login; 243 246 bu->idle_time = idle; 244 247 } 245 248 246 void imcb_buddy_msg( struct im_connection *ic, const char *handle, char *msg, uint32_t flags, time_t sent_at ) 247 { 248 bee_t *bee = ic->bee; 249 bee_user_t *bu; 250 251 bu = bee_user_by_handle( bee, ic, handle ); 252 253 if( !bu && !( ic->flags & OPT_LOGGING_OUT ) ) 254 { 255 char *h = set_getstr( &bee->set, "handle_unknown" ); 256 257 if( g_strcasecmp( h, "ignore" ) == 0 ) 258 { 249 void imcb_buddy_msg(struct im_connection *ic, const char *handle, char *msg, uint32_t flags, time_t sent_at) 250 { 251 bee_t *bee = ic->bee; 252 bee_user_t *bu; 253 254 bu = bee_user_by_handle(bee, ic, handle); 255 256 if (!bu && !(ic->flags & OPT_LOGGING_OUT)) { 257 char *h = set_getstr(&bee->set, "handle_unknown"); 258 259 if (g_strcasecmp(h, "ignore") == 0) { 259 260 return; 260 } 261 else if( g_strncasecmp( h, "add", 3 ) == 0 ) 262 { 263 bu = bee_user_new( bee, ic, handle, BEE_USER_LOCAL ); 264 } 265 } 266 267 if( bee->ui->user_msg && bu ) 268 bee->ui->user_msg( bee, bu, msg, sent_at ); 269 else 270 imcb_log( ic, "Message from unknown handle %s:\n%s", handle, msg ); 271 } 272 273 void imcb_buddy_typing( struct im_connection *ic, const char *handle, uint32_t flags ) 274 { 275 bee_user_t *bu; 276 277 if( ic->bee->ui->user_typing && 278 ( bu = bee_user_by_handle( ic->bee, ic, handle ) ) ) 279 { 280 ic->bee->ui->user_typing( ic->bee, bu, flags ); 281 } 282 } 283 284 void imcb_buddy_action_response( bee_user_t *bu, const char *action, char * const args[], void *data ) 285 { 286 if( bu->bee->ui->user_action_response ) 287 bu->bee->ui->user_action_response( bu->bee, bu, action, args, data ); 288 } 261 } else if (g_strncasecmp(h, "add", 3) == 0) { 262 bu = bee_user_new(bee, ic, handle, BEE_USER_LOCAL); 263 } 264 } 265 266 if (bee->ui->user_msg && bu) { 267 bee->ui->user_msg(bee, bu, msg, sent_at); 268 } else { 269 imcb_log(ic, "Message from unknown handle %s:\n%s", handle, msg); 270 } 271 } 272 273 void imcb_buddy_typing(struct im_connection *ic, const char *handle, uint32_t flags) 274 { 275 bee_user_t *bu; 276 277 if (ic->bee->ui->user_typing && 278 (bu = bee_user_by_handle(ic->bee, ic, handle))) { 279 ic->bee->ui->user_typing(ic->bee, bu, flags); 280 } 281 } 282 283 void imcb_buddy_action_response(bee_user_t *bu, const char *action, char * const args[], void *data) 284 { 285 if (bu->bee->ui->user_action_response) { 286 bu->bee->ui->user_action_response(bu->bee, bu, action, args, data); 287 } 288 }
Note: See TracChangeset
for help on using the changeset viewer.