summaryrefslogtreecommitdiff
path: root/src/csvlib.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/csvlib.c')
-rw-r--r--src/csvlib.c671
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);
-}