Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • irc_send.c

    rc54bb11 r2d93f113  
    172172        irc_t *irc = ic->irc;
    173173
    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         }
     174        irc_write(irc, ":%s!%s@%s JOIN :%s", iu->nick, iu->user, iu->host, ic->name);
    179175
    180176        if (iu == irc->user) {
     
    202198}
    203199
    204 #define IRC_NAMES_LEN 385
    205 
    206200void irc_send_names(irc_channel_t *ic)
    207201{
    208202        GSList *l;
    209         GString *namelist = g_string_sized_new(IRC_NAMES_LEN);
    210         gboolean uhnames = (ic->irc->caps & CAP_USERHOST_IN_NAMES);
     203        char namelist[385] = "";
    211204
    212205        /* RFCs say there is no error reply allowed on NAMES, so when the
     
    215208                irc_channel_user_t *icu = l->data;
    216209                irc_user_t *iu = icu->iu;
    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);
     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);
    243230        }
    244231
    245232        irc_send_num(ic->irc, 366, "%s :End of /NAMES list", ic->name);
    246 
    247         g_string_free(namelist, TRUE);
    248233}
    249234
     
    264249}
    265250
    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 
    292251void irc_send_whois(irc_user_t *iu)
    293252{
     
    299258        if (iu->bu) {
    300259                bee_user_t *bu = iu->bu;
    301                 char *msg1, *msg2;
    302                 int num;
    303260
    304261                irc_send_num(irc, 312, "%s %s.%s :%s network", iu->nick, bu->ic->acc->user,
     
    306263                             bu->ic->acc->prpl->name);
    307264
    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);
     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");
    316276                }
    317277
     
    334294
    335295        while (l) {
    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 
     296                irc_user_t *iu = l->data;
    342297                if (is_channel) {
    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",
     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",
    354302                             is_channel ? channel : "*", iu->user, iu->host, irc->root->host,
    355                              iu->nick, status_prefix, iu->fullname);
     303                             iu->nick, iu->flags & IRC_USER_AWAY ? 'G' : 'H',
     304                             iu->fullname);
    356305                l = l->next;
    357306        }
     
    479428                  iu->nick, iu->user, iu->host, irc->user->nick, ic->name);
    480429}
    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.