+2007-03-17 Michael Poole <mdpoole@troilus.org>
+
+ * doc/example.conf (Operator): Update documentation to mention
+ more than one host entry is allowed.
+ (Motd): Likewise.
+
+ * ircd/ircd_parser.y (hosts): New file-scope variable.
+ (free_slist): New helper function.
+ (operblock): Iterate over hosts instead of using the single host.
+ (operhost): Prepend the mask to hosts.
+ (motdblock): Iterate over hosts instead of using the single host.
+ (motdhost): Prepend the mask to hosts.
+ (motdfile): Fix possible leak of "pass" string (the filename).
+
+ * ircd/s_conf.c (conf_parse_userhost): Stop freeing the host
+ string; operblock (the only caller) frees it now.
+
2007-03-17 Michael Poole <mdpoole@troilus.org>
* ircd/list.c (free_link): Only decrement the in-use count of
# file = "path/to/motd/file";
# };
#
+# More than one host = "mask"; entry may be present in one block; this
+# has the same effect as one Motd block for each host entry, but makes
+# it easier to update the messages's filename.
+#
# DPATH/net_com.motd contains a special MOTD where users are encouraged
# to register their domains and get their own client{} lines if they're in
# Europe, or move to US.UnderNet.org if they're in the USA.
# is not not passed along to other servers. On Undernet, this prevents
# them from using Uworld as well.
#
+# More than one host = "mask"; entry may be present in one block; this
+# has the same effect as one Operator block for each host entry, but
+# makes it easier to update operator nicks, passwords, classes, and
+# privileges.
+#
# Operator {
# host = "host/IP mask";
# name = "opername";
/* Now all the globals we need :/... */
int tping, tconn, maxlinks, sendq, port, invert, stringno, flags;
char *name, *pass, *host, *ip, *username, *origin, *hub_limit;
+ struct SLink *hosts;
char *stringlist[MAX_STRINGS];
struct ListenerFlags listen_flags;
struct ConnectionClass *c_class;
yyerror(error_buffer);
}
+static void free_slist(struct SLink **link) {
+ struct SLink *next;
+ while (*link != NULL) {
+ next = (*link)->next;
+ MyFree((*link)->value.cp);
+ free_link(*link);
+ *link = next;
+ }
+}
+
%}
%token <text> QSTRING
operblock: OPER '{' operitems '}' ';'
{
struct ConfItem *aconf = NULL;
+ struct SLink *link;
+
if (name == NULL)
parse_error("Missing name in operator block");
else if (pass == NULL)
parse_error("Missing password in operator block");
/* Do not check password length because it may be crypted. */
- else if (host == NULL)
- parse_error("Missing host in operator block");
+ else if (hosts == NULL)
+ parse_error("Missing host(s) in operator block");
else if (c_class == NULL)
parse_error("Invalid or missing class in operator block");
else if (!FlagHas(&privs_dirty, PRIV_PROPAGATE)
&& !FlagHas(&c_class->privs_dirty, PRIV_PROPAGATE))
parse_error("Operator block for %s and class %s have no LOCAL setting", name, c_class->cc_name);
- else {
+ else for (link = hosts; link != NULL; link = link->next) {
aconf = make_conf(CONF_OPERATOR);
- aconf->name = name;
- aconf->passwd = pass;
- conf_parse_userhost(aconf, host);
+ DupString(aconf->name, name);
+ DupString(aconf->passwd, pass);
+ conf_parse_userhost(aconf, link->value.cp);
aconf->conn_class = c_class;
memcpy(&aconf->privs, &privs, sizeof(aconf->privs));
memcpy(&aconf->privs_dirty, &privs_dirty, sizeof(aconf->privs_dirty));
}
- if (!aconf) {
- MyFree(name);
- MyFree(pass);
- MyFree(host);
- }
- name = pass = host = NULL;
+ MyFree(name);
+ MyFree(pass);
+ free_slist(&hosts);
+ name = pass = NULL;
c_class = NULL;
memset(&privs, 0, sizeof(privs));
memset(&privs_dirty, 0, sizeof(privs_dirty));
};
operhost: HOST '=' QSTRING ';'
{
- MyFree(host);
+ struct SLink *link;
+ link = make_link();
if (!strchr($3, '@'))
{
int uh_len;
- host = (char*) MyMalloc((uh_len = strlen($3)+3));
- ircd_snprintf(0, host, uh_len, "*@%s", $3);
- MyFree($3);
+ link->value.cp = (char*) MyMalloc((uh_len = strlen($3)+3));
+ ircd_snprintf(0, link->value.cp, uh_len, "*@%s", $3);
}
else
- host = $3;
+ DupString(link->value.cp, $3);
+ MyFree($3);
+ link->next = hosts;
+ hosts = link;
};
operclass: CLASS '=' QSTRING ';'
{
motdblock: MOTD '{' motditems '}' ';'
{
- if (host != NULL && pass != NULL)
- motd_add(host, pass);
- MyFree(host);
+ struct SLink *link;
+ if (pass != NULL)
+ for (link = hosts; link != NULL; link = link->next)
+ motd_add(link->value.cp, pass);
+ free_slist(&hosts);
MyFree(pass);
- host = pass = NULL;
+ pass = NULL;
};
motditems: motditem motditems | motditem;
motditem: motdhost | motdfile;
motdhost: HOST '=' QSTRING ';'
{
- host = $3;
+ struct SLink *link;
+ link = make_link();
+ link->value.cp = $3;
+ link->next = hosts;
+ hosts = link;
};
motdfile: TFILE '=' QSTRING ';'
{
+ MyFree(pass);
pass = $3;
};