Cleanup and simplify get_reason() and related functions
Rename randreason() to fread_random() to better reflect its function, and change it to a one-pass algorithm. Have it write into a caller-provided buffer instead of a static buffer. Fixes a file leak when an empty file is given to this function. Change freadln() so that it never returns an empty line - it only returns 0 at end-of-file now. This simplifies its callers. Factor out some common code from the several get_reason()-type functions, which greatly simplifies them.
This commit is contained in:
@@ -130,8 +130,7 @@ ChannelList * BX_prepare_command (int *, char *, int);
|
|||||||
void set_nslookupfd(fd_set *);
|
void set_nslookupfd(fd_set *);
|
||||||
long print_nslookup(fd_set *);
|
long print_nslookup(fd_set *);
|
||||||
void auto_nslookup();
|
void auto_nslookup();
|
||||||
int freadln(FILE *, char *);
|
int freadln(FILE *, char *, size_t);
|
||||||
|
|
||||||
|
|
||||||
void BX_close_socketread(int);
|
void BX_close_socketread(int);
|
||||||
int BX_add_socketread(int, int, unsigned long, char *, void (*func_read)(int), void (*func_write)(int));
|
int BX_add_socketread(int, int, unsigned long, char *, void (*func_read)(int), void (*func_write)(int));
|
||||||
|
|||||||
@@ -4012,10 +4012,10 @@ FILE *f;
|
|||||||
{
|
{
|
||||||
char *hst = NULL;
|
char *hst = NULL;
|
||||||
buffer = alloca(sb.st_size+1);
|
buffer = alloca(sb.st_size+1);
|
||||||
freadln(f, buffer);
|
freadln(f, buffer, sb.st_size + 1);
|
||||||
while(!feof(f))
|
while(!feof(f))
|
||||||
{
|
{
|
||||||
if ((freadln(f, buffer)))
|
if ((freadln(f, buffer, sb.st_size + 1)))
|
||||||
{
|
{
|
||||||
if (*buffer == '#')
|
if (*buffer == '#')
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
118
source/misc.c
118
source/misc.c
@@ -1734,99 +1734,89 @@ void error_not_opped(const char *channel)
|
|||||||
reset_display_target();
|
reset_display_target();
|
||||||
}
|
}
|
||||||
|
|
||||||
int freadln(FILE *stream, char *lin)
|
/* Reads a single non-empty line from a file. Ignores lines beginning with # */
|
||||||
|
int freadln(FILE *stream, char *lin, size_t len)
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
do
|
do
|
||||||
p = fgets(lin, IRCD_BUFFER_SIZE/4, stream);
|
p = fgets(lin, len, stream);
|
||||||
while (p && (*lin == '#'));
|
while (p && (*lin == '#' || *lin == '\n'));
|
||||||
|
|
||||||
if (!p)
|
if (!p)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
chop(lin, 1);
|
chop(lin, 1);
|
||||||
if (!*lin)
|
|
||||||
return 0;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *randreason(char *filename)
|
/* Open a file and read a random non-empty, non-comment line from it. */
|
||||||
|
static char *fread_random(const char *filename, char *line, size_t len)
|
||||||
{
|
{
|
||||||
int count, min, i;
|
int count = 0;
|
||||||
FILE *bleah;
|
int i = 0;
|
||||||
char *f = NULL;
|
FILE *reason_file;
|
||||||
static char buffer[IRCD_BUFFER_SIZE/4 + 1];
|
char *f = m_strdup(filename);
|
||||||
|
char buffer[2][IRCD_BUFFER_SIZE];
|
||||||
|
|
||||||
min = 1;
|
/* This is an algorithm that lets us choose an evenly-distributed
|
||||||
count = 0;
|
* random line with one pass through the file. At line N, we replace
|
||||||
|
* the previously chosen line with this line, with probability 1/N.
|
||||||
|
*/
|
||||||
|
if ((reason_file = uzfopen(&f, get_string_var(LOAD_PATH_VAR), 0)))
|
||||||
|
{
|
||||||
|
while (freadln(reason_file, buffer[i], sizeof buffer[i]))
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
if (getrandom(0, count - 1) == 0)
|
||||||
|
i = !i;
|
||||||
|
}
|
||||||
|
fclose(reason_file);
|
||||||
|
}
|
||||||
|
|
||||||
buffer[0] = '\0';
|
|
||||||
f = m_strdup(filename);
|
|
||||||
if (filename && (bleah = uzfopen(&f, get_string_var(LOAD_PATH_VAR), 0)))
|
|
||||||
{
|
|
||||||
while (!feof(bleah))
|
|
||||||
if (freadln(bleah, buffer))
|
|
||||||
count++;
|
|
||||||
if (!count)
|
|
||||||
{
|
|
||||||
strcpy(buffer, "No Reason");
|
|
||||||
new_free(&f);
|
new_free(&f);
|
||||||
return buffer;
|
|
||||||
|
if (count > 0)
|
||||||
|
{
|
||||||
|
strlcpy(line, buffer[!i], len);
|
||||||
|
return line;
|
||||||
}
|
}
|
||||||
i = getrandom(1, count);
|
|
||||||
count = 0;
|
|
||||||
fclose(bleah);
|
|
||||||
bleah = uzfopen(&f, get_string_var(LOAD_PATH_VAR), 0);
|
|
||||||
while (!feof(bleah) && (count < i))
|
|
||||||
if (freadln(bleah, buffer))
|
|
||||||
count++;
|
|
||||||
fclose(bleah);
|
|
||||||
}
|
|
||||||
new_free(&f);
|
|
||||||
if (*buffer)
|
|
||||||
return buffer;
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Read a random text format from a file, convert it and strip it. A default
|
||||||
|
format is supplied if a format cannot be read from the file.
|
||||||
|
arg0 and arg1 replace $0 and $1 in the format. */
|
||||||
|
static char *random_text(const char *filename, const char *arg0,
|
||||||
|
const char *arg1, const char *default_format)
|
||||||
|
{
|
||||||
|
char line[IRCD_BUFFER_SIZE];
|
||||||
|
const char *format = fread_random(filename, line, sizeof line);
|
||||||
|
|
||||||
|
if (!format)
|
||||||
|
format = default_format;
|
||||||
|
|
||||||
|
return stripansicodes(convert_output_format(format, "%s %s", arg0, arg1));
|
||||||
|
}
|
||||||
|
|
||||||
char *get_reason(char *nick, char *file)
|
char *get_reason(char *nick, char *file)
|
||||||
{
|
{
|
||||||
char *temp;
|
char *filename = file;
|
||||||
char *filename = NULL;
|
|
||||||
if (file && *file)
|
if (!file || !*file)
|
||||||
malloc_strcpy(&filename, file);
|
filename = DEFAULT_BITCHX_KICK_FILE;
|
||||||
else
|
|
||||||
malloc_sprintf(&filename, "%s", DEFAULT_BITCHX_KICK_FILE);
|
return random_text(filename, nick ? nick : "error", get_server_nickname(from_server), get_string_var(DEFAULT_REASON_VAR));
|
||||||
temp = randreason(filename);
|
|
||||||
new_free(&filename);
|
|
||||||
if ((!temp || !*temp) && get_string_var(DEFAULT_REASON_VAR))
|
|
||||||
temp = get_string_var(DEFAULT_REASON_VAR);
|
|
||||||
return (stripansicodes(convert_output_format(temp, "%s %s", nick? nick: "error", get_server_nickname(from_server) )));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char *get_realname(char *nick)
|
char *get_realname(char *nick)
|
||||||
{
|
{
|
||||||
char *temp;
|
return random_text(DEFAULT_BITCHX_IRCNAME_FILE, nick, nick, "Who cares?");
|
||||||
char *filename = NULL;
|
|
||||||
|
|
||||||
malloc_sprintf(&filename, "%s", DEFAULT_BITCHX_IRCNAME_FILE);
|
|
||||||
temp = randreason(filename);
|
|
||||||
new_free(&filename);
|
|
||||||
if ((!temp || !*temp))
|
|
||||||
temp = "Who cares?";
|
|
||||||
return (stripansicodes(convert_output_format(temp, "%s %s", nick? nick: "error", get_server_nickname(from_server) )));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char *get_signoffreason(char *nick)
|
char *get_signoffreason(char *nick)
|
||||||
{
|
{
|
||||||
char *temp;
|
return random_text(DEFAULT_BITCHX_QUIT_FILE, nick, nick, "$0 has no reason");
|
||||||
char *filename = NULL;
|
|
||||||
|
|
||||||
malloc_sprintf(&filename, "%s", DEFAULT_BITCHX_QUIT_FILE);
|
|
||||||
temp = randreason(filename);
|
|
||||||
new_free(&filename);
|
|
||||||
if (!temp || !*temp)
|
|
||||||
temp = "$0 has no reason";
|
|
||||||
return (stripansicodes(convert_output_format(temp, "%s %s", nick? nick: "error", get_server_nickname(from_server))));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WANT_NSLOOKUP
|
#ifdef WANT_NSLOOKUP
|
||||||
|
|||||||
Reference in New Issue
Block a user