Compare commits
23 commits
492d560ee1
...
5c01fc8bd7
Author | SHA1 | Date | |
---|---|---|---|
|
5c01fc8bd7 | ||
|
12cee8ab78 | ||
|
9d2e66c08d | ||
|
5a3e99829a | ||
|
3fdf26aa19 | ||
|
c0d93064a6 | ||
|
62f6351d90 | ||
|
57aa79acb8 | ||
|
e239ac8785 | ||
|
fae8f2517c | ||
|
4f46809305 | ||
|
8e239de831 | ||
|
e73eade529 | ||
|
2681c7d2e4 | ||
|
48a06ae3d7 | ||
|
b2fa28dd95 | ||
|
ba95896969 | ||
|
1fcdacb424 | ||
|
2f596395fa | ||
|
099d470763 | ||
|
80d71456cf | ||
|
9dd98618d0 | ||
|
c2fdb023a9 |
38 changed files with 386 additions and 157 deletions
|
@ -26,6 +26,8 @@
|
|||
#include "notice.h"
|
||||
#include "provider.h"
|
||||
|
||||
#include <netinet/tcp.h> // TCP_NODELAY
|
||||
|
||||
#define SELF_PID (opm_provider.id)
|
||||
|
||||
#define OPM_READSIZE 128
|
||||
|
|
|
@ -514,7 +514,7 @@ static void do_query_number(struct DNSQuery *query, const struct rb_sockaddr_sto
|
|||
request->name = (char *)rb_malloc(IRCD_RES_HOSTLEN + 1);
|
||||
}
|
||||
|
||||
build_rdns(request->queryname, IRCD_RES_HOSTLEN + 1, addr, NULL);
|
||||
build_rdns(request->queryname, sizeof request->queryname, addr, NULL);
|
||||
|
||||
request->type = T_PTR;
|
||||
query_name(request);
|
||||
|
|
|
@ -344,6 +344,11 @@ listen {
|
|||
|
||||
/* auth {}: allow users to connect to the ircd (OLD I:) */
|
||||
auth {
|
||||
/* description: descriptive text to help recognize this auth block in
|
||||
* stats i output.
|
||||
*/
|
||||
description = "example oper";
|
||||
|
||||
/* user: the user@host allowed to connect. Multiple IPv4/IPv6 user
|
||||
* lines are permitted per auth block. This is matched against the
|
||||
* hostname and IP address (using :: shortening for IPv6 and
|
||||
|
|
|
@ -41,7 +41,7 @@ static int eb_extended(const char *data, struct Client *client_p,
|
|||
if (data == NULL)
|
||||
return EXTBAN_INVALID;
|
||||
|
||||
snprintf(buf, BUFSIZE, "%s!%s@%s#%s",
|
||||
snprintf(buf, sizeof buf, "%s!%s@%s#%s",
|
||||
client_p->name, client_p->username, client_p->host, client_p->info);
|
||||
|
||||
return match(data, buf) ? EXTBAN_MATCH : EXTBAN_NOMATCH;
|
||||
|
|
|
@ -134,7 +134,7 @@ mo_ojoin(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
|
|||
sendto_one(source_p, form_str(RPL_TOPIC), me.name,
|
||||
source_p->name, chptr->chname, chptr->topic);
|
||||
sendto_one(source_p, form_str(RPL_TOPICWHOTIME), me.name,
|
||||
source_p->name, chptr->chname, chptr->topic_info, chptr->topic_time);
|
||||
source_p->name, chptr->chname, chptr->topic_info, (long long)chptr->topic_time);
|
||||
}
|
||||
|
||||
source_p->localClient->last_join_time = rb_current_time();
|
||||
|
|
|
@ -106,17 +106,17 @@ mr_webirc(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sourc
|
|||
if (!IsConfDoSpoofIp(aconf) || irccmp(aconf->info.name, "webirc."))
|
||||
{
|
||||
/* XXX */
|
||||
sendto_one(source_p, "NOTICE * :Not a CGI:IRC auth block");
|
||||
exit_client(client_p, source_p, &me, "Not a CGI:IRC auth block");
|
||||
return;
|
||||
}
|
||||
if (EmptyString(aconf->passwd))
|
||||
{
|
||||
sendto_one(source_p, "NOTICE * :CGI:IRC auth blocks must have a password");
|
||||
exit_client(client_p, source_p, &me, "CGI:IRC auth blocks must have a password");
|
||||
return;
|
||||
}
|
||||
if (!IsSecure(source_p) && aconf->flags & CONF_FLAGS_NEED_SSL)
|
||||
{
|
||||
sendto_one(source_p, "NOTICE * :Your CGI:IRC block requires TLS");
|
||||
exit_client(client_p, source_p, &me, "Your CGI:IRC block requires TLS");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -129,13 +129,13 @@ mr_webirc(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sourc
|
|||
|
||||
if (encr == NULL || strcmp(encr, aconf->passwd))
|
||||
{
|
||||
sendto_one(source_p, "NOTICE * :CGI:IRC password incorrect");
|
||||
exit_client(client_p, source_p, &me, "CGI:IRC password incorrect");
|
||||
return;
|
||||
}
|
||||
|
||||
if (rb_inet_pton_sock(parv[4], &addr) <= 0)
|
||||
{
|
||||
sendto_one(source_p, "NOTICE * :Invalid IP");
|
||||
exit_client(client_p, source_p, &me, "Invalid IP");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
#define NUMERIC_STR_209 "Class %s %d"
|
||||
#define NUMERIC_STR_212 "%s %u %lu :%u"
|
||||
#define NUMERIC_STR_213 "C %s %s %s %d %s %s"
|
||||
#define NUMERIC_STR_215 "I %s %s %s@%s %d %s"
|
||||
#define NUMERIC_STR_215 "I %s %s %s@%s %d %s :%s"
|
||||
#define NUMERIC_STR_216 "%c %s * %s :%s%s%s"
|
||||
#define NUMERIC_STR_217 "%c %d %s :%s"
|
||||
#define NUMERIC_STR_218 "Y %s %d %d %d %u %d.%d %d.%d %u"
|
||||
|
@ -101,11 +101,11 @@
|
|||
#define NUMERIC_STR_323 ":%s 323 %s :End of /LIST"
|
||||
#define NUMERIC_STR_324 ":%s 324 %s %s %s"
|
||||
#define NUMERIC_STR_325 ":%s 325 %s %s %s :is the current channel mode-lock"
|
||||
#define NUMERIC_STR_329 ":%s 329 %s %s %lu"
|
||||
#define NUMERIC_STR_329 ":%s 329 %s %s %lld"
|
||||
#define NUMERIC_STR_330 "%s %s :is logged in as"
|
||||
#define NUMERIC_STR_331 ":%s 331 %s %s :No topic is set."
|
||||
#define NUMERIC_STR_332 ":%s 332 %s %s :%s"
|
||||
#define NUMERIC_STR_333 ":%s 333 %s %s %s %lu"
|
||||
#define NUMERIC_STR_333 ":%s 333 %s %s %s %lld"
|
||||
#define NUMERIC_STR_337 "%s :%s"
|
||||
#define NUMERIC_STR_338 "%s %s :actually using host"
|
||||
#define NUMERIC_STR_341 ":%s 341 %s %s %s"
|
||||
|
|
|
@ -65,6 +65,7 @@ struct ConfItem
|
|||
char *passwd; /* doubles as kline reason *ugh* */
|
||||
char *spasswd; /* Password to send. */
|
||||
char *user; /* user part of user@host */
|
||||
char *desc; /* description */
|
||||
int port;
|
||||
time_t hold; /* Hold action until this time (calendar time) */
|
||||
time_t created; /* Creation time (for klines etc) */
|
||||
|
@ -384,7 +385,7 @@ extern int detach_conf(struct Client *);
|
|||
extern struct ConfItem *find_tkline(const char *, const char *, struct sockaddr *);
|
||||
extern char *show_iline_prefix(struct Client *, struct ConfItem *, char *);
|
||||
extern void get_printable_conf(struct ConfItem *,
|
||||
char **, char **, const char **, char **, int *, char **);
|
||||
char **, char **, const char **, char **, int *, char **, char **);
|
||||
extern char *get_user_ban_reason(struct ConfItem *aconf);
|
||||
extern void get_printable_kline(struct Client *, struct ConfItem *,
|
||||
char **, char **, char **, char **);
|
||||
|
|
|
@ -40,6 +40,8 @@
|
|||
#include <openssl/rsa.h>
|
||||
#endif
|
||||
|
||||
#define MAX_TEMP_TIME (52 * 7 * 24 * 60 * 60)
|
||||
|
||||
struct Client;
|
||||
struct ConfItem;
|
||||
|
||||
|
|
|
@ -249,9 +249,7 @@ add_id(struct Client *source_p, struct Channel *chptr, const char *banid, const
|
|||
char *realban = LOCAL_COPY(banid);
|
||||
rb_dlink_node *ptr;
|
||||
|
||||
/* dont let local clients overflow the banlist, or set redundant
|
||||
* bans
|
||||
*/
|
||||
/* dont let local clients overflow the banlist */
|
||||
if(MyClient(source_p))
|
||||
{
|
||||
if((rb_dlink_list_length(&chptr->banlist) + rb_dlink_list_length(&chptr->exceptlist) + rb_dlink_list_length(&chptr->invexlist) + rb_dlink_list_length(&chptr->quietlist)) >= (unsigned long)((chptr->mode.mode & MODE_EXLIMIT) ? ConfigChannel.max_bans_large : ConfigChannel.max_bans))
|
||||
|
@ -260,26 +258,16 @@ add_id(struct Client *source_p, struct Channel *chptr, const char *banid, const
|
|||
me.name, source_p->name, chptr->chname, realban);
|
||||
return false;
|
||||
}
|
||||
|
||||
RB_DLINK_FOREACH(ptr, list->head)
|
||||
{
|
||||
actualBan = ptr->data;
|
||||
if(mask_match(actualBan->banstr, realban))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/* dont let remotes set duplicates */
|
||||
else
|
||||
|
||||
/* don't let anyone set duplicate bans */
|
||||
RB_DLINK_FOREACH(ptr, list->head)
|
||||
{
|
||||
RB_DLINK_FOREACH(ptr, list->head)
|
||||
{
|
||||
actualBan = ptr->data;
|
||||
if(!irccmp(actualBan->banstr, realban))
|
||||
return false;
|
||||
}
|
||||
actualBan = ptr->data;
|
||||
if(!irccmp(actualBan->banstr, realban))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if(IsPerson(source_p))
|
||||
sprintf(who, "%s!%s@%s", source_p->name, source_p->username, source_p->host);
|
||||
else
|
||||
|
@ -937,9 +925,9 @@ chm_ban(struct Client *source_p, struct Channel *chptr,
|
|||
}
|
||||
|
||||
if (removed && removed->forward)
|
||||
removed_mask_pos += snprintf(buf + old_removed_mask_pos, sizeof(buf), "%s$%s", removed->banstr, removed->forward) + 1;
|
||||
removed_mask_pos += snprintf(buf + old_removed_mask_pos, sizeof(buf) - old_removed_mask_pos, "%s$%s", removed->banstr, removed->forward) + 1;
|
||||
else
|
||||
removed_mask_pos += rb_strlcpy(buf + old_removed_mask_pos, mask, sizeof(buf)) + 1;
|
||||
removed_mask_pos += rb_strlcpy(buf + old_removed_mask_pos, removed ? removed->banstr : mask, sizeof(buf)) + 1;
|
||||
if (removed)
|
||||
{
|
||||
free_ban(removed);
|
||||
|
|
|
@ -1573,11 +1573,11 @@ exit_local_server(struct Client *client_p, struct Client *source_p, struct Clien
|
|||
remove_dependents(client_p, source_p, from, IsPerson(from) ? newcomment : comment, comment1);
|
||||
|
||||
sendto_realops_snomask(SNO_GENERAL, L_ALL, "%s was connected"
|
||||
" for %ld seconds. %d/%d sendK/recvK.",
|
||||
source_p->name, (long) rb_current_time() - source_p->localClient->firsttime, sendk, recvk);
|
||||
" for %lld seconds. %d/%d sendK/recvK.",
|
||||
source_p->name, (long long)(rb_current_time() - source_p->localClient->firsttime), sendk, recvk);
|
||||
|
||||
ilog(L_SERVER, "%s was connected for %ld seconds. %d/%d sendK/recvK.",
|
||||
source_p->name, (long) rb_current_time() - source_p->localClient->firsttime, sendk, recvk);
|
||||
ilog(L_SERVER, "%s was connected for %lld seconds. %d/%d sendK/recvK.",
|
||||
source_p->name, (long long)(rb_current_time() - source_p->localClient->firsttime), sendk, recvk);
|
||||
|
||||
if(has_id(source_p))
|
||||
del_from_id_hash(source_p->id, source_p);
|
||||
|
@ -1844,7 +1844,7 @@ show_ip_conf(struct ConfItem *aconf, struct Client *source_p)
|
|||
{
|
||||
if(IsConfDoSpoofIp(aconf))
|
||||
{
|
||||
if(!ConfigFileEntry.hide_spoof_ips && MyOper(source_p))
|
||||
if(!ConfigFileEntry.hide_spoof_ips && IsOper(source_p))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
|
@ -1857,7 +1857,7 @@ int
|
|||
show_ip_whowas(struct Whowas *whowas, struct Client *source_p)
|
||||
{
|
||||
if(whowas->flags & WHOWAS_IP_SPOOFING)
|
||||
if(ConfigFileEntry.hide_spoof_ips || !MyOper(source_p))
|
||||
if(ConfigFileEntry.hide_spoof_ips || !IsOper(source_p))
|
||||
return 0;
|
||||
if(whowas->flags & WHOWAS_DYNSPOOF)
|
||||
if(!IsOper(source_p))
|
||||
|
|
|
@ -723,7 +723,7 @@ show_iline_prefix(struct Client *sptr, struct ConfItem *aconf, char *name)
|
|||
void
|
||||
report_auth(struct Client *client_p)
|
||||
{
|
||||
char *name, *host, *user, *classname;
|
||||
char *name, *host, *user, *classname, *desc;
|
||||
const char *pass;
|
||||
struct AddressRec *arec;
|
||||
struct ConfItem *aconf;
|
||||
|
@ -739,7 +739,7 @@ report_auth(struct Client *client_p)
|
|||
continue;
|
||||
|
||||
get_printable_conf(aconf, &name, &host, &pass, &user, &port,
|
||||
&classname);
|
||||
&classname, &desc);
|
||||
|
||||
if(!EmptyString(aconf->spasswd))
|
||||
pass = aconf->spasswd;
|
||||
|
@ -748,7 +748,7 @@ report_auth(struct Client *client_p)
|
|||
form_str(RPL_STATSILINE),
|
||||
name, pass, show_iline_prefix(client_p, aconf, user),
|
||||
show_ip_conf(aconf, client_p) ? host : "255.255.255.255",
|
||||
port, classname);
|
||||
port, classname, desc);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -756,8 +756,8 @@ solanum_main(int argc, char * const argv[])
|
|||
check_splitmode_ev = rb_event_add("check_splitmode", check_splitmode, NULL, 5);
|
||||
|
||||
if(server_state_foreground)
|
||||
inotice("now running in foreground mode from %s as pid %d ...",
|
||||
ConfigFileEntry.dpath, getpid());
|
||||
inotice("now running in foreground mode from %s as pid %ld ...",
|
||||
ConfigFileEntry.dpath, (long)getpid());
|
||||
|
||||
rb_lib_loop(0);
|
||||
|
||||
|
|
|
@ -572,8 +572,6 @@ accept_sslcallback(struct Client *client_p, int status)
|
|||
return 0; /* use default handler if status != RB_OK */
|
||||
}
|
||||
|
||||
static const char *toofast = "ERROR :Reconnecting too fast, throttled.\r\n";
|
||||
|
||||
static int
|
||||
accept_precallback(rb_fde_t *F, struct sockaddr *addr, rb_socklen_t addrlen, void *data)
|
||||
{
|
||||
|
@ -583,6 +581,13 @@ accept_precallback(rb_fde_t *F, struct sockaddr *addr, rb_socklen_t addrlen, voi
|
|||
static time_t last_oper_notice = 0;
|
||||
int len;
|
||||
|
||||
static const char *toofast = "ERROR :Reconnecting too fast, throttled.\r\n";
|
||||
|
||||
static const unsigned char sslerrcode[] = {
|
||||
// SSLv3.0 Fatal Alert: Access Denied
|
||||
0x15, 0x03, 0x00, 0x00, 0x02, 0x02, 0x31
|
||||
};
|
||||
|
||||
if(listener->ssl && (!ircd_ssl_ok || !get_ssld_count()))
|
||||
{
|
||||
rb_close(F);
|
||||
|
@ -618,7 +623,11 @@ accept_precallback(rb_fde_t *F, struct sockaddr *addr, rb_socklen_t addrlen, voi
|
|||
{
|
||||
ServerStats.is_ref++;
|
||||
|
||||
if(ConfigFileEntry.dline_with_reason)
|
||||
if(listener->ssl)
|
||||
{
|
||||
rb_write(F, sslerrcode, sizeof(sslerrcode));
|
||||
}
|
||||
else if(ConfigFileEntry.dline_with_reason)
|
||||
{
|
||||
len = snprintf(buf, sizeof(buf), "ERROR :*** Banned: %s\r\n", get_user_ban_reason(aconf));
|
||||
if (len >= (int)(sizeof(buf)-1))
|
||||
|
@ -627,11 +636,14 @@ accept_precallback(rb_fde_t *F, struct sockaddr *addr, rb_socklen_t addrlen, voi
|
|||
buf[sizeof(buf) - 2] = '\n';
|
||||
buf[sizeof(buf) - 1] = '\0';
|
||||
}
|
||||
rb_write(F, buf, strlen(buf));
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(buf, "ERROR :You have been D-lined.\r\n");
|
||||
rb_write(F, buf, strlen(buf));
|
||||
}
|
||||
|
||||
rb_write(F, buf, strlen(buf));
|
||||
rb_close(F);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1037,6 +1037,9 @@ conf_end_auth(struct TopConf *tc)
|
|||
if(yy_aconf->className)
|
||||
yy_tmp->className = rb_strdup(yy_aconf->className);
|
||||
|
||||
if(yy_aconf->desc)
|
||||
yy_tmp->desc = rb_strdup(yy_aconf->desc);
|
||||
|
||||
yy_tmp->flags = yy_aconf->flags;
|
||||
yy_tmp->port = yy_aconf->port;
|
||||
|
||||
|
@ -1172,6 +1175,13 @@ conf_set_auth_spoof(void *data)
|
|||
yy_aconf->flags |= CONF_FLAGS_SPOOF_IP;
|
||||
}
|
||||
|
||||
static void
|
||||
conf_set_auth_desc(void *data)
|
||||
{
|
||||
rb_free(yy_aconf->desc);
|
||||
yy_aconf->desc = rb_strdup(data);
|
||||
}
|
||||
|
||||
static void
|
||||
conf_set_auth_flags(void *data)
|
||||
{
|
||||
|
@ -2318,7 +2328,7 @@ conf_report_error(const char *fmt, ...)
|
|||
char msg[BUFSIZE + 1] = { 0 };
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(msg, BUFSIZE, fmt, ap);
|
||||
vsnprintf(msg, sizeof msg, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (testing_conf)
|
||||
|
@ -2338,7 +2348,7 @@ conf_report_warning(const char *fmt, ...)
|
|||
char msg[BUFSIZE + 1] = { 0 };
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(msg, BUFSIZE, fmt, ap);
|
||||
vsnprintf(msg, sizeof msg, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (testing_conf)
|
||||
|
@ -2640,6 +2650,7 @@ static struct ConfEntry conf_auth_table[] =
|
|||
{ "redirport", CF_INT, conf_set_auth_redir_port, 0, NULL },
|
||||
{ "flags", CF_STRING | CF_FLIST, conf_set_auth_flags, 0, NULL },
|
||||
{ "umodes", CF_QSTRING, conf_set_auth_umodes, 0, NULL},
|
||||
{ "description",CF_QSTRING, conf_set_auth_desc, 0, NULL},
|
||||
{ "\0", 0, NULL, 0, NULL }
|
||||
};
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@ reject_exit(void *unused)
|
|||
|
||||
if (ddata->aconf)
|
||||
{
|
||||
snprintf(dynamic_reason, BUFSIZE, form_str(ERR_YOUREBANNEDCREEP) "\r\n",
|
||||
snprintf(dynamic_reason, sizeof dynamic_reason, form_str(ERR_YOUREBANNEDCREEP) "\r\n",
|
||||
me.name, "*", get_user_ban_reason(ddata->aconf));
|
||||
rb_write(ddata->F, dynamic_reason, strlen(dynamic_reason));
|
||||
|
||||
|
@ -108,7 +108,7 @@ reject_exit(void *unused)
|
|||
}
|
||||
else if (ddata->reason)
|
||||
{
|
||||
snprintf(dynamic_reason, BUFSIZE, ":%s 465 %s :%s\r\n",
|
||||
snprintf(dynamic_reason, sizeof dynamic_reason, ":%s 465 %s :%s\r\n",
|
||||
me.name, "*", ddata->reason);
|
||||
rb_write(ddata->F, dynamic_reason, strlen(dynamic_reason));
|
||||
}
|
||||
|
|
|
@ -154,6 +154,7 @@ free_conf(struct ConfItem *aconf)
|
|||
rb_free(aconf->className);
|
||||
rb_free(aconf->user);
|
||||
rb_free(aconf->host);
|
||||
rb_free(aconf->desc);
|
||||
|
||||
if(IsConfBan(aconf))
|
||||
operhash_delete(aconf->info.oper);
|
||||
|
@ -1346,7 +1347,8 @@ get_oper_name(struct Client *client_p)
|
|||
*/
|
||||
void
|
||||
get_printable_conf(struct ConfItem *aconf, char **name, char **host,
|
||||
const char **pass, char **user, int *port, char **classname)
|
||||
const char **pass, char **user, int *port,
|
||||
char **classname, char **desc)
|
||||
{
|
||||
static char null[] = "<NULL>";
|
||||
static char zero[] = "default";
|
||||
|
@ -1356,6 +1358,7 @@ get_printable_conf(struct ConfItem *aconf, char **name, char **host,
|
|||
*pass = EmptyString(aconf->passwd) ? null : aconf->passwd;
|
||||
*user = EmptyString(aconf->user) ? null : aconf->user;
|
||||
*classname = EmptyString(aconf->className) ? zero : aconf->className;
|
||||
*desc = CheckEmpty(aconf->desc);
|
||||
*port = (int) aconf->port;
|
||||
}
|
||||
|
||||
|
|
|
@ -689,40 +689,51 @@ valid_temp_time(const char *p)
|
|||
|
||||
while (*p) {
|
||||
char *endp;
|
||||
int mul;
|
||||
|
||||
errno = 0;
|
||||
current = strtol(p, &endp, 10);
|
||||
|
||||
if (errno == ERANGE)
|
||||
return -1;
|
||||
if (endp == p)
|
||||
return -1;
|
||||
if (current < 0)
|
||||
return -1;
|
||||
|
||||
switch (*endp) {
|
||||
case '\0': /* No unit was given so send it back as minutes */
|
||||
case 'm':
|
||||
result += current * 60;
|
||||
mul = 60;
|
||||
break;
|
||||
case 'h':
|
||||
result += current * 3600;
|
||||
mul = 3600;
|
||||
break;
|
||||
case 'd':
|
||||
result += current * 86400;
|
||||
mul = 86400;
|
||||
break;
|
||||
case 'w':
|
||||
result += current * 604800;
|
||||
mul = 604800;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (current > LONG_MAX / mul)
|
||||
return MAX_TEMP_TIME;
|
||||
|
||||
current *= mul;
|
||||
|
||||
if (current > MAX_TEMP_TIME - result)
|
||||
return MAX_TEMP_TIME;
|
||||
|
||||
result += current;
|
||||
|
||||
if (*endp == '\0')
|
||||
break;
|
||||
|
||||
p = endp + 1;
|
||||
}
|
||||
|
||||
return MIN(result, 60 * 60 * 24 * 7 * 52);
|
||||
return MIN(result, MAX_TEMP_TIME);
|
||||
}
|
||||
|
||||
/* Propagated bans are expired elsewhere. */
|
||||
|
|
|
@ -1640,7 +1640,7 @@ change_nick_user_host(struct Client *target_p, const char *nick, const char *use
|
|||
if(do_qjm)
|
||||
{
|
||||
va_start(ap, format);
|
||||
vsnprintf(reason, 255, format, ap);
|
||||
vsnprintf(reason, sizeof reason, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
sendto_common_channels_local_butone(target_p, NOCAPS, CLICAP_CHGHOST, ":%s!%s@%s QUIT :%s",
|
||||
|
|
|
@ -26,6 +26,7 @@ else \
|
|||
{ print $1 " " $2 " " $3 " " $7 " at " $4 " " $5 " " $6 }}'`
|
||||
else
|
||||
creation="$EXTERNAL_BUILD_TIMESTAMP"
|
||||
generation=1
|
||||
fi
|
||||
|
||||
$spitshell >version.c <<!SUB!THIS!
|
||||
|
|
|
@ -112,6 +112,7 @@ whowas_add_history(struct Client *client_p, int online)
|
|||
rb_strlcpy(who->hostname, client_p->host, sizeof(who->hostname));
|
||||
rb_strlcpy(who->realname, client_p->info, sizeof(who->realname));
|
||||
rb_strlcpy(who->sockhost, client_p->sockhost, sizeof(who->sockhost));
|
||||
rb_strlcpy(who->suser, client_p->user->suser, sizeof(who->suser));
|
||||
|
||||
who->flags = (IsIPSpoof(client_p) ? WHOWAS_IP_SPOOFING : 0) |
|
||||
(IsDynSpoof(client_p) ? WHOWAS_DYNSPOOF : 0);
|
||||
|
|
|
@ -52,7 +52,7 @@ rb_crypt(const char *key, const char *salt)
|
|||
return rb_sha512_crypt(key, salt);
|
||||
default:
|
||||
return NULL;
|
||||
};
|
||||
}
|
||||
}
|
||||
else
|
||||
return rb_des_crypt(key, salt);
|
||||
|
|
|
@ -294,23 +294,21 @@ rb_event_init(void)
|
|||
void
|
||||
rb_dump_events(void (*func) (char *, void *), void *ptr)
|
||||
{
|
||||
int len;
|
||||
char buf[512];
|
||||
rb_dlink_node *dptr;
|
||||
struct ev_entry *ev;
|
||||
len = sizeof(buf);
|
||||
|
||||
snprintf(buf, len, "Last event to run: %s", last_event_ran);
|
||||
snprintf(buf, sizeof buf, "Last event to run: %s", last_event_ran);
|
||||
func(buf, ptr);
|
||||
|
||||
rb_strlcpy(buf, "Operation Next Execution", len);
|
||||
rb_strlcpy(buf, "Operation Next Execution", sizeof buf);
|
||||
func(buf, ptr);
|
||||
|
||||
RB_DLINK_FOREACH(dptr, event_list.head)
|
||||
{
|
||||
ev = dptr->data;
|
||||
snprintf(buf, len, "%-28s %-4ld seconds (frequency=%d)", ev->name,
|
||||
ev->when - (long)rb_current_time(), (int)ev->frequency);
|
||||
snprintf(buf, sizeof buf, "%-28s %-4lld seconds (frequency=%d)", ev->name,
|
||||
(long long)(ev->when - rb_current_time()), (int)ev->frequency);
|
||||
func(buf, ptr);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -172,7 +172,7 @@ int
|
|||
rb_ports_supports_event(void)
|
||||
{
|
||||
return 1;
|
||||
};
|
||||
}
|
||||
|
||||
void
|
||||
rb_ports_init_event(void)
|
||||
|
|
|
@ -162,7 +162,7 @@ rb_path_to_self(void)
|
|||
{
|
||||
static char path_buf[4096];
|
||||
#if defined(HAVE_GETEXECNAME)
|
||||
char *s = getexecname();
|
||||
const char *s = getexecname();
|
||||
if (s == NULL)
|
||||
return NULL;
|
||||
realpath(s, path_buf);
|
||||
|
|
|
@ -51,10 +51,12 @@ chm_noctcp_process(void *data_)
|
|||
{
|
||||
hook_data_privmsg_channel *data = data_;
|
||||
/* don't waste CPU if message is already blocked */
|
||||
if (data->approved || data->msgtype == MESSAGE_TYPE_NOTICE)
|
||||
if (data->approved)
|
||||
return;
|
||||
|
||||
if (*data->text == '\001' && rb_strncasecmp(data->text + 1, "ACTION ", 7) && data->chptr->mode.mode & mode_noctcp)
|
||||
if (*data->text == '\001' &&
|
||||
data->chptr->mode.mode & mode_noctcp &&
|
||||
!(data->msgtype == MESSAGE_TYPE_PRIVMSG && !rb_strncasecmp(data->text + 1, "ACTION ", 7)))
|
||||
{
|
||||
sendto_one_numeric(data->source_p, ERR_CANNOTSENDTOCHAN, form_str(ERR_CANNOTSENDTOCHAN), data->chptr->chname);
|
||||
data->approved = ERR_CANNOTSENDTOCHAN;
|
||||
|
|
|
@ -374,7 +374,7 @@ m_join(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p
|
|||
sendto_one(source_p, form_str(RPL_TOPICWHOTIME),
|
||||
me.name, source_p->name, chptr->chname,
|
||||
chptr->topic_info,
|
||||
(unsigned long)chptr->topic_time);
|
||||
(long long)chptr->topic_time);
|
||||
}
|
||||
|
||||
channel_member_names(chptr, source_p, 1);
|
||||
|
|
|
@ -132,7 +132,7 @@ m_mode(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p
|
|||
operspy ? channel_modes(chptr, &me) : channel_modes(chptr, source_p));
|
||||
|
||||
sendto_one(source_p, form_str(RPL_CREATIONTIME),
|
||||
me.name, source_p->name, parv[1], chptr->channelts);
|
||||
me.name, source_p->name, parv[1], (long long)chptr->channelts);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -340,20 +340,10 @@ mo_masktrace(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *so
|
|||
const char *parv[])
|
||||
{
|
||||
char *name, *username, *hostname, *gecos;
|
||||
const char *mask;
|
||||
int operspy = 0;
|
||||
|
||||
mask = parv[1];
|
||||
name = LOCAL_COPY(parv[1]);
|
||||
collapse(name);
|
||||
|
||||
if(IsOperSpy(source_p) && parv[1][0] == '!')
|
||||
{
|
||||
name++;
|
||||
mask++;
|
||||
operspy = 1;
|
||||
}
|
||||
|
||||
if(parc > 2 && !EmptyString(parv[2]))
|
||||
{
|
||||
gecos = LOCAL_COPY(parv[2]);
|
||||
|
@ -383,21 +373,6 @@ mo_masktrace(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *so
|
|||
return;
|
||||
}
|
||||
|
||||
if(operspy) {
|
||||
if (!ConfigFileEntry.operspy_dont_care_user_info)
|
||||
{
|
||||
char buf[512];
|
||||
rb_strlcpy(buf, mask, sizeof(buf));
|
||||
if(!EmptyString(gecos)) {
|
||||
rb_strlcat(buf, " ", sizeof(buf));
|
||||
rb_strlcat(buf, gecos, sizeof(buf));
|
||||
}
|
||||
|
||||
report_operspy(source_p, "MASKTRACE", buf);
|
||||
}
|
||||
match_masktrace(source_p, &global_client_list, username, hostname, name, gecos);
|
||||
} else
|
||||
match_masktrace(source_p, &lclient_list, username, hostname, name, gecos);
|
||||
|
||||
match_masktrace(source_p, &global_client_list, username, hostname, name, gecos);
|
||||
sendto_one_numeric(source_p, RPL_ENDOFTRACE, form_str(RPL_ENDOFTRACE), me.name);
|
||||
}
|
||||
|
|
|
@ -165,6 +165,11 @@ mo_kline(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
|
|||
}
|
||||
|
||||
reason = LOCAL_COPY(parv[loc]);
|
||||
if(strlen(reason) > BANREASONLEN)
|
||||
{
|
||||
sendto_one_notice(source_p, ":K-Line reason exceeds %d characters", BANREASONLEN);
|
||||
return;
|
||||
}
|
||||
|
||||
if(parse_netmask_strict(host, NULL, NULL) == HM_ERROR)
|
||||
{
|
||||
|
@ -234,9 +239,6 @@ mo_kline(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source
|
|||
aconf->port = 0;
|
||||
aconf->info.oper = operhash_add(get_oper_name(source_p));
|
||||
|
||||
if(strlen(reason) > BANREASONLEN)
|
||||
reason[BANREASONLEN] = '\0';
|
||||
|
||||
/* Look for an oper reason */
|
||||
if((oper_reason = strchr(reason, '|')) != NULL)
|
||||
{
|
||||
|
|
|
@ -108,7 +108,7 @@ dump_map(struct Client *client_p, struct Client *root_p, char *pbuf)
|
|||
}
|
||||
|
||||
frac = (1000 * rb_dlink_list_length(&root_p->serv->users) + Count.total / 2) / Count.total;
|
||||
snprintf(buf + USER_COL, BUFSIZE - USER_COL,
|
||||
snprintf(buf + USER_COL, sizeof buf - USER_COL,
|
||||
" | Users: %5lu (%2d.%1d%%)", rb_dlink_list_length(&root_p->serv->users),
|
||||
frac / 10, frac % 10);
|
||||
|
||||
|
@ -172,7 +172,7 @@ flattened_map(struct Client *client_p)
|
|||
}
|
||||
}
|
||||
|
||||
snprintf(buf + USER_COL, BUFSIZE - USER_COL,
|
||||
snprintf(buf + USER_COL, sizeof buf - USER_COL,
|
||||
" | Users: %5lu (%4.1f%%)", rb_dlink_list_length(&me.serv->users),
|
||||
100 * (float) rb_dlink_list_length(&me.serv->users) / (float) Count.total);
|
||||
|
||||
|
@ -210,7 +210,7 @@ flattened_map(struct Client *client_p)
|
|||
}
|
||||
}
|
||||
|
||||
snprintf(buf + USER_COL, BUFSIZE - USER_COL,
|
||||
snprintf(buf + USER_COL, sizeof buf - USER_COL,
|
||||
" | Users: %5lu (%4.1f%%)", rb_dlink_list_length(&target_p->serv->users),
|
||||
100 * (float) rb_dlink_list_length(&target_p->serv->users) / (float) Count.total);
|
||||
|
||||
|
|
|
@ -237,7 +237,7 @@ scan_umodes(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sou
|
|||
|
||||
if (mask != NULL)
|
||||
{
|
||||
snprintf(maskbuf, BUFSIZE, "%s!%s@%s",
|
||||
snprintf(maskbuf, sizeof maskbuf, "%s!%s@%s",
|
||||
target_p->name, target_p->username, target_p->host);
|
||||
|
||||
if (!match(mask, maskbuf))
|
||||
|
|
|
@ -453,7 +453,7 @@ stats_deny (struct Client *source_p)
|
|||
static void
|
||||
stats_exempt(struct Client *source_p)
|
||||
{
|
||||
char *name, *host, *user, *classname;
|
||||
char *name, *host, *user, *classname, *desc;
|
||||
const char *pass;
|
||||
struct AddressRec *arec;
|
||||
struct ConfItem *aconf;
|
||||
|
@ -474,7 +474,7 @@ stats_exempt(struct Client *source_p)
|
|||
{
|
||||
aconf = arec->aconf;
|
||||
get_printable_conf (aconf, &name, &host, &pass,
|
||||
&user, &port, &classname);
|
||||
&user, &port, &classname, &desc);
|
||||
|
||||
sendto_one_numeric(source_p, RPL_STATSDLINE,
|
||||
form_str(RPL_STATSDLINE),
|
||||
|
@ -533,7 +533,7 @@ stats_auth (struct Client *source_p)
|
|||
else if((ConfigFileEntry.stats_i_oper_only == 1) && !IsOperGeneral (source_p))
|
||||
{
|
||||
struct ConfItem *aconf;
|
||||
char *name, *host, *user, *classname;
|
||||
char *name, *host, *user, *classname, *desc;
|
||||
const char *pass = "*";
|
||||
int port;
|
||||
|
||||
|
@ -550,13 +550,13 @@ stats_auth (struct Client *source_p)
|
|||
if(aconf == NULL)
|
||||
return;
|
||||
|
||||
get_printable_conf (aconf, &name, &host, &pass, &user, &port, &classname);
|
||||
get_printable_conf (aconf, &name, &host, &pass, &user, &port, &classname, &desc);
|
||||
if(!EmptyString(aconf->spasswd))
|
||||
pass = aconf->spasswd;
|
||||
|
||||
sendto_one_numeric(source_p, RPL_STATSILINE, form_str(RPL_STATSILINE),
|
||||
name, pass, show_iline_prefix(source_p, aconf, user),
|
||||
host, port, classname);
|
||||
host, port, classname, desc);
|
||||
}
|
||||
|
||||
/* Theyre opered, or allowed to see all auth blocks */
|
||||
|
@ -908,8 +908,8 @@ stats_ssld_foreach(void *data, pid_t pid, int cli_count, enum ssld_status status
|
|||
struct Client *source_p = data;
|
||||
|
||||
sendto_one_numeric(source_p, RPL_STATSDEBUG,
|
||||
"S :%u %c %u :%s",
|
||||
pid,
|
||||
"S :%ld %c %u :%s",
|
||||
(long)pid,
|
||||
status == SSLD_DEAD ? 'D' : (status == SSLD_SHUTDOWN ? 'S' : 'A'),
|
||||
cli_count,
|
||||
version);
|
||||
|
@ -960,8 +960,8 @@ stats_usage (struct Client *source_p)
|
|||
(int) (rus.ru_stime.tv_sec % 60));
|
||||
sendto_one_numeric(source_p, RPL_STATSDEBUG,
|
||||
"R :RSS %ld ShMem %ld Data %ld Stack %ld",
|
||||
rus.ru_maxrss, (rus.ru_ixrss / rup),
|
||||
(rus.ru_idrss / rup), (rus.ru_isrss / rup));
|
||||
rus.ru_maxrss, (long)(rus.ru_ixrss / rup),
|
||||
(long)(rus.ru_idrss / rup), (long)(rus.ru_isrss / rup));
|
||||
sendto_one_numeric(source_p, RPL_STATSDEBUG,
|
||||
"R :Swaps %d Reclaims %d Faults %d",
|
||||
(int) rus.ru_nswap, (int) rus.ru_minflt, (int) rus.ru_majflt);
|
||||
|
|
|
@ -235,7 +235,8 @@ mo_testline(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sou
|
|||
sendto_one_numeric(source_p, RPL_STATSILINE, form_str(RPL_STATSILINE),
|
||||
aconf->info.name, EmptyString(aconf->spasswd) ? "<NULL>" : aconf->spasswd,
|
||||
show_iline_prefix(source_p, aconf, aconf->user),
|
||||
aconf->host, aconf->port, aconf->className);
|
||||
aconf->host, aconf->port, aconf->className,
|
||||
CheckEmpty(aconf->desc));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -173,7 +173,7 @@ m_topic(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_
|
|||
sendto_one(source_p, form_str(RPL_TOPICWHOTIME),
|
||||
me.name, source_p->name, chptr->chname,
|
||||
chptr->topic_info,
|
||||
(unsigned long)chptr->topic_time);
|
||||
(long long)chptr->topic_time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -367,8 +367,12 @@ who_global(struct Client *source_p, const char *mask, int server_oper, int opers
|
|||
who_common_channel(source_p, msptr->chptr, mask, server_oper, &maxmatches, fmt);
|
||||
}
|
||||
}
|
||||
else if (!ConfigFileEntry.operspy_dont_care_user_info)
|
||||
report_operspy(source_p, "WHO", mask);
|
||||
else
|
||||
{
|
||||
maxmatches = INT_MAX;
|
||||
if (!ConfigFileEntry.operspy_dont_care_user_info)
|
||||
report_operspy(source_p, "WHO", mask);
|
||||
}
|
||||
|
||||
/* second, list all matching visible clients and clear all marks
|
||||
* on invisible clients
|
||||
|
|
|
@ -44,49 +44,78 @@
|
|||
#include "supported.h"
|
||||
#include "logger.h"
|
||||
|
||||
static int
|
||||
um_callerid_modinit(void)
|
||||
{
|
||||
user_modes['g'] = find_umode_slot();
|
||||
if (!user_modes['g'])
|
||||
{
|
||||
ierror("um_callerid: unable to allocate usermode slot for +g; unloading module.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
user_modes['G'] = find_umode_slot();
|
||||
if (!user_modes['G'])
|
||||
{
|
||||
user_modes['g'] = 0;
|
||||
|
||||
ierror("um_callerid: unable to allocate usermode slot for +G; unloading module.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
construct_umodebuf();
|
||||
|
||||
add_isupport("CALLERID", isupport_umode, "g");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
um_callerid_moddeinit(void)
|
||||
{
|
||||
user_modes['g'] = 0;
|
||||
user_modes['G'] = 0;
|
||||
construct_umodebuf();
|
||||
|
||||
delete_isupport("CALLERID");
|
||||
}
|
||||
|
||||
#define IsSetStrictCallerID(c) ((c->umodes & user_modes['g']) == user_modes['g'])
|
||||
#define IsSetRelaxedCallerID(c) ((c->umodes & user_modes['G']) == user_modes['G'])
|
||||
#define IsSetAnyCallerID(c) (IsSetStrictCallerID(c) || IsSetRelaxedCallerID(c))
|
||||
#define IsSetTalkThroughCallerID(c) ((c->umodes & user_modes['M']) == user_modes['M'])
|
||||
|
||||
static const char um_callerid_desc[] =
|
||||
"Provides usermodes +g and +G which restrict messages from unauthorized users.";
|
||||
|
||||
|
||||
struct CallerIDOverrideSession {
|
||||
rb_dlink_node node;
|
||||
|
||||
struct Client *client;
|
||||
time_t deadline;
|
||||
};
|
||||
|
||||
static rb_dlink_list callerid_overriding_opers = { NULL, NULL, 0 };
|
||||
struct ev_entry *expire_callerid_override_deadlines_ev = NULL;
|
||||
|
||||
static void
|
||||
update_session_deadline(struct Client *source_p)
|
||||
{
|
||||
struct CallerIDOverrideSession *session_p = NULL;
|
||||
rb_dlink_node *n;
|
||||
|
||||
RB_DLINK_FOREACH(n, callerid_overriding_opers.head)
|
||||
{
|
||||
struct CallerIDOverrideSession *s = n->data;
|
||||
|
||||
if (s->client == source_p)
|
||||
{
|
||||
session_p = s;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (session_p != NULL)
|
||||
{
|
||||
rb_dlinkDelete(&session_p->node, &callerid_overriding_opers);
|
||||
}
|
||||
else
|
||||
{
|
||||
session_p = rb_malloc(sizeof(struct CallerIDOverrideSession));
|
||||
session_p->client = source_p;
|
||||
}
|
||||
|
||||
session_p->deadline = rb_current_time() + 1800;
|
||||
|
||||
rb_dlinkAddTail(session_p, &session_p->node, &callerid_overriding_opers);
|
||||
}
|
||||
|
||||
static void
|
||||
expire_callerid_override_deadlines(void *unused)
|
||||
{
|
||||
rb_dlink_node *n, *tn;
|
||||
|
||||
RB_DLINK_FOREACH_SAFE(n, tn, callerid_overriding_opers.head)
|
||||
{
|
||||
struct CallerIDOverrideSession *session_p = n->data;
|
||||
|
||||
if (session_p->deadline >= rb_current_time())
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *parv[4] = {session_p->client->name, session_p->client->name, "-M", NULL};
|
||||
user_mode(session_p->client, session_p->client, 3, parv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
allow_message(struct Client *source_p, struct Client *target_p)
|
||||
{
|
||||
|
@ -105,7 +134,7 @@ allow_message(struct Client *source_p, struct Client *target_p)
|
|||
return true;
|
||||
|
||||
/* XXX: controversial? allow opers to send through +g */
|
||||
if (MayHavePrivilege(source_p, "oper:message"))
|
||||
if (IsSetTalkThroughCallerID(source_p) || MayHavePrivilege(source_p, "oper:always_message"))
|
||||
return true;
|
||||
|
||||
if (accept_message(source_p, target_p))
|
||||
|
@ -227,11 +256,156 @@ h_hdl_privmsg_user(void *vdata)
|
|||
data->approved = ERR_TARGUMODEG;
|
||||
}
|
||||
|
||||
static void
|
||||
check_umode_change(void *vdata)
|
||||
{
|
||||
hook_data_umode_changed *data = (hook_data_umode_changed *)vdata;
|
||||
bool changed = false;
|
||||
struct Client *source_p = data->client;
|
||||
|
||||
if (!MyClient(source_p))
|
||||
return;
|
||||
|
||||
if (data->oldumodes & UMODE_OPER && !IsOper(source_p))
|
||||
source_p->umodes &= ~user_modes['M'];
|
||||
|
||||
changed = ((data->oldumodes ^ source_p->umodes) & user_modes['M']);
|
||||
|
||||
if (changed && source_p->umodes & user_modes['M'])
|
||||
{
|
||||
if (!HasPrivilege(source_p, "oper:message"))
|
||||
{
|
||||
sendto_one_notice(source_p, ":*** You need oper:message privilege for +M");
|
||||
source_p->umodes &= ~user_modes['M'];
|
||||
return;
|
||||
}
|
||||
|
||||
update_session_deadline(source_p);
|
||||
}
|
||||
else if (changed)
|
||||
{
|
||||
// Unsetting +M; remove the timeout session
|
||||
rb_dlink_node *n, *tn;
|
||||
|
||||
RB_DLINK_FOREACH_SAFE(n, tn, callerid_overriding_opers.head)
|
||||
{
|
||||
struct CallerIDOverrideSession *session_p = n->data;
|
||||
|
||||
if (session_p->client != source_p)
|
||||
continue;
|
||||
|
||||
rb_dlinkDelete(n, &callerid_overriding_opers);
|
||||
rb_free(session_p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void check_priv_change(void *vdata)
|
||||
{
|
||||
hook_data_priv_change *data = (hook_data_priv_change*)vdata;
|
||||
struct Client *source_p = data->client;
|
||||
const char *fakeparv[4];
|
||||
|
||||
if (!MyClient(source_p))
|
||||
return;
|
||||
|
||||
if (source_p->umodes & user_modes['M'] && !HasPrivilege(source_p, "oper:message"))
|
||||
{
|
||||
sendto_one_notice(source_p, ":*** You need oper:message privilege for +M");
|
||||
fakeparv[0] = fakeparv[1] = source_p->name;
|
||||
fakeparv[2] = "-M";
|
||||
fakeparv[3] = NULL;
|
||||
user_mode(source_p, source_p, 3, fakeparv);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
handle_client_exit(void *vdata)
|
||||
{
|
||||
hook_data_client_exit *data = (hook_data_client_exit *) vdata;
|
||||
rb_dlink_node *n, *tn;
|
||||
struct Client *source_p = data->target;
|
||||
|
||||
RB_DLINK_FOREACH_SAFE(n, tn, callerid_overriding_opers.head)
|
||||
{
|
||||
struct CallerIDOverrideSession *session_p = n->data;
|
||||
|
||||
if (session_p->client != source_p)
|
||||
continue;
|
||||
|
||||
rb_dlinkDelete(n, &callerid_overriding_opers);
|
||||
rb_free(session_p);
|
||||
}
|
||||
}
|
||||
|
||||
static mapi_hfn_list_av1 um_callerid_hfnlist[] = {
|
||||
{ "umode_changed", check_umode_change },
|
||||
{ "priv_change", check_priv_change },
|
||||
{ "invite", h_hdl_invite },
|
||||
{ "privmsg_user", h_hdl_privmsg_user },
|
||||
{ "client_exit", handle_client_exit },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static int
|
||||
um_callerid_modinit(void)
|
||||
{
|
||||
rb_dlink_node *ptr;
|
||||
|
||||
user_modes['g'] = find_umode_slot();
|
||||
if (!user_modes['g'])
|
||||
{
|
||||
ierror("um_callerid: unable to allocate usermode slot for +g; unloading module.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
user_modes['G'] = find_umode_slot();
|
||||
if (!user_modes['G'])
|
||||
{
|
||||
user_modes['g'] = 0;
|
||||
|
||||
ierror("um_callerid: unable to allocate usermode slot for +G; unloading module.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
user_modes['M'] = find_umode_slot();
|
||||
if (!user_modes['M'])
|
||||
{
|
||||
user_modes['g'] = 0;
|
||||
user_modes['G'] = 0;
|
||||
|
||||
ierror("um_callerid: unable to allocate usermode slot for +M; unloading module.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
construct_umodebuf();
|
||||
|
||||
add_isupport("CALLERID", isupport_umode, "g");
|
||||
|
||||
RB_DLINK_FOREACH(ptr, lclient_list.head)
|
||||
{
|
||||
struct Client *client_p = ptr->data;
|
||||
if (IsPerson(client_p) && (client_p->umodes & user_modes['M']))
|
||||
update_session_deadline(client_p);
|
||||
}
|
||||
|
||||
expire_callerid_override_deadlines_ev = rb_event_add("expire_callerid_override_deadlines", expire_callerid_override_deadlines, NULL, 60);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
um_callerid_moddeinit(void)
|
||||
{
|
||||
user_modes['g'] = 0;
|
||||
user_modes['G'] = 0;
|
||||
user_modes['M'] = 0;
|
||||
construct_umodebuf();
|
||||
|
||||
delete_isupport("CALLERID");
|
||||
|
||||
rb_event_delete(expire_callerid_override_deadlines_ev);
|
||||
}
|
||||
|
||||
DECLARE_MODULE_AV2(um_callerid, um_callerid_modinit, um_callerid_moddeinit,
|
||||
NULL, NULL, um_callerid_hfnlist, NULL, NULL, um_callerid_desc);
|
||||
|
|
36
tests/misc.c
36
tests/misc.c
|
@ -42,11 +42,47 @@ static void valid_temp_time1(void)
|
|||
is_int(52 * WEEK, t, MSG);
|
||||
}
|
||||
|
||||
static void valid_temp_time_invalid(void)
|
||||
{
|
||||
time_t t;
|
||||
t = valid_temp_time("-2w");
|
||||
is_int(-1, t, MSG);
|
||||
|
||||
t = valid_temp_time("hello");
|
||||
is_int(-1, t, MSG);
|
||||
|
||||
t = valid_temp_time("m");
|
||||
is_int(-1, t, MSG);
|
||||
|
||||
t = valid_temp_time("1w-1w");
|
||||
is_int(-1, t, MSG);
|
||||
}
|
||||
|
||||
static void valid_temp_time_overflow(void)
|
||||
{
|
||||
char s[100];
|
||||
time_t t;
|
||||
|
||||
snprintf(s, sizeof s, "%" PRIuMAX "m", UINTMAX_MAX / 60 + 2);
|
||||
t = valid_temp_time(s);
|
||||
is_int(52 * WEEK, t, MSG);
|
||||
|
||||
snprintf(s, sizeof s, "%ldm", LONG_MAX / 60 + 2);
|
||||
t = valid_temp_time(s);
|
||||
is_int(52 * WEEK, t, MSG);
|
||||
|
||||
snprintf(s, sizeof s, "%ldm%ldm", LONG_MAX / 60 - 1, LONG_MAX / 60 - 1);
|
||||
t = valid_temp_time(s);
|
||||
is_int(52 * WEEK, t, MSG);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
plan_lazy();
|
||||
|
||||
valid_temp_time1();
|
||||
valid_temp_time_invalid();
|
||||
valid_temp_time_overflow();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue