struct ConnectionClass *c_class;
struct DenyConf *dconf;
struct ServerConf *sconf;
- struct qline *qconf = NULL;
struct s_map *smap;
struct Privs privs;
struct Privs privs_dirty;
%token <text> QSTRING
%token <num> NUMBER
-%token <text> FNAME
%token GENERAL
%token ADMIN
%token USERMODE
%token IAUTH
%token TIMEOUT
-/* and now a lot of priviledges... */
+%token FAST
+/* and now a lot of privileges... */
%token TPRIV_CHAN_LIMIT TPRIV_MODE_LCHAN TPRIV_DEOP_LCHAN TPRIV_WALK_LCHAN
%token TPRIV_LOCAL_KILL TPRIV_REHASH TPRIV_RESTART TPRIV_DIE
%token TPRIV_GLINE TPRIV_LOCAL_GLINE TPRIV_LOCAL_JUPE TPRIV_LOCAL_BADCHAN
%token TPRIV_LOCAL_OPMODE TPRIV_OPMODE TPRIV_SET TPRIV_WHOX TPRIV_BADCHAN
%token TPRIV_SEE_CHAN TPRIV_SHOW_INVIS TPRIV_SHOW_ALL_INVIS TPRIV_PROPAGATE
%token TPRIV_UNLIMIT_QUERY TPRIV_DISPLAY TPRIV_SEE_OPERS TPRIV_WIDE_GLINE
-%token TPRIV_FORCE_OPMODE TPRIV_FORCE_LOCAL_OPMODE
+%token TPRIV_FORCE_OPMODE TPRIV_FORCE_LOCAL_OPMODE TPRIV_APASS_OPMODE
/* and some types... */
%type <num> sizespec
%type <num> timespec timefactor factoredtimes factoredtime
}
;
-/* this is an arithmatic expression */
+/* this is an arithmetic expression */
expr: NUMBER
{
$$ = $1;
$$ = $1 / $3;
}
/* leave this out until we find why it makes BSD yacc dump core -larne
- | '-' expr %prec NEG
- = {
+ | '-' expr %prec NEG {
$$ = -$2;
} */
| '(' expr ')' {
jupenick: NICK '=' QSTRING
{
addNickJupes($3);
+ MyFree($3);
} ';';
generalblock: GENERAL '{' generalitems '}'
generalname: NAME '=' QSTRING ';'
{
if (localConf.name == NULL)
- DupString(localConf.name, $3);
- else if (strcmp(localConf.name, $3))
- parse_error("Redefinition of server name %s (%s)", $3,
- localConf.name);
+ localConf.name = $3;
+ else {
+ if (strcmp(localConf.name, $3))
+ parse_error("Redefinition of server name %s (%s)", $3,
+ localConf.name);
+ MyFree($3);
+ }
};
generaldesc: DESCRIPTION '=' QSTRING ';'
{
MyFree(localConf.description);
- DupString(localConf.description, $3);
+ localConf.description = $3;
ircd_strncpy(cli_info(&me), $3, REALLEN);
};
memcpy(&VirtualHost_v4.addr, &addr, sizeof(addr));
else
memcpy(&VirtualHost_v6.addr, &addr, sizeof(addr));
+ MyFree($3);
};
adminblock: ADMIN '{' adminitems '}'
adminitem: adminlocation | admincontact | error;
adminlocation: LOCATION '=' QSTRING ';'
{
- if (localConf.location1 == NULL)
- DupString(localConf.location1, $3);
- else if (localConf.location2 == NULL)
- DupString(localConf.location2, $3);
- /* Otherwise just drop it. -A1kmm */
+ if (localConf.location1 == NULL)
+ localConf.location1 = $3;
+ else if (localConf.location2 == NULL)
+ localConf.location2 = $3;
+ else /* Otherwise just drop it. -A1kmm */
+ MyFree($3);
};
admincontact: CONTACT '=' QSTRING ';'
{
- if (localConf.contact != NULL)
- MyFree(localConf.contact);
- DupString(localConf.contact, $3);
+ MyFree(localConf.contact);
+ localConf.contact = $3;
};
classblock: CLASS {
struct ConnectionClass *c_class;
add_class(name, tping, tconn, maxlinks, sendq);
c_class = find_class(name);
+ MyFree(c_class->default_umode);
c_class->default_umode = pass;
memcpy(&c_class->privs, &privs, sizeof(c_class->privs));
memcpy(&c_class->privs_dirty, &privs_dirty, sizeof(c_class->privs_dirty));
classname: NAME '=' QSTRING ';'
{
MyFree(name);
- DupString(name, $3);
+ name = $3;
};
classpingfreq: PINGFREQ '=' timespec ';'
{
classusermode: USERMODE '=' QSTRING ';'
{
MyFree(pass);
- DupString(pass, $3);
+ pass = $3;
};
connectblock: CONNECT
connectname: NAME '=' QSTRING ';'
{
MyFree(name);
- DupString(name, $3);
+ name = $3;
};
connectpass: PASS '=' QSTRING ';'
{
MyFree(pass);
- DupString(pass, $3);
+ pass = $3;
};
connectclass: CLASS '=' QSTRING ';'
{
c_class = find_class($3);
+ MyFree($3);
};
connecthost: HOST '=' QSTRING ';'
{
MyFree(host);
- DupString(host, $3);
+ host = $3;
};
connectport: PORT '=' NUMBER ';'
{
connectvhost: VHOST '=' QSTRING ';'
{
MyFree(origin);
- DupString(origin, $3);
+ origin = $3;
};
connectleaf: LEAF ';'
{
connecthublimit: HUB '=' QSTRING ';'
{
MyFree(hub_limit);
- DupString(hub_limit, $3);
+ hub_limit = $3;
};
connectmaxhops: MAXHOPS '=' expr ';'
{
maxlinks = $3;
};
-uworldblock: UWORLD '{' uworlditems '}' ';'
-{
- if (name)
- {
- struct ConfItem *aconf = make_conf(CONF_UWORLD);
- aconf->host = name;
- }
- else
- {
- MyFree(name);
- parse_error("Bad UWorld block");
- }
- name = NULL;
-};
+uworldblock: UWORLD '{' uworlditems '}' ';';
uworlditems: uworlditem uworlditems | uworlditem;
uworlditem: uworldname | error;
uworldname: NAME '=' QSTRING ';'
{
- MyFree(name);
- DupString(name, $3);
+ make_conf(CONF_UWORLD)->host = $3;
};
operblock: OPER '{' operitems '}' ';'
}
else
{
- log_write(LS_CONFIG, L_ERROR, 0, "operator blocks need a name, password, and host.");
+ parse_error("operator blocks need a name, password, class and host.");
MyFree(name);
MyFree(pass);
MyFree(host);
opername: NAME '=' QSTRING ';'
{
MyFree(name);
- DupString(name, $3);
+ name = $3;
};
operpass: PASS '=' QSTRING ';'
{
MyFree(pass);
- DupString(pass, $3);
+ pass = $3;
};
operhost: HOST '=' QSTRING ';'
{
if (!strchr($3, '@'))
{
int uh_len;
- char *b = (char*) MyMalloc((uh_len = strlen($3)+3));
- ircd_snprintf(0, b, uh_len, "*@%s", $3);
- host = b;
+ host = (char*) MyMalloc((uh_len = strlen($3)+3));
+ ircd_snprintf(0, host, uh_len, "*@%s", $3);
+ MyFree($3);
}
else
- DupString(host, $3);
+ host = $3;
};
operclass: CLASS '=' QSTRING ';'
{
c_class = find_class($3);
+ MyFree($3);
};
priv: privtype '=' yesorno ';'
TPRIV_SET { $$ = PRIV_SET; } |
TPRIV_WHOX { $$ = PRIV_WHOX; } |
TPRIV_BADCHAN { $$ = PRIV_BADCHAN; } |
- TPRIV_LOCAL_BADCHAN { $$ = TPRIV_LOCAL_BADCHAN; } |
+ TPRIV_LOCAL_BADCHAN { $$ = PRIV_LOCAL_BADCHAN; } |
TPRIV_SEE_CHAN { $$ = PRIV_SEE_CHAN; } |
TPRIV_SHOW_INVIS { $$ = PRIV_SHOW_INVIS; } |
TPRIV_SHOW_ALL_INVIS { $$ = PRIV_SHOW_ALL_INVIS; } |
TPRIV_WIDE_GLINE { $$ = PRIV_WIDE_GLINE; } |
LOCAL { $$ = PRIV_PROPAGATE; invert = 1; } |
TPRIV_FORCE_OPMODE { $$ = PRIV_FORCE_OPMODE; } |
- TPRIV_FORCE_LOCAL_OPMODE { $$ = PRIV_FORCE_LOCAL_OPMODE; };
+ TPRIV_FORCE_LOCAL_OPMODE { $$ = PRIV_FORCE_LOCAL_OPMODE; } |
+ TPRIV_APASS_OPMODE { $$ = PRIV_APASS_OPMODE; } ;
yesorno: YES { $$ = 1; } | NO { $$ = 0; };
portvhost: VHOST '=' QSTRING ';'
{
MyFree(host);
- DupString(host, $3);
+ host = $3;
};
portmask: MASK '=' QSTRING ';'
{
MyFree(pass);
- DupString(pass, $3);
+ pass = $3;
};
portserver: SERVER '=' YES ';'
}
'{' clientitems '}' ';'
{
- struct ConfItem *aconf = make_conf(CONF_CLIENT);
- unsigned char addrbits;
- aconf->username = username;
- aconf->host = host;
- if (ip && ipmask_parse(ip, &aconf->address.addr, &addrbits)) {
+ struct irc_in_addr addr;
+ unsigned char addrbits = 0;
+
+ if (ip && !ipmask_parse(ip, &addr, &addrbits)) {
+ parse_error("Invalid IP address in block");
+ MyFree(username);
+ MyFree(host);
+ MyFree(ip);
+ MyFree(pass);
+ } else {
+ struct ConfItem *aconf = make_conf(CONF_CLIENT);
+ aconf->username = username;
+ aconf->host = host;
+ if (ip)
+ memcpy(&aconf->address.addr, &addr, sizeof(aconf->address.addr));
+ else
+ memset(&aconf->address.addr, 0, sizeof(aconf->address.addr));
aconf->addrbits = addrbits;
aconf->name = ip;
- } else {
- MyFree(ip);
- aconf->addrbits = -1;
- DupString(aconf->name, "*");
+ aconf->conn_class = c_class ? c_class : find_class("default");
+ aconf->maximum = maxlinks;
+ aconf->passwd = pass;
}
- aconf->conn_class = c_class ? c_class : find_class("default");
- aconf->maximum = maxlinks;
host = NULL;
username = NULL;
c_class = NULL;
ip = NULL;
+ pass = NULL;
};
clientitems: clientitem clientitems | clientitem;
clientitem: clienthost | clientip | clientusername | clientclass | clientpass | clientmaxlinks | error;
if (sep) {
*sep++ = '\0';
MyFree(username);
- DupString(username, $3);
DupString(host, sep);
+ username = $3;
} else {
- DupString(host, $3);
+ host = $3;
}
};
clientip: IP '=' QSTRING ';'
{
- char *sep = strchr($3, '@');
+ char *sep;
+ sep = strchr($3, '@');
MyFree(ip);
if (sep) {
*sep++ = '\0';
MyFree(username);
- DupString(username, $3);
DupString(ip, sep);
+ username = $3;
} else {
- DupString(ip, $3);
+ ip = $3;
}
};
clientusername: USERNAME '=' QSTRING ';'
{
MyFree(username);
- DupString(username, $3);
+ username = $3;
};
clientclass: CLASS '=' QSTRING ';'
{
c_class = find_class($3);
+ MyFree($3);
};
clientpass: PASS '=' QSTRING ';'
{
MyFree(pass);
- DupString(pass, $3);
+ pass = $3;
};
clientmaxlinks: MAXLINKS '=' expr ';'
{
dconf = (struct DenyConf*) MyCalloc(1, sizeof(*dconf));
} '{' killitems '}'
{
- if (dconf->hostmask != NULL)
- {
- if (dconf->usermask == NULL)
- DupString(dconf->usermask, "*");
+ if (dconf->usermask || dconf->hostmask ||dconf->realmask) {
dconf->next = denyConfList;
denyConfList = dconf;
}
else
{
+ MyFree(dconf->usermask);
MyFree(dconf->hostmask);
+ MyFree(dconf->realmask);
MyFree(dconf->message);
MyFree(dconf);
parse_error("Bad kill block");
dconf = NULL;
} ';';
killitems: killitem killitems | killitem;
-killitem: killuhost | killreal | killreasonfile | killreason | error;
+killitem: killuhost | killreal | killusername | killreasonfile | killreason | error;
killuhost: HOST '=' QSTRING ';'
{
- char *u, *h;
- dconf->flags &= ~DENY_FLAGS_REALNAME;
+ char *h;
MyFree(dconf->hostmask);
MyFree(dconf->usermask);
if ((h = strchr($3, '@')) == NULL)
{
- u = "*";
- h = $3;
+ DupString(dconf->usermask, "*");
+ dconf->hostmask = $3;
}
else
{
- u = $3;
- h++;
+ *h++ = '\0';
+ DupString(dconf->hostmask, h);
+ dconf->usermask = $3;
}
- DupString(dconf->hostmask, h);
- DupString(dconf->usermask, u);
ipmask_parse(dconf->hostmask, &dconf->address, &dconf->bits);
};
+killusername: USERNAME '=' QSTRING ';'
+{
+ MyFree(dconf->usermask);
+ dconf->usermask = $3;
+};
+
killreal: REAL '=' QSTRING ';'
{
- dconf->flags &= ~DENY_FLAGS_IP;
- dconf->flags |= DENY_FLAGS_REALNAME;
- MyFree(dconf->hostmask);
- /* Leave usermask so you can specify user and real... */
- DupString(dconf->hostmask, $3);
+ MyFree(dconf->realmask);
+ dconf->realmask = $3;
};
killreason: REASON '=' QSTRING ';'
{
dconf->flags &= ~DENY_FLAGS_FILE;
MyFree(dconf->message);
- DupString(dconf->message, $3);
+ dconf->message = $3;
};
killreasonfile: TFILE '=' QSTRING ';'
{
dconf->flags |= DENY_FLAGS_FILE;
MyFree(dconf->message);
- DupString(dconf->message, $3);
+ dconf->message = $3;
};
cruleblock: CRULE
{
MyFree(host);
collapse($3);
- DupString(host, $3);
+ host = $3;
};
crulerule: RULE '=' QSTRING ';'
{
MyFree(pass);
- DupString(pass, $3);
+ pass = $3;
};
cruleall: ALL '=' YES ';'
motditem: motdhost | motdfile | error;
motdhost: HOST '=' QSTRING ';'
{
- DupString(host, $3);
+ host = $3;
};
motdfile: TFILE '=' QSTRING ';'
{
- DupString(pass, $3);
+ pass = $3;
};
featuresblock: FEATURES '{' featureitems '}' ';';
stringno = 2;
} posextrastrings
{
+ unsigned int ii;
feature_set(NULL, (const char * const *)stringlist, stringno);
+ for (ii = 0; ii < stringno; ++ii)
+ MyFree(stringlist[ii]);
};
posextrastrings: /* empty */ | extrastrings;
extrastrings: extrastrings extrastring | extrastring;
{
if (stringno < MAX_STRINGS)
stringlist[stringno++] = $1;
+ else
+ MyFree($1);
};
-quarantineblock: QUARANTINE '{'
+quarantineblock: QUARANTINE '{' quarantineitems '}' ';';
+quarantineitems: quarantineitems quarantineitem | quarantineitem;
+quarantineitem: QSTRING '=' QSTRING ';'
{
- qconf = (struct qline*) MyCalloc(1, sizeof(*qconf));
-} quarantineitems '}' ';'
-{
- if (qconf->chname == NULL || qconf->reason == NULL)
- {
- log_write(LS_CONFIG, L_ERROR, 0, "quarantine blocks need a channel name "
- "and a reason.");
- return 0;
- }
+ struct qline *qconf = MyCalloc(1, sizeof(*qconf));
+ qconf->chname = $1;
+ qconf->reason = $3;
qconf->next = GlobalQuarantineList;
GlobalQuarantineList = qconf;
- qconf = NULL;
-};
-
-quarantineitems: CHANNEL NAME '=' QSTRING ';'
-{
- DupString(qconf->chname, $4);
-} | REASON '=' QSTRING ';'
-{
- DupString(qconf->reason, $3);
};
pseudoblock: PSEUDO QSTRING '{'
{
smap = MyCalloc(1, sizeof(struct s_map));
- DupString(smap->command, $2);
+ smap->command = $2;
}
pseudoitems '}' ';'
{
if (!smap->name || !smap->services)
{
- log_write(LS_CONFIG, L_ERROR, 0, "pseudo commands need a service name and list of target nicks.");
+ parse_error("pseudo commands need a service name and list of target nicks.");
return 0;
}
if (register_mapping(smap))
};
pseudoitems: pseudoitem pseudoitems | pseudoitem;
-pseudoitem: pseudoname | pseudoprepend | pseudonick | error;
+pseudoitem: pseudoname | pseudoprepend | pseudonick | pseudoflags | error;
pseudoname: NAME '=' QSTRING ';'
{
- DupString(smap->name, $3);
+ MyFree(smap->name);
+ smap->name = $3;
};
pseudoprepend: PREPEND '=' QSTRING ';'
{
- DupString(smap->prepend, $3);
+ MyFree(smap->prepend);
+ smap->prepend = $3;
};
pseudonick: NICK '=' QSTRING ';'
{
nh->next = smap->services;
smap->services = nh;
}
+ MyFree($3);
+};
+pseudoflags: FAST ';'
+{
+ smap->flags |= SMAP_FAST;
};
iauthblock: IAUTH '{'
} iauthitems '}' ';'
{
if (!host || !port) {
- log_write(LS_CONFIG, L_ERROR, 0, "IAuth block needs a server name and port.");
+ parse_error("IAuth block needs a server name and port.");
return 0;
}
iauth_connect(host, port, pass, tconn, tping);
iauthpass: PASS '=' QSTRING ';'
{
MyFree(pass);
- DupString(pass, $3);
+ pass = $3;
};
iauthhost: HOST '=' QSTRING ';'
{
MyFree(host);
- DupString(host, $3);
+ host = $3;
};
iauthport: PORT '=' NUMBER ';'
{