Add a new irc_user_modes() helper function and irc_user_mode_chars[] array.
authorMichael Poole <mdpoole@troilus.org>
Thu, 17 Sep 2009 20:45:49 +0000 (16:45 -0400)
committerMichael Poole <mdpoole@troilus.org>
Thu, 17 Sep 2009 21:05:39 +0000 (17:05 -0400)
src/proto.h (irc_user_modes): Declare.
  (irc_user_mode_chars): Likewise.
src/proto-common.c (irc_user_modes): Define.
src/proto-bahamut.c (irc_user_mode_chars): Define.
  (irc_user): Use irc_user_mode_chars() instead of open-coding it.
src/proto-p10.c (irc_user_mode_chars): Define.
  (irc_user): Use irc_user_mode_chars() instead of open-coding it.
src/opserv.c (cmd_whois): Use irc_user_mode_chars() here too.
src/modcmd.c (modcmd_saxdb_write): Write bot modes to the database.
  (modcmd_load_bots): Read them out and use them.

src/modcmd.c
src/opserv.c
src/proto-bahamut.c
src/proto-common.c
src/proto-p10.c
src/proto.h

index 53bb49004c489850afbf2ff6202f71c726357430..58ab816a81fe431ad22376920120f9a57f57b839 100644 (file)
@@ -1971,6 +1971,8 @@ modcmd_saxdb_write(struct saxdb_context *ctx) {
     saxdb_start_record(ctx, "bots", 1);
     for (it = dict_first(services); it; it = iter_next(it)) {
         char buff[16];
+        char modes[32];
+
         service = iter_data(it);
         saxdb_start_record(ctx, service->bot->nick, 1);
         if (service->trigger) {
@@ -1980,6 +1982,10 @@ modcmd_saxdb_write(struct saxdb_context *ctx) {
         }
         saxdb_write_string(ctx, "description", service->bot->info);
         saxdb_write_string(ctx, "hostname", service->bot->hostname);
+        if (service->bot->modes) {
+            irc_user_modes(service->bot, modes, sizeof(modes));
+            saxdb_write_string(ctx, "modes", modes);
+        }
         if (service->privileged)
             saxdb_write_string(ctx, "privileged", "1");
         saxdb_end_record(ctx);
@@ -2064,7 +2070,7 @@ modcmd_load_bots(struct dict *db, int default_nick) {
     for (it = dict_first(db); it; it = iter_next(it)) {
         struct record_data *rd;
         struct service *svc;
-        const char *nick, *desc, *hostname;
+        const char *nick, *desc, *hostname, *modes;
 
         rd = iter_data(it);
         if (rd->type != RECDB_OBJECT) {
@@ -2081,9 +2087,10 @@ modcmd_load_bots(struct dict *db, int default_nick) {
         svc = service_find(nick);
         desc = database_get_data(rd->d.object, "description", RECDB_QSTRING);
         hostname = database_get_data(rd->d.object, "hostname", RECDB_QSTRING);
+        modes = database_get_data(rd->d.object, "modes", RECDB_QSTRING);
         if (desc) {
             if (!svc)
-                svc = service_register(AddLocalUser(nick, nick, hostname, desc, NULL));
+                svc = service_register(AddLocalUser(nick, nick, hostname, desc, modes));
             else if (hostname)
                 strcpy(svc->bot->hostname, hostname);
             desc = database_get_data(rd->d.object, "trigger", RECDB_QSTRING);
index 608ff403ba676bf44a5962d983f3e04de9431ff3..488f2a7c2379fdc4a0ccd75f34d176c0d31f2f0a 100644 (file)
@@ -1256,17 +1256,8 @@ static MODCMD_FUNC(cmd_whois)
         reply("OSMSG_WHOIS_FAKEHOST", target->fakehost);
     reply("OSMSG_WHOIS_IP", irc_ntoa(&target->ip));
     if (target->modes) {
-        bpos = 0;
+        bpos = irc_user_modes(target, buffer, sizeof(buffer));
 #define buffer_cat(str) (herelen = strlen(str), memcpy(buffer+bpos, str, herelen), bpos += herelen)
-        if (IsInvisible(target)) buffer[bpos++] = 'i';
-        if (IsWallOp(target)) buffer[bpos++] = 'w';
-        if (IsOper(target)) buffer[bpos++] = 'o';
-        if (IsGlobal(target)) buffer[bpos++] = 'g';
-        if (IsService(target)) buffer[bpos++] = 'k';
-        if (IsDeaf(target)) buffer[bpos++] = 'd';
-        if (IsNoChan(target)) buffer[bpos++] = 'n';
-        if (IsHiddenHost(target)) buffer[bpos++] = 'x';
-        if (IsNoIdle(target)) buffer[bpos++] = 'I';
         if (IsGagged(target)) buffer_cat(" (gagged)");
         if (IsRegistering(target)) buffer_cat(" (registered account)");
         buffer[bpos] = 0;
index 8f25c0bfbd607290f6f63ed25b2bbf71443d0970..01c71d8a2ee9ff56d8b4bd6f8d3f9e7cadc3b912 100644 (file)
@@ -38,6 +38,9 @@ static dict_t service_msginfo_dict; /* holds service_message_info structs */
 static int uplink_capab;
 static void privmsg_user_helper(struct userNode *un, void *data);
 
+/* These correspond to 1 << X:      012345678901234567 */
+const char irc_user_mode_chars[] = "o iw dkg      r   ";
+
 void irc_svsmode(struct userNode *target, char *modes, unsigned long stamp);
 
 struct server *
@@ -241,16 +244,8 @@ irc_server(struct server *srv) {
 void
 irc_user(struct userNode *user) {
     char modes[32];
-    int modelen = 0;
     if (!user || user->nick[0] != ' ') return;
-    if (IsOper(user)) modes[modelen++] = 'o';
-    if (IsInvisible(user)) modes[modelen++] = 'i';
-    if (IsWallOp(user)) modes[modelen++] = 'w';
-    if (IsService(user)) modes[modelen++] = 'k';
-    if (IsDeaf(user)) modes[modelen++] = 'd';
-    if (IsReggedNick(user)) modes[modelen++] = 'r';
-    if (IsGlobal(user)) modes[modelen++] = 'g';
-    modes[modelen] = 0;
+    irc_user_modes(user, modes, sizeof(modes));
     putsock("NICK %s %d %lu +%s %s %s %s %d %u :%s",
             user->nick, user->uplink->hops+2, (unsigned long)user->timestamp,
             modes, user->ident, user->hostname, user->uplink->name, 0,
index 3a14c68bdc0670b0371028711c61d30fa8d20273..967cb77f2ed823f0b31f678b7621baf5e32b1d29 100644 (file)
@@ -816,3 +816,20 @@ IsChannelName(const char *name) {
     }
     return 1;
 }
+
+unsigned int
+irc_user_modes(const struct userNode *user, char modes[], size_t length)
+{
+    unsigned int ii, jj;
+
+    for (ii = jj = 0; (jj < length) && (irc_user_mode_chars[ii] != '\0'); ++ii) {
+        if ((user->modes & (1 << ii)) && (irc_user_mode_chars[ii] != ' '))
+            modes[jj++] = irc_user_mode_chars[ii];
+    }
+
+    ii = jj;
+    while (jj < length)
+        modes[jj++] = '\0';
+
+    return ii;
+}
index dbf0bd0a34245ee4d3414541ee63398ace8dce5f..c4e6696366d635f598aa0c1f77bf590ea50f4baa 100644 (file)
@@ -292,6 +292,9 @@ static struct dict *unbursted_channels;
 static const char *his_servername;
 static const char *his_servercomment;
 
+/* These correspond to 1 << X:      012345678901234567 */
+const char irc_user_mode_chars[] = "o iw dkgn        I";
+
 static struct userNode *AddUser(struct server* uplink, const char *nick, const char *ident, const char *hostname, const char *modes, const char *numeric, const char *userinfo, unsigned long timestamp, const char *realip);
 
 extern int off_channel;
@@ -459,31 +462,8 @@ irc_user(struct userNode *user)
         return;
     irc_p10_ntop(b64ip, &user->ip);
     if (user->modes) {
-        int modelen;
         char modes[32];
-
-        modelen = 0;
-        if (IsOper(user))
-            modes[modelen++] = 'o';
-        if (IsInvisible(user))
-            modes[modelen++] = 'i';
-        if (IsWallOp(user))
-            modes[modelen++] = 'w';
-        if (IsService(user))
-            modes[modelen++] = 'k';
-        if (IsDeaf(user))
-            modes[modelen++] = 'd';
-        if (IsGlobal(user))
-            modes[modelen++] = 'g';
-        if (IsNoChan(user))
-            modes[modelen++] = 'n';
-        if (IsHiddenHost(user))
-            modes[modelen++] = 'x';
-        if (IsNoIdle(user))
-            modes[modelen++] = 'I';
-        modes[modelen] = 0;
-
-        /* we don't need to put the + in modes because it's in the format string. */
+        irc_user_modes(user, modes, sizeof(modes));
         putsock("%s " P10_NICK " %s %d %lu %s %s +%s %s %s :%s",
                 user->uplink->numeric, user->nick, user->uplink->hops+1, (unsigned long)user->timestamp, user->ident, user->hostname, modes, b64ip, user->numeric, user->info);
     } else {
index 3ee7cb58faa607dcb48b5c7ee7a8ce13acc6cba1..8a223bfdec21c4e9276647eb62f7be20f764e2a8 100644 (file)
@@ -175,7 +175,9 @@ void DelUser(struct userNode* user, struct userNode *killer, int announce, const
 /* Most protocols will want to make an AddUser helper function. */
 
 /* User modes */
+extern const char irc_user_mode_chars[];
 void mod_usermode(struct userNode *user, const char *modes);
+unsigned int irc_user_modes(const struct userNode *user, char modes[], size_t length);
 
 /* Channel mode manipulation */
 #define KEYLEN          23