X-Git-Url: https://jfr.im/git/solanum.git/blobdiff_plain/35eccf49306c5f774229a67b4966719c14444d0f..6a0074bfaa195daa621ec6348f2abc2720e65ab0:/modules/m_whois.c diff --git a/modules/m_whois.c b/modules/m_whois.c index 40544b7e..68bb17c9 100644 --- a/modules/m_whois.c +++ b/modules/m_whois.c @@ -60,12 +60,14 @@ struct Message whois_msgtab = { int doing_whois_hook; int doing_whois_global_hook; int doing_whois_channel_visibility_hook; +int doing_whois_show_idle_hook; mapi_clist_av1 whois_clist[] = { &whois_msgtab, NULL }; mapi_hlist_av1 whois_hlist[] = { { "doing_whois", &doing_whois_hook }, { "doing_whois_global", &doing_whois_global_hook }, { "doing_whois_channel_visibility", &doing_whois_channel_visibility_hook }, + { "doing_whois_show_idle", &doing_whois_show_idle_hook }, { NULL, NULL } }; @@ -224,12 +226,7 @@ static void single_whois(struct Client *source_p, struct Client *target_p, int operspy) { char buf[BUFSIZE]; - int cur_len = 0; - int mlen; - char *t; - int tlen; hook_data_client hdata; - int extra_space = 0; struct sockaddr_in ip4; if(target_p->user == NULL) @@ -242,7 +239,7 @@ single_whois(struct Client *source_p, struct Client *target_p, int operspy) target_p->name, target_p->username, target_p->host, target_p->info); - cur_len = mlen = sprintf(buf, form_str(RPL_WHOISCHANNELS), + send_multiline_init(source_p, " ", form_str(RPL_WHOISCHANNELS), get_id(&me, source_p), get_id(source_p, source_p), target_p->name); @@ -250,16 +247,8 @@ single_whois(struct Client *source_p, struct Client *target_p, int operspy) * in full names; note that serverhiding may require more space * for a different server name (not done here) -- jilles */ - if (!MyConnect(source_p)) - { - extra_space = strlen(source_p->name) - 9; - if (extra_space < 0) - extra_space = 0; - extra_space += strlen(me.name) - 2; /* make sure >= 0 */ - cur_len += extra_space; - } - - t = buf + mlen; + send_multiline_remote_pad(source_p, &me); + send_multiline_remote_pad(source_p, source_p); hdata.client = source_p; hdata.target = target_p; @@ -288,25 +277,15 @@ single_whois(struct Client *source_p, struct Client *target_p, int operspy) if(hdata_vis.approved || operspy) { - if((cur_len + strlen(chptr->chname) + strlen("!@+ ")) > (BUFSIZE - strlen("\r\n"))) - { - sendto_one(source_p, "%s", buf); - cur_len = mlen + extra_space; - t = buf + mlen; - } - - tlen = sprintf(t, "%s%s%s ", + send_multiline_item(source_p, "%s%s%s", hdata_vis.approved ? "" : "!", find_channel_status(mt, 1), chptr->chname); - t += tlen; - cur_len += tlen; } } } - if(cur_len > mlen + extra_space) - sendto_one(source_p, "%s", buf); + send_multiline_fini(source_p, NULL); sendto_one_numeric(source_p, RPL_WHOISSERVER, form_str(RPL_WHOISSERVER), target_p->name, target_p->servptr->name, @@ -316,25 +295,36 @@ single_whois(struct Client *source_p, struct Client *target_p, int operspy) sendto_one_numeric(source_p, RPL_AWAY, form_str(RPL_AWAY), target_p->name, target_p->user->away); - if((!ConfigFileEntry.hide_opers_in_whois || IsOper(source_p)) && SeesOper(target_p, source_p)) + char *s = NULL; + if (IsService(target_p)) { - sendto_one_numeric(source_p, RPL_WHOISOPERATOR, form_str(RPL_WHOISOPERATOR), - target_p->name, - IsService(target_p) ? ConfigFileEntry.servicestring : - (IsAdmin(target_p) ? GlobalSetOptions.adminstring : - GlobalSetOptions.operstring)); + s = ConfigFileEntry.servicestring; } - - if(!EmptyString(target_p->user->opername) && IsOper(target_p) && (target_p == source_p || HasPrivilege(source_p, "oper:privs"))) + if (!EmptyString(target_p->user->opername) && IsOper(target_p)) + { + if (target_p == source_p || HasPrivilege(source_p, "oper:privs")) + { + const char *privset = "(missing)"; + if (target_p->user->privset != NULL) + privset = target_p->user->privset->name; + snprintf(buf, sizeof buf, "is opered as %s, privset %s", target_p->user->opername, privset); + s = buf; + } + else if (IsOper(source_p) && SeesOper(target_p, source_p)) + { + snprintf(buf, sizeof buf, "is opered as %s", target_p->user->opername); + s = buf; + } + else if (!ConfigFileEntry.hide_opers_in_whois && SeesOper(target_p, source_p)) + { + s = IsAdmin(target_p) ? GlobalSetOptions.adminstring : + GlobalSetOptions.operstring; + } + } + if (s != NULL) { - char buf[512]; - const char *privset = "(missing)"; - if (target_p->user->privset != NULL) - privset = target_p->user->privset->name; - snprintf(buf, sizeof(buf), "is opered as %s, privset %s", - target_p->user->opername, privset); - sendto_one_numeric(source_p, RPL_WHOISSPECIAL, form_str(RPL_WHOISSPECIAL), - target_p->name, buf); + sendto_one_numeric(source_p, RPL_WHOISOPERATOR, form_str(RPL_WHOISOPERATOR), + target_p->name, s); } if(IsSecureClient(target_p)) @@ -385,10 +375,23 @@ single_whois(struct Client *source_p, struct Client *target_p, int operspy) target_p->name, buf); } + /* fire the doing_whois_show_idle hook to allow modules to tell us whether to show the idle time */ + hook_data_client_approval hdata_showidle; + + hdata_showidle.client = source_p; + hdata_showidle.target = target_p; + hdata_showidle.approved = WHOIS_IDLE_SHOW; + + call_hook(doing_whois_show_idle_hook, &hdata_showidle); + sendto_one_numeric(source_p, RPL_WHOISIDLE, form_str(RPL_WHOISIDLE), - target_p->name, - (long)(rb_current_time() - target_p->localClient->last), - (unsigned long)target_p->localClient->firsttime); + target_p->name, + hdata_showidle.approved ? (long)(rb_current_time() - target_p->localClient->last) : 0, + (unsigned long)target_p->localClient->firsttime); + + if (hdata_showidle.approved == WHOIS_IDLE_AUSPEX || hdata_showidle.approved == WHOIS_IDLE_HIDE) + /* if the target has hidden their idle time, notify the source */ + sendto_one_numeric(source_p, RPL_WHOISTEXT, form_str(RPL_WHOISTEXT), target_p->name, "is using a private idle time"); } else {