2005-10-09 13:47:20 +02:00
|
|
|
/*
|
|
|
|
* $Id$
|
|
|
|
*
|
|
|
|
* This file is part of the bip project
|
2008-01-09 23:45:40 +01:00
|
|
|
* Copyright (C) 2004 2005 Arnaud Cornet and Loïc Gomez
|
2005-10-09 13:47:20 +02:00
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
* See the file "COPYING" for the exact licensing terms.
|
|
|
|
*/
|
|
|
|
|
2005-04-28 10:26:44 +02:00
|
|
|
#include "config.h"
|
|
|
|
#include "line.h"
|
|
|
|
|
|
|
|
void irc_line_init(struct line *l)
|
|
|
|
{
|
|
|
|
memset(l, 0, sizeof(struct line));
|
|
|
|
}
|
|
|
|
|
|
|
|
struct line *irc_line_new()
|
|
|
|
{
|
|
|
|
struct line *l;
|
2008-12-10 23:26:37 +01:00
|
|
|
l = bip_malloc(sizeof(struct line));
|
2005-04-28 10:26:44 +02:00
|
|
|
irc_line_init(l);
|
|
|
|
return l;
|
|
|
|
}
|
|
|
|
|
|
|
|
void irc_line_write(struct line *l, connection_t *c)
|
|
|
|
{
|
|
|
|
char *bytes = irc_line_to_string(l);
|
|
|
|
write_line(c, bytes);
|
|
|
|
free(bytes);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct line *irc_line_dup(struct line *line)
|
|
|
|
{
|
2008-12-15 19:19:27 +01:00
|
|
|
int i;
|
2005-04-28 10:26:44 +02:00
|
|
|
struct line *nl = irc_line_new();
|
2008-12-15 19:19:27 +01:00
|
|
|
nl->origin = line->origin ? bip_strdup(line->origin) : NULL;
|
2005-04-28 10:26:44 +02:00
|
|
|
nl->elemc = line->elemc;
|
2008-12-10 23:26:37 +01:00
|
|
|
nl->elemv = bip_malloc(sizeof(char *) * line->elemc);
|
2005-04-28 10:26:44 +02:00
|
|
|
for (i = 0; i < line->elemc; i++)
|
2008-12-15 19:19:27 +01:00
|
|
|
nl->elemv[i] = bip_strdup(line->elemv[i]);
|
2005-04-28 10:26:44 +02:00
|
|
|
nl->colon = line->colon;
|
|
|
|
return nl;
|
|
|
|
}
|
|
|
|
|
2008-12-15 19:19:27 +01:00
|
|
|
char *irc_line_pop(struct line *l)
|
|
|
|
{
|
|
|
|
char *ret;
|
|
|
|
|
|
|
|
if (irc_line_count(l) == 0)
|
|
|
|
return NULL;
|
|
|
|
ret = (char *)l->elemv[l->elemc - 1];
|
|
|
|
l->elemc--;
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void _irc_line_append(struct line *l, const char *s)
|
2005-04-28 10:26:44 +02:00
|
|
|
{
|
|
|
|
l->elemc++;
|
2008-12-11 11:00:05 +01:00
|
|
|
l->elemv = bip_realloc(l->elemv, l->elemc * sizeof(char *));
|
2008-12-15 19:19:27 +01:00
|
|
|
l->elemv[l->elemc - 1] = (char *)s;
|
2005-04-28 10:26:44 +02:00
|
|
|
}
|
|
|
|
|
2008-12-15 19:19:27 +01:00
|
|
|
void irc_line_append(struct line *l, const char *s)
|
2005-04-28 10:26:44 +02:00
|
|
|
{
|
2008-12-15 19:19:27 +01:00
|
|
|
_irc_line_append(l, bip_strdup(s));
|
2005-04-28 10:26:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
char *irc_line_to_string(struct line *l)
|
|
|
|
{
|
|
|
|
size_t len = 0;
|
2008-12-15 19:19:27 +01:00
|
|
|
int i;
|
2005-04-28 10:26:44 +02:00
|
|
|
char *ret;
|
|
|
|
|
|
|
|
if (l->origin)
|
|
|
|
len = strlen(l->origin) + 2;
|
|
|
|
for (i = 0; i < l->elemc; i++)
|
|
|
|
len += strlen(l->elemv[i]) + 1;
|
|
|
|
len += 1; /* remove one trailing space and add \r\n */
|
|
|
|
len++; /* last args ":" */
|
2008-12-10 23:26:37 +01:00
|
|
|
ret = bip_malloc(len + 1);
|
2005-04-28 10:26:44 +02:00
|
|
|
ret[0] = 0;
|
|
|
|
|
|
|
|
if (l->origin) {
|
|
|
|
strcat(ret, ":");
|
|
|
|
strcat(ret, l->origin);
|
|
|
|
strcat(ret, " ");
|
|
|
|
}
|
|
|
|
for (i = 0; i < l->elemc - 1; i++) {
|
|
|
|
strcat(ret, l->elemv[i]);
|
|
|
|
strcat(ret, " ");
|
|
|
|
}
|
|
|
|
if (strchr(l->elemv[i], ' ') || l->colon)
|
|
|
|
strcat(ret, ":");
|
|
|
|
|
|
|
|
strcat(ret, l->elemv[i]);
|
|
|
|
strcat(ret, "\r\n");
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2008-12-15 19:19:27 +01:00
|
|
|
int irc_line_count(struct line *line)
|
|
|
|
{
|
|
|
|
return line->elemc;
|
|
|
|
}
|
|
|
|
|
|
|
|
int irc_line_include(struct line *line, int elem)
|
|
|
|
{
|
|
|
|
if (elem < 0)
|
|
|
|
fatal("internal error: irc_line_elem got negative elem");
|
|
|
|
return elem < line->elemc;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *irc_line_elem(struct line *line, int elem)
|
|
|
|
{
|
|
|
|
if (!irc_line_include(line, elem))
|
|
|
|
fatal("internal error: irc_line_elem got too large elem");
|
|
|
|
return line->elemv[elem];
|
|
|
|
}
|
|
|
|
|
|
|
|
int irc_line_elem_equals(struct line *line, int elem, const char *cmp)
|
|
|
|
{
|
|
|
|
return !strcmp(irc_line_elem(line, elem), cmp);
|
|
|
|
}
|
|
|
|
|
|
|
|
int irc_line_elem_case_equals(struct line *line, int elem, const char *cmp)
|
|
|
|
{
|
|
|
|
return !strcasecmp(irc_line_elem(line, elem), cmp);
|
|
|
|
}
|
|
|
|
|
2005-04-28 10:26:44 +02:00
|
|
|
/*
|
|
|
|
* takes a null terminated string as input w/o \r\n
|
|
|
|
*/
|
|
|
|
struct line *irc_line(char *str)
|
|
|
|
{
|
|
|
|
struct line *line;
|
|
|
|
char *space;
|
|
|
|
size_t len;
|
|
|
|
int curelem = 0;
|
|
|
|
|
2008-12-11 11:00:05 +01:00
|
|
|
line = bip_calloc(sizeof(struct line), 1);
|
2005-04-28 10:26:44 +02:00
|
|
|
if (str[0] == ':') {
|
|
|
|
space = str + 1;
|
|
|
|
|
|
|
|
while (*space && *space != ' ')
|
|
|
|
space++;
|
|
|
|
if (!*space)
|
|
|
|
return NULL;
|
|
|
|
len = space - str - 1; /* leading ':' */
|
2008-12-10 23:26:37 +01:00
|
|
|
line->origin = bip_malloc(len + 1);
|
2005-04-28 10:26:44 +02:00
|
|
|
memcpy(line->origin, str + 1, len);
|
|
|
|
line->origin[len] = 0;
|
|
|
|
str = space;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (*str == ' ')
|
|
|
|
str++;
|
|
|
|
|
|
|
|
while (*str) {
|
|
|
|
char *tmp;
|
|
|
|
|
|
|
|
line->elemc++;
|
2008-12-11 11:00:05 +01:00
|
|
|
line->elemv = bip_realloc(line->elemv,
|
2005-04-28 10:26:44 +02:00
|
|
|
line->elemc * sizeof(char *));
|
|
|
|
|
|
|
|
space = str;
|
|
|
|
if (*space == ':') {
|
|
|
|
line->colon = 1;
|
|
|
|
str++;
|
|
|
|
while (*space)
|
|
|
|
space++;
|
|
|
|
} else {
|
|
|
|
while (*space && *space != ' ')
|
|
|
|
space++;
|
|
|
|
}
|
|
|
|
len = space - str;
|
2008-12-15 19:19:27 +01:00
|
|
|
tmp = bip_malloc(len + 1);
|
2005-04-28 10:26:44 +02:00
|
|
|
memcpy(tmp, str, len);
|
|
|
|
tmp[len] = 0;
|
|
|
|
if (curelem == 0)
|
2008-12-15 19:19:27 +01:00
|
|
|
strucase(tmp);
|
|
|
|
line->elemv[curelem] = (const char *)tmp;
|
2005-04-28 10:26:44 +02:00
|
|
|
|
|
|
|
curelem++;
|
|
|
|
|
|
|
|
str = space;
|
|
|
|
while (*str == ' ')
|
|
|
|
str++;
|
|
|
|
}
|
|
|
|
return line;
|
|
|
|
}
|
|
|
|
|
|
|
|
void irc_line_free(struct line *l)
|
|
|
|
{
|
2008-12-15 19:19:27 +01:00
|
|
|
int i;
|
|
|
|
|
2005-04-28 10:26:44 +02:00
|
|
|
for (i = 0; i < l->elemc; i++)
|
2008-12-15 19:19:27 +01:00
|
|
|
free((char *)l->elemv[i]);
|
2005-04-28 10:26:44 +02:00
|
|
|
free(l->elemv);
|
|
|
|
if (l->origin)
|
|
|
|
free(l->origin);
|
|
|
|
free(l);
|
|
|
|
}
|