- 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_op_mask(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 '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 */
- aconf->status = CONF_KILL;
- break;
- case 'k': /* Kill user line based on IP in ircd.conf */
- aconf->status = CONF_IPKILL;
- 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':
- aconf->status = CONF_ME;
- 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 */
- conf_add_motd(field_vector, field_count, &motdConfList);
- 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_op_mask(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])) {
- int n = atoi(field_vector[5]);
- if (CONF_ME == (aconf->status & CONF_ME))
- SetYXXServerName(&me, n); /* Our Numeric Nick */
- else
- aconf->confClass = find_class(n);
- }
- else if (CONF_ME == (aconf->status & CONF_ME)) {
- Debug((DEBUG_FATAL, "Your M: line must have the Numeric, "
- "assigned to you by routing-com!\n"));
- ircd_log(L_WARNING, "Your M: line must have the Numeric, "
- "assigned to you by routing-com!\n");
- exit(-1);
- }
- /*
- * 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->confClass == 0)
- aconf->confClass = 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->confClass = aconf->confClass;
- if (bconf->confClass)
- 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);
- }
- /*
- * Own port and name cannot be changed after the startup.
- * (or could be allowed, but only if all links are closed first).
- * Configuration info does not override the name and port
- * if previously defined. Note, that "info"-field can be
- * changed by "/rehash".
- */
- if (aconf->status == CONF_ME) {
- ircd_strncpy(me.info, aconf->name, REALLEN);
- }
-
- if (aconf->status == CONF_IPKILL) {
- /*
- * Here we use the same kludge as in listener.c to parse
- * a.b.c.d, or a.b.c.*, or a.b.c.d/e.
- */
- int class;
- char ipname[16];
- int ad[4] = { 0 };
- int bits2=0;
- class=sscanf(aconf->host,"%d.%d.%d.%d/%d",
- &ad[0], &ad[1], &ad[2], &ad[3], &bits2);
- if (class!=5) {
- aconf->bits=class*8;
- }
- else {
- aconf->bits=bits2;
- }
- sprintf_irc(ipname,"%d.%d.%d.%d",ad[0], ad[1], ad[2], ad[3]);
-
- /* This ensures endian correctness */
- aconf->ipnum.s_addr = inet_addr(ipname);
- Debug((DEBUG_DEBUG,"IPkill: %s = %08x/%i (%08x)",ipname,
- aconf->ipnum.s_addr,aconf->bits,NETMASK(aconf->bits)));
- }