]> jfr.im git - irc/quakenet/newserv.git/blobdiff - helpmod2/hcommands.c
Merge chanserv-live into default.
[irc/quakenet/newserv.git] / helpmod2 / hcommands.c
index c33d9117ad55c5542998964d8c1861008cc9d003..d7544074d2796cb84858458a4e6047d57a7c3d0c 100644 (file)
@@ -5,9 +5,7 @@
 #include <sys/types.h>
 #include <dirent.h>
 
-#include "../nick/nick.h"
-#include "../channel/channel.h"
-#include "../lib/irc_string.h"
+#include "../lib/strlfunc.h"
 
 #include "hcommands.h"
 #include "hcommand.h"
@@ -770,30 +768,31 @@ static void helpmod_cmd_welcome (huser *sender, channel* returntype, char* ostr,
     }
     else
     {
-        strcpy(hchan->welcome, ostr);
+        strlcpy(hchan->welcome, ostr, HCHANNEL_WELCOME_LEN);
         helpmod_reply(sender, returntype, "Welcome message for channel %s (%s) is now: %s", hchan->real_channel->index->name->content, hchannel_get_state(hchan, H_WELCOME), hchan->welcome);
     }
 }
 
+static void helpmod_list_aliases(huser *sender, channel *returntype, char *buf, int *p_i, alias_tree node)
+{
+    if (*p_i > 256)
+    {
+        helpmod_reply(sender, returntype, "%s", buf);
+        *p_i = 0;
+    }
+    if (!node)
+        return;
+    sprintf(buf+*p_i,"%.200s ",node->name->content);
+    *p_i+=(1+strlen(node->name->content));
+    helpmod_list_aliases(sender, returntype, buf, p_i, node->left);
+    helpmod_list_aliases(sender, returntype, buf, p_i, node->right);
+}
+
 static void helpmod_cmd_aliases (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
 {
     char buf[512];
     int i = 0;
-    void helpmod_list_aliases(alias_tree node)
-    {
-       if (i > 256)
-       {
-           helpmod_reply(sender, returntype, "%s", buf);
-           i = 0;
-       }
-       if (!node)
-           return;
-        sprintf(buf+i,"%.200s ",node->name->content);
-       i+=(1+strlen(node->name->content));
-        helpmod_list_aliases(node->left);
-       helpmod_list_aliases(node->right);
-    }
-    helpmod_list_aliases(aliases);
+    helpmod_list_aliases(sender, returntype, buf, &i, aliases);
     if (i)
        helpmod_reply(sender, returntype, "%s", buf);
 }
@@ -897,7 +896,7 @@ static void helpmod_cmd_term_find_general (huser *sender, channel* returntype, i
         helpmod_reply(sender, returntype, "No term found matching '%s'", argv[0]);
         return;
     }
-    if (returntype != NULL && huser_get_level(sender) > H_PEON)
+    if (returntype != NULL && huser_get_level(sender) >= H_TRIAL)
     {
         HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
 
@@ -1042,7 +1041,7 @@ void helpmod_cmd_term (huser *sender, channel* returntype, char* ostr, int argc,
             }
             if (strregexp(htrm->description->content, pattern) || strregexp(htrm->name->content, pattern))
             {
-                sprintf(buffer+strlen(buffer) /* :) */, "%s(%d) ", htrm->name->content, strlen(htrm->description->content));
+                sprintf(buffer+strlen(buffer) /* :) */, "%s(%u) ", htrm->name->content, (unsigned int)strlen(htrm->description->content));
                 count++;
             }
         }
@@ -1083,7 +1082,7 @@ void helpmod_cmd_term (huser *sender, channel* returntype, char* ostr, int argc,
             char *name = argv[1], *description;
             SKIP_WORD; SKIP_WORD;
             description = ostr;
-            htrm = hterm_add(source, name, description);
+            hterm_add(source, name, description);
             helpmod_reply(sender, returntype, "Term %s added succesfully", name);
         }
     }
@@ -1123,7 +1122,7 @@ void helpmod_cmd_term (huser *sender, channel* returntype, char* ostr, int argc,
             helpmod_reply(sender, returntype, "No term found matching '%s'", argv[1]);
             return;
         }
-        if (returntype != NULL && huser_get_level(sender) > H_PEON)
+        if (returntype != NULL && huser_get_level(sender) >= H_TRIAL)
             helpmod_message_channel(hchannel_get_by_channel(returntype), "(%s): %s", htrm->name->content, htrm->description->content);
         else
             helpmod_reply(sender, returntype, "(%s): %s", htrm->name->content, htrm->description->content);
@@ -1687,7 +1686,7 @@ static void helpmod_cmd_everyoneout (huser *sender, channel* returntype, char* o
        if (huser_get_level((*hchanuser)->husr) < H_TRIAL)
            if (kickmode == HELPMOD_KICKMODE_ALL || (kickmode == HELPMOD_KICKMODE_UNAUTHED && !IsAccount((*hchanuser)->husr->real_user)))
            {
-               helpmod_kick(hchan, (*hchanuser)->husr, reason);
+               helpmod_kick(hchan, (*hchanuser)->husr, "%s", reason);
                continue;
            }
        hchanuser = &(*hchanuser)->next;
@@ -1760,7 +1759,7 @@ static void helpmod_cmd_kick (huser *sender, channel* returntype, char* ostr, in
     }
 
     for (i=0;i<ntargets;i++)
-        helpmod_kick(hchan, targets[i], reason);
+        helpmod_kick(hchan, targets[i], "%s", reason);
 }
 
 static void helpmod_cmd_stats (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
@@ -1890,7 +1889,6 @@ static void helpmod_cmd_stats (huser *sender, channel* returntype, char* ostr, i
 static void helpmod_cmd_chanstats (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
 {
     hchannel *hchan;
-    hstat_channel *channel_stats;
     hstat_channel_entry *stat_entry;
 
     time_t timer = time(NULL);
@@ -1954,8 +1952,6 @@ static void helpmod_cmd_chanstats (huser *sender, channel* returntype, char* ost
             }
         }
 
-    channel_stats = hchan->stats;
-
     if (!days && !weeks)
         return;
 
@@ -2033,18 +2029,20 @@ static void helpmod_cmd_activestaff (huser *sender, channel* returntype, char* o
         }
     }
 
-    arr = create_hstat_account_array(hchan, lvl);
+    arr = create_hstat_account_array(hchan, lvl, HSTAT_ACCOUNT_ARRAY_TOP10);
 
     helpmod_reply(sender, returntype, "%s %ss for channel %s", listtype?"Inactive":"Active", hlevel_name(lvl), hchannel_get_name(hchan));
     switch (listtype)
     {
     case 0:
-        for (i=0;i < arr.arrlen && arr.array[i].prime_time_spent > H_ACTIVE_LIMIT;i++)
-            helpmod_reply(sender, returntype, "#%-2d %-20s %-20s %-20s", i+1,((haccount*)(arr.array[i].owner))->name->content, helpmod_strtime(arr.array[i].prime_time_spent), helpmod_strtime(arr.array[i].time_spent));
+        for (i=0;i < arr.arrlen;i++)
+            if (arr.array[i].prime_time_spent > H_ACTIVE_LIMIT)
+                helpmod_reply(sender, returntype, "#%-2d %-20s %-20s %-20s", i+1,((haccount*)(arr.array[i].owner))->name->content, helpmod_strtime(arr.array[i].prime_time_spent), helpmod_strtime(arr.array[i].time_spent));
         break;
     case 1:
-        for (i=arr.arrlen-1;i >= 0 && arr.array[i].prime_time_spent < H_ACTIVE_LIMIT;i--)
-            helpmod_reply(sender, returntype, "#%-2d %-20s %-20s %-20s", (arr.arrlen - i),((haccount*)(arr.array[i].owner))->name->content, helpmod_strtime(arr.array[i].prime_time_spent), helpmod_strtime(arr.array[i].time_spent));
+        for (i=arr.arrlen-1;i >= 0;i--)
+            if (arr.array[i].prime_time_spent < H_ACTIVE_LIMIT)
+                helpmod_reply(sender, returntype, "#%-2d %-20s %-20s %-20s", (arr.arrlen - i),((haccount*)(arr.array[i].owner))->name->content, helpmod_strtime(arr.array[i].prime_time_spent), helpmod_strtime(arr.array[i].time_spent));
         break;
     }
 
@@ -2084,7 +2082,7 @@ static void helpmod_cmd_top10 (huser *sender, channel* returntype, char* ostr, i
             top_n = tmp;
     }
 
-    arr = create_hstat_account_array(hchan, lvl);
+    arr = create_hstat_account_array(hchan, lvl, HSTAT_ACCOUNT_ARRAY_TOP10);
 
     helpmod_reply(sender, returntype, "Top%d most active %ss of channel %s", top_n, hlevel_name(lvl), hchannel_get_name(hchan));
     for (i=0;i < arr.arrlen && i < top_n;i++)
@@ -2159,7 +2157,7 @@ static void helpmod_cmd_mode(huser *sender, channel* returntype, int change, cha
         husr = huser_get(getnickbynick(argv[i]));
         if (husr == NULL)
         {
-            helpmod_reply(sender, returntype, "Cannot change mode: User %s not found", argv[i], hchannel_get_name(hchan));
+            helpmod_reply(sender, returntype, "Cannot change mode: User %s not found", argv[i]);
             continue;
         }
         huserchan = huser_on_channel(husr, hchan);
@@ -2277,7 +2275,7 @@ static void helpmod_cmd_invite (huser *sender, channel *returntype, char* arg, i
         return;
     }
 
-    if (huser_get_level(sender) == H_PEON || huser_get_level(sender) == H_FRIEND)
+    if (huser_get_level(sender) < H_STAFF)
     {
         hticket *htick;
         hchan = hchannel_get_by_name(argv[0]);
@@ -2300,7 +2298,7 @@ static void helpmod_cmd_invite (huser *sender, channel *returntype, char* arg, i
             return;
         }
 
-        if (nickbanned(sender->real_user, hchan->real_channel))
+        if (nickbanned(sender->real_user, hchan->real_channel, 0))
         {
             helpmod_reply(sender, returntype, "Cannot invite: You are banned from channel %s", argv[0]);
             return;
@@ -2347,6 +2345,7 @@ static void helpmod_cmd_ticket (huser *sender, channel* returntype, char* ostr,
     hchannel *hchan;
     huser *husr;
     hticket *htick;
+    const char *message = NULL;
 
     if (argc < 1)
     {
@@ -2392,12 +2391,17 @@ static void helpmod_cmd_ticket (huser *sender, channel* returntype, char* ostr,
         helpmod_reply(sender, returntype, "Cannot issue a ticket: User %s does not require a ticket", argv[1]);
         return;
     }
-    if (argc >= 3)
+    if (argc > 3)
     {
-        int tmp;
+       int tmp;
         tmp = helpmod_read_strtime(argv[2]);
         if (tmp > HDEF_m && tmp < 2 * HDEF_M)
-            expiration = tmp;
+           expiration = tmp;
+    }
+    if (argc >= 4 && strlen(argv[3]) < 128)
+    {
+       if (argv[3][0] != '\0')
+            message = argv[3];
     }
 
     htick = hticket_get(huser_get_auth(husr), hchan);
@@ -2405,7 +2409,7 @@ static void helpmod_cmd_ticket (huser *sender, channel* returntype, char* ostr,
     if (htick != NULL)
         htick->time_expiration = time(NULL) + expiration;
     else
-        hticket_add(huser_get_auth(husr), time(NULL) + expiration, hchan);
+        hticket_add(huser_get_auth(husr), time(NULL) + expiration, hchan, message);
 
     helpmod_reply(sender, returntype, "Issued an invite ticket to user %s for channel %s expiring in %s", huser_get_nick(husr), hchannel_get_name(hchan), helpmod_strtime(expiration));
     helpmod_reply(husr, NULL, "You have been issued an invite ticket for channel %s. This ticket is valid for a period of %s. You can use my invite command to get to the channel now. Type /msg %s invite %s",hchannel_get_name(hchan), helpmod_strtime(HTICKET_EXPIRATION_TIME), helpmodnick->nick, hchannel_get_name(hchan));
@@ -2517,9 +2521,7 @@ static void helpmod_cmd_showticket (huser *sender, channel* returntype, char* os
     int i;
 
     DEFINE_HCHANNEL;
-/*
-    HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
-*/
+
     if (argc > H_CMD_MAX_ARGS)
         argc = H_CMD_MAX_ARGS;
 
@@ -2546,8 +2548,11 @@ static void helpmod_cmd_showticket (huser *sender, channel* returntype, char* os
         {
             helpmod_reply(sender, returntype, "Cannot show the ticket: User %s does not have a valid ticket for channel %s", argv[i], hchannel_get_name(hchan));
             continue;
-        }
-        helpmod_reply(sender, returntype, "User %s has a ticket for channel %s expiring in %s", argv[i], hchannel_get_name(hchan), helpmod_strtime(htick->time_expiration - time(NULL)));
+       }
+       if (htick->message == NULL)
+           helpmod_reply(sender, returntype, "User %s has a ticket for channel %s expiring in %s. No message is attached.", argv[i], hchannel_get_name(hchan), helpmod_strtime(htick->time_expiration - time(NULL)));
+       else
+           helpmod_reply(sender, returntype, "User %s has a ticket for channel %s expiring in %s. With message: %s", argv[i], hchannel_get_name(hchan), helpmod_strtime(htick->time_expiration - time(NULL)), htick->message->content);
     }
 }
 
@@ -2654,9 +2659,9 @@ static void helpmod_cmd_checkchannel(huser *sender, channel* returntype, char* o
            if (IsAccount(nck))
                 authed_count++;
 
-            if (IsOper(nck) && strlen(nck->nick) > 1)
+            if (IsOper(nck) && strlen(nck->nick) > 1 && (IsSecret(chan) || IsPrivate(chan) || IsKey(chan) || IsInviteOnly(chan)))
             {
-                helpmod_reply(sender, returntype, "Cannot check channel: Permission denied. Channel %s has an oper on it", argv[0]);
+                helpmod_reply(sender, returntype, "Cannot check channel: Permission denied. Channel %s has an oper on it and one or more of +i/+k/+p/+s", argv[0]);
                 return;
             }
        }
@@ -2677,7 +2682,6 @@ static void helpmod_cmd_checkchannel(huser *sender, channel* returntype, char* o
     /* third pass - find status boundaries */
     {
        for (;o_limit < nick_count && numeric_array[o_limit] & CUMODE_OP; o_limit++);
-        v_limit = o_limit;
        for(v_limit = o_limit; (v_limit < nick_count) && numeric_array[v_limit] & CUMODE_VOICE; v_limit++);
     }
 
@@ -3173,7 +3177,7 @@ static void helpmod_cmd_text (huser *sender, channel* returntype, char* ostr, in
        DIR *dir;
        struct dirent *dent;
        char buffer[384], **lines, *start;
-        int nwritten, bufpos = 0, nlines = 0,i;
+        int bufpos = 0, nlines = 0,i;
 
        dir = opendir(HELPMOD_TEXT_DIR);
        assert(dir != NULL);
@@ -3224,18 +3228,17 @@ static void helpmod_cmd_text (huser *sender, channel* returntype, char* ostr, in
                buffer[bufpos] = ' ';
                bufpos++;
            }
-           sprintf(buffer + bufpos, "%s%n", lines[i], &nwritten);
-           bufpos+=nwritten;
+           bufpos+=sprintf(buffer + bufpos, "%s", lines[i]);
 
            if (bufpos > (384 - (HED_FILENAME_LENGTH+1)))
            {
-               helpmod_reply(sender, returntype, buffer);
+               helpmod_reply(sender, returntype, "%s", buffer);
                bufpos = 0;
            }
        }
 
        if (bufpos)
-           helpmod_reply(sender, returntype, buffer);
+           helpmod_reply(sender, returntype, "%s", buffer);
 
        free(start);
         free(lines);
@@ -3266,7 +3269,7 @@ static void helpmod_cmd_text (huser *sender, channel* returntype, char* ostr, in
        {
            if (!fgets(buffer, 512, in))
                 break;
-           if (returntype != NULL && huser_get_level(sender) > H_PEON)
+           if (returntype != NULL && huser_get_level(sender) >= H_TRIAL)
                helpmod_message_channel(hchannel_get_by_channel(returntype), "%s", buffer);
            else
                helpmod_reply(sender, returntype, "%s", buffer);
@@ -3298,6 +3301,7 @@ static void helpmod_cmd_text (huser *sender, channel* returntype, char* ostr, in
        if ((in = fopen(fname_buffer, "rt")) != NULL)
        {
            helpmod_reply(sender, returntype, "Can not add text: Text %s already exists", argv[1]);
+            fclose(in);
             return;
        }
        else
@@ -3450,6 +3454,68 @@ static void helpmod_cmd_evilhack2 (huser *sender, channel* returntype, char* ost
     helpmod_reply(sender, returntype, "Evilhack2 done: Swapped %d and %d", first, second);
 }
 
+static void helpmod_cmd_channel (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
+{
+    hchannel *hchan;
+    hchannel_user *hchanuser;
+
+    DEFINE_HCHANNEL;
+
+    if (hchan == NULL)
+    {
+       helpmod_reply(sender, returntype, "Can not show channel: Channel not specified");
+        return;
+    }
+
+    HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
+
+    helpmod_reply(sender, returntype, "Users for channel %s", hchannel_get_name(hchan));
+    helpmod_reply(sender, returntype, "Nick             Account          User level               Idle time");
+
+    for (hchanuser = hchan->channel_users;hchanuser;hchanuser=hchanuser->next)
+       helpmod_reply(sender, returntype, "%-16s %-16s %-24s %s",hchanuser->husr->real_user->nick,hchanuser->husr->account?hchanuser->husr->account->name->content:"-",hlevel_name(huser_get_level(hchanuser->husr)), helpmod_strtime(time(NULL)-huser_on_channel(hchanuser->husr, hchan)->last_activity));
+
+    helpmod_reply(sender, returntype, "Listed %d users for channel %s", hchannel_count_users(hchan, H_ANY), hchannel_get_name(hchan));
+}
+
+static void helpmod_cmd_weekstats (huser *sender, channel* returntype, char* ostr, int argc, char *argv[])
+{
+    hchannel *hchan;
+    hstat_accounts_array arr;
+    int i;
+    hlevel lvl = H_ANY;
+
+    DEFINE_HCHANNEL;
+
+    if (hchan == NULL)
+    {
+       helpmod_reply(sender, returntype, "Can not list weekly stats: Channel not specified");
+        return;
+    }
+
+    HCHANNEL_VERIFY_AUTHORITY(hchan, sender);
+
+    if (argc >= 1)
+    {
+        if (!ci_strcmp(argv[0], "opers") || !ci_strcmp(argv[0], "o"))
+            lvl = H_OPER;
+       else if (!ci_strcmp(argv[0], "staff") || !ci_strcmp(argv[0], "s"))
+           lvl = H_STAFF;
+       else if (!ci_strcmp(argv[0], "all") || !ci_strcmp(argv[0], "a"))
+            lvl = H_ANY;
+    }
+
+    arr = create_hstat_account_array(hchan, lvl, HSTAT_ACCOUNT_ARRAY_WEEKSTATS);
+
+    helpmod_reply(sender, returntype, "Weekly statistics for %ss on channel %s", hlevel_name(lvl), hchannel_get_name(hchan));
+
+    for (i=0;i < arr.arrlen;i++)
+      if (arr.array[i].time_spent > HDEF_m)
+       helpmod_reply(sender, returntype, "%-20s %-20s %-20s",((haccount*)(arr.array[i].owner))->name->content, helpmod_strtime(arr.array[i].prime_time_spent), helpmod_strtime(arr.array[i].time_spent));
+
+    free(arr.array);
+}
+
 /* old H stuff */
 void helpmod_cmd_load (huser *sender, channel *returntype, char* arg, int argc, char *argv[])
 {
@@ -3489,9 +3555,9 @@ void helpmod_cmd_status (huser *sender, channel* returntype, char* ostr, int arg
     helpmod_reply(sender, returntype, "Channels          %d", hchannel_count());
     helpmod_reply(sender, returntype, "Accounts          %d", haccount_count(H_ANY));
     helpmod_reply(sender, returntype, "Users             %d", huser_count());
-    helpmod_reply(sender, returntype, "Help entries      %d", helpmod_entry_count(helpmod_base));
+    helpmod_reply(sender, returntype, "Help entries      %ld", helpmod_entry_count(helpmod_base));
     helpmod_reply(sender, returntype, "Bans              %d", hban_count());
-    helpmod_reply(sender, returntype, "Help provided     %d", helpmod_usage);
+    helpmod_reply(sender, returntype, "Help provided     %ld", helpmod_usage);
     helpmod_reply(sender, returntype, "Tickets           %d", hticket_count());
 }
 
@@ -3624,6 +3690,7 @@ void hcommands_add(void)
     hcommand_add("friend", H_STAFF, helpmod_cmd_friend, "Sets the userlevel of the target to friend (lvl 2)");
     hcommand_add("trial", H_OPER, helpmod_cmd_trial, "Sets the userlevel of the target to trial staff (lvl 3)");
     hcommand_add("staff", H_OPER, helpmod_cmd_staff, "Sets the userlevel of the target to staff (lvl 4)");
+
     hcommand_add("oper", H_OPER, helpmod_cmd_oper, "Sets the userlevel of the target to oper (lvl 5)");
     hcommand_add("admin", H_ADMIN, helpmod_cmd_admin, "Sets the userlevel of the target to admin (lvl 6)");
     hcommand_add("deluser", H_OPER, helpmod_cmd_deluser, "Removes an account from " HELPMOD_NICK);
@@ -3699,6 +3766,8 @@ void hcommands_add(void)
     hcommand_add("rating", H_TRIAL, helpmod_cmd_rating, "Simple rating for the current week");
     hcommand_add("writedb", H_OPER, helpmod_cmd_writedb, "Writes the " HELPMOD_NICK " database to disk");
 
+    hcommand_add("channel", H_TRIAL, helpmod_cmd_channel, "Gives a list of all channel users");
+    hcommand_add("weekstats", H_ADMIN, helpmod_cmd_weekstats, "Gives weekly stats for a channel");
     /*hcommand_add("megod", H_PEON, helpmod_cmd_megod, "Gives you userlevel 4, if you see this in the final version, please kill strutsi");*/
     /*hcommand_add("test", H_PEON, helpmod_cmd_test, "Gives you userlevel 4, if you see this in the final version, please kill strutsi");*/
 }
@@ -3707,7 +3776,7 @@ void helpmod_command(huser *sender, channel* returntype, char *args)
 {
     int argc = 0, useless_var;
     char args_copy[512];
-    char *parsed_args[H_CMD_MAX_ARGS + 3], *ptr = args_copy;
+    char *parsed_args[H_CMD_MAX_ARGS + 4], *ptr = args_copy;
 
     /* only accept commands from valid sources */
     if (huser_get_level(sender) > H_ADMIN)
@@ -3724,9 +3793,11 @@ void helpmod_command(huser *sender, channel* returntype, char *args)
     if (*args == '-' || *args == '?')
         args++;
 
-    strcpy(args_copy, args);
+    strncpy(args_copy, args, (sizeof(args_copy) - 1));
+    args_copy[sizeof(args_copy) - 1] = '\0';
+
     /* FIX stringituki */
-    while (argc < 10)
+    while (argc < (H_CMD_MAX_ARGS + 4))
     {
         while (isspace(*ptr) && *ptr)
             ptr++;
@@ -3777,12 +3848,17 @@ void helpmod_command(huser *sender, channel* returntype, char *args)
 
        if (hcom == NULL)
        {
+            controlwall(NO_DEVELOPER, NL_ALL_COMMANDS, "(G) From: %s!%s@%s%s%s: %s",
+                        sender->real_user->nick, sender->real_user->ident,
+                        sender->real_user->host->name->content, IsAccount(sender->real_user)?"/":"",
+                        IsAccount(sender->real_user)?sender->real_user->authname:"", args);            
            if ((returntype == NULL) ||
                (sender->account != NULL && !(sender->account->flags & H_NO_CMD_ERROR)))
                helpmod_reply(sender, returntype, "Unknown command '%s', please see showcommands for a list of all commands available to you", parsed_args[0]);
        }
         else
         {
+            controlwall(NO_DEVELOPER, NL_ALL_COMMANDS, "(G) From: %s!%s@%s%s%s: %s", sender->real_user->nick, sender->real_user->ident, sender->real_user->host->name->content, IsAccount(sender->real_user)?"/":"", IsAccount(sender->real_user)?sender->real_user->authname:"", args);
             SKIP_WORD;
             hcom->function(sender, returntype, ostr, argc, argv);
         }