#include "common.h"
#include "dict.h"
#include "policer.h"
+#include "recdb.h"
#define MODE_CHANOP 0x00000001 /* +o USER */
#define MODE_VOICE 0x00000002 /* +v USER */
char *version_reply; /* only filled in if a version query was triggered */
char *sslfp; /* only filled in if a mark SSLCLIFP is received */
+ struct string_list *marks; /* list of user's marks */
+
time_t timestamp; /* Time of last nick change */
time_t idle_since;
struct server *uplink; /* Server that user is connected to */
{ "OSMSG_WHOIS_HIDECHANS", "Channel list omitted for your sanity." },
{ "OSMSG_WHOIS_VERSION", "Version : %s" },
{ "OSMSG_WHOIS_SSLFP", "SSL f/print : %s" },
- { "OSMSG_WHOIS_MARK", "Mark : %s" },
+ { "OSMSG_WHOIS_MARK", "Mark : %s" },
+ { "OSMSG_WHOIS_MARKS", "Marks : %s" },
{ "OSMSG_WHOIS_NO_NOTICE", "No_notices : %s" },
{ "OSMSG_UNBAN_DONE", "Ban(s) removed from channel %s." },
{ "OSMSG_CHANNEL_VOICED", "All users on %s voiced." },
if(target->mark) {
reply("OSMSG_WHOIS_MARK", target->mark);
}
+ if(target->marks) {
+ char markbuf[MAXLEN] = "";
+ unsigned int ii = 0;
+
+ string_list_sort(user->marks);
+
+ for (ii=0; ii<user->marks->used; ii++)
+ {
+ if (markbuf[0] && strlen(markbuf) + strlen(user->marks->list[ii]) + 4 > 70) {
+ reply("OSMSG_WHOIS_MARKS", markbuf);
+ memset(&markbuf, 0, MAXLEN);
+ }
+
+ if (markbuf[0])
+ strcat(markbuf, ", ");
+ strcat(markbuf, user->marks->list[ii]);
+ }
+
+ if (markbuf[0])
+ reply("OSMSG_WHOIS_MARKS", markbuf);
+ }
+
reply("OSMSG_WHOIS_NO_NOTICE", target->no_notice ? "YES":"NO");
if (target->modes) {
{
unsigned int level, i;
char *scmp=NULL, *dcmp=NULL;
+ int markmatched = 0;
+
+ if (discrim->mask_mark)
+ {
+ unsigned int ii = 0;
+
+ if (user->mark && match_ircglob(user->mark, discrim->mask_mark))
+ markmatched = 1;
+
+ if (user->marks)
+ for (ii=0; ii<user->marks->used; ii++)
+ if (match_ircglob(user->marks->list[ii], discrim->mask_mark))
+ markmatched = 1;
+ }
if ((user->timestamp < discrim->min_ts)
|| (user->timestamp > discrim->max_ts)
|| (discrim->info_space == 0 && user->info[0] == ' ')
|| (discrim->info_space == 1 && user->info[0] != ' ')
|| (discrim->server && !match_ircglob(user->uplink->name, discrim->server))
- || (discrim->mask_mark && (!user->mark || !match_ircglob(user->mark, discrim->mask_mark)))
+ || (discrim->mask_mark && !markmatched)
|| (discrim->accountmask && (!user->handle_info || !match_ircglob(user->handle_info->handle, discrim->accountmask)))
|| (discrim->ip_mask_bits && !irc_check_mask(&user->ip, &discrim->ip_mask, discrim->ip_mask_bits))
)
char *host = user->hostname;
int type = 4;
const char *tstr = NULL;
-
- /* TODO: Allow mark overwrite. If they are marked, and their fakehost is oldmark.hostname, update it to newmark.hostname so mark can be called multiple times. Probably requires ircd modification also */
- if(user->mark)
- return;
+ unsigned int ii = 0;
+ int markfound = 0;
tstr = conf_get_data("server/type", RECDB_QSTRING);
if(tstr)
else
type = 4;
+ if (user->marks)
+ for (ii=0; ii<user->marks->used; ii++)
+ if (!irccasecmp(user->marks->list[ii], mark))
+ markfound = 1;
+
+ if (!markfound)
+ {
+ if (!user->marks)
+ user->marks = alloc_string_list(1);
+ string_list_append(user->marks, strdup(mark));
+ }
+
if (type >= 9)
{
putsock("%s " CMD_MARK " %s MARK %s", self->numeric, user->nick, mark);
return;
}
+ /* TODO: Allow mark overwrite. If they are marked, and their fakehost is oldmark.hostname, update it to newmark.hostname so mark can be called multiple times. Probably requires ircd modification also */
+ if(user->mark)
+ return;
+
/* if the mark will put us over the host length, clip some off the left hand side
* to make room...
*/
*/
static CMD_FUNC(cmd_mark)
{
+ const char *tstr;
+ int type = 4;
struct userNode *target;
/*
* log_module(MAIN_LOG, LOG_ERROR, "DEBUG: mark, user %s, type %s, arg %s", argv[1], argv[2], argv[3]);
*/
+ tstr = conf_get_data("server/type", RECDB_QSTRING);
+ if(tstr)
+ type = atoi(tstr);
+ else
+ type = 4;/* default to 040 style topics */
+
if(argc < 4)
return 0;
if(!strcasecmp(argv[2], "DNSBL")) {
/* DNSBL <modes> */
return 1;
}
- else if(!strcasecmp(argv[2], "DNSBL_DATA")) {
+ else if(!strcasecmp(argv[2], "DNSBL_DATA") || !strcasecmp(argv[2], "MARK")) {
+ int markfound = 0;
+ unsigned int ii = 0;
/* DNSBL_DATA name */
target = GetUserH(argv[1]);
if(!target) {
log_module(MAIN_LOG, LOG_ERROR, "Unable to find user %s whose dnsbl mark is changing.", argv[1]);
return 0;
}
- target->mark = strdup(argv[3]);
+ if (type >= 9) {
+ if (target->marks)
+ for (ii=0; ii<target->marks->used; ii++)
+ if (!irccasecmp(target->marks->list[ii], argv[3]))
+ markfound = 1;
+ if (!markfound)
+ {
+ if (!target->marks)
+ target->marks = alloc_string_list(1);
+ string_list_append(target->marks, strdup(argv[3]));
+ }
+ } else
+ target->mark = strdup(argv[3]);
return 1;
}
free(user->mark);
user->mark = NULL;
}
+ free_string_list(user->marks);
+ user->marks = NULL;
/* clean up geoip data if any */
if(user->country_code) free(user->country_code);