Add support for snircd-style fakehosts (usermode +h, fake idents)
authorThiefMaster <thiefmaster@gamesurge.net>
Sat, 28 Mar 2009 13:12:07 +0000 (14:12 +0100)
committerMichael Poole <mdpoole@troilus.org>
Mon, 15 Feb 2010 20:55:47 +0000 (15:55 -0500)
src/hash.c
src/hash.h
src/nickserv.c
src/nickserv.h
src/opserv.c
src/proto-bahamut.c
src/proto-p10.c
src/proto.h

index 75769fa09706c6e4ebdf5962af50b6f0bb431c8c..5a8df93dd53c23f75145ef77976000b67315a230 100644 (file)
@@ -253,11 +253,14 @@ StampUser(struct userNode *user, const char *stamp, unsigned long timestamp, uns
 }
 
 void
-assign_fakehost(struct userNode *user, const char *host, int announce)
+assign_fakehost(struct userNode *user, const char *host, const char *ident, int force, int announce)
 {
-    safestrncpy(user->fakehost, host, sizeof(user->fakehost));
+    if (host)
+        safestrncpy(user->fakehost, host, sizeof(user->fakehost));
+    if (ident)
+        safestrncpy(user->fakeident, ident, sizeof(user->ident));
     if (announce)
-        irc_fakehost(user, host);
+        irc_fakehost(user, host, ident, force);
 }
 
 static new_channel_func_t *ncf_list;
index 71b925182bba7f945faff809e66b2fbb0e2c7891..bd7b3353fae7d73a982da612b2a1a86ff3c5f8f8 100644 (file)
@@ -79,6 +79,7 @@
 #define IsDummy(x)              ((x)->modes & FLAGS_DUMMY)
 #define IsNoIdle(x)             ((x)->modes & FLAGS_NOIDLE)
 #define IsFakeHost(x)           ((x)->fakehost[0] != '\0')
+#define IsFakeIdent(x)          ((x)->fakeident[0] != '\0')
 #define IsLocal(x)              ((x)->uplink == self)
 
 #define NICKLEN         30
@@ -107,6 +108,7 @@ struct userNode {
     char info[REALLEN + 1];       /* Free form additional client information */
     char hostname[HOSTLEN + 1];   /* DNS name or IP address */
     char fakehost[HOSTLEN + 1];   /* Assigned fake host */
+    char fakeident[USERLEN + 1];  /* Assigned fake ident */
 #ifdef WITH_PROTOCOL_P10
     char numeric[COMBO_NUMERIC_LEN+1];
     unsigned int num_local : 18;
@@ -219,7 +221,7 @@ typedef void (*account_func_t) (struct userNode *user, const char *stamp, unsign
 void reg_account_func(account_func_t handler);
 void call_account_func(struct userNode *user, const char *stamp, unsigned long timestamp, unsigned long serial);
 void StampUser(struct userNode *user, const char *stamp, unsigned long timestamp, unsigned long serial);
-void assign_fakehost(struct userNode *user, const char *host, int announce);
+void assign_fakehost(struct userNode *user, const char *host, const char *ident, int force, int announce);
 
 typedef void (*new_channel_func_t) (struct chanNode *chan);
 void reg_new_channel_func(new_channel_func_t handler);
index 0ba125e5bfd8658657383b308111f0ef880e2556..b1f0d294382812ce2a9bc8e818b070fa0a8108cd 100644 (file)
@@ -51,6 +51,7 @@
 #define KEY_SET_EPITHET_LEVEL "set_epithet_level"
 #define KEY_SET_TITLE_LEVEL "set_title_level"
 #define KEY_SET_FAKEHOST_LEVEL "set_fakehost_level"
+#define KEY_SET_FAKEIDENT_LEVEL "set_fakeident_level"
 #define KEY_TITLEHOST_SUFFIX "titlehost_suffix"
 #define KEY_FLAG_LEVELS "flag_levels"
 #define KEY_HANDLE_EXPIRE_FREQ "handle_expire_freq"
 #define KEY_TABLE_WIDTH "table_width"
 #define KEY_MAXLOGINS "maxlogins"
 #define KEY_FAKEHOST "fakehost"
+#define KEY_FAKEIDENT "fakeident"
 #define KEY_NOTES "notes"
 #define KEY_NOTE_EXPIRES "expires"
 #define KEY_NOTE_SET "set"
@@ -193,6 +195,7 @@ static const struct message_entry msgtab[] = {
     { "NSMSG_TITLE_INVALID", "Titles cannot contain any dots; please choose another." },
     { "NSMSG_TITLE_TRUNCATED", "That title combined with the user's account name would result in a truncated host; please choose a shorter title." },
     { "NSMSG_FAKEHOST_INVALID", "Fake hosts must be shorter than %d characters and cannot start with a dot." },
+    { "NSMSG_FAKEIDENT_INVALID", "Fake idents must be shorter than %d characters." },
     { "NSMSG_HANDLEINFO_ON", "Account information for $b%s$b:" },
     { "NSMSG_HANDLEINFO_ID", "  Account ID: %lu" },
     { "NSMSG_HANDLEINFO_REGGED", "  Registered on: %s" },
@@ -209,6 +212,7 @@ static const struct message_entry msgtab[] = {
     { "NSMSG_HANDLEINFO_INFOLINE", "  Infoline: %s" },
     { "NSMSG_HANDLEINFO_FLAGS", "  Flags: %s" },
     { "NSMSG_HANDLEINFO_EPITHET", "  Epithet: %s" },
+    { "NSMSG_HANDLEINFO_FAKEIDENT", "  Fake ident: %s" },
     { "NSMSG_HANDLEINFO_FAKEHOST", "  Fake host: %s" },
     { "NSMSG_HANDLEINFO_LAST_HOST", "  Last quit hostmask: %s" },
     { "NSMSG_HANDLEINFO_NO_NOTES", "  Notes: None" },
@@ -312,6 +316,7 @@ static const struct message_entry msgtab[] = {
     { "NSMSG_SET_EPITHET", "$bEPITHET:      $b%s" },
     { "NSMSG_SET_TITLE", "$bTITLE:        $b%s" },
     { "NSMSG_SET_FAKEHOST", "$bFAKEHOST:    $b%s" },
+    { "NSMSG_SET_FAKEIDENT", "$bFAKEIDENT:   $b%s" },
     { "NSMSG_INVALID_KARMA", "$b%s$b is not a valid karma modifier." },
     { "NSMSG_SET_KARMA", "$bKARMA:       $b%d$b" },
     { "NSEMAIL_ACTIVATION_SUBJECT", "Account verification for %s" },
@@ -374,6 +379,7 @@ static struct {
     unsigned long set_epithet_level;
     unsigned long set_title_level;
     unsigned long set_fakehost_level;
+    unsigned long set_fakeident_level;
     unsigned long handles_per_email;
     unsigned long email_search_level;
     const char *network_name;
@@ -538,6 +544,7 @@ free_handle_info(void *vhi)
     free(hi->infoline);
     free(hi->epithet);
     free(hi->fakehost);
+    free(hi->fakeident);
     if (hi->cookie) {
         timeq_del(hi->cookie->expires, nickserv_free_cookie, hi->cookie, 0);
         nickserv_free_cookie(hi->cookie);
@@ -883,17 +890,41 @@ generate_fakehost(struct handle_info *handle)
     return handle->fakehost;
 }
 
+static char *
+generate_fakeident(struct handle_info *handle, struct userNode *user)
+{
+    static char buffer[USERLEN+1];
+
+    if (!handle->fakeident) {
+        if (!user)
+            return NULL;
+        safestrncpy(buffer, user->ident, sizeof(buffer));
+        return buffer;
+    }
+    return handle->fakeident;
+}
+
 static void
-apply_fakehost(struct handle_info *handle)
+apply_fakehost(struct handle_info *handle, struct userNode *user)
 {
     struct userNode *target;
-    char *fake;
+    char *fakehost, *fakeident;
 
     if (!handle->users)
         return;
-    fake = generate_fakehost(handle);
-    for (target = handle->users; target; target = target->next_authed)
-        assign_fakehost(target, fake, 1);
+
+    fakehost = generate_fakehost(handle);
+
+    if (user) {
+        fakeident = generate_fakeident(handle, user);
+        assign_fakehost(user, fakehost, fakeident, 0, 1);
+        return;
+    }
+
+    for (target = handle->users; target; target = target->next_authed) {
+        fakeident = generate_fakeident(handle, target);
+        assign_fakehost(target, fakehost, fakeident, 0, 1);
+    }
 }
 
 static void
@@ -958,8 +989,8 @@ set_user_handle_info(struct userNode *user, struct handle_info *hi, int stamp)
         if (IsHelper(user) && !userList_contains(&curr_helpers, user))
             userList_append(&curr_helpers, user);
 
-        if (hi->fakehost || old_info)
-            apply_fakehost(hi);
+        if (hi->fakehost || hi->fakeident || old_info)
+            apply_fakehost(hi, user);
 
         if (stamp) {
             if (!nickserv_conf.disable_nicks) {
@@ -1410,6 +1441,9 @@ static NICKSERV_FUNC(cmd_handleinfo)
         reply("NSMSG_HANDLEINFO_EPITHET", (hi->epithet ? hi->epithet : nsmsg_none));
     }
 
+    if (hi->fakeident)
+        reply("NSMSG_HANDLEINFO_FAKEIDENT", (hi->fakeident ? hi->fakeident : handle_find_message(hi, "MSG_NONE")));
+
     if (hi->fakehost)
         reply("NSMSG_HANDLEINFO_FAKEHOST", (hi->fakehost ? hi->fakehost : handle_find_message(hi, "MSG_NONE")));
 
@@ -2575,7 +2609,7 @@ static OPTION_FUNC(opt_title)
             hi->fakehost[0] = '.';
             strcpy(hi->fakehost+1, title);
         }
-        apply_fakehost(hi);
+        apply_fakehost(hi, NULL);
     } else if (hi->fakehost && (hi->fakehost[0] == '.'))
         title = hi->fakehost + 1;
     else
@@ -2588,7 +2622,8 @@ static OPTION_FUNC(opt_title)
 
 static OPTION_FUNC(opt_fakehost)
 {
-    const char *fake;
+    char mask[USERLEN + HOSTLEN + 2];
+    char *host, *ident;
 
     if (!override) {
         send_message(user, nickserv, "MSG_SETTING_PRIVILEGED", argv[0]);
@@ -2596,23 +2631,83 @@ static OPTION_FUNC(opt_fakehost)
     }
 
     if ((argc > 1) && oper_has_access(user, nickserv, nickserv_conf.set_fakehost_level, 0)) {
-        fake = argv[1];
-        if ((strlen(fake) > HOSTLEN) || (fake[0] == '.')) {
+        safestrncpy(mask, argv[1], sizeof(mask));
+
+        if ((host = strrchr(mask, '@')) && host != mask &&
+            oper_has_access(user, nickserv, nickserv_conf.set_fakeident_level, 0)) {
+            ident = mask;
+            *host++ = '\0';
+        } else {
+            ident = NULL;
+            host = mask;
+        }
+
+        if ((strlen(host) > HOSTLEN) || (host[0] == '.')) {
             send_message(user, nickserv, "NSMSG_FAKEHOST_INVALID", HOSTLEN);
             return 0;
         }
+
+        if (ident && strlen(ident) > USERLEN) {
+            send_message(user, nickserv, "NSMSG_FAKEIDENT_INVALID", USERLEN);
+            return 0;
+        }
+
         free(hi->fakehost);
-        if (!strcmp(fake, "*"))
+        if (!strcmp(host, "*"))
             hi->fakehost = NULL;
         else
-            hi->fakehost = strdup(fake);
-        fake = hi->fakehost;
-        apply_fakehost(hi);
+            hi->fakehost = strdup(host);
+        host = hi->fakehost;
+
+        if (ident) {
+            free(hi->fakeident);
+            if (!strcmp(ident, "*"))
+                hi->fakeident = NULL;
+            else
+                hi->fakeident = strdup(ident);
+            ident = hi->fakeident;
+        }
+
+        apply_fakehost(hi, NULL);
+    } else {
+        host = generate_fakehost(hi);
+        ident = generate_fakeident(hi, NULL);
+    }
+    if (!host)
+        host = (char *) user_find_message(user, "MSG_NONE");
+    send_message(user, nickserv, "NSMSG_SET_FAKEHOST", host);
+    if (ident)
+        send_message(user, nickserv, "NSMSG_SET_FAKEIDENT", ident);
+    return 1;
+}
+
+static OPTION_FUNC(opt_fakeident)
+{
+    const char *ident;
+
+    if (!override) {
+        send_message(user, nickserv, "MSG_SETTING_PRIVILEGED", argv[0]);
+        return 0;
+    }
+
+    if ((argc > 1) && oper_has_access(user, nickserv, nickserv_conf.set_fakeident_level, 0)) {
+        ident = argv[1];
+        if (strlen(ident) > USERLEN) {
+            send_message(user, nickserv, "NSMSG_FAKEIDENT_INVALID", USERLEN);
+            return 0;
+        }
+        free(hi->fakeident);
+        if (!strcmp(ident, "*"))
+            hi->fakeident = NULL;
+        else
+            hi->fakeident = strdup(ident);
+        ident = hi->fakeident;
+        apply_fakehost(hi, NULL);
     } else
-        fake = generate_fakehost(hi);
-    if (!fake)
-        fake = user_find_message(user, "MSG_NONE");
-    send_message(user, nickserv, "NSMSG_SET_FAKEHOST", fake);
+        ident = generate_fakeident(hi, NULL); /* NULL if no fake ident set */
+    if (!ident)
+        ident = user_find_message(user, "MSG_NONE");
+    send_message(user, nickserv, "NSMSG_SET_FAKEIDENT", ident);
     return 1;
 }
 
@@ -2915,6 +3010,8 @@ nickserv_saxdb_write(struct saxdb_context *ctx) {
             saxdb_write_string(ctx, KEY_EPITHET, hi->epithet);
         if (hi->fakehost)
             saxdb_write_string(ctx, KEY_FAKEHOST, hi->fakehost);
+        if (hi->fakeident)
+            saxdb_write_string(ctx, KEY_FAKEIDENT, hi->fakeident);
         if (hi->flags) {
             int ii, flen;
 
@@ -3090,6 +3187,8 @@ static NICKSERV_FUNC(cmd_merge)
      */
     if (hi_from->fakehost && !hi_to->fakehost)
         hi_to->fakehost = strdup(hi_from->fakehost);
+    if (hi_from->fakeident && !hi_to->fakeident)
+        hi_to->fakeident = strdup(hi_from->fakeident);
 
     /* Notify of success. */
     sprintf(buffer, "%s (%s) merged account %s into %s.", user->nick, user->handle_info->handle, hi_from->handle, hi_to->handle);
@@ -3113,6 +3212,7 @@ struct nickserv_discrim {
     const char *nickmask;
     const char *hostmask;
     const char *fakehostmask;
+    const char *fakeidentmask;
     const char *handlemask;
     const char *emailmask;
 };
@@ -3212,6 +3312,12 @@ nickserv_discrim_create(struct userNode *user, unsigned int argc, char *argv[])
             } else {
                 discrim->fakehostmask = argv[i];
             }
+        } else if (!irccasecmp(argv[i], "fakeident")) {
+            if (!irccasecmp(argv[++i], "*")) {
+                discrim->fakeidentmask = 0;
+            } else {
+                discrim->fakeidentmask = argv[i];
+            }
         } else if (!irccasecmp(argv[i], "handlemask") || !irccasecmp(argv[i], "accountmask")) {
             if (!irccasecmp(argv[++i], "*")) {
                 discrim->handlemask = 0;
@@ -3287,6 +3393,7 @@ nickserv_discrim_match(struct nickserv_discrim *discrim, struct handle_info *hi)
         || (discrim->lastseen < (hi->users?now:hi->lastseen))
         || (discrim->handlemask && !match_ircglob(hi->handle, discrim->handlemask))
         || (discrim->fakehostmask && (!hi->fakehost || !match_ircglob(hi->fakehost, discrim->fakehostmask)))
+        || (discrim->fakeidentmask && (!hi->fakeident || !match_ircglob(hi->fakeident, discrim->fakeidentmask)))
         || (discrim->emailmask && (!hi->email_addr || !match_ircglob(hi->email_addr, discrim->emailmask)))
         || (discrim->min_level > hi->opserv_level)
         || (discrim->max_level < hi->opserv_level)
@@ -3571,6 +3678,9 @@ nickserv_db_read_handle(const char *handle, dict_t obj)
     str = database_get_data(obj, KEY_FAKEHOST, RECDB_QSTRING);
     if (str)
         hi->fakehost = strdup(str);
+    str = database_get_data(obj, KEY_FAKEIDENT, RECDB_QSTRING);
+    if (str)
+        hi->fakeident = strdup(str);
     /* Read the "cookie" sub-database (if it exists). */
     subdb = database_get_data(obj, KEY_COOKIE, RECDB_OBJECT);
     if (subdb) {
@@ -3813,6 +3923,8 @@ nickserv_conf_read(void)
     nickserv_conf.set_title_level = str ? strtoul(str, NULL, 0) : 900;
     str = database_get_data(conf_node, KEY_SET_FAKEHOST_LEVEL, RECDB_QSTRING);
     nickserv_conf.set_fakehost_level = str ? strtoul(str, NULL, 0) : 1000;
+    str = database_get_data(conf_node, KEY_SET_FAKEIDENT_LEVEL, RECDB_QSTRING);
+    nickserv_conf.set_fakeident_level = str ? strtoul(str, NULL, 0) : 1000;
     str = database_get_data(conf_node, KEY_HANDLE_EXPIRE_FREQ, RECDB_QSTRING);
     if (!str)
         str = database_get_data(conf_node, KEY_ACCOUNT_EXPIRE_FREQ, RECDB_QSTRING);
@@ -4161,6 +4273,7 @@ init_nickserv(const char *nick)
     if (nickserv_conf.titlehost_suffix) {
         dict_insert(nickserv_opt_dict, "TITLE", opt_title);
         dict_insert(nickserv_opt_dict, "FAKEHOST", opt_fakehost);
+        dict_insert(nickserv_opt_dict, "FAKEIDENT", opt_fakeident);
     }
     dict_insert(nickserv_opt_dict, "MAXLOGINS", opt_maxlogins);
     dict_insert(nickserv_opt_dict, "LANGUAGE", opt_language);
index 3311c9083d6c941365d6c948c7b6150730af751e..6d6bcd5eedc012daca005b5e4d13347509c20d0f 100644 (file)
@@ -97,6 +97,7 @@ struct handle_info {
     char *infoline;
     char *handle;
     char *fakehost;
+    char *fakeident;
     unsigned long id;
     unsigned long registered;
     unsigned long lastseen;
index 488f2a7c2379fdc4a0ccd75f34d176c0d31f2f0a..198f5e72a5f6e788da4155b574aa86bb6ed2e7f7 100644 (file)
@@ -116,17 +116,18 @@ static const struct message_entry msgtab[] = {
     { "OSMSG_OP_DONE", "Opped the requested lusers." },
     { "OSMSG_OPALL_DONE", "Opped everyone on $b%s$b." },
     { "OSMSG_WHOIS_IDENT", "%s (%s@%s) from %d.%d.%d.%d" },
-    { "OSMSG_WHOIS_NICK", "Nick    : %s" },
-    { "OSMSG_WHOIS_HOST", "Host    : %s@%s" },
-    { "OSMSG_WHOIS_FAKEHOST", "Fakehost: %s" },
-    { "OSMSG_WHOIS_IP",   "Real IP : %s" },
-    { "OSMSG_WHOIS_MODES", "Modes   : +%s " },
-    { "OSMSG_WHOIS_INFO", "Info    : %s" },
-    { "OSMSG_WHOIS_NUMERIC", "Numnick : %s" },
-    { "OSMSG_WHOIS_SERVER", "Server  : %s" },
-    { "OSMSG_WHOIS_NICK_AGE", "Nick Age: %s" },
-    { "OSMSG_WHOIS_ACCOUNT", "Account : %s" },
-    { "OSMSG_WHOIS_CHANNELS", "Channels: %s" },
+    { "OSMSG_WHOIS_NICK", "Nick     : %s" },
+    { "OSMSG_WHOIS_HOST", "Host     : %s@%s" },
+    { "OSMSG_WHOIS_FAKEHOST", "Fakehost : %s" },
+    { "OSMSG_WHOIS_FAKEIDENT", "Fakeident: %s" },
+    { "OSMSG_WHOIS_IP",   "Real IP  : %s" },
+    { "OSMSG_WHOIS_MODES", "Modes    : +%s " },
+    { "OSMSG_WHOIS_INFO", "Info     : %s" },
+    { "OSMSG_WHOIS_NUMERIC", "Numnick  : %s" },
+    { "OSMSG_WHOIS_SERVER", "Server   : %s" },
+    { "OSMSG_WHOIS_NICK_AGE", "Nick Age : %s" },
+    { "OSMSG_WHOIS_ACCOUNT", "Account  : %s" },
+    { "OSMSG_WHOIS_CHANNELS", "Channels : %s" },
     { "OSMSG_WHOIS_HIDECHANS", "Channel list omitted for your sanity." },
     { "OSMSG_UNBAN_DONE", "Ban(s) removed from channel %s." },
     { "OSMSG_CHANNEL_VOICED", "All users on %s voiced." },
@@ -1252,6 +1253,8 @@ static MODCMD_FUNC(cmd_whois)
     }
     reply("OSMSG_WHOIS_NICK", target->nick);
     reply("OSMSG_WHOIS_HOST", target->ident, target->hostname);
+    if (IsFakeIdent(target))
+        reply("OSMSG_WHOIS_FAKEIDENT", target->fakeident);
     if (IsFakeHost(target))
         reply("OSMSG_WHOIS_FAKEHOST", target->fakehost);
     reply("OSMSG_WHOIS_IP", irc_ntoa(&target->ip));
index 01c71d8a2ee9ff56d8b4bd6f8d3f9e7cadc3b912..aa1436ce59b7b0c7afa0ddb77ffc7fbc3b5c21d7 100644 (file)
@@ -263,7 +263,7 @@ irc_account(struct userNode *user, UNUSED_ARG(const char *stamp), UNUSED_ARG(uns
 }
 
 void
-irc_fakehost(UNUSED_ARG(struct userNode *user), UNUSED_ARG(const char *host))
+irc_fakehost(UNUSED_ARG(struct userNode *user), UNUSED_ARG(const char *host), UNUSED_ARG(const char *ident), UNUSED_ARG(int force))
 {
     /* not supported in bahamut */
 }
index f6eb772525dd8b147ddb62520deb6779a4bb251c..4f7f29025a36fa53081b073253d37f477014e8d3 100644 (file)
@@ -490,9 +490,9 @@ irc_account(struct userNode *user, const char *stamp, unsigned long timestamp, u
 }
 
 void
-irc_fakehost(struct userNode *user, const char *host)
+irc_fakehost(struct userNode *user, const char *host, const char *ident, int force)
 {
-    putsock("%s " P10_FAKEHOST " %s %s", self->numeric, user->numeric, host);
+    putsock("%s " P10_FAKEHOST " %s %s %s%s", self->numeric, user->numeric, ident, host, force ? " FORCE" : "");
 }
 
 void
@@ -1242,12 +1242,22 @@ static CMD_FUNC(cmd_account)
 static CMD_FUNC(cmd_fakehost)
 {
     struct userNode *user;
+    const char *host, *ident;
 
     if ((argc < 3) || !origin || !GetServerH(origin))
         return 0;
     if (!(user = GetUserN(argv[1])))
         return 1;
-    assign_fakehost(user, argv[2], 0);
+
+    if (argc > 3) {
+        ident = argv[2];
+        host = argv[3];
+    } else {
+        ident = NULL;
+        host = argv[2];
+    }
+
+    assign_fakehost(user, host, ident, 0, 0);
     return 1;
 }
 
@@ -2297,16 +2307,25 @@ void mod_usermode(struct userNode *user, const char *mode_change) {
                 call_account_func(user, tag, ts, id);
             }
             break;
-        case 'f':
+        case 'h':
             if (*word) {
-                char host[MAXLEN];
+                char mask[MAXLEN];
+                char *host, *ident;
                 unsigned int ii;
                 for (ii=0; (*word != ' ') && (*word != '\0'); )
-                    host[ii++] = *word++;
-                host[ii] = 0;
+                    mask[ii++] = *word++;
+                mask[ii] = 0;
                 while (*word == ' ')
                     word++;
-                assign_fakehost(user, host, 0);
+
+                if ((host = strrchr(mask, '@'))) {
+                    ident = mask;
+                    *host++ = '\0';
+                } else {
+                    ident = NULL;
+                    host = mask;
+                }
+                assign_fakehost(user, host, ident, 0, 0);
             }
             break;
         }
index 8a223bfdec21c4e9276647eb62f7be20f764e2a8..3d8e2e74083b30d637b3ad0c2609d10a36250600 100644 (file)
@@ -146,7 +146,7 @@ void irc_svsnick(struct userNode *from, struct userNode *target, const char *new
 /* account maintenance */
 void irc_account(struct userNode *user, const char *stamp, unsigned long timestamp, unsigned long serial);
 void irc_regnick(struct userNode *user);
-void irc_fakehost(struct userNode *user, const char *host);
+void irc_fakehost(struct userNode *user, const char *host, const char *ident, int force);
 
 /* numeric messages */
 void irc_numeric(struct userNode *user, unsigned int num, const char *format, ...);