#include "s_debug.h"
#include "s_misc.h"
#include "send.h"
-#include "sprintf_irc.h"
#include "struct.h"
#include "support.h"
#include "sys.h"
#define INADDR_NONE 0xffffffff
#endif
-struct ConfItem* GlobalConfList = 0;
+struct ConfItem *GlobalConfList = 0;
int GlobalConfCount = 0;
+struct s_map *GlobalServiceMapList = 0;
+struct qline *GlobalQuarantineList = 0;
-static struct LocalConf localConf;
-static struct CRuleConf* cruleConfList;
-static struct ServerConf* serverConfList;
-static struct DenyConf* denyConfList;
+void yyparse(void);
+int conf_fd, lineno;
+
+struct LocalConf localConf;
+struct CRuleConf* cruleConfList;
+/* struct ServerConf* serverConfList; */
+struct DenyConf* denyConfList;
/*
* output the reason for being k lined from a file - Mmmm
* a non-null pointer, otherwise hp will be null.
* if successful save hp in the conf item it was called with
*/
-static void conf_dns_callback(void* vptr, struct DNSReply* reply)
+static void conf_dns_callback(void* vptr, struct hostent* hp)
{
struct ConfItem* aconf = (struct ConfItem*) vptr;
+ assert(aconf);
aconf->dns_pending = 0;
- if (reply)
- memcpy(&aconf->ipnum, reply->hp->h_addr, sizeof(struct in_addr));
+ if (hp) {
+ memcpy(&aconf->ipnum, hp->h_addr, sizeof(struct in_addr));
+ MyFree(hp);
+ }
}
/*
* if the conf entry is currently doing a ns lookup do nothing, otherwise
* if the lookup returns a null pointer, set the conf dns_pending flag
*/
-static struct DNSReply* conf_dns_lookup(struct ConfItem* aconf)
+static void conf_dns_lookup(struct ConfItem* aconf)
{
- struct DNSReply* dns_reply = 0;
if (!aconf->dns_pending) {
char buf[HOSTLEN + 1];
struct DNSQuery query;
host_from_uh(buf, aconf->host, HOSTLEN);
buf[HOSTLEN] = '\0';
- if (0 == (dns_reply = gethost_byname(buf, &query)))
- aconf->dns_pending = 1;
+ gethost_byname(buf, &query);
+ aconf->dns_pending = 1;
}
- return dns_reply;
}
* Do (start) DNS lookups of all hostnames in the conf line and convert
* an IP addresses in a.b.c.d number for to IP#s.
*/
-static void lookup_confhost(struct ConfItem *aconf)
+void
+lookup_confhost(struct ConfItem *aconf)
{
- struct DNSReply* reply;
-
if (EmptyString(aconf->host) || EmptyString(aconf->name)) {
Debug((DEBUG_ERROR, "Host/server name error: (%s) (%s)",
aconf->host, aconf->name));
aconf->host, aconf->name));
}
}
- else if ((reply = conf_dns_lookup(aconf)))
- memcpy(&aconf->ipnum, reply->hp->h_addr, sizeof(struct in_addr));
+ else
+ conf_dns_lookup(aconf);
}
/*
assert(0 != cptr);
if (cli_dns_reply(cptr))
- hp = cli_dns_reply(cptr)->hp;
+ hp = cli_dns_reply(cptr);
for (aconf = GlobalConfList; aconf; aconf = aconf->next) {
if (aconf->status != CONF_CLIENT)
uhost[sizeof(uhost) - 1] = 0;
if (0 == match(aconf->name, uhost)) {
if (strchr(uhost, '@'))
- cli_flags(cptr) |= FLAGS_DOID;
+ SetFlag(cptr, FLAG_DOID);
return check_limit_and_attach(cptr, aconf);
}
}
if (match(aconf->host, uhost))
continue;
if (strchr(uhost, '@'))
- cli_flags(cptr) |= FLAGS_DOID;
+ SetFlag(cptr, FLAG_DOID);
return check_limit_and_attach(cptr, aconf);
}
*
* - looks for a match on all given fields.
*/
+#if 0
static struct ConfItem *find_conf_entry(struct ConfItem *aconf,
unsigned int mask)
{
return bconf;
}
-
/*
* If conf line is a class definition, create a class entry
* for it and make the conf_line illegal and delete it.
cruleConfList = p;
}
}
+#endif
void conf_erase_crule_list(void)
{
return cruleConfList;
}
+#if 0
void conf_add_server(const char* const* fields, int count)
{
struct ServerConf* server;
else {
conf->bits = bits2;
}
- sprintf_irc(ipname, "%d.%d.%d.%d", ad[0], ad[1], ad[2], ad[3]);
+ ircd_snprintf(0, ipname, sizeof(ipname), "%d.%d.%d.%d", ad[0], ad[1],
+ ad[2], ad[3]);
/*
* This ensures endian correctness
conf->next = denyConfList;
denyConfList = conf;
}
+#endif
+
void conf_erase_deny_list(void)
{
return denyConfList;
}
+#if 0
+void conf_add_quarantine(const char *chname, const char *reason)
+{
+ struct qline *qline;
+
+ qline = (struct qline *) MyMalloc(sizeof(struct qline));
+ DupString(qline->chname, chname);
+ DupString(qline->reason, reason);
+ qline->next = GlobalQuarantineList;
+ GlobalQuarantineList = qline;
+}
+#endif
+
+const char*
+find_quarantine(const char *chname)
+{
+ struct qline *qline;
+
+ for (qline = GlobalQuarantineList; qline; qline = qline->next)
+ if (!ircd_strcmp(qline->chname, chname))
+ return qline->reason;
+ return NULL;
+}
+
+void clear_quarantines(void)
+{
+ struct qline *qline;
+ while ((qline = GlobalQuarantineList))
+ {
+ GlobalQuarantineList = qline->next;
+ MyFree(qline->reason);
+ MyFree(qline->chname);
+ MyFree(qline);
+ }
+}
+
+
/*
* read_configuration_file
*
#define MAXCONFLINKS 150
+static int conf_error;
+static int conf_already_read;
+extern FILE *yyin;
+void init_lexer(void);
+
int read_configuration_file(void)
{
- enum { MAX_FIELDS = 15 };
-
- char* src;
- char* dest;
- int quoted;
- FBFILE *file;
- char line[512];
- int ccount = 0;
- struct ConfItem *aconf = 0;
-
- int field_count = 0;
- const char* field_vector[MAX_FIELDS + 1];
-
- Debug((DEBUG_DEBUG, "read_configuration_file: ircd.conf = %s", configfile));
- if (0 == (file = fbopen(configfile, "r"))) {
- return 0;
- }
-
+ conf_error = 0;
feature_unmark(); /* unmark all features for resetting later */
-
- while (fbgets(line, sizeof(line) - 1, file)) {
- if ('#' == *line || IsSpace(*line))
- continue;
-
- if ((src = strchr(line, '\n')))
- *src = '\0';
-
- if (':' != line[1]) {
- Debug((DEBUG_ERROR, "Bad config line: %s", line));
- sendto_opmask_butone(0, SNO_OLDSNO,"Bad Config line");
- continue;
- }
-
- /*
- * do escapes, quoting, comments, and field breakup in place
- * in one pass with a poor mans state machine
- */
- field_vector[0] = line;
- field_count = 1;
- quoted = 0;
-
- for (src = line, dest = line; *src; ) {
- switch (*src) {
- case '\\':
- ++src;
- switch (*src) {
- case 'b':
- *dest++ = '\b';
- ++src;
- break;
- case 'f':
- *dest++ = '\f';
- ++src;
- break;
- case 'n':
- *dest++ = '\n';
- ++src;
- break;
- case 'r':
- *dest++ = '\r';
- ++src;
- break;
- case 't':
- *dest++ = '\t';
- ++src;
- break;
- case 'v':
- *dest++ = '\v';
- ++src;
- break;
- case '\\':
- *dest++ = '\\';
- ++src;
- break;
- case '\0':
- break;
- default:
- *dest++ = *src++;
- break;
- }
- break;
- case '"':
- if (quoted)
- quoted = 0;
- else
- quoted = 1;
- /*
- * strip quotes
- */
- ++src;
- break;
- case ':':
- if (quoted)
- *dest++ = *src++;
- else {
- *dest++ = '\0';
- field_vector[field_count++] = dest;
- if (field_count > MAX_FIELDS)
- *src = '\0';
- else
- ++src;
- }
- break;
- case '#':
- *src = '\0';
- break;
- default:
- *dest++ = *src++;
- break;
- }
- }
- *dest = '\0';
-
- if (field_count < 2 || EmptyString(field_vector[0]))
- continue;
-
- if (aconf)
- free_conf(aconf);
-
- aconf = make_conf();
-
- switch (*field_vector[0]) {
- case 'A': /* Name, e-mail address of administrator */
- case 'a': /* of this server. CONF_ADMIN */
- conf_add_admin(field_vector, field_count);
- aconf->status = CONF_ILLEGAL;
- break;
- case 'C': /* Server where I should try to connect */
- case 'c': /* in case of lp failures */
- ++ccount;
- aconf->status = CONF_SERVER;
- break;
- /* Connect rule */
- case 'D': /* CONF_CRULEALL */
- conf_add_crule(field_vector, field_count, CRULE_ALL);
- aconf->status = CONF_ILLEGAL;
- break;
- /* Connect rule - autos only */
- case 'd': /* CONF_CRULEAUTO */
- conf_add_crule(field_vector, field_count, CRULE_AUTO);
- aconf->status = CONF_ILLEGAL;
- break;
- case 'F': /* Feature line */
- case 'f':
- feature_set(0, &field_vector[1], field_count - 1);
- aconf->status = CONF_ILLEGAL;
- break;
- case 'H': /* Hub server line */
- case 'h':
- aconf->status = CONF_HUB;
- break;
- case 'I': /* Just plain normal irc client trying */
- case 'i': /* to connect me */
- aconf->status = CONF_CLIENT;
- break;
- case 'K': /* Kill user line on irc.conf */
- conf_add_deny(field_vector, field_count, 0);
- aconf->status = CONF_ILLEGAL;
- break;
- case 'k': /* Kill user line based on IP in ircd.conf */
- conf_add_deny(field_vector, field_count, 1);
- aconf->status = CONF_ILLEGAL;
- break;
- /* Operator. Line should contain at least */
- /* password and host where connection is */
- case 'L': /* guaranteed leaf server */
- case 'l':
- aconf->status = CONF_LEAF;
- break;
- /* Me. Host field is name used for this host */
- /* and port number is the number of the port */
- case 'M':
- case 'm': /* CONF_ME */
- conf_add_local(field_vector, field_count);
- aconf->status = CONF_ILLEGAL;
- break;
- case 'O':
- aconf->status = CONF_OPERATOR;
- break;
- /* Local Operator, (limited privs --SRB) */
- case 'o':
- aconf->status = CONF_LOCOP;
- break;
- case 'P': /* listen port line */
- case 'p': /* CONF_LISTEN_PORT */
- conf_add_listener(field_vector, field_count);
- aconf->status = CONF_ILLEGAL;
- break;
- case 'T': /* print out different motd's */
- case 't': /* based on hostmask - CONF_TLINES */
- motd_add(field_vector[1], field_vector[2]);
- aconf->status = CONF_ILLEGAL;
- break;
- case 'U': /* Underworld server, allowed to hack modes */
- case 'u': /* *Every* server on the net must define the same !!! */
- aconf->status = CONF_UWORLD;
- break;
- case 'Y':
- case 'y': /* CONF_CLASS */
- conf_add_class(field_vector, field_count);
- aconf->status = CONF_ILLEGAL;
- break;
- default:
- Debug((DEBUG_ERROR, "Error in config file: %s", line));
- sendto_opmask_butone(0, SNO_OLDSNO, "Unknown prefix in config file: %c",
- *field_vector[0]);
- aconf->status = CONF_ILLEGAL;
- break;
- }
- if (IsIllegal(aconf))
- continue;
-
- if (!EmptyString(field_vector[1]))
- DupString(aconf->host, field_vector[1]);
-
- if (!EmptyString(field_vector[2]))
- DupString(aconf->passwd, field_vector[2]);
-
- if (field_count > 3 && !EmptyString(field_vector[3]))
- DupString(aconf->name, field_vector[3]);
-
- if (field_count > 4 && !EmptyString(field_vector[4]))
- aconf->port = atoi(field_vector[4]);
-
- if (field_count > 5 && !EmptyString(field_vector[5]))
- aconf->conn_class = find_class(atoi(field_vector[5]));
-
- /*
- * Associate each conf line with a class by using a pointer
- * to the correct class record. -avalon
- */
- if (aconf->status & CONF_CLIENT_MASK) {
- if (aconf->conn_class == 0)
- aconf->conn_class = find_class(0);
- }
- if (aconf->status & CONF_CLIENT) {
- struct ConfItem *bconf;
-
- if ((bconf = find_conf_entry(aconf, aconf->status))) {
- delist_conf(bconf);
- bconf->status &= ~CONF_ILLEGAL;
- if (aconf->status == CONF_CLIENT) {
- /*
- * copy the password field in case it changed
- */
- MyFree(bconf->passwd);
- bconf->passwd = aconf->passwd;
- aconf->passwd = 0;
-
- ConfLinks(bconf) -= bconf->clients;
- bconf->conn_class = aconf->conn_class;
- if (bconf->conn_class)
- ConfLinks(bconf) += bconf->clients;
- }
- free_conf(aconf);
- aconf = bconf;
- }
- }
- if (aconf->status & CONF_SERVER) {
- if (ccount > MAXCONFLINKS || !aconf->host || strchr(aconf->host, '*') ||
- strchr(aconf->host, '?') || !aconf->name)
- continue;
- }
- if (aconf->status & (CONF_LOCOP | CONF_OPERATOR)) {
- if (!strchr(aconf->host, '@')) {
- char* newhost;
- int len = 3; /* *@\0 = 3 */
-
- len += strlen(aconf->host);
- newhost = (char*) MyMalloc(len);
- assert(0 != newhost);
- ircd_snprintf(0, newhost, len, "*@%s", aconf->host);
- MyFree(aconf->host);
- aconf->host = newhost;
- }
- }
- if (aconf->status & CONF_SERVER) {
- if (EmptyString(aconf->passwd))
- continue;
- lookup_confhost(aconf);
- }
- /*
- * Juped nicks are listed in the 'password' field of U:lines,
- * the list is comma separated and might be empty and/or contain
- * empty elements... the only limit is that it MUST be shorter
- * than 512 chars, or they will be cutted out :)
- */
- if ((aconf->status == CONF_UWORLD) && (aconf->passwd) && (*aconf->passwd))
- addNickJupes(aconf->passwd);
-
- collapse(aconf->host);
- collapse(aconf->name);
- Debug((DEBUG_NOTICE,
- "Read Init: (%d) (%s) (%s) (%s) (%u) (%p)",
- aconf->status, aconf->host, aconf->passwd,
- aconf->name, aconf->port, aconf->conn_class));
- aconf->next = GlobalConfList;
- GlobalConfList = aconf;
- aconf = NULL;
- }
- if (aconf)
- free_conf(aconf);
- fbclose(file);
-/* nextping = nextconnect = CurrentTime; */
+ /* Now just open an fd. The buffering isn't really needed... */
+ init_lexer();
+ yyparse();
+ fclose(yyin);
+ yyin = NULL;
feature_mark(); /* reset unmarked features */
+ conf_already_read = 1;
return 1;
}
+void
+yyerror(const char *msg)
+{
+ sendto_opmask_butone(0, SNO_ALL, "Config file parse error line %d: %s",
+ lineno, msg);
+ log_write(LS_CONFIG, L_ERROR, 0, "Config file parse error line %d: %s",
+ lineno, msg);
+ if (!conf_already_read)
+ fprintf(stderr, "Config file parse error line %d: %s\n", lineno, msg);
+ conf_error = 1;
+}
+
/*
* rehash
*
clearNickJupes();
if (sig != 2)
- flush_resolver_cache();
+ restart_resolver();
class_mark_delete();
mark_listeners_closing();
else
tmp = &tmp2->next;
}
+
for (i = 0; i <= HighestFd; i++) {
if ((acptr = LocalClientArray[i])) {
assert(!IsMe(acptr));
}
}
}
+
return ret;
}
*/
if (0 == localConf.name || 0 == localConf.numeric)
return 0;
+ if (conf_error)
+ return 0;
if (0 == localConf.location1)
DupString(localConf.location1, "");
DupString(localConf.location2, "");
if (0 == localConf.contact)
DupString(localConf.contact, "");
-
+
return 1;
}
return 0;
break;
if (deny->flags & DENY_FLAGS_REALNAME) { /* K: by real name */
- if (0 == match(deny->hostmask + 2, realname))
+ if (0 == match(deny->hostmask, realname))
break;
} else if (deny->flags & DENY_FLAGS_IP) { /* k: by IP */
Debug((DEBUG_DEBUG, "ip: %08x network: %08x/%i mask: %08x",
if (!c_conf) {
if (cli_dns_reply(cptr)) {
int i;
- struct hostent* hp = cli_dns_reply(cptr)->hp;
+ struct hostent* hp = cli_dns_reply(cptr);
const char* name = hp->h_name;
/*
* If we are missing a C or N line from above, search for
if (INADDR_NONE == c_conf->ipnum.s_addr)
c_conf->ipnum.s_addr = cli_ip(cptr).s_addr;
- Debug((DEBUG_DNS, "sv_cl: access ok: %s[%s]", cli_name(cptr), cli_sockhost(cptr)));
+ Debug((DEBUG_DNS, "sv_cl: access ok: %s[%s]",
+ cli_name(cptr), cli_sockhost(cptr)));
return 0;
}