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.
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) {
}
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);
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) {
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);
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;
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 *
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,
}
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;
+}
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;
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 {
/* 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