Changes in irc_send.c [2d93f113:c54bb11]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
irc_send.c
r2d93f113 rc54bb11 172 172 irc_t *irc = ic->irc; 173 173 174 irc_write(irc, ":%s!%s@%s JOIN :%s", iu->nick, iu->user, iu->host, ic->name); 174 if (irc->caps & CAP_EXTENDED_JOIN) { 175 irc_write(irc, ":%s!%s@%s JOIN %s * :%s", iu->nick, iu->user, iu->host, ic->name, iu->fullname); 176 } else { 177 irc_write(irc, ":%s!%s@%s JOIN :%s", iu->nick, iu->user, iu->host, ic->name); 178 } 175 179 176 180 if (iu == irc->user) { … … 198 202 } 199 203 204 #define IRC_NAMES_LEN 385 205 200 206 void irc_send_names(irc_channel_t *ic) 201 207 { 202 208 GSList *l; 203 char namelist[385] = ""; 209 GString *namelist = g_string_sized_new(IRC_NAMES_LEN); 210 gboolean uhnames = (ic->irc->caps & CAP_USERHOST_IN_NAMES); 204 211 205 212 /* RFCs say there is no error reply allowed on NAMES, so when the … … 208 215 irc_channel_user_t *icu = l->data; 209 216 irc_user_t *iu = icu->iu; 210 211 if (strlen(namelist) + strlen(iu->nick) > sizeof(namelist) - 4) { 212 irc_send_num(ic->irc, 353, "= %s :%s", ic->name, namelist); 213 *namelist = 0; 214 } 215 216 if (icu->flags & IRC_CHANNEL_USER_OP) { 217 strcat(namelist, "@"); 218 } else if (icu->flags & IRC_CHANNEL_USER_HALFOP) { 219 strcat(namelist, "%"); 220 } else if (icu->flags & IRC_CHANNEL_USER_VOICE) { 221 strcat(namelist, "+"); 222 } 223 224 strcat(namelist, iu->nick); 225 strcat(namelist, " "); 226 } 227 228 if (*namelist) { 229 irc_send_num(ic->irc, 353, "= %s :%s", ic->name, namelist); 217 size_t extra_len = strlen(iu->nick); 218 char prefix; 219 220 if (uhnames) { 221 extra_len += strlen(iu->user) + strlen(iu->host) + 2; 222 } 223 224 if (namelist->len + extra_len > IRC_NAMES_LEN - 4) { 225 irc_send_num(ic->irc, 353, "= %s :%s", ic->name, namelist->str); 226 g_string_truncate(namelist, 0); 227 } 228 229 if ((prefix = irc_channel_user_get_prefix(icu))) { 230 g_string_append_c(namelist, prefix); 231 } 232 233 if (uhnames) { 234 g_string_append_printf(namelist, "%s!%s@%s ", iu->nick, iu->user, iu->host); 235 } else { 236 g_string_append(namelist, iu->nick); 237 g_string_append_c(namelist, ' '); 238 } 239 } 240 241 if (namelist->len) { 242 irc_send_num(ic->irc, 353, "= %s :%s", ic->name, namelist->str); 230 243 } 231 244 232 245 irc_send_num(ic->irc, 366, "%s :End of /NAMES list", ic->name); 246 247 g_string_free(namelist, TRUE); 233 248 } 234 249 … … 249 264 } 250 265 266 /* msg1 and msg2 are output parameters. If msg2 is non-null, msg1 is guaranteed to be non-null too. 267 The idea is to defer the formatting of "$msg1 ($msg2)" to later calls to avoid a g_strdup_printf() here. */ 268 static void get_status_message(bee_user_t *bu, char **msg1, char **msg2) 269 { 270 *msg1 = NULL; 271 *msg2 = NULL; 272 273 if (!(bu->flags & BEE_USER_ONLINE)) { 274 *msg1 = "User is offline"; 275 276 } else if ((bu->status && *bu->status) || 277 (bu->status_msg && *bu->status_msg)) { 278 279 if (bu->status && bu->status_msg) { 280 *msg1 = bu->status; 281 *msg2 = bu->status_msg; 282 } else { 283 *msg1 = bu->status ? : bu->status_msg; 284 } 285 } 286 287 if (*msg1 && !**msg1) { 288 *msg1 = (bu->flags & BEE_USER_AWAY) ? "Away" : NULL; 289 } 290 } 291 251 292 void irc_send_whois(irc_user_t *iu) 252 293 { … … 258 299 if (iu->bu) { 259 300 bee_user_t *bu = iu->bu; 301 char *msg1, *msg2; 302 int num; 260 303 261 304 irc_send_num(irc, 312, "%s %s.%s :%s network", iu->nick, bu->ic->acc->user, … … 263 306 bu->ic->acc->prpl->name); 264 307 265 if ((bu->status && *bu->status) || 266 (bu->status_msg && *bu->status_msg)) { 267 int num = bu->flags & BEE_USER_AWAY ? 301 : 320; 268 269 if (bu->status && bu->status_msg) { 270 irc_send_num(irc, num, "%s :%s (%s)", iu->nick, bu->status, bu->status_msg); 271 } else { 272 irc_send_num(irc, num, "%s :%s", iu->nick, bu->status ? : bu->status_msg); 273 } 274 } else if (!(bu->flags & BEE_USER_ONLINE)) { 275 irc_send_num(irc, 301, "%s :%s", iu->nick, "User is offline"); 308 num = (bu->flags & BEE_USER_AWAY || !(bu->flags & BEE_USER_ONLINE)) ? 301 : 320; 309 310 get_status_message(bu, &msg1, &msg2); 311 312 if (msg1 && msg2) { 313 irc_send_num(irc, num, "%s :%s (%s)", iu->nick, msg1, msg2); 314 } else if (msg1) { 315 irc_send_num(irc, num, "%s :%s", iu->nick, msg1); 276 316 } 277 317 … … 294 334 295 335 while (l) { 296 irc_user_t *iu = l->data; 336 irc_user_t *iu; 337 338 /* Null terminated string with three chars, respectively: 339 * { <H|G>, <@|%|+|\0>, \0 } */ 340 char status_prefix[3] = {0}; 341 297 342 if (is_channel) { 298 iu = ((irc_channel_user_t *) iu)->iu; 299 } 300 /* TODO(wilmer): Restore away/channel information here */ 301 irc_send_num(irc, 352, "%s %s %s %s %s %c :0 %s", 343 irc_channel_user_t *icu = l->data; 344 status_prefix[1] = irc_channel_user_get_prefix(icu); 345 iu = icu->iu; 346 } else { 347 iu = l->data; 348 } 349 350 /* rfc1459 doesn't mention this: G means gone, H means here */ 351 status_prefix[0] = iu->flags & IRC_USER_AWAY ? 'G' : 'H'; 352 353 irc_send_num(irc, 352, "%s %s %s %s %s %s :0 %s", 302 354 is_channel ? channel : "*", iu->user, iu->host, irc->root->host, 303 iu->nick, iu->flags & IRC_USER_AWAY ? 'G' : 'H', 304 iu->fullname); 355 iu->nick, status_prefix, iu->fullname); 305 356 l = l->next; 306 357 } … … 428 479 iu->nick, iu->user, iu->host, irc->user->nick, ic->name); 429 480 } 481 482 void irc_send_cap(irc_t *irc, char *subcommand, char *body) 483 { 484 char *nick = irc->user->nick ? : "*"; 485 486 irc_write(irc, ":%s CAP %s %s :%s", irc->root->host, nick, subcommand, body); 487 } 488 489 void irc_send_away_notify(irc_user_t *iu) 490 { 491 bee_user_t *bu = iu->bu; 492 493 if (!bu) { 494 return; 495 } 496 497 if (bu->flags & BEE_USER_AWAY || !(bu->flags & BEE_USER_ONLINE)) { 498 char *msg1, *msg2; 499 500 get_status_message(bu, &msg1, &msg2); 501 502 if (msg2) { 503 irc_write(iu->irc, ":%s!%s@%s AWAY :%s (%s)", iu->nick, iu->user, iu->host, msg1, msg2); 504 } else { 505 irc_write(iu->irc, ":%s!%s@%s AWAY :%s", iu->nick, iu->user, iu->host, msg1); 506 } 507 } else { 508 irc_write(iu->irc, ":%s!%s@%s AWAY", iu->nick, iu->user, iu->host); 509 } 510 } 511
Note: See TracChangeset
for help on using the changeset viewer.