diff options
Diffstat (limited to 'src/csvlib.c')
-rw-r--r-- | src/csvlib.c | 671 |
1 files changed, 0 insertions, 671 deletions
diff --git a/src/csvlib.c b/src/csvlib.c deleted file mode 100644 index cb43243..0000000 --- a/src/csvlib.c +++ /dev/null @@ -1,671 +0,0 @@ -/* - * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). - * csvlib.c - set of functions to deal with csv type of conf files - * - * Copyright (C) 2003 by Diane Bruce, Stuart Walsh - * Use it anywhere you like, if you like it buy us a beer. - * If it's broken, don't bother us with the lawyers. - * - * $Id$ - */ - -#include "config.h" -#include "stdinc.h" -#include "list.h" -#include "log.h" -#include "conf.h" -#include "hostmask.h" -#include "client.h" -#include "irc_string.h" -#include "sprintf_irc.h" -#include "memory.h" -#include "send.h" -#include "resv.h" -#include "s_serv.h" - -/* Fix "statement not reached" warnings on Sun WorkShop C */ -#ifdef __SUNPRO_C -# pragma error_messages(off, E_STATEMENT_NOT_REACHED) -#endif - - -static void parse_csv_line(char *, ...); -static int write_csv_line(FILE *, const char *, ...); -static int flush_write(struct Client *, FILE *, FILE *, - const char *, const char *); -static char *getfield(char *); - -int -find_and_delete_temporary(const char *user, const char *host, int type) -{ - struct irc_ssaddr iphost, *piphost; - struct AccessItem *aconf; - int t; - - if ((t = parse_netmask(host, &iphost, NULL)) != HM_HOST) - { -#ifdef IPV6 - if (t == HM_IPV6) - t = AF_INET6; - else -#endif - t = AF_INET; - piphost = &iphost; - } - else - { - t = 0; - piphost = NULL; - } - - if ((aconf = find_conf_by_address(host, piphost, type, t, user, NULL, 0))) - { - if (IsConfTemporary(aconf)) - { - delete_one_address_conf(host, aconf); - return 1; - } - } - - return 0; -} - -/* parse_csv_file() - * - * inputs - FILE pointer - * - type of conf to parse - * output - none - * side effects - - */ -void -parse_csv_file(FILE *file, ConfType conf_type) -{ - struct ConfItem *conf; - struct AccessItem *aconf; - struct MatchItem *match_item; - char *name_field=NULL; - char *user_field=NULL; - char *reason_field=NULL; - char *oper_reason=NULL; - char *host_field=NULL; - char line[IRCD_BUFSIZE]; - char *p; - - while (fgets(line, sizeof(line), file) != NULL) - { - if ((p = strchr(line, '\n')) != NULL) - *p = '\0'; - - if ((line[0] == '\0') || (line[0] == '#')) - continue; - - switch(conf_type) - { - case KLINE_TYPE: - parse_csv_line(line, &user_field, &host_field, &reason_field, NULL); - - find_and_delete_temporary(user_field, host_field, CONF_KLINE); - - conf = make_conf_item(KLINE_TYPE); - aconf = map_to_conf(conf); - - if (host_field != NULL) - DupString(aconf->host, host_field); - if (reason_field != NULL) - DupString(aconf->reason, reason_field); - if (user_field != NULL) - DupString(aconf->user, user_field); - if (aconf->host != NULL) - add_conf_by_address(CONF_KLINE, aconf); - break; - case DLINE_TYPE: - parse_csv_line(line, &host_field, &reason_field, NULL); - - if (host_field && parse_netmask(host_field, NULL, NULL) != HM_HOST) - { - find_and_delete_temporary(NULL, host_field, CONF_DLINE); - - aconf = map_to_conf(make_conf_item(DLINE_TYPE)); - DupString(aconf->host, host_field); - - if (reason_field != NULL) - DupString(aconf->reason, reason_field); - else - DupString(aconf->reason, "No reason"); - add_conf_by_address(CONF_DLINE, aconf); - } - - break; - - case XLINE_TYPE: - parse_csv_line(line, &name_field, &reason_field, &oper_reason, NULL); - conf = make_conf_item(XLINE_TYPE); - match_item = (struct MatchItem *)map_to_conf(conf); - if (name_field != NULL) - DupString(conf->name, name_field); - if (reason_field != NULL) - DupString(match_item->reason, reason_field); - break; - case CRESV_TYPE: - parse_csv_line(line, &name_field, &reason_field, NULL); - (void)create_channel_resv(name_field, reason_field, 0); - break; - - case NRESV_TYPE: - parse_csv_line(line, &name_field, &reason_field, NULL); - (void)create_nick_resv(name_field, reason_field, 0); - break; - - case GLINE_TYPE: - case CONF_TYPE: - case OPER_TYPE: - case CLIENT_TYPE: - case SERVER_TYPE: - case CLUSTER_TYPE: - case HUB_TYPE: - case LEAF_TYPE: - case ULINE_TYPE: - case EXEMPTDLINE_TYPE: - case CLASS_TYPE: - default: - break; - } - } -} - -/* - * parse_csv_line() - * - * inputs - pointer to line to parse - * output - - * side effects - - */ - -static void -parse_csv_line(char *line, ...) -{ - va_list args; - char **dest; - char *field = NULL; - - va_start(args, line); - - for (; ;) - { - dest = va_arg(args, char **); - if ((dest == NULL) || ((field = getfield(field ? NULL : line)) == NULL)) - { - va_end(args); - return; - } - *dest = field; - } -} - -/* write_conf_line() - * - * inputs - pointer to struct AccessItem - * - string current_date (small date) - * - time_t cur_time - * output - NONE - * side effects - This function takes care of - * finding right conf file, writing - * the right lines to this file, - * notifying the oper that their kline/dline etc. is in place - * notifying the opers on the server about the k/d etc. line - * - * - Dianora - */ -void -write_conf_line(struct Client *source_p, struct ConfItem *conf, - const char *current_date, time_t cur_time) -{ - FILE *out; - const char *filename, *from, *to; - struct AccessItem *aconf; - struct MatchItem *xconf; - struct ResvChannel *cresv_p=NULL; - struct MatchItem *nresv_p=NULL; - ConfType type; - - type = conf->type; - filename = get_conf_name(type); - - if (!MyConnect(source_p) && IsCapable(source_p->from, CAP_TS6) && HasID(source_p)) - { - from = me.id; - to = source_p->id; - } - else - { - from = me.name; - to = source_p->name; - } - - if ((out = fopen(filename, "a")) == NULL) - { - sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE, - "*** Problem opening %s ", filename); - return; - } - - switch(type) - { - case KLINE_TYPE: - aconf = (struct AccessItem *)map_to_conf(conf); - sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE, - "%s added K-Line for [%s@%s] [%s]", - get_oper_name(source_p), - aconf->user, aconf->host, aconf->reason); - sendto_one(source_p, ":%s NOTICE %s :Added K-Line [%s@%s]", - from, to, aconf->user, aconf->host); - ilog(LOG_TYPE_KLINE, "%s added K-Line for [%s@%s] [%s]", - source_p->name, aconf->user, aconf->host, aconf->reason); - write_csv_line(out, "%s%s%s%s%s%s%d", - aconf->user, aconf->host, - aconf->reason, aconf->oper_reason, current_date, - get_oper_name(source_p), cur_time); - break; - case DLINE_TYPE: - aconf = (struct AccessItem *)map_to_conf(conf); - sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE, - "%s added D-Line for [%s] [%s]", - get_oper_name(source_p), aconf->host, aconf->reason); - sendto_one(source_p, ":%s NOTICE %s :Added D-Line [%s] to %s", - from, to, aconf->host, filename); - ilog(LOG_TYPE_DLINE, "%s added D-Line for [%s] [%s]", - get_oper_name(source_p), aconf->host, aconf->reason); - write_csv_line(out, "%s%s%s%s%s%d", - aconf->host, aconf->reason, aconf->oper_reason, - current_date, - get_oper_name(source_p), cur_time); - break; - - case XLINE_TYPE: - xconf = (struct MatchItem *)map_to_conf(conf); - sendto_realops_flags(UMODE_ALL, L_ALL, SEND_NOTICE, - "%s added X-Line for [%s] [%s]", - get_oper_name(source_p), conf->name, - xconf->reason); - sendto_one(source_p, - ":%s NOTICE %s :Added X-Line [%s] [%d] [%s] to %s", - from, to, conf->name, - xconf->action, xconf->reason, filename); - ilog(LOG_TYPE_IRCD, "%s added X-Line for [%s] [%s]", - get_oper_name(source_p), conf->name, xconf->reason); - write_csv_line(out, "%s%s%s%s%s%d", - conf->name, xconf->reason, xconf->oper_reason, - current_date, get_oper_name(source_p), cur_time); - break; - case CRESV_TYPE: - cresv_p = (struct ResvChannel *)map_to_conf(conf); - - write_csv_line(out, "%s%s", - cresv_p->name, cresv_p->reason); - break; - - case NRESV_TYPE: - nresv_p = (struct MatchItem *)map_to_conf(conf); - - write_csv_line(out, "%s%s", - conf->name, nresv_p->reason); - break; - - default: - fclose(out); - return; - } - - fclose(out); -} - -/* - * write_csv_line() - * - * inputs - pointer to FILE * - * - formatted string - * output - - * side effects - single line is written to csv conf file - */ -static int -write_csv_line(FILE *out, const char *format, ...) -{ - char c; - size_t bytes = 0; - va_list args; - char tmp[1024]; - char *str = tmp; - const char *null_string = ""; - - if (out == NULL) - return(0); - - va_start(args, format); - - while ((c = *format++)) - { - if (c == '%') - { - c = *format++; - if (c == 's') - { - const char *p1 = va_arg(args, const char *); - if (p1 == NULL) - p1 = null_string; - *str++ = '\"'; - ++bytes; - while (*p1 != '\0') - { - *str++ = *p1++; - ++bytes; - } - *str++ = '\"'; - *str++ = ','; - - bytes += 2; - continue; - } - if (c == 'c') - { - *str++ = '\"'; - ++bytes; - *str++ = (char) va_arg(args, int); - ++bytes; - *str++ = '\"'; - *str++ = ','; - - bytes += 2; - continue; - } - - if (c == 'd') - { - int v = va_arg(args, int); - char t[40]; - char *p=t; - - while (v > 10) - { - *p++ = (v % 10) + '0'; - v = v/10; - } - *p++ = (v % 10) + '0'; - - *str++ = '\"'; - ++bytes; - while (p != t) - { - *str++ = *--p; - ++bytes; - } - - *str++ = '\"'; - *str++ = ','; - bytes += 2; - continue; - } - if (c != '%') - { - int ret; - - format -= 2; - ret = vsprintf(str, format, args); - str += ret; - bytes += ret; - *str++ = ','; - - ++bytes; - break; - } - } - *str++ = c; - ++bytes; - } - - if (*(str-1) == ',') - { - *(str-1) = '\n'; - *str = '\0'; - } - else - { - *str++ = '\n'; - ++bytes; - *str = '\0'; - } - - va_end(args); - str = tmp; - fputs(str, out); - - return(bytes); -} - -/* - * getfield - * - * inputs - input buffer - * output - next field - * side effects - field breakup for ircd.conf file. - */ -static char * -getfield(char *newline) -{ - static char *line = NULL; - char *end, *field; - - if (newline != NULL) - line = newline; - - if (line == NULL) - return(NULL); - - field = line; - - /* skip everything that's not a starting quote */ - for(;;) - { - if (*field == '\0') - return(NULL); - else if (*field == '"') - break; - ++field; - } - - /* skip over the beginning " */ - end = ++field; - - for (;;) - { - /* At end of string, mark it as end and return */ - if ((*end == '\0') || (*end == '\n')) - { - line = NULL; - return(NULL); - } - else if (*end == '\\') /* found escape character ? */ - { - end++; - } - else if (*end == '"') /* found terminating " */ - { - *end++ = '\0'; - line = end; - return(field); - } - - end++; - } - - return (NULL); -} - -/* remove_conf_line() - * - * inputs - type of kline to remove - * - pointer to oper removing - * - pat1 pat2 patterns to match - * output - -1 if unsuccessful 0 if no change 1 if change - * side effects - - */ -int -remove_conf_line(ConfType type, struct Client *source_p, const char *pat1, const char *pat2) -{ - const char *filename; - FILE *in, *out; - int pairme=0; - char buf[IRCD_BUFSIZE], buff[IRCD_BUFSIZE], temppath[IRCD_BUFSIZE]; - char *found1; - char *found2; - int oldumask; - - filename = get_conf_name(type); - - if ((in = fopen(filename, "r")) == NULL) - { - sendto_one(source_p, ":%s NOTICE %s :Cannot open %s", me.name, - source_p->name, filename); - return -1; - } - - ircsprintf(temppath, "%s.tmp", filename); - oldumask = umask(0); - - if ((out = fopen(temppath, "w")) == NULL) - { - sendto_one(source_p, ":%s NOTICE %s :Cannot open %s", me.name, - source_p->name, temppath); - fclose(in); - umask(oldumask); - return -1; - } - - umask(oldumask); - oldumask = umask(0); - - while (fgets(buf, sizeof(buf), in) != NULL) - { - if ((*buf == '\0') || (*buf == '#')) - { - if (flush_write(source_p, in, out, buf, temppath) < 0) - return -1; - } - - /* Keep copy of original line, getfield trashes line as it goes */ - strlcpy(buff, buf, sizeof(buff)); - - if ((found1 = getfield(buff)) == NULL) - { - if (flush_write(source_p, in, out, buf, temppath) < 0) - return -1; - continue; - } - - if (pat2 != NULL) - { - if ((found2 = getfield(NULL)) == NULL) - { - if (flush_write(source_p, in, out, buf, temppath) < 0) - return -1; - continue; - } - - if (!irccmp(pat1, found1) && !irccmp(pat2, found2)) - { - pairme = 1; - continue; - } - else - { - if(flush_write(source_p, in, out, buf, temppath) < 0) - return -1; - continue; - } - } - else - { - if (!irccmp(pat1, found1)) - { - pairme = 1; - continue; - } - else - { - if(flush_write(source_p, in, out, buf, temppath) < 0) - return -1; - continue; - } - } - } - - fclose(in); - fclose(out); - -/* The result of the rename should be checked too... oh well */ -/* If there was an error on a write above, then its been reported - * and I am not going to trash the original kline /conf file - */ - - if (pairme == 0) - { - if(temppath != NULL) - (void)unlink(temppath); - return 0; - } - else - { - (void)rename(temppath, filename); - - /* XXX - * This is a very inefficient way of removing a kline/xline etc. - * This next function call forces a complete re-read of all conf - * files, instead of a re-read of the kline/dline etc. files modified - * But, consider how often an /quote unkline etc. is done compared - * to how often a /quote kline is done. Its not a biggie in - * the grand scheme of things. If it does become a biggie, - * we will rewrite it - Dianora - */ - - rehash(0); - return 1; - } -} - -/* - * flush_write() - * - * inputs - pointer to client structure of oper requesting unkline - * - in is the input file descriptor - * - out is the output file descriptor - * - buf is the buffer to write - * - ntowrite is the expected number of character to be written - * - temppath is the temporary file name to be written - * output - -1 for error on write - * - 0 for ok - * side effects - if successful, the buf is written to output file - * if a write failure happesn, and the file pointed to - * by temppath, if its non NULL, is removed. - * - * The idea here is, to be as robust as possible when writing to the - * kline file. - * - * -Dianora - */ -static int -flush_write(struct Client *source_p, FILE *in, FILE* out, - const char *buf, const char *temppath) -{ - int error_on_write = fputs(buf, out) < 0 ? (-1) : (0); - - if (error_on_write) - { - sendto_one(source_p,":%s NOTICE %s :Unable to write to %s aborting", - me.name, source_p->name, temppath); - if(temppath != NULL) - (void)unlink(temppath); - fclose(in); - fclose(out); - } - - return (error_on_write); -} |