/* * ircd-ratbox: A slightly useful ircd. * kdparse.c: Parses K and D lines. * * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center * Copyright (C) 1996-2002 Hybrid Development Team * Copyright (C) 2002-2005 ircd-ratbox development team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * * $Id: kdparse.c 254 2005-09-21 23:35:12Z nenolod $ */ #include "stdinc.h" #include "logger.h" #include "s_conf.h" #include "s_newconf.h" #include "hostmask.h" #include "client.h" #include "match.h" #include "hash.h" /* conf_add_fields() * * inputs - pointer to config item, host/pass/user/operreason/date fields * output - NONE * side effects - update respective fields with pointers */ static void conf_add_fields(struct ConfItem *aconf, const char *host_field, const char *pass_field, const char *user_field, const char *operreason_field, const char *date_field) { if(host_field != NULL) aconf->host = rb_strdup(host_field); if(pass_field != NULL) { if(!EmptyString(date_field)) { aconf->passwd = rb_malloc(strlen(pass_field) + strlen(date_field) + 4); rb_sprintf(aconf->passwd, "%s (%s)", pass_field, date_field); } else aconf->passwd = rb_strdup(pass_field); } if(user_field != NULL) aconf->user = rb_strdup(user_field); if(operreason_field != NULL) aconf->spasswd = rb_strdup(operreason_field); } /* * parse_k_file * Inputs - pointer to line to parse * Output - NONE * Side Effects - Parse one new style K line */ void parse_k_file(FILE * file) { struct ConfItem *aconf; char *user_field = NULL; char *reason_field = NULL; char *operreason_field = NULL; char *host_field = NULL; char *date_field = NULL; char line[BUFSIZE]; char *p; while (fgets(line, sizeof(line), file)) { if((p = strchr(line, '\n')) != NULL) *p = '\0'; if((*line == '\0') || (*line == '#')) continue; user_field = getfield(line); if(EmptyString(user_field)) continue; host_field = getfield(NULL); if(EmptyString(host_field)) continue; reason_field = getfield(NULL); if(EmptyString(reason_field)) continue; operreason_field = getfield(NULL); date_field = getfield(NULL); aconf = make_conf(); aconf->status = CONF_KILL; conf_add_fields(aconf, host_field, reason_field, user_field, operreason_field, date_field); if(aconf->host != NULL) add_conf_by_address(aconf->host, CONF_KILL, aconf->user, NULL, aconf); } } /* * parse_d_file * Inputs - pointer to line to parse * Output - NONE * Side Effects - Parse one new style D line */ void parse_d_file(FILE * file) { struct ConfItem *aconf; char *reason_field = NULL; char *host_field = NULL; char *operreason_field = NULL; char *date_field = NULL; char line[BUFSIZE]; char *p; while (fgets(line, sizeof(line), file)) { if((p = strchr(line, '\n'))) *p = '\0'; if((*line == '\0') || (line[0] == '#')) continue; host_field = getfield(line); if(EmptyString(host_field)) continue; reason_field = getfield(NULL); if(EmptyString(reason_field)) continue; operreason_field = getfield(NULL); date_field = getfield(NULL); aconf = make_conf(); aconf->status = CONF_DLINE; conf_add_fields(aconf, host_field, reason_field, "", operreason_field, date_field); conf_add_d_conf(aconf); } } char * xline_encode_spaces(const char *mask) { int i, j; int spaces = 0; int backslash = 0; char *encoded; for (i = 0; mask[i] != '\0'; i++) if (mask[i] == ' ') spaces++; encoded = rb_malloc(i + spaces + 1); for (i = 0, j = 0; mask[i] != '\0'; i++) { if (mask[i] == '\\') backslash = !backslash; else if (mask[i] == ' ') { if (!backslash) encoded[j++] = '\\'; encoded[j++] = 's'; backslash = 0; continue; } else backslash = 0; encoded[j++] = mask[i]; } return encoded; } void parse_x_file(FILE * file) { struct ConfItem *aconf; char *gecos_field = NULL; char *reason_field = NULL; char line[BUFSIZE]; char *p; char *encoded; while (fgets(line, sizeof(line), file)) { if((p = strchr(line, '\n'))) *p = '\0'; if((*line == '\0') || (line[0] == '#')) continue; gecos_field = getfield(line); if(EmptyString(gecos_field)) continue; /* field for xline types, which no longer exist */ getfield(NULL); reason_field = getfield(NULL); if(EmptyString(reason_field)) continue; /* sanity checking */ if((find_xline_mask(gecos_field) != NULL) || (strchr(reason_field, ':') != NULL)) continue; encoded = xline_encode_spaces(gecos_field); if (find_xline_mask(encoded) != NULL) { rb_free(encoded); continue; } aconf = make_conf(); aconf->status = CONF_XLINE; aconf->name = encoded; aconf->passwd = rb_strdup(reason_field); rb_dlinkAddAlloc(aconf, &xline_conf_list); } } void parse_resv_file(FILE * file) { struct ConfItem *aconf; char *reason_field; char *host_field; char line[BUFSIZE]; char *p; while (fgets(line, sizeof(line), file)) { if((p = strchr(line, '\n'))) *p = '\0'; if((*line == '\0') || (line[0] == '#')) continue; host_field = getfield(line); if(EmptyString(host_field)) continue; reason_field = getfield(NULL); if(EmptyString(reason_field)) continue; if(IsChannelName(host_field)) { if(hash_find_resv(host_field)) continue; aconf = make_conf(); aconf->status = CONF_RESV_CHANNEL; aconf->port = 0; aconf->name = rb_strdup(host_field); aconf->passwd = rb_strdup(reason_field); add_to_resv_hash(aconf->name, aconf); } else if(clean_resv_nick(host_field)) { if(find_nick_resv_mask(host_field)) continue; aconf = make_conf(); aconf->status = CONF_RESV_NICK; aconf->port = 0; aconf->name = rb_strdup(host_field); aconf->passwd = rb_strdup(reason_field); rb_dlinkAddAlloc(aconf, &resv_conf_list); } } } /* * getfield * * inputs - input buffer * output - next field * side effects - field breakup for ircd.conf file. */ char * getfield(char *newline) { static char *line = NULL; char *end, *field; if(newline != NULL) line = newline; if(line == NULL) return (NULL); field = line; /* XXX make this skip to first " if present */ if(*field == '"') field++; else return (NULL); /* mal-formed field */ end = strchr(line, ','); while(1) { /* no trailing , - last field */ if(end == NULL) { end = line + strlen(line); line = NULL; if(*end == '"') { *end = '\0'; return field; } else return NULL; } else { /* look for a ", to mark the end of a field.. */ if(*(end - 1) == '"') { line = end + 1; end--; *end = '\0'; return field; } /* search for the next ',' */ end++; end = strchr(end, ','); } } return NULL; }