diff --git a/auth.c b/auth.c index c3598f3..65d6ff3 100644 --- a/auth.c +++ b/auth.c @@ -19,6 +19,7 @@ #include #include +#include #include #include "usg.h" diff --git a/dynstuff.c b/dynstuff.c index 52ea61c..60da37d 100644 --- a/dynstuff.c +++ b/dynstuff.c @@ -1,7 +1,8 @@ /* $Id$ */ /* - * (C) Copyright 2001-2002 Wojtek Kaniewski + * (C) Copyright 2001-2003 Wojtek Kaniewski + * Dawid Jarosz * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License Version 2 as @@ -181,111 +182,121 @@ int list_destroy(struct list *list, int free_data) } /* - * string_append_c() + * string_realloc() * - * dodaje do danego ciągu jeden znak, alokując przy tym odpowiednią ilość - * pamięci. + * upewnia się, że w stringu będzie wystarczająco dużo miejsca. * - * - s - wskaźnik do `struct string', - * - c - znaczek do dopisania. + * - s - ciąg znaków, + * - count - wymagana ilość znaków (bez końcowego '\0'). */ -int string_append_c(struct string *s, char c) +static void string_realloc(string_t s, int count) { - char *new; + char *tmp; + + if (s->str && (count + 1) <= s->size) + return; + + tmp = xrealloc(s->str, count + 81); + if (!s->str) + *tmp = 0; + tmp[count + 80] = 0; + s->size = count + 81; + s->str = tmp; +} + +string_t string_init(const char *value) { + string_t tmp = xmalloc(sizeof(struct string)); + size_t valuelen; + + if (!value) + value = ""; + + valuelen = strlen(value); + + tmp->str = xstrdup(value); + tmp->len = valuelen; + tmp->size = valuelen + 1; + + return tmp; +} +int string_append_c(string_t s, char c) +{ if (!s) { errno = EFAULT; return -1; } - if (!s->str || strlen(s->str) + 2 > s->size) { - new = xrealloc(s->str, s->size + 80); - if (!s->str) - *new = 0; - s->size += 80; - s->str = new; - } + string_realloc(s, s->len + 1); - s->str[strlen(s->str) + 1] = 0; - s->str[strlen(s->str)] = c; + s->str[s->len + 1] = 0; + s->str[s->len++] = c; return 0; } -/* - * string_append_n() - * - * dodaje tekst do bufora alokując odpowiednią ilość pamięci. - * - * - s - wskaźnik `struct string', - * - str - tekst do dopisania, - * - count - ile znaków tego tekstu dopisać? (-1 znaczy, że cały). - */ -int string_append_n(struct string *s, const char *str, int count) +int string_append_n(string_t s, const char *str, int count) { - char *new; - - if (!s) { + if (!s || !str || count < 0) { errno = EFAULT; return -1; } - if (count == -1) - count = strlen(str); + string_realloc(s, s->len + count); - if (!s->str || strlen(s->str) + count + 1 > s->size) { - new = xrealloc(s->str, s->size + count + 80); - if (!s->str) - *new = 0; - s->size += count + 80; - s->str = new; - } + s->str[s->len + count] = 0; + strncpy(s->str + s->len, str, count); - s->str[strlen(s->str) + count] = 0; - strncpy(s->str + strlen(s->str), str, count); + s->len += count; return 0; } -int string_append(struct string *s, const char *str) +int string_append_raw(string_t s, const char *str, int count) { - return string_append_n(s, str, -1); + if (!s || !str || count < 0) { + errno = EFAULT; + return -1; + } + + string_realloc(s, s->len + count); + + s->str[s->len + count] = 0; + memcpy(s->str + s->len, str, count); + + s->len += count; + + return 0; } -/* - * string_init() - * - * inicjuje strukturę string. alokuje pamięć i przypisuje pierwszą wartość. - * - * - value - jeśli NULL, ciąg jest pusty, inaczej kopiuje tam. - * - * zwraca zaalokowaną strukturę `string'. - */ -struct string *string_init(const char *value) +int string_append(string_t s, const char *str) { - struct string *tmp = xmalloc(sizeof(struct string)); + if (!s || !str) { + errno = EFAULT; + return -1; + } - if (!value) - value = ""; + return string_append_n(s, str, strlen(str)); +} - tmp->str = xstrdup(value); - tmp->size = strlen(value) + 1; +void string_remove(string_t s, int count) +{ + if (!s || count <= 0) + return; + + if (count >= s->len) { + /* string_clear() */ + s->str[0] = '\0'; + s->len = 0; - return tmp; + } else { + memmove(s->str, s->str + count, s->len - count); + s->len -= count; + s->str[s->len] = '\0'; + } } -/* - * string_free() - * - * zwalnia pamięć po strukturze string i może też zwolnić pamięć po samym - * ciągu znaków. - * - * - s - struktura, którą wycinamy, - * - free_string - zwolnić pamięć po ciągu znaków? - * - * jeśli free_string=0 zwraca wskaźnik do ciągu, inaczej NULL. - */ -char *string_free(struct string *s, int free_string) +char *string_free(string_t s, int free_string) { char *tmp = NULL; @@ -293,11 +304,11 @@ char *string_free(struct string *s, int free_string) return NULL; if (free_string) - free(s->str); + xfree(s->str); else tmp = s->str; - free(s); + xfree(s); return tmp; } diff --git a/dynstuff.h b/dynstuff.h index 59f572e..b0ef8e2 100644 --- a/dynstuff.h +++ b/dynstuff.h @@ -38,15 +38,18 @@ int list_destroy(struct list *list, int free_data); struct string { char *str; - int size; + int len, size; }; + typedef struct string * string_t; struct string *string_init(const char *str); int string_append(struct string *s, const char *str); int string_append_n(struct string *s, const char *str, int count); int string_append_c(struct string *s, char ch); +int string_append_raw(string_t s, const char *str, int count); +void string_remove(string_t s, int count); char *string_free(struct string *s, int free_string); /* tablice stringów */ diff --git a/usg.c b/usg.c index ef913d9..0c7819d 100644 --- a/usg.c +++ b/usg.c @@ -40,10 +40,7 @@ int obuf_len = 0, ibuf_len = 0, ufds_len = 0; /* wysyła dane do danego klienta */ void write_client(client_t *c, void *buf, int len) { - c->obuf = xrealloc(c->obuf, c->obuf_len + len); - memcpy(c->obuf + c->obuf_len, buf, len); - c->obuf_len += len; - obuf_len += len; + string_append_raw(c->obuf, (char *) buf, len); } /* wysyła dane do wszystkich, którzy mają go w userliście */ @@ -179,6 +176,8 @@ void remove_client(client_t *c) shutdown(c->fd, 2); close(c->fd); + string_free(c->ibuf, 1); + string_free(c->obuf, 1); list_remove(&clients, c, 1); } @@ -451,6 +450,8 @@ int handle_connection(client_t *c) h.type = GG_WELCOME; h.length = sizeof(w); n.seed = w.key = random(); + n.ibuf = string_init(NULL); + n.obuf = string_init(NULL); write_client(&n, &h, sizeof(h)); write_client(&n, &w, sizeof(w)); @@ -471,12 +472,8 @@ int handle_input(client_t *c) res = read(c->fd, buf, sizeof(buf)); printf("read: fd=%d, res=%d\n", c->fd, res); - if (res > 0) { - c->ibuf = xrealloc(c->ibuf, c->ibuf_len + res); - memcpy(c->ibuf + c->ibuf_len, buf, res); - c->ibuf_len += res; - ibuf_len += res; - } + if (res > 0) + string_append_raw(c->ibuf, buf, res); if (res == -1) { if (errno == EAGAIN) @@ -499,9 +496,9 @@ int handle_input(client_t *c) first = 0; } - printf(" ibuf_len = %d\n", c->ibuf_len); + printf(" ibuf->len = %d\n", c->ibuf->len); - while (c->ibuf_len >= 8) { + while (c->ibuf->len >= 8) { struct gg_header *h = (struct gg_header*) c->ibuf; if (h->length < 0 || h->length > 2500) { @@ -509,20 +506,12 @@ int handle_input(client_t *c) return 1; } - if (c->ibuf_len >= 8 + h->length) { + if (c->ibuf->len >= 8 + h->length) { handle_input_packet(c); - if (c->ibuf_len == 8 + h->length) { - xfree(c->ibuf); - c->ibuf_len = 0; - c->ibuf = NULL; - ibuf_len -= c->ibuf_len; - } else { - memmove(c->ibuf, c->ibuf + 8 + h->length, c->ibuf_len - 8 - h->length); - c->ibuf_len -= (8 + h->length); - ibuf_len -= (8 + h->length); - } - } + string_remove(c->ibuf, 8 + h->length); + } else + break; /* czekaj na wiecej danych.. */ } return 0; @@ -533,29 +522,20 @@ int handle_output(client_t *c) { int res; - if (!c->obuf_len) + if (!c->obuf->len) return 0; - res = write(c->fd, c->obuf, c->obuf_len); + res = write(c->fd, c->obuf->str, c->obuf->len); if (res < 1) { printf("write failed. removing client fd=%d\n", c->fd); remove_client(c); return 1; } - - if (res >= c->obuf_len) { - xfree(c->obuf); - c->obuf = NULL; - c->obuf_len = 0; - } else { - memmove(c->obuf, c->obuf + res, c->obuf_len - res); - c->obuf = xrealloc(c->obuf, c->obuf_len - res); - c->obuf_len -= res; - } - obuf_len -= res; - if (!c->obuf_len && c->remove) { + string_remove(c->obuf, res); + + if (!c->obuf->len && c->remove) { c->status = GG_STATUS_NOT_AVAIL; remove_client(c); return 1; @@ -626,7 +606,7 @@ int main(int argc, char **argv) ufds[i].fd = c->fd; ufds[i].events = POLLIN | POLLERR | POLLHUP; - if (c->obuf_len) + if (c->obuf->len) ufds[i].events |= POLLOUT; printf("poll: ufds[%d].fd = %d, ufds[%d].events = 0x%.2x\n", i, c->fd, i, ufds[i].events); } diff --git a/usg.h b/usg.h index f0522fd..ee5c32b 100644 --- a/usg.h +++ b/usg.h @@ -16,10 +16,8 @@ typedef struct { int seed; /* seed */ int status; /* stan klienta */ char *status_descr; /* opis stanu */ - char *ibuf; /* bufor wejściowy */ - int ibuf_len; - char *obuf; /* bufor wyjściowy */ - int obuf_len; + string_t ibuf; /* bufor wejściowy */ + string_t obuf; /* bufor wyjściowy */ unsigned long ip; /* adres */ unsigned short port; /* port */ int version; /* wersja protokołu */